summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <LukeShu@sbcglobal.net>2013-04-25 15:55:41 -0400
committerLuke Shumaker <LukeShu@sbcglobal.net>2013-04-25 15:55:41 -0400
commit2ca1bce59850d92bb2cb6eb6c8f69f4ba10acbd8 (patch)
tree7d27cf2c20587113106d128097947ea754338dd2
parent4f8385602a2cedecd2affe45ef281727ad4677af (diff)
initial implementation of librefetch
-rw-r--r--src/librefetch/Makefile3
-rwxr-xr-xsrc/librefetch/librefetch320
-rw-r--r--src/librefetch/librefetch.conf2
3 files changed, 325 insertions, 0 deletions
diff --git a/src/librefetch/Makefile b/src/librefetch/Makefile
new file mode 100644
index 0000000..f2cec54
--- /dev/null
+++ b/src/librefetch/Makefile
@@ -0,0 +1,3 @@
+libre_execdir=$(bindir)
+libre_datadir=$(sysconfdir)/libretools.d
+include ../../common.mk
diff --git a/src/librefetch/librefetch b/src/librefetch/librefetch
new file mode 100755
index 0000000..9ba2a84
--- /dev/null
+++ b/src/librefetch/librefetch
@@ -0,0 +1,320 @@
+#!/bin/bash -euE
+# librefetch
+#
+# Copyright 2013 Luke Shumaker <lukeshu@sbcglobal.net>
+#
+# This file is part of Parabola.
+#
+# Parabola 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.
+#
+# Parabola 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 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}
+
+usage() {
+ print "Usage: ${0##*/} [OPTIONS] SOURCEURL OUTFILE"
+ print "Downloads or creates a liberated source tarball."
+ 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"
+}
+
+# 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;;
+ esac
+ done
+ shift $(($OPTIND - 1))
+
+ # Lock in these variables globally
+ declare -rg USE_COLOR
+ declare -rg startdir
+ declare -rg BUILDDIR
+
+ # Main routine #########################################################
+
+ 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")"
+
+ 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"
+ ;;
+ esac
+ fi
+}
+
+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"
+ done
+ set -u
+}
+
+# Emulates the behavior of bleeding /usr/share/libretools/conf.sh
+# without requiring bleeding libretools
+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
+ fi >>/dev/stderr
+ done
+ if [[ $ret != 0 ]]; then
+ return 1
+ fi
+}
+
+################################################################################
+
+copy_array() {
+ local src=$1
+ local dst=$2
+ eval "$(printf '%s=("${%s[@]}")' "${dst}" "${src}")"
+}
+
+print() {
+ local fmt=$1
+ shift
+ printf -- "$(gettext "$fmt")\n" "$@"
+}
+
+################################################################################
+
+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 "$@"
diff --git a/src/librefetch/librefetch.conf b/src/librefetch/librefetch.conf
new file mode 100644
index 0000000..40d2078
--- /dev/null
+++ b/src/librefetch/librefetch.conf
@@ -0,0 +1,2 @@
+MIRROR='https://repo.parabolagnulinux.org/sources/'
+DOWNLOADER='/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'