summaryrefslogtreecommitdiff
path: root/src/librefetch
diff options
context:
space:
mode:
authorLuke Shumaker <LukeShu@sbcglobal.net>2013-04-25 15:53:55 -0400
committerLuke Shumaker <LukeShu@sbcglobal.net>2013-04-25 15:57:26 -0400
commitc8a5d97eeadb53f4b3a6f4931f5278a99b2c3ff4 (patch)
tree0fa8c0f696af1215b4d620c389a81b32c67fcbdd /src/librefetch
parent2ca1bce59850d92bb2cb6eb6c8f69f4ba10acbd8 (diff)
second iteration of librefetch
Diffstat (limited to 'src/librefetch')
-rwxr-xr-xsrc/librefetch/librefetch504
1 files changed, 247 insertions, 257 deletions
diff --git a/src/librefetch/librefetch b/src/librefetch/librefetch
index 9ba2a84..b637661 100755
--- a/src/librefetch/librefetch
+++ b/src/librefetch/librefetch
@@ -1,4 +1,4 @@
-#!/bin/bash -euE
+#!/bin/bash
# librefetch
#
# Copyright 2013 Luke Shumaker <lukeshu@sbcglobal.net>
@@ -18,157 +18,264 @@
# You should have received a copy of the GNU General Public License
# along with Parabola. If not, see <http://www.gnu.org/licenses/>.
-# Overview:
-# For 'create' (default) mode, the program flow is easily summarized as:
-# librefetch_extract() {
-# download_sources
-# check_source_integrity
-# extract_sources
-# }
-# librefetch_create() {
-# librefetch_extract
-# run_function_safe 'mksource'
-# create_package
-# }
-
-unset CDPATH
export TEXTDOMAIN='libretools'
export TEXTDOMAINDIR='/usr/share/locale'
-# Constants
-declare -r confdir='/etc'
-declare -r BUILDSCRIPT='PKGBUILD' # The default for ${BUILDFILE}
+declare -r tempdir="$(mktemp -d --tmpdir ${0##*/}.XXXXXXXXXXX)"
+cleanup() { rm -rf -- "$tempdir"; }
+trap cleanup EXIT
+cmd=${0##*/}
usage() {
- print "Usage: ${0##*/} [OPTIONS] SOURCEURL OUTFILE"
+ print "Usage: %s [options] <source-url> <output-file>" "$cmd"
+ print "Usage: %s [options] -g" "$cmd"
print "Downloads or creates a liberated source tarball."
echo
+ print "The default build script is 'PKGBUILD', or 'SRCBUILD' if it exists."
+ echo
+ print "Unrecognized options are passed straight to makepkg."
+ echo
print "Options:"
- print " -c Force create mode (don't download)"
- print " -d Force download mode (don't create)"
- print " -e Extract only (don't run \`mksource\` or \`tar\`)"
- print " -g Generate checksums for the \`mksource\` array"
- print " -m Do not use color"
- print " -p Do Use an alternative build script (instead of 'PKGBUILD')"
- print " -h Show this message"
+ print " -C Force create mode (don't download)"
+ print " -D Force download mode (don't create)"
+ print " -p <file> Use an alternate build script (instead of 'PKGBUILD')"
+ print " If an SRCBUILD exists in the same directory, it is used"
+ print " instead"
+ print " -g, --geninteg Generage integrity checks for source files"
+ print " -V, --version Show version information"
+ print " -h, --help Show this message"
+}
+
+version() {
+ print "librefetch (libretools) beta 2"
+ echo
+ print "Copyright (C) 2013 Luke Shumaksr <lukeshu@sbcglobal.net>"
+ print "This is free software; see the source for copying conditions."
+ print "There is NO WARRANTY, to the extent permitted by law."
}
-# The semantics of ${BUILDDIR} and ${startdir} are a little confusing.
-# - ${startdir} is the directory that the program is run from.
-# This is either where output files are created, or where they are linked to
-# if the relevent *DEST is set.
-# - ${BUILDDIR} is the directory that ${srcdir} and ${pkgdir} are in.
-#
-# How ${BUILDDIR} is set varries between makepkg an librefetch:
-# (high precedence is higher up; lower number)
-# - makepkg:
-# 1. The `BUILDDIR` environmental variable
-# 2. ${startdir}
-# - librefetch
-# 1. The directory a manually specified (`-p` flag) PKGBUILD is in
-# 2. The `BUILDDIR` environmental variable
-# 3. ${startdir}
-#
-# librefetch forces PKGDEST=$startdir; so it does not symlink the output into
-# $startdir
main() {
- # Init/Parse command line ##############################################
-
- # Global variables
- USE_COLOR=y
- startdir=$PWD
- [[ -n ${BUILDDIR:-} ]] || BUILDDIR=$startdir
-
- local mode='download-or-create'
- while getopts 'cdegmp:h' arg; do
- case $arg in
- c) mode='create';;
- d) mode='download';;
- e) mode='extract';;
- g) mode='generate-checksums';;
- m) USE_COLOR=n;;
- p)
- BUILDFILE="$(readlink -m "$OPTARG")"
- BUILDDIR="${BUILDFILE%/*}"
- ;;
- h) usage; return 0;;
- *) usage; return 1;;
+ BUILDFILE="$(readlink -m PKGBUILD)"
+ makepkg_opts=()
+ extra_opts=()
+ mode=create # download-create
+ parse_options "$@"
+
+ local startdir=$PWD
+ export BUILDDIR="${BUILDFILE%/*}"
+ if [[ -f "${BUILDDIR}/SRCBUILD" ]]; then
+ BUILDFILE="${BUILDDIR}/SRCBUILD"
+ srcbuild="$(modified_srcbuild "$BUILDFILE")"
+ else
+ srcbuild="$(modified_pkgbuild "$BUILDFILE")"
+ fi
+ makepkg="$(modified_makepkg "$(which "${MAKEPKG:-makepkg}")")"
+
+ # Mode: checksums ######################################################
+
+ if [[ $mode =~ checksums ]]; then
+ if [[ ${#extra_opts[@]} != 0 ]]; then
+ print "%s: found extra non-flag arguments: %s" "$cmd" "${extra_opts[*]}"
+ 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
- done
- shift $(($OPTIND - 1))
+ return 0
+ fi
- # Lock in these variables globally
- declare -rg USE_COLOR
- declare -rg startdir
- declare -rg BUILDDIR
+ ########################################################################
- # Main routine #########################################################
+ if [[ ${#extra_opts[@]} != 2 ]]; then
+ print "%s: %d non-flag arguments found, expected 2: %s" "$cmd" ${#extra_opts[@]}
+ usage >> /dev/stderr
+ return 1
+ fi
+ local src="${extra_opts[0]#*://}"
+ local dst="$(readlink -m "${extra_opts[1]}")"
- if [[ $mode = 'generate-checksums' ]]; then
- librefetch_makepkg_init '/dev/null' '/dev/null'
- librefetch_generate_checksums
- return $?
- else
- if [[ $# != 2 ]]; then
- usage
- return 1;
- fi
- local src="${1#*://}"
- local dst="$(readlink -m "$2")"
+ # Mode: download #######################################################
- case $mode in
- download)
- librefetch_download "$src" "$dst"
- ;;
- extract)
- librefetch_makepkg_init "$src" "$dst"
- librefetch_extract
- ;;
- download-or-create)
- librefetch_makepkg_init "$src" "$dst"
- librefetch_download "$src" "$dst" || librefetch_create "$dst"
- ;;
- create)
- librefetch_makepkg_init "$src" "$dst"
- librefetch_create "$dst"
+ if [[ $mode =~ download ]]; then
+ load_conf_libretools_librefetch || return 1
+
+ local url="${MIRROR}/${src}"
+
+ local dlcmd="${DOWNLOADER}"
+ dlcmd="${dlcmd//\%o/\"$dst\"}"
+ dlcmd="${dlcmd//\%u/\"$url\"}"
+ { eval "$dlcmd"; } && return 0
+ fi
+
+ # Mode: create #########################################################
+
+ if [[ $mode =~ create ]]; then
+ PKGEXT=${dst##*/}
+ export PKGEXT=${PKGEXT%.part}
+ export PKGDEST=$startdir
+ export pkg_file=$dst
+ "$makepkg" "${makepkg_opts[@]}" -p "$srcbuild"
+ fi
+}
+
+# sets the variables BUILDFILE, makepkg_opts, extra_opts, mode
+parse_options() {
+ # Detect makepkg options that take a second argument
+ local makepkg_orig="$(which "${MAKEPKG:-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'))
+
+ local opt
+ local have_opt
+ while [[ $# > 0 ]]; do
+ arg=$1
+ have_opt=false
+ if in_array "${arg%%=*}" "${makepkg_opt2long[@]}"; then
+ opt="${arg#*=}"
+ arg="${arg%%=*}"
+ have_opt=true
+ fi
+ if in_array "${arg}" "${makepkg_opt2short[@]}"; then
+ shift
+ opt=$1
+ have_opt=true
+ fi
+ case "$arg" in
+ -C) mode=create;;
+ -D) mode=download;;
+ -g|--geninteg) mode=checksums;;
+ -p) BUILDFILE="$(readlink -m "$opt")";;
+ -*)
+ makepkg_opts+=("$arg")
+ $have_opt && makepkg_opts+=("$opt")
;;
+ --) shift; break;;
+ *) extra_opts+=("$arg");;
esac
- fi
+ shift
+ done
+ extra_opts+=("$@")
+}
+
+# Modify makepkg ###############################################################
+
+# an ERE
+makepkg_modify='
+/create_package\(\) \{/,/^\}$/ {
+ /pkg_file=/d # allow us to set pkg_file
+ /check_package/d # do not run check_package
+ s/"?\$\{comp_files\[@\]\}"?// # do not include .{PKGINFO,INSTALL,CHANGELOG}
+}
+
+/tidy_install\(\) \{/,/^\}$/ {
+ /for .*PURGE_TARGETS/itidy_install_purge
+ /for .*PURGE_TARGETS/,/done/d
+ /^\}$/ifind . -exec touch --date="1990-01-01 0:0:0 +0" {} +
}
-librefetch_makepkg_init() {
- local src=$1
- local dst=$2
-
- import_makepkg_functions
-
- makepkg_variables
- makepkg_preimport
-
- set +u
- makepkg_import
- set -u
-
- # Override certain variables
- declare -rg srcdir="$BUILDDIR/src-libre"
- declare -rg pkgdir="$BUILDDIR/pkg-libre"
- declare -rg PKGDEST=$startdir
-
- declare -rg PKGEXT="${src##*/}" # this affects the tar command used, and
- # pkg_file
- declare -rg pkg_file=$dst # but we already know what we want this to be
- # (so PKGEXT only affects tar)
- declare -rg changelog='' # don't include a special changelog file in the tarball
- declare -rg install='' # don't include an install script in the tarball
-
- # copy the mk* source-related arrays to the standard names
- set +u
- for var in source noextract md5sums sha1sums sha256sums sha384sums sha512sums; do
- copy_array "mk${var}" "${var}"
- [[ -n "${!var}" ]] || eval "${var}=''"
- declare -rga "$var"
+s|srcdir=.*|srcdir="$BUILDDIR/src-libre"|
+s|pkgdir=.*|pkgdir="$BUILDDIR/pkg-libre"|
+s|check_build_status$|:|
+'
+
+tidy_install_purge() {
+ local pt
+ for pt in "${PURGE_TARGETS[@]}"; do
+ if [[ ${pt} = "${pt%/}" ]]; then
+ if [[ ${pt} = "${pt//\/}" ]]; then
+ find . ! -type d -name "${pt}" -exec rm -f -- '{}' +
+ else
+ rm -f "${pt}"
+ fi
+ else
+ if [[ ${pt%/} = "${pt//\/}" ]]; then
+ find . -type d -name "${pt%/}" -exec rm -rf -- '{}' +
+ else
+ rm -rf "${pt}"
+ fi
+ fi
done
- set -u
+}
+
+modified_makepkg() {
+ local makepkg_orig=$1
+ local makepkg_mine="$tempdir/makepkg"
+ {
+ echo '#!/bin/bash'
+ declare -f tidy_install_purge
+ sed -r "$makepkg_modify" < "$makepkg_orig"
+ } > "$makepkg_mine"
+ chmod 755 "$makepkg_mine"
+ printf "%s\n" "$makepkg_mine"
+}
+
+# Modify PKGBUILD ##############################################################
+
+# a string to be appended
+pkgbuild_append='
+# do not do split packages
+if [[ -n $pkgbase ]]; then
+ pkgname=$pkgbase
+else
+ pkgname=$pkgname
+fi
+
+# copy source variables
+source=("${mksource[@]}")
+noextract=("${mknoextract[@]}")
+md5sums=("${mkmd5sums[@]}")
+sha1sums=("${mksha1sums[@]}")
+sha256sums=("${mksha256sums[@]}")
+sha384sums=("${mksha384sums[@]}")
+sha512sums=("${mksha512sums[@]}")
+
+depends=()
+checkdepends=()
+makedepends=("${mkdepends[@]}")
+
+####
+options+=(!strip docs libtool emptydirs !zipman purge !upx)
+PURGE_TARGETS+=(.bzr/ .cvs/ .git/ .hg/ .svn/)
+
+####
+if ! declare -f mksource >/dev/null; then
+ mksource() { :; }
+fi
+build() { mksource; }
+package() {
+ if [[ $(ls "$pkgdir" | wc -l) == 0 ]]; then
+ # pkgdir is empty; provide good default behavior
+ cp -a "${srcdir}"/*/ "$pkgdir/"
+ fi
+}
+'
+
+modified_pkgbuild() {
+ local pkgbuild=$1
+ local srcbuild="$tempdir/SRCBUILD"
+ printf '%s' "$pkgbuild_append" | cat "$pkgbuild" - > "$srcbuild"
+ printf '%s\n' "$srcbuild"
+}
+
+
+# Modify SRCBUILD ##############################################################
+
+modified_srcbuild() {
+ local orig=$1
+ local new="$tempdir/SRCBUILD"
+ sed -e '/PKGDEST=/d' -e 's/PKGEXT=/d' < "$orig" > "$new"
+ printf '%s\n' "$new"
+}
+
+# "Library" crap ###############################################################
+
+print() {
+ local fmt=$1
+ shift
+ printf -- "$(gettext "$fmt")\n" "$@"
}
# Emulates the behavior of bleeding /usr/share/libretools/conf.sh
@@ -177,7 +284,6 @@ load_conf_libretools_librefetch() {
. /etc/libretools.d/librefetch.conf
local ret=0
for VAR in MIRROR DOWNLOADER; do
- echo "$VAR: ${!VAR:-}"
if [[ -z ${!VAR:-} ]]; then
echo "Configure '$VAR' in /etc/libretools.d/librefetch.conf"
ret=1
@@ -188,133 +294,17 @@ load_conf_libretools_librefetch() {
fi
}
-################################################################################
-
-copy_array() {
- local src=$1
- local dst=$2
- eval "$(printf '%s=("${%s[@]}")' "${dst}" "${src}")"
-}
-
-print() {
- local fmt=$1
- shift
- printf -- "$(gettext "$fmt")\n" "$@"
+# From devtools common.sh, which is only distributed in a package with bleeding
+# libretools
+in_array() {
+ local needle=$1; shift
+ local item
+ for item in "$@"; do
+ [[ $item = $needle ]] && return 0 # Found
+ done
+ return 1 # Not Found
}
################################################################################
-librefetch_download() {
- local src=$1
- local dst=$2
- load_conf_libretools_librefetch || exit 1
-
- local url="${MIRROR}/${src}"
-
- local dlcmd="${DOWNLOADER}"
- dlcmd="${dlcmd//\%o/\"$dst\"}"
- dlcmd="${dlcmd//\%u/\"$url\"}"
- eval "$dlcmd"
-}
-
-librefetch_extract() {
- mkdir -p "$srcdir"
- # The 'full' is for compatability with makepkg-git-2abe1f1; whose design
- # I disagree with, but I'll play along.
- # (it could be any value, except 'fast')
- download_sources 'full'
- check_source_integrity
- extract_sources
-}
-
-librefetch_create() {
- local dst=$1
- librefetch_extract
-
- rm -rf "$pkgdir"
- mkdir -p "$pkgdir"
-
- if declare -f mksource >/dev/null; then
- run_function_safe "mksource"
- else
- mv "$srcdir"/*/ "$pkgdir"
- fi
- create_package
-}
-
-librefetch_generate_checksums() {
- mkdir -p "$srcdir"
- chmod a-s "$srcdir"
- cd_safe "$srcdir"
- # The 'fast' is for compatability with makepkg-git-2abe1f1; whose design
- # I disagree with, but I'll play along.
- download_sources fast
- generate_checksums | sed -e 's/^[a-z]/mk&/' -e 's/^\s/ &/' && (exit $PIPESTATUS)
-}
-
-# Hack to load functions defined in makepkg
-import_makepkg_functions() {
- # The file we are reading from
- local makepkg="$(which "${MAKEPKG:-makepkg}")"
- # The temporary file that we will include
- local makepkg_lib="$(mktemp --tmpdir makepkg-lib.XXXXXXXXXX.sh)"
-
- # Extract all functions defined in $makepkg
- sed -n '/^[a-z0-9_]*() {/,/^}$/p' < $makepkg >> $makepkg_lib
- # Extract variable initialization as `makepkg_variables()`
- {
- echo 'makepkg_variables() {'
- sed -n '/^# Options/,/^\s*$/p'
- echo '}'
- } < $makepkg >> $makepkg_lib
-
- # Extract the init routine between parsing options and first looking at
- # the PKGBUILD as `makepkg_preimport()`
- {
- echo 'makepkg_preimport() {'
- sed -n '/^# setup signal traps/,/^unset pkgname/p' | sed '$d'
- echo '}'
- } < $makepkg >> $makepkg_lib
- # Extract the PKGBUILD inclusion routine as `makepkg_import()`
- # from the main routine
- {
- echo 'makepkg_import() {'
- sed -n '/^unset pkgname/,/^epoch=/p'
- echo '}'
- } < $makepkg >> $makepkg_lib
-
- # Modify `create_package()` suit our needs.
- sed -ri '
- /create_package() \{/,/^\}$/ {
- /PKGINFO/d
- /pkg_file=/d
- /check_package/d
- s/"?\$\{comp_files\[@\]\}"?//
- }
- ' $makepkg_lib
-
- # Modify `get_filepath()` to work with `set -e`, as it is frequently
- # expected to not output a value.
- sed -i '
- /get_filepath() {/,/^}$/ {
- s/return 1/return 0/
- }
- ' $makepkg_lib
-
- # Modify everything to make `[[ -z VARIABLE ]]` and `[[ -n VARIABLE ]]`
- # tests work with `set -u`
- sed -ri 's/\[\[ -([nz]) "?\$\{?(!?[A-Za-z0-9_]+)\}?"? /[[ -\1 ${\2:-} /g' $makepkg_lib
-
- . $makepkg_lib
- echo rm -- $makepkg_lib
-
- # makepkg-git defines these *_safe functions that makepkg-4.0.3 doesn't use; if
- # ${MAKEPKG} doesn't define them, define them as no-op wrappers for our use.
- for func in cd run_function; do
- if ! declare -f "${func}_safe" >/dev/null; then
- eval "${func}_safe() { ${func} \"\$@\"; }"
- fi
- done
-}
-
main "$@"