diff options
Diffstat (limited to 'reproduce/software/shell/tarball-prepare.sh')
-rwxr-xr-x | reproduce/software/shell/tarball-prepare.sh | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/reproduce/software/shell/tarball-prepare.sh b/reproduce/software/shell/tarball-prepare.sh new file mode 100755 index 0000000..8e30931 --- /dev/null +++ b/reproduce/software/shell/tarball-prepare.sh @@ -0,0 +1,268 @@ +#!/bin/bash + +# Script to convert all files (tarballs in any format; just recognized +# by 'tar') within an 'odir' to a unified '.tar.lz' format. +# +# The inputs are assumed to be formatted with 'NAME_VERSION', and only for +# the names, we are currently assuming '.tar.*' (for the 'sed' +# command). Please modify/generalize accordingly. +# +# It will unpack the source in a certain empty directory with the +# 'tmpunpack' suffix, and rename the top directory to the requested format +# of NAME-VERSION also. So irrespective of the name of the top original +# tarball directory, the resulting tarball's top directory will have a name +# formatting of NAME-VERSION. +# +# Discussion: https://savannah.nongnu.org/task/?15699 +# +# Copyright (C) 2022-2025 Mohammad Akhlaghi <mohammad@akhlaghi.org> +# Copyright (C) 2022-2025 Pedram Ashofteh Ardakani <pedramardakani@pm.me> +# Copyright (C) 2025-2025 Giacomo Lorenzetti <glorenzetti@cefca.es> +# +# This script is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This script is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this script. If not, see <http://www.gnu.org/licenses/>. + + + + + +# Abort the script in case of an error. +set -e + + + + + +# Default arguments +odir= +idir= +quiet= +basedir=$PWD +scriptname=$0 + + +# The --help output +print_help() { + cat <<EOF +Usage: $scriptname [OPTIONS] + +Low-level script to create maneage-standard tarballs. + -o, --output-dir Target directory to write the packed tarballs. + Current: $odir + -i, --input-dir Directory containing original tarballs. + Current: $idir + -q, --quiet Suppress logging information. Only print the + final packed file and its sha512sum. +Maneage URL: https://maneage.org + +Report bugs: https://savannah.nongnu.org/bugs/?group=reproduce +EOF +} + + + + + +# Functions to check option values and complain if necessary. +on_off_option_error() { + if [ x"$2" = x ]; then + echo "$scriptname: '$1' doesn't take any values" + else + echo "$scriptname: '$1' (or '$2') doesn't take any values" + fi + exit 1 +} + +check_v() { + if [ x"$2" = x ]; then + cat <<EOF +$scriptname: option '$1' requires an argument. Try '$scriptname --help' for more information +EOF + exit 1; + fi +} + +option_given_and_valid() { + dirname="$1" + optionlong="$2" + optionshort="$3" + if [ x"$dirname" = x ]; then + cat <<EOF +$scriptname: no '--$optionlong' (or '-$optionshort') given: use this for identifying the directory containing the input tarballs +EOF + exit 1 + else + dirname=$(echo "$dirname" | sed 's|/$||'); # Remove possible trailing slash + if [ ! -d "$dirname" ]; then + cat <<EOF +$scriptname: '$dirname' that is given to '--$optionlong' (or '-$optionshort') couldn't be opened +EOF + exit 1 + else + outdir=$(realpath $dirname) + fi + fi + ogvout=$outdir +} + + + + + +# Parse the arguments +while [ $# -gt 0 ] +do + case $1 in + # Input and Output directories + -i|--input-dir) idir="$2"; check_v "$1" "$idir"; shift;shift;; + -i=*|--input-dir=*) idir="${1#*=}"; check_v "$1" "$idir"; shift;; + -i*) idir=$(echo "$1" | sed -e's/-i//'); check_v "$1" "$idir"; shift;; + -o|--output-dir) odir="$2"; check_v "$1" "$odir"; shift;shift;; + -o=*|--output-dir=*) odir="${1#*=}"; check_v "$1" "$odir"; shift;; + -o*) odir=$(echo "$1" | sed -e's/-o//'); check_v "$1" "$odir"; shift;; + + # Operating mode options + -?|--help) print_help; exit 0;; + -'?'*|--help=*) on_off_option_error --help -?;; + -q|--quiet) quiet=1; shift;; + -q*|--quiet=*) on_off_option_error --quiet -q;; + *) echo "$scriptname: unknown option '$1'"; exit 1;; + esac +done + + + + + +# Basic sanity checks +# +# Make sure the input and output directories are given. Also extract +# the absolute path to input and output directories and remove any +# possible trailing '/'. Working with a relative path is a great +# source of confusion and unwanted side-effects like moving/removing +# files by accident. +option_given_and_valid "$idir" "input-dir" "i" && idir=$ogvout +option_given_and_valid "$odir" "output-dir" "o" && odir=$ogvout + + + + + +# Unpack and pack all files in the '$idir' +# ---------------------------------------- +allfiles=$(ls $idir | sort) + +# Let user know number of tarballs if its not in quiet mode +if [ -z $quiet ]; then + nfiles=$(ls $idir | wc -l) + echo "Found $nfiles file(s) in '$idir/'" +fi + +# Process all files +for f in $allfiles; do + + # Extract the name and version (while replacing any possible '_' with + # '-' because some software separate name and version with '_'). + name=$(echo $(basename $f) \ + | sed -e 's/.tar.*//' -e's/_/-/') + + # Extract the software's name from the tarball name (needed later + # for software-specific checks). + sname=$(echo $name | sed -e's|-| |' | awk '{print $1}') + + # Lzip will not be available to unpack Lzip itself, so just use Tar. + if [[ $name =~ ^lzip ]]; then + outname=$name.tar + else + outname=$name.tar.lz + fi + + # Skip previously packed files + if [ -f $odir/$outname ]; then + + # Print the info message if not in quiet mode + if [ -z $quiet ]; then + echo "$scriptname: $odir/$outname: already present in output directory" + fi + + # skip this file + continue + else + + # Print the info message if not in quiet mode + if [ -z $quiet ]; then + echo "$scriptname: processing '$idir/$f'" + fi + fi + + # Create a temporary directory name + tmpdir=$odir/$name-tmpunpack + + # If the temporary directory exists, delete it and build an empty + # directory to work on (to avoid potential conflicts). + if [ -d $tmpdir ]; then rm -rf $tmpdir; fi + mkdir $tmpdir + + + + + + # Move into the temporary directory + # --------------------------------- + # + # The default output directory for all the following commands: $tmpdir + cd $tmpdir + + # Unpack + tar -xf $idir/$f + + # Make sure the unpacked tarball is contained within a directory with + # the clean program name + if [ ! -d "$name" ]; then + mv * $name/ + fi + + # Put the current date on all the files because some packagers will not + # add dates to their release tarballs, resulting in dates of the + # Unix-time zero'th second (1970-01-01 at 00:00:00)! + # -print0 is needed for those tarballs that has paths with spaces. For + # the same reason it's needed also `xargs -0`. (`xargs` is needed also + # for large tarballs such as gcc's) + find "$name"/ -type f -print0 | xargs -0 touch + + # Some software source files (like Boost; https://www.boost.io) + # have names that are too long for the more robust 'ustar' + # format. So for we should use 'pax' for them. + if [ $sname = boost ]; then tarformat=pax + else tarformat=ustar + fi + + # Pack with recommended options + tar -c -H$tarformat --owner=root --group=root \ + -f $name.tar $name/ + + # Lzip will not be available when unpacking Lzip, so we just use Tar. + if [[ ! $name =~ ^lzip ]]; then + lzip -9 $name.tar + fi + + # Move the compressed file from the temporary directory to the target + # output directory + mv $outname $odir/ + + # Print the sha512sum along with the filename for a quick reference + echo $(sha512sum $odir/$outname) + + # Clean up the temporary directory + rm -rf $tmpdir +done |