diff options
Diffstat (limited to 'src/librefetch/librefetch')
-rwxr-xr-x | src/librefetch/librefetch | 191 |
1 files changed, 128 insertions, 63 deletions
diff --git a/src/librefetch/librefetch b/src/librefetch/librefetch index 93bcd1e..8b02205 100755 --- a/src/librefetch/librefetch +++ b/src/librefetch/librefetch @@ -1,7 +1,9 @@ #!/usr/bin/env bash # librefetch # -# Copyright 2013 Luke Shumaker <lukeshu@sbcglobal.net> +# Copyright (C) 2013-2014 Luke Shumaker <lukeshu@sbcglobal.net> +# +# License: GNU GPLv3+ # # This file is part of Parabola. # @@ -18,17 +20,17 @@ # You should have received a copy of the GNU General Public License # along with Parabola. If not, see <http://www.gnu.org/licenses/>. -. $(librelib conf.sh) -. libremessages +. $(librelib conf) +. $(librelib messages) +setup_traps declare -r tempdir="$(mktemp -d --tmpdir ${0##*/}.XXXXXXXXXXX)" -cleanup() { rm -rf -- "$tempdir"; } -trap cleanup EXIT +trap "rm -rf -- $(printf '%q' "$tempdir")" EXIT cmd=${0##*/} usage() { print "Usage: %s [OPTIONS] SOURCE_URL [OUTPUT_FILE]" "$cmd" - print "Usage: %s -[g|P|V|h]" "$cmd" + print "Usage: %s -[g|S|M|h]" "$cmd" print "Downloads or creates a liberated source tarball." echo prose "The default mode is to create OUTPUT_FILE, first by trying @@ -37,9 +39,12 @@ usage() { prose "If OUTPUT_FILE isn't specified, it defaults to the non-directory part of SOURCE_URL, in the current directory." echo - prose "In download mode, the glob '*://' is stripped from the beginning - of SOURCE_URL, and the resulting path is attempted to be - downloaded from the configured mirror." + prose "Unless '-C' is specified, if SOURCE_URL does not begin with a + configured mirror, create mode is inhibited." + echo + prose "In download mode, it simply tries to download SOURCE_URL. At the + beginning of a URL, 'libre://' expands to the first configured + mirror." echo prose "In create mode, it looks at a build script, and uses that to create the source tarball. SOURCE_URL is ignored, except that it @@ -48,13 +53,14 @@ usage() { prose "The default build script is 'PKGBUILD', or 'SRCBUILD' if it exists." echo - prose "Unrecognized options are passed straight to makepkg." + prose "Other options, if they are valid \`makepkg\` options, are passed + straight to makepkg." echo prose "%s does NOT support getopt-style flag combining. You must use '-a -b', not '-ab'." "$cmd" echo print "Example usage:" - print ' $ %s libre://mypackage-1.0.tar.gz' "$cmd" + print ' $ %s https://repo.parabolagnulinux.org/other/mypackage/mypackage-1.0.tar.gz' "$cmd" echo print "Options:" print " Settings:" @@ -65,7 +71,8 @@ usage() { directory, it is used instead" print " Alternate modes:" flag "-g, --geninteg" "Generage integrity checks for source files" - flag "-P, --print" "Print the effective build script (SRCBUILD)" + flag "-S, --srcbuild" "Print the effective build script (SRCBUILD)" + flag "-M, --makepkg" "Print the effective makepkg script" flag "-h, --help" "Show this message" } @@ -74,13 +81,27 @@ main() { makepkg_opts=() extra_opts=() mode=download-create - parse_options "$@" + if ! parse_options "$@"; then + usage >&2 + exit 1 + fi # Mode: help ########################################################### if [[ $mode =~ help ]]; then usage - return 0 + exit 0 + fi + + ######################################################################## + + makepkg="$(modified_makepkg "$(which makepkg)")" + + # Mode: makepkg ######################################################## + + if [[ $mode =~ makepkg ]]; then + cat "$makepkg" + exit 0 fi ######################################################################## @@ -88,70 +109,76 @@ main() { local BUILDFILEDIR="${BUILDFILE%/*}" if [[ -f "${BUILDFILEDIR}/SRCBUILD" ]]; then BUILDFILE="${BUILDFILEDIR}/SRCBUILD" - srcbuild="$(modified_srcbuild "$BUILDFILE")" - else - srcbuild="$(modified_pkgbuild "$BUILDFILE")" fi - makepkg="$(modified_makepkg "$(which makepkg)")" + if [[ ! -f "$BUILDFILE" ]]; then + error "%s does not exist." "$BUILDFILE" + exit 1 + fi + case "$BUILDFILE" in + */SRCBUILD) srcbuild="$(modified_srcbuild "$BUILDFILE")";; + *) srcbuild="$(modified_pkgbuild "$BUILDFILE")";; + esac # Mode: checksums ###################################################### if [[ $mode =~ checksums ]]; then - if [[ ${#extra_opts[@]} != 0 ]]; then - print "%s: found extra non-flag arguments: %s" "$cmd" "${extra_opts[*]}" >> /dev/stderr - usage >> /dev/stderr - return 1 - fi "$makepkg" "${makepkg_opts[@]}" -g -p "$srcbuild" | case ${BUILDFILE##*/} in PKGBUILD) sed -e 's/^[a-z]/mk&/' -e 's/^\s/ &/';; SRCBUILD) cat;; esac - return 0 + exit 0 fi - # Mode: print ########################################################## + # Mode: srcbuild ####################################################### - if [[ $mode =~ print ]]; then - if [[ ${#extra_opts[@]} != 0 ]]; then - print "%s: found extra non-flag arguments: %s" "$cmd" "${extra_opts[*]}" >> /dev/stderr - usage >> /dev/stderr - return 1 - fi + if [[ $mode =~ srcbuild ]]; then cat "$srcbuild" - return 0 + exit 0 fi ######################################################################## - local src dst - case ${#extra_opts[@]} in - 1) - src="${extra_opts[0]#*://}" - dst="$(readlink -m -- "${src##*/}")" - ;; - 2) - src="${extra_opts[0]#*://}" - dst="$(readlink -m -- "${extra_opts[1]}")" - ;; - *) - print "%s: %d non-flag arguments found, expected 1 or 2: %s" "$cmd" ${#extra_opts[@]} >> /dev/stderr - usage >> /dev/stderr - return 1 - esac + local src="${extra_opts[0]}" + local dst="${extra_opts[1]:-${src##*/}}" + + # Don't canonicalize $src unless mode =~ download, and we've validated + # that $MIRRORS is configured. + + # Canonicalize $dst + dst="$(readlink -m -- "$dst")" # Mode: download ####################################################### if [[ $mode =~ download ]]; then load_files librefetch - check_vars librefetch MIRROR DOWNLOADER || return 1 + check_vars librefetch MIRRORS DOWNLOADER || exit 1 - local url="${MIRROR}/${src}" + # Canonicalize $src + if [[ "$src" == libre://* ]]; then + src="${MIRRORS[0]}/${src#libre://}" + fi + + # check to see if $src is a candidate for create mode + local inmirror=false; + local mirror + for mirror in "${MIRRORS[@]}"; do + if [[ "$src" == "$mirror"* ]]; then + inmirror=true + break + fi + done + if ! $inmirror; then + # inhibit create + mode=download + fi local dlcmd="${DOWNLOADER}" - dlcmd="${dlcmd//\%o/\"$dst\"}" - dlcmd="${dlcmd//\%u/\"$url\"}" - { eval "$dlcmd"; } >> /dev/stderr && return 0 + [[ $dlcmd = *%u* ]] || dlcmd="$dlcmd %u" + dlcmd="${dlcmd//\%o/\"\$dst\"}" + dlcmd="${dlcmd//\%u/\"\$src\"}" + + { eval "$dlcmd"; } >&2 && exit 0 fi # Mode: create ######################################################### @@ -163,16 +190,23 @@ main() { export pkg_file=$dst cd "$BUILDFILEDIR" - "$makepkg" "${makepkg_opts[@]}" -p "$srcbuild" >> /dev/stderr || return $? + "$makepkg" "${makepkg_opts[@]}" -p "$srcbuild" >&2 || exit $? fi } # sets the variables BUILDFILE, makepkg_opts, extra_opts, mode parse_options() { - # Detect makepkg options that take a second argument + # Detect makepkg options local makepkg_orig="$(which makepkg)" - local makepkg_opt2long=($("${makepkg_orig}" -h | sed -rn 's/\s*(--\S*) <.*/\1/p')) - local makepkg_opt2short=($("${makepkg_orig}" -h | sed -rn 's/\s*(-.) <.*/\1/p')) + # --long flags that take a second argument + local makepkg_opt2long=( $(LC_ALL=C "${makepkg_orig}" -h | sed -rn 's/\s*(--\S*) <.*/\1/p')) + # -s hort flags that take a second argument + local makepkg_opt2short=($(LC_ALL=C "${makepkg_orig}" -h | sed -rn 's/\s*(-.) <.*/\1/p')) + # all flags + local makepkg_argall=( $(LC_ALL=C "${makepkg_orig}" -h | sed -rn \ + -e 's/^ +(-.) .*/\1/p' \ + -e 's/^ +(-.), (--\S*) .*/\1\n\2/p' \ + -e 's/^ +(--\S*) .*/\1/p')) local opt local have_opt @@ -193,19 +227,43 @@ parse_options() { -C) mode=create;; -D) mode=download;; -g|--geninteg) mode=checksums;; - -P|--print) mode=print;; + -S|--srcbuild) mode=srcbuild;; + -M|--makepkg) mode=makepkg;; -p) BUILDFILE="$(readlink -m -- "$opt")";; -h|--help) mode=help;; + --) shift; break;; -*) - makepkg_opts+=("$arg") - $have_opt && makepkg_opts+=("$opt") + if in_array "${arg}" "${makepkg_argall[@]}"; then + makepkg_opts+=("$arg") + $have_opt && makepkg_opts+=("$opt") + else + print '%s: invalid flag: %s' "$cmd" "$arg" + return 1 + fi ;; - --) shift; break;; *) extra_opts+=("$arg");; esac shift done extra_opts+=("$@") + + # check the number of extra_opts + case "$mode" in + help) # don't worry about it + :;; + checksums|srcbuild|makepkg) # don't take any extra arguments + if [[ ${#extra_opts[@]} != 0 ]]; then + print "%s: found extra non-flag arguments: %s" "$cmd" "${extra_opts[*]}" >&2 + return 1 + fi + ;; + *download*|*create*) # take 1 or 2 extra arguments + if [[ ${#extra_opts[@]} != 1 ]] && [[ ${#extra_opts[@]} != 2 ]]; then + print "%s: %d non-flag arguments found, expected 1 or 2: %s" "$cmd" ${#extra_opts[@]} >&2 + return 1 + fi + ;; + esac } # Modify makepkg ############################################################### @@ -215,20 +273,27 @@ makepkg_modify=' /create_package\(\) \{/,/^\}$/ { /pkg_file=/d # allow us to set pkg_file s/"?\$\{comp_files\[@\]\}"?// # do not include .{PKGINFO,INSTALL,CHANGELOG} - s/bsdtar /&--format=ustar / # ustar, not pax + # This is long/gross. What it does: + # - pass --format=ustar to bsdtar, to inhibit it using the pax format + # - take the files that would be included in the tarball, and use + # find/sort/xargs to order them before passing them to bsdtar + s/bsdtar(.*) - ([^|]*) \|/find \2 -print0 | LC_ALL=C sort --zero-terminated | bsdtar --null --files-from - --format=ustar --no-recursion \1 - |/ s/create_signature .*/&; return $?/ # do not procede to create symlinks } /tidy_install\(\) \{/,/^\}$/ { - /for .*PURGE_TARGETS/itidy_install_purge + /for .*PURGE_TARGETS/itidy_install_purge /for .*PURGE_TARGETS/,/done/d - /^\}$/ifind . -exec touch --date="1990-01-01 0:0:0 +0" {} + + /^\}$/ifind . -exec touch --no-dereference --date="1990-01-01 0:0:0 +0" -- {} + } /download_sources\(\) \{/ { arm -rf "$srcdir"\nmkdir "$srcdir" } +s|Making package:|Making source:| +s:Checking (run|build)time dependencies\.\.\.:Checking source dependencies...: + s|srcdir=.*|&-libre| s|pkgdirbase=.*|&-libre| s|check_build_status$|:| |