diff options
Diffstat (limited to 'src/librefetch')
-rw-r--r-- | src/librefetch/.gitignore | 2 | ||||
-rw-r--r-- | src/librefetch/Makefile | 13 | ||||
-rwxr-xr-x | src/librefetch/librefetch | 400 | ||||
-rw-r--r-- | src/librefetch/librefetch-install.in | 114 | ||||
-rw-r--r-- | src/librefetch/librefetch-makepkg.conf.in | 16 | ||||
-rw-r--r-- | src/librefetch/librefetch.8.ronn | 214 | ||||
-rw-r--r-- | src/librefetch/librefetch.conf | 7 | ||||
-rw-r--r-- | src/librefetch/librefetch.conf.5.ronn | 42 | ||||
-rw-r--r-- | src/librefetch/librefetchdir/Makefile | 56 | ||||
-rwxr-xr-x | src/librefetch/librefetchdir/libmakepkg/source.sh.gen | 25 | ||||
-rwxr-xr-x | src/librefetch/librefetchdir/libmakepkg/tidy/purge.sh | 58 | ||||
-rwxr-xr-x | src/librefetch/librefetchdir/libmakepkg/tidy/~source_date_epoch.sh | 38 | ||||
-rwxr-xr-x | src/librefetch/librefetchdir/makepkg.gen | 42 |
13 files changed, 1027 insertions, 0 deletions
diff --git a/src/librefetch/.gitignore b/src/librefetch/.gitignore new file mode 100644 index 0000000..d34a2fc --- /dev/null +++ b/src/librefetch/.gitignore @@ -0,0 +1,2 @@ +librefetch-install +librefetch-makepkg.conf diff --git a/src/librefetch/Makefile b/src/librefetch/Makefile new file mode 100644 index 0000000..26ee2ee --- /dev/null +++ b/src/librefetch/Makefile @@ -0,0 +1,13 @@ +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk + +libretools-bins = librefetch librefetch-install +libretools-confs += librefetch-makepkg.conf +libretools-libexecs += $(filter librefetchdir/%,$(detect-exec)) +libretools-libs += $(filter-out $(libretools-libexecs),$(filter librefetchdir/%,$(detect-all))) +pots = $(libretools-bins) + +$(outdir)/librefetch-install: $(var)pkgconfdir +$(outdir)/librefetch-makepkg.conf: $(var)bindir + +include $(topsrcdir)/automake.tail.mk diff --git a/src/librefetch/librefetch b/src/librefetch/librefetch new file mode 100755 index 0000000..2b8af61 --- /dev/null +++ b/src/librefetch/librefetch @@ -0,0 +1,400 @@ +#!/usr/bin/env bash +# librefetch +# +# Copyright (C) 2013-2016 Luke Shumaker <lukeshu@sbcglobal.net> +# +# For just the create_signature() function: +# Copyright (C) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org> +# Copyright (C) 2005 Aurelien Foret <orelien@chez.com> +# Copyright (C) 2006 Miklos Vajna <vmiklos@frugalware.org> +# Copyright (C) 2005 Christian Hamar <krics@linuxforum.hu> +# Copyright (C) 2006 Alex Smith <alex@alex-smith.me.uk> +# Copyright (C) 2006 Andras Voroskoi <voroskoi@frugalware.org> +# +# License: GNU GPLv3+ +# +# This file is part of LibreFetch. +# +# LibreFetch 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. +# +# LibreFetch 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 LibreFetch. If not, see <http://www.gnu.org/licenses/>. + +# create_signature() is taken from pacman:makepkg, which is GPLv2+, +# so we take the '+' to combine it with our GPLv3+. + +. "$(librelib conf)" +. "$(librelib messages)" +setup_traps + +tmpfiles=() +tmpdirs=() +trap 'rm -f -- "${tmpfiles[@]}"; rm -rf -- "${tmpdirs[@]}"' EXIT + +cmd=${0##*/} +usage() { + print "Usage: %s [OPTIONS] SOURCE_URL [OUTPUT_FILE]" "$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 + download mode, then create mode." + echo + prose "If OUTPUT_FILE isn't specified, it defaults to the non-directory + part of SOURCE_URL, in the current directory." + echo + 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 either looks at a build script and uses that + to create the source tarball, or it uses GPG to create a + signature (if OUTPUT_FILE ends with \`.sig\` or \`.sig.part\`). + If it is using GPG to create a signature, but the file that it is + trying to sign doesn't exist yet, it recurses on itself to first + create that file. SOURCE_URL is ignored, except that it is used + to set the default value of OUTPUT_FILE, and that it may be used + when recursing." + echo + prose "The default build script is 'PKGBUILD', or 'SRCBUILD' if it + exists." + echo + prose "Other options, if they are valid \`makepkg\` options, are passed + straight to makepkg." + echo + print "Example usage:" + print ' $ %s https://repo.parabola.nu/other/mypackage/mypackage-1.0.tar.gz' "$cmd" + echo + print "Options:" + flag 'Settings:' \ + "-C" "Force create mode (don't download)" \ + "-D" "Force download mode (don't create)" \ + "-p <$(_ FILE)>" "Use an alternate build script (instead of + 'PKGBUILD'). If an SRCBUILD exists in the same + directory, it is used instead" \ + 'Alternate modes:' \ + "-g, --geninteg" "Generate integrity checks for source files" \ + "-S, --srcbuild" "Print the effective build script (SRCBUILD)" \ + "-M, --makepkg" "Generate and print the location of the + effective makepkg script" \ + "-h, --help" "Show this message" +} + +main() { + BUILDFILE="$(realpath -Lm PKGBUILD)" + makepkg_opts=() + extra_opts=() + mode=download-create + if ! parse_options "$@"; then + usage >&2 + exit 1 + fi + + doit +} + +doit() { + # Mode: help ########################################################### + + if [[ $mode =~ help ]]; then + usage + exit 0 + fi + + ######################################################################## + + makepkg="$(modified_makepkg)" + + # Mode: makepkg ######################################################## + + if [[ $mode =~ makepkg ]]; then + printf '%s\n' "$makepkg" + exit 0 + else + tmpdirs+=("${makepkg%/*}") + fi + + ######################################################################## + + local BUILDFILEDIR="${BUILDFILE%/*}" + if [[ -f "${BUILDFILEDIR}/SRCBUILD" ]]; then + BUILDFILE="${BUILDFILEDIR}/SRCBUILD" + fi + 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 + tmpfiles+=("$srcbuild") + + # Mode: checksums ###################################################### + + if [[ $mode =~ checksums ]]; then + "$makepkg" "${makepkg_opts[@]}" -g -p "$srcbuild" | + case ${BUILDFILE##*/} in + PKGBUILD) sed -e 's/^[a-z]/mk&/' -e 's/^\s/ &/';; + SRCBUILD) cat;; + esac + exit 0 + fi + + # Mode: srcbuild ####################################################### + + if [[ $mode =~ srcbuild ]]; then + cat "$srcbuild" + exit 0 + fi + + ######################################################################## + + 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="$(realpath -Lm -- "$dst")" + + # Mode: download ####################################################### + + if [[ $mode =~ download ]]; then + load_files librefetch + check_vars librefetch MIRRORS DOWNLOADER || exit 1 + + # 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 = *%u* ]] || dlcmd="$dlcmd %u" + dlcmd="${dlcmd//\%o/\"\$dst\"}" + dlcmd="${dlcmd//\%u/\"\$src\"}" + + { eval "$dlcmd"; } >&2 && exit 0 + fi + + # Mode: create ######################################################### + + if [[ $mode =~ create ]]; then + local base_dst=${dst%.part} + local suffix=${dst#"$base_dst"} + + if [[ $base_dst == *.sig ]]; then + if ! [[ -e $base_dst ]]; then + extra_opts=("${src%.sig}" "${base_dst%.sig}") + doit || exit $? + fi + create_signature "${base_dst%.sig}" || exit $? + if [[ -n $suffix ]]; then + mv -f "$base_dst" "$dst" + fi + else + export PKGEXT=${base_dst##*/} + export PKGDEST=${dst%/*} + export pkg_file=$dst + + cd "$BUILDFILEDIR" + "$makepkg" "${makepkg_opts[@]}" -p "$srcbuild" >&2 || exit $? + fi + fi +} + +# sets the variables BUILDFILE, makepkg_opts, extra_opts, mode +parse_options() { + declare -i ret=0 + local {shrt,long}{1,2} + + # makepkg options + local makepkg_orig="$(which makepkg)" + shrt1=($(LC_ALL=C "${makepkg_orig}" -h | sed -rn 's/^ +-(.)(,| [^<]).*/\1/p')) + shrt2=($(LC_ALL=C "${makepkg_orig}" -h | sed -rn 's/^ +-(.) <.*/\1/p')) + long1=($(LC_ALL=C "${makepkg_orig}" -h | sed -rn -e 's/^ +(-., )?--(\S*) [^<].*/\2/p')) + long2=($(LC_ALL=C "${makepkg_orig}" -h | sed -rn 's/^ +--(\S*) <.*/\1/p')) + + # librefetch options + shrt1+=(C D g S M h) + shrt2+=(p) + long1+=(geninteg srcbuild makepkg help) + long2+=() + + # Feed the options through getopt (sanitize them) + local shrt="$({ printf '%s\0' "${shrt1[@]}"; printf '%s:\0' "${shrt2[@]}"; } | sort -zu | xargs -0 printf '%s')" + local long="$({ printf '%s\0' "${long1[@]}"; printf '%s:\0' "${long2[@]}"; } | sort -zu | xargs -0 printf '%s,')" + local args="$(getopt -n "$cmd" -o "$shrt" -l "${long%,}" -- "$@")" + ret=$? + eval set -- "$args" + unset shrt long args + + # Parse the options. + local opt optarg have_optarg + while [[ $# -gt 0 ]]; do + opt=$1; shift + have_optarg=false + + if { [[ $opt == --?* ]] && in_array "${opt#--}" "${long2[@]}"; } \ + || { [[ $opt == -? ]] && in_array "${opt#-}" "${shrt2[@]}"; } + then + optarg=$1; shift + have_optarg=true + fi + + case "$opt" in + -C) mode=create;; + -D) mode=download;; + -g|--geninteg) mode=checksums;; + -S|--srcbuild) mode=srcbuild;; + -M|--makepkg) mode=makepkg;; + -p) BUILDFILE="$(realpath -Lm -- "$optarg")";; + -h|--help) mode=help;; + --) break;; + *) + makepkg_opts+=("$opt") + if $have_optarg; then makepkg_opts+=("$optarg"); fi + ;; + esac + 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 + ret=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 + ret=1 + fi + ;; + esac + + return $ret +} + +# Modify makepkg ############################################################### + +modified_makepkg() { + local dir="$(mktemp --tmpdir --directory "${cmd}.XXXXXXXXXXX.makepkg")" + make -s -f "$(librelib librefetchdir/Makefile)" new="$dir" + realpath -es "$dir/makepkg" +} + +# Modify PKGBUILD ############################################################## + +# a string to be appended +pkgbuild_append=' +# do not do split packages +if [[ ${#pkgname[@]} -gt 1 ]]; then + if [[ -n $pkgbase ]]; then + pkgname=("$pkgbase") + else + pkgname=("$pkgname") + fi +fi + +# copy source variables +source=("${mksource[@]}") ; unset "source_${CARCH}" +noextract=("${mknoextract[@]}") + +declare algo +for algo in "${known_hash_algos[@]}"; do + eval "${algo}sums=(\"\${mk${algo}sums[@]}\")" + unset "${algo}sums_${CARCH}" +done + +depends=() ; unset "depends_${CARCH}" +checkdepends=() ; unset "checkdepends_${CARCH}" +makedepends=("${mkdepends[@]}") ; unset "makedepends_${CARCH}" + +#### +options=(!strip docs libtool staticlibs emptydirs !zipman purge !upx !optipng !debug) +PURGE_TARGETS=(.bzr/ .cvs/ .git/ .hg/ .svn/ .makepkg/) + +#### +if ! declare -f mksource >/dev/null; then + mksource() { :; } +fi +prepare() { :; } +build() { mksource; } +check() { :; } +package() { cp -a "$srcdir"/*/ "$pkgdir/"; } +' + +modified_pkgbuild() { + local pkgbuild=$1 + local srcbuild="$(mktemp "${pkgbuild%/*}/${cmd}.XXXXXXXXXXX.PKGBUILD.to.SRCBUILD")" + printf '%s' "$pkgbuild_append" | cat "$pkgbuild" - > "$srcbuild" + printf '%s\n' "$srcbuild" +} + + +# Modify SRCBUILD ############################################################## + +modified_srcbuild() { + local orig=$1 + local srcbuild="$(mktemp "${orig%/*}/${cmd}.XXXXXXXXXXX.SRCBUILD.to.SRCBUILD")" + sed -e '/PKGDEST=/d' -e '/PKGEXT=/d' < "$orig" > "$new" + printf '%s\n' "$new" +} + +################################################################################ + +# This function is taken almost verbatim from makepkg +create_signature() { + local ret=0 + local filename="$1" + msg "Signing package..." + + local SIGNWITHKEY=() + if [[ -n $GPGKEY ]]; then + SIGNWITHKEY=(-u "${GPGKEY}") + fi + + gpg --detach-sign --use-agent "${SIGNWITHKEY[@]}" --no-armor "$filename" &>/dev/null || ret=$? + + + if (( ! ret )); then + msg2 "Created signature file %s." "$filename.sig" + else + error "Failed to sign package file." + return $ret + fi +} + +main "$@" diff --git a/src/librefetch/librefetch-install.in b/src/librefetch/librefetch-install.in new file mode 100644 index 0000000..34815a7 --- /dev/null +++ b/src/librefetch/librefetch-install.in @@ -0,0 +1,114 @@ +#!/usr/bin/env bash +# lirefetch-install: (un)install librefetch to /etc/makepkg.conf +# +# Copyright (C) 2013-2015 Luke Shumaker <lukeshu@sbcglobal.net> +# +# License: GNU GPLv3+ +# +# 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/>. + +set -ueE +. "$(librelib messages)" + +# This line should be installed +new_code='. @pkgconfdir@/librefetch-makepkg.conf # This line was added by librefetch-install' + +# These lines were installed by previous versions of this script +old_code=( + '# The following line is added by the libretools post_install script' + '[[ ! -x /usr/bin/librefetch ]] || DLAGENTS+=("libre::/usr/bin/librefetch -p \"\$BUILDFILE\" %u %o")' + '[[ ! -x /usr/bin/librefetch ]] || DLAGENTS+=({https,libre}"::/usr/bin/librefetch -p \"\$BUILDFILE\" -- %u %o")' + 'DLAGENTS+=({https,libre}"::/usr/bin/librefetch -p $(printf "%q" "$BUILDFILE") -- %u %o")' + 'DLAGENTS+=({https,libre}'\''::/usr/bin/librefetch -p "$BUILDFILE" -- %u %o'\'')' +) + +# has_line $file $line +has_line() { + local file=$1 + local line=$2 + grep -Fxq -- "$line" "$file" +} +# del_line $file $line +del_line() { + local file=$1 + local line=$2 + local lineno=($(grep -Fxn -- "$line" "$file" | cut -d: -f1)) + if [[ "${#lineno[@]}" -gt 0 ]]; then + sed -i "$(printf '%dd;' "${lineno[@]}")" "$file" + fi +} + +# post_install $file +post_install() { + local file=$1 + if grep -q 'librefetch' "$file"; then + msg2 "%s: librefetch is already in %q" "${0##*/}" "$(realpath -s "$file")" + local line del=false + for line in "${old_code[@]}"; do + if has_line "$file" "$line"; then + msg2 "%s: ... but it's an old version" "${0##*/}" + pre_remove "$file" + post_install "$file" + return $? + fi + done + else + msg2 "%s: adding librefetch to %q" "${0##*/}" "$(realpath -s "$file")" + printf '%s\n' "$new_code" >> "$file" + fi +} + +# pre_remove $file +pre_remove() { + local file=$1 + msg2 "%s: removing librefetch from %q" "${0##*/}" "$(realpath -s "$file")" + + # Check for the old stuff + sed -ri 's/^#(.*) # commented out by the libretools post_install script/\1/' "$file" + local line + for line in "${old_code[@]}"; do + del_line "$file" "$line" + done + + # Check for the current stuff + del_line "$file" "$new_code" +} + +usage() { + print "Usage: %s [install|remove] MAKEPKG_CONF_FILE" "${0##*/}" + print "Adds or removes librefetch to/from makepkg.conf:DLAGENTS" +} + +main() { + if [[ $# != 2 ]]; then + usage >&2 + return 1 + fi + local file=$2 + if [[ ! -f "$file" ]]; then + msg2 "%s: does not exist: %q" "${0##*/}" "$(realpath -s "$file")" + fi + if [[ ! -w "$file" ]]; then + msg2 "%s: cannot write to file: %q" "${0##*/}" "$(realpath -s "$file")" + fi + case "$1" in + install) post_install "$file";; + remove) pre_remove "$file";; + *) usage >&2; return 1;; + esac +} + +main "$@" diff --git a/src/librefetch/librefetch-makepkg.conf.in b/src/librefetch/librefetch-makepkg.conf.in new file mode 100644 index 0000000..723bc15 --- /dev/null +++ b/src/librefetch/librefetch-makepkg.conf.in @@ -0,0 +1,16 @@ +#!/hint/bash + +# This file should be 'source'd by makepkg.conf to enable librefetch +edit_dlagents() { + local dlagent="@bindir@/librefetch -p $(printf %q "$(realpath -Lm "${BUILDFILE:-${BUILDSCRIPT:-PKGBUILD}}")") -- %u %o" + + local i + for i in "${!DLAGENTS[@]}"; do + if [[ "${DLAGENTS[$i]}" = https::* ]]; then + DLAGENTS[$i]="https::$dlagent" + fi + done + DLAGENTS+=("libre::$dlagent") +} +edit_dlagents +unset -f edit_dlagents diff --git a/src/librefetch/librefetch.8.ronn b/src/librefetch/librefetch.8.ronn new file mode 100644 index 0000000..cf009de --- /dev/null +++ b/src/librefetch/librefetch.8.ronn @@ -0,0 +1,214 @@ +librefetch(8) -- downloads or creates a liberated source tarball +================================================================ + +## SYNOPSIS + +`librefetch` [<OPTIONS>] <SOURCE-URL> [<OUTPUT-FILE>]<br> +`librefetch` `-`[`g`|`S`|`M`|`h`] + +## DESCRIPTION + +`librefetch` is a program to streamline creation of custom source +tarballs for `PKGBUILD(5)` files. + +If a URL mentioned in the <source> array in a `PKGBUILD` is in a +location that Parabola uploads "custom" source tarballs to (or +configured locations), and no file is at that URL, librefetch will +automatically create it for you. + +This works because a post-install script for the package configures +`librefetch` as the download agent for `https://` URLs in +`makepkg.conf`; allowing it to jump in and create a file if need be. +Because of this, it is almost never necessary to call `librefetch` +manually. + +The post-install script also configures `librefetch` as the download +agent for `libre://` URLs, for compatibility with `PKGBUILD` files +that used a previous version of librefetch. + +There are 5 modes: + + * `download`: Download the tarball from the configured mirror. + * `create`: Create the tarball from a `PKGBUILD`/`SRCBUILD`. + * `checksums`: Generate integrity checks for source files. + * `srcbuild`: Print the effective build script. + * `makepkg`: Generate and print the location of the effective makepkg + script. + * `help`: Print `librefetch` usage information. + +The normal mode of operation is `download` mode. If `download` mode +fails, it may choose to try `create` mode. + +## OPTIONS + + * `-C`: Force `create` mode (don't download) + * `-D`: Force `download` mode (don't create) + * `-p` <file>: Use an alternate build script for `create` mode + (instead of `PKGBUILD`). If an `SRCBUILD` file exists in the same + directory, it is used instead. + * `-g` | `--geninteg`: Use `checksums` mode: Generate integrity + checks for source files. + * `-S` | `--srcbuild`: Use `srcbuild` mode: print the effective build + script. + * `-M` | `--makepkg`: Use `makepkg` mode: generate and print the + location of the effective makepkg script. + * `-h` | `--help`: Use `help` mode: Show usage information. + +Other options, if they are documented in `makepkg -h`, are passed to +the modified copy of makepkg created during `create` mode. + +## DOWNLOAD MODE + +If <SOURCE-URL> begins with the string `libre://`, it is replaced with +the first value in <MIRRORS>, as configured in `librefetch.conf(5)`; +this is for compatibility with `PKGBUILD` files that used a previous +version of librefetch. + +It uses <DOWNLOADER>, as configured in `librefetch.conf` to attempt to +download the source tarball from that URL. If that fails, and +following conditions are met, it proceeds to `create` mode: + + * The `-D` flag has not been specified to inhibit `create` mode. + * The <SOURCE-URL> begins with one of the values in <MIRRORS>. + +The latter requirement allows librefetch to be used as a generic +HTTP(S) download agent, that can automatically create files from +whitelisted locations. + +## CREATE MODE + +The principle of `create` mode is that a special `PKGBUILD(5)` (called +`SRCBUILD(5)`) installs source files to <$pkgdir>, and the resulting +"package" is then used as a source tarball. The `SRCBUILD` exists in +the same directory as the `PKGBUILD`. It can be created manually, or +generated on-the-fly from the `PKGBUILD`. Extra steps are taken to +ensure that as long as the same directory contents go in, an identical +tarball will come out--the checksum of the file should not change +based on when it is built or who builds it. + +The `SRCBUILD` is either created, or sanitized if it already exists. +If the output filename does not end with `.sig` or `.sig.part`, then +the `SRCBUILD` is fed to a modified version of `makepkg(8)`. If the +output filename does end with `.sig` or `.sig.part`, then it uses GPG +to create a signature. If the file it is trying to sign does not +exist yet, librefetch recurses on itself to create it. + +The reason `makepkg` must be modified is that we need the resulting +tarball to be deterministic (as well as not containing package +metadata). + +When this documentation speaks of a file being modified, it is a +temporary copy of the file that is modified, your original file will +remain intact. + +## SRCBUILD GENERATION + +As explained in the `CREATE MODE` section, in `create` mode, this +program generates an `SRCBUILD` file. For debugging purposes, this +file can be printed instead of executed with `srcbuild` mode. + +### PRE-EXISTING SRCBUILD + +The use of `SRCBUILD` files pre-dates `librefetch`. By convention, +they set <PKGDEST> and <PKGEXT> in `package()` in order to modify the +behavior of `makepkg`. Because a modified version of `makepkg` is +used, this interferes with the correct behavior. To compensate for +this, lines containing "`PKGDEST=`" or "`PKGEXT=`" are deleted from +the `SRCBUILD`. + +The general idea is that `build()` makes any modifications to the +source, then `package()` copies it from <$srcdir> to <$pkgdir>. + +### SRCBUILD FROM PKGBUILD + +Possibly more elegant than having a separate `SRCBUILD` file is having +an `mksource()` function in the main `PKGBUILD`. This results in less +boilerplate and fewer files to edit. + +Note that this only happens if a file named `SRCBUILD` doesn't already +exist; when migrating a package from a manually created `SRCBUILD` to +this method, the `SRCBUILD` must be deleted (or renamed) for this to +work. + +The dynamically created `SRCBUILD` is created by copying `PKGBUILD` to +a temporary file, then re-setting variables and re-defining functions. +Following is a table of the translations. + + Variables + source = mksource + noextract = mknoextract + *sums = mk*sums (md5, sha1, sha224, sha256, sha384, sha512) + depends = <empty> + checkdepends = <empty> + makedepends = mkdepends + *_$CARCH = <unset> + Functions + prepare() { :; } + build() { mksource; } + check() { :; } + package() { cp -a "$srcdir"/*/ "$pkgdir/"; } + +The `mksource()` function does not need to be defined. If it isn't +defined, then no transformations will be made to the source between it +being extracted to <$srcdir> and copied to <$pkgdir>. + +In summary: + + * Set <mksource=()> and <mkmd5sums=()> to act as <source=()> and + <md5sums=()>, respectively. + * Declare a `mksource()` function to make modifications to the + source, if necessary. + +Other changes: + + * <pkgname> is set to <pkgbase>, or the first element of the + <pkgname> array (the effect is that split packaging is turned + off). + * <options=()> is set have `makepkg` avoid making changes to + <$pkgdir>. The exact change is: + + options=(!strip docs libtool staticlibs emptydirs !zipman purge !upx) + + * <PURGE_TARGETS=()> has VCS directories added to it: + + PURGE_TARGETS=(.bzr/ .cvs/ .git/ .hg/ .svn/ .makepkg/) + +### MAKEPKG MODIFICATIONS + +The following modifications are made to makepkg: + + * Allow us to manipulate the output file (<$pkg_file>) + * Do not include metadata in the output file (<${comp_files[@]}>) + * Force 'ustar' tar format, don't allow it to upgrade to 'pax' to + store extended file attributes. + * Don't symlink the resulting file into the current directory. + * <PURGE_TARGETS> interprets an item as a directory if it ends with a + slash ("/"). + * Timestamps in <$pkgdir> are reset to the date specified in + <SOURCE_DATE_EPOCH>[1], or "1990-01-01 0:0:0 +0" if it's not set, so + that the resulting tarball will be the same, regardless of when it + was created. + * Sort the files included in the tarball; normally the order of files + in a tarball is essentially random (even if it tends to be the same + when re-created on the same machine). + * append `-libre` to <$srcdir> + * append `-libre` to <$pkgbasedir> (which becomes <$pkgdir>) + * Don't check if the package has already been built. + +For debugging purposes, this modified makepkg can be printed instead +of executed with `makepkg` mode. Before it is run in create mode, +`PKGEXT`, `PKGDEST`, and `pkg_file` are set as environment variables. + +## CONFIGURATION + +See `librefetch.conf(5)` for details on configuring librefetch using +the `librefetch.conf` file. + +## SEE ALSO + +librefetch.conf(5), makepkg(8), PKGBUILD(5), SRCBUILD(5) + +## NOTES + + 1. <SOURCE_DATE_EPOCH> specification for build systems + https://reproducible-builds.org/specs/source-date-epoch/ diff --git a/src/librefetch/librefetch.conf b/src/librefetch/librefetch.conf new file mode 100644 index 0000000..7251ff3 --- /dev/null +++ b/src/librefetch/librefetch.conf @@ -0,0 +1,7 @@ +MIRRORS=( + 'https://repo.parabola.nu/sources/' + 'https://repo.parabola.nu/other/' + 'https://repo.parabolagnulinux.org/sources/' + 'https://repo.parabolagnulinux.org/other/' +) +DOWNLOADER='/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u' diff --git a/src/librefetch/librefetch.conf.5.ronn b/src/librefetch/librefetch.conf.5.ronn new file mode 100644 index 0000000..29df4d2 --- /dev/null +++ b/src/librefetch/librefetch.conf.5.ronn @@ -0,0 +1,42 @@ +librefetch.conf(5) -- librefetch configuration file +=================================================== + +## SYNOPSIS + +`/etc/libretools.d/librefetch.conf`, `~/.config/libretools/librefetch.conf` + +## DESCRIPTION + +Configuration for librefetch is stored in `librefetch.conf`. The +several places it looks for the file are: + + * `/etc/libretools.d/librefetch.conf` + * `$XDG_CONFIG_HOME/libretools/librefetch.conf` + +The later files take precedence over earlier files, but earlier files +are loaded, so that later files only need to set the values they want +to override. + +If `$XDG_CONFIG_HOME` is not set, a default value is set: + + * if `$SUDO_USER` is set: `$(eval echo ~$SUDO_USER)/.config` + * else: `$HOME/.config` + +## OPTIONS + + * `MIRRORS=( ... )`: + A list of locations that generated source tarballs may be located + at. If a URL begins with `libre://`, then `libre://` is replaced + with the first location listed here. + * `DOWNLOADER='/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'`: + The HTTP client to use when downloading pre-built source tarballs + in download mode. The format and semantics are similar to + `DLAGENTS` in `makepkg.conf`(5). If present, `%u` will be replaced + with the download URL (correctly quoted), otherwise the download + URL will be appended to the end of the command. If present, `%o` + will be replaced with the local filename that it should be + downloaded to. + +## SEE ALSO + +librefetch(8), makepkg.conf(5) diff --git a/src/librefetch/librefetchdir/Makefile b/src/librefetch/librefetchdir/Makefile new file mode 100644 index 0000000..58116bb --- /dev/null +++ b/src/librefetch/librefetchdir/Makefile @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# librefetchdir/Makefile +# +# Copyright (C) 2016 Luke Shumaker <lukeshu@sbcglobal.net> +# +# License: GNU GPLv3+ +# +# This file is part of LibreFetch. +# +# LibreFetch 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. +# +# LibreFetch 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 LibreFetch. If not, see <http://www.gnu.org/licenses/>. + +# new = +librefetchdir := $(dir $(lastword $(MAKEFILE_LIST))) + +old_makepkg := $(shell which makepkg) +old_library := $(shell $(shell grep LIBRARY= $(old_makepkg)); echo $$LIBRARY) + +new_makepkg = $(new)/makepkg +new_library = $(new)/libmakepkg + +targets += $(new_makepkg) +targets += $(patsubst $(old_library)/%,$(new_library)/%,$(shell find $(old_library) -type f)) +targets += $(new_library)/tidy/~source_date_epoch.sh + +all: $(targets) +.PHONY: all + +.SECONDARY: +.DELETE_ON_ERROR: + +$(new_makepkg): $(old_makepkg) $(librefetchdir)/makepkg.gen + <$^ | install -Dm755 /dev/stdin $@ + +$(new_library)/source.sh: \ +$(new_library)/%: $(old_library)/% $(librefetchdir)/libmakepkg/%.gen + <$^ | install -Dm755 /dev/stdin $@ + +$(new_library)/tidy/purge.sh $(new_library)/tidy/~source_date_epoch.sh: \ +$(new_library)/%: $(librefetchdir)/libmakepkg/% + mkdir -p $(@D) + ln -sfT $(abspath $< $@) + +$(new_library)/%: $(old_library)/% + mkdir -p $(@D) + ln -sfT $(abspath $< $@) diff --git a/src/librefetch/librefetchdir/libmakepkg/source.sh.gen b/src/librefetch/librefetchdir/libmakepkg/source.sh.gen new file mode 100755 index 0000000..269f9fd --- /dev/null +++ b/src/librefetch/librefetchdir/libmakepkg/source.sh.gen @@ -0,0 +1,25 @@ +#!/usr/bin/sed -rf +# librefetchdir/makepkg.gen +# +# Copyright (C) 2013, 2016 Luke Shumaker <lukeshu@sbcglobal.net> +# +# License: GNU GPLv3+ +# +# This file is part of LibreFetch. +# +# LibreFetch 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. +# +# LibreFetch 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 LibreFetch. If not, see <http://www.gnu.org/licenses/>. + +/download_sources\(\) \{/ { + arm -rf "$srcdir"\nmkdir "$srcdir" +} diff --git a/src/librefetch/librefetchdir/libmakepkg/tidy/purge.sh b/src/librefetch/librefetchdir/libmakepkg/tidy/purge.sh new file mode 100755 index 0000000..acb0030 --- /dev/null +++ b/src/librefetch/librefetchdir/libmakepkg/tidy/purge.sh @@ -0,0 +1,58 @@ +#!/usr/bin/bash +# +# purge.sh - Remove unwanted files from the package +# +# Copyright (c) 2008-2016 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (c) 2013-2016 Luke Shumaker <lukeshu@sbcglobal.net> +# +# License: GNU GPLv2+ +# +# This file is part of LibreFetch +# +# This program 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 2 of the License, or +# (at your option) any later version. +# +# This program 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 program. If not, see <http://www.gnu.org/licenses/>. +# + +[[ -n "$LIBMAKEPKG_TIDY_PURGE_SH" ]] && return +LIBMAKEPKG_TIDY_PURGE_SH=1 + +LIBRARY=${LIBRARY:-'/usr/share/makepkg'} + +source "$LIBRARY/util/message.sh" +source "$LIBRARY/util/option.sh" + + +packaging_options+=('purge') +tidy_remove+=('tidy_purge') + +tidy_purge() { + if check_option "purge" "y" && [[ -n ${PURGE_TARGETS[*]} ]]; then + msg2 "$(gettext "Purging unwanted files...")" + 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 + fi +} diff --git a/src/librefetch/librefetchdir/libmakepkg/tidy/~source_date_epoch.sh b/src/librefetch/librefetchdir/libmakepkg/tidy/~source_date_epoch.sh new file mode 100755 index 0000000..9141d67 --- /dev/null +++ b/src/librefetch/librefetchdir/libmakepkg/tidy/~source_date_epoch.sh @@ -0,0 +1,38 @@ +#!/usr/bin/bash +# +# librefetchdir/libmakepkg/tidy/~source_date_epoch.sh +# +# Copyright (C) 2013-2016 Luke Shumaker <lukeshu@sbcglobal.net> +# +# License: GNU GPLv3+ +# +# This file is part of LibreFetch. +# +# LibreFetch 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. +# +# LibreFetch 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 LibreFetch. If not, see <http://www.gnu.org/licenses/>. + +# This filename starts with a ~ because it sorts after every other +# (printable) ASCII character, and we want this to run last. + +[[ -n "$LIBMAKEPKG_TIDY_SOURCE_DATE_EPOCH_SH" ]] && return +LIBMAKEPKG_TIDY_SOURCE_DATE_EPOCH_SH=1 + +tidy_modify+=('tidy_source_date_epoch') + +tidy_source_date_epoch() { + local date='1990-01-01 0:0:0 +0' + if [[ -n "$SOURCE_DATE_EPOCH" ]]; then + date="@$SOURCE_DATE_EPOCH" + fi + find . -exec touch --no-dereference --date="$date" -- {} + +} diff --git a/src/librefetch/librefetchdir/makepkg.gen b/src/librefetch/librefetchdir/makepkg.gen new file mode 100755 index 0000000..8928d91 --- /dev/null +++ b/src/librefetch/librefetchdir/makepkg.gen @@ -0,0 +1,42 @@ +#!/usr/bin/sed -rf +# librefetchdir/makepkg.gen +# +# Copyright (C) 2013-2016 Luke Shumaker <lukeshu@sbcglobal.net> +# +# License: GNU GPLv3+ +# +# This file is part of LibreFetch. +# +# LibreFetch 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. +# +# LibreFetch 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 LibreFetch. If not, see <http://www.gnu.org/licenses/>. + +/LIBRARY=/iexport LIBRARY="${0%/*}/libmakepkg" + +/create_package\(\) \{/,/^\}$/ { + /pkg_file=/d # allow us to set pkg_file + s/"?\$\{comp_files\[@\]\}"?// # do not include .{PKGINFO,BUILDINGO,CHANGELOG,INSTALL,MTREE} + # 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/--files-from to order them for 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 +} + +s|Making package:|Making source:| +s|Checking runtime dependencies\.\.\.|Checking source dependencies...| + /Checking buildtime dependencies\.\.\./d + +s|srcdir=.*|&-libre| +s|pkgdirbase=.*|&-libre| +s|check_build_status$|:| |