summaryrefslogtreecommitdiff
path: root/src/abslibre-tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/abslibre-tools')
-rw-r--r--src/abslibre-tools/Makefile4
-rwxr-xr-xsrc/abslibre-tools/createworkdir54
-rw-r--r--src/abslibre-tools/createworkdir.md36
-rwxr-xr-xsrc/abslibre-tools/diff-unfree89
-rwxr-xr-xsrc/abslibre-tools/libreaddiff98
-rwxr-xr-xsrc/abslibre-tools/libredbdiff360
-rwxr-xr-xsrc/abslibre-tools/librerelease257
-rwxr-xr-xsrc/abslibre-tools/librestage154
8 files changed, 1052 insertions, 0 deletions
diff --git a/src/abslibre-tools/Makefile b/src/abslibre-tools/Makefile
new file mode 100644
index 0000000..2903f4a
--- /dev/null
+++ b/src/abslibre-tools/Makefile
@@ -0,0 +1,4 @@
+include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
+include $(topsrcdir)/automake.head.mk
+
+include $(topsrcdir)/automake.tail.mk
diff --git a/src/abslibre-tools/createworkdir b/src/abslibre-tools/createworkdir
new file mode 100755
index 0000000..5599de9
--- /dev/null
+++ b/src/abslibre-tools/createworkdir
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+# CreateWorkDir
+# Creates a dir structure for working with Parabola packages
+
+# Copyright (C) 2010-2011 Nicolás Reynolds <fauno@parabola.nu>
+# Copyright (C) 2011 Joshua Ismael Haase Hernández (xihh) <hahj87@gmail.com>
+# Copyright (C) 2013 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 -euE
+
+. libremessages
+. "$(librelib conf.sh)"
+load_files libretools
+check_vars libretools WORKDIR ABSLIBRERECV ABSLIBRESEND # these are asked for by `xbs download`
+
+trap 'error "Aborting..."' EXIT
+
+msg "Creating WORKDIR at %s..." "$WORKDIR"
+mkdir -p "$WORKDIR"
+
+msg "Creating staging directory in WORKDIR..."
+mkdir -p "$WORKDIR/staging"
+
+cmd=(xbs -b abslibre download)
+if ! "${cmd[@]}"; then
+ error "Could not clone ABSLibre"
+ plain "Try running this command:"
+ echo
+ printf '%q ' "${cmd[@]}"
+ echo
+ exit 1
+fi
+
+msg "Finished, your packaging directory tree looks like this now:"
+ls --color=auto "${WORKDIR}"/*
+
+trap -- EXIT
diff --git a/src/abslibre-tools/createworkdir.md b/src/abslibre-tools/createworkdir.md
new file mode 100644
index 0000000..e50b00f
--- /dev/null
+++ b/src/abslibre-tools/createworkdir.md
@@ -0,0 +1,36 @@
+# CreateWorkDir
+
+This script recreates a proper directory tree for packaging. Its aim is to help
+you be organized with the work you do as a packager, and establish a certain
+standard for packages' publication, so you don't have to lose much time with
+them. Just package and upload!
+
+It will create a directory tree like this:
+
+ $WORKDIR/
+ ├── abslibre/
+ │ ├── .git/
+ │ ├── libre/<PKGBUILDS>
+ │ └── libre-testing/<PKGBUILDS>
+ └── staging/
+ ├── libre/
+ └── libre-testing/
+
+*Related Variables*
+ - WORKDIR
+
+## staging/
+
+This directory contains one directory for each repository, where the resulting
+packages are in moved for syncing against the main repository on Parabola's
+server. This directory is architecture independent.
+
+## abslibre/
+
+This is the git repo for Parabola's PKGBUILDs. Here you can find the ABS tree
+for our packages, and also where you'll have to put new ones for commit.
+
+(You'll need push access to Parabola's main server, but pulling is public.)
+
+*Related Variables*
+ - ABSLIBREGIT
diff --git a/src/abslibre-tools/diff-unfree b/src/abslibre-tools/diff-unfree
new file mode 100755
index 0000000..12c919f
--- /dev/null
+++ b/src/abslibre-tools/diff-unfree
@@ -0,0 +1,89 @@
+#!/usr/bin/env bash
+# This script will help you diff a *-libre PKGBUILD against the unfree one
+# to check for updates.
+
+# Copyright (C) 2010-2011 Nicolás Reynolds <fauno@parabola.nu>
+# Copyright (C) 2011 Joshua Ismael Haase Hernández (xihh) <hahj87@gmail.com>
+#
+# 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/>.
+
+. libremessages
+. "$(librelib conf.sh)"
+load_files libretools
+check_vars libretools DIFFPROG || exit 1
+
+usage() {
+ print "Usage: %s [community|packages] [unfree-package] [repo]" "${0##*/}"
+ print "Usage: %s --help" "${0##*/}"
+ prose "Helps you diff build scripts from ABSLibre against (Unfree) ABS."
+ echo
+ prose "Package name and repo will we guessed if you don't specify them."
+}
+
+main() {
+ if [[ "$1" == "--help" ]]; then
+ usage
+ exit 0
+ fi
+
+ local package_guess=${PWD##*/}
+ local repo=${1:-$(basename ${PWD%/*})}
+ local package=${2:-${package_guess%-libre}}
+ local trunk=${3:-trunk}
+
+ svnrepo="packages"
+ case $repo in
+ community*) svnrepo="community";;
+ multilib*) svnrepo="community";;
+ *) :;;
+ esac
+
+ if [[ ! -r PKGBUILD ]]; then
+ error "This is not a build dir."
+ exit 1
+ fi
+
+
+ tmp_dir="$(mktemp --tmpdir -d ${package}.XXXXXX)"
+ if [[ ! -d "${tmp_dir}" ]]; then
+ error "Can't create temp dir"
+ exit 1
+ fi
+ unfree_dir="${tmp_dir}/${svnrepo}/${package}/${trunk}"
+
+ pushd "${tmp_dir}" &>/dev/null
+
+ msg "Getting diff from %s..." "$repo/$package"
+
+ svn checkout --depth=empty svn://svn.archlinux.org/$svnrepo &>/dev/null
+
+ cd ${svnrepo}
+ svn update ${package}
+
+ # Back to start dir
+ popd &>/dev/null
+
+ msg "Diffing files"
+
+ for _file in ${unfree_dir}/*; do
+ msg2 "%s" "$(basename "${_file}")"
+ ${DIFFPROG} "$PWD/$(basename "${_file}")" "${_file}"
+ done
+}
+
+main "$@"
diff --git a/src/abslibre-tools/libreaddiff b/src/abslibre-tools/libreaddiff
new file mode 100755
index 0000000..8698920
--- /dev/null
+++ b/src/abslibre-tools/libreaddiff
@@ -0,0 +1,98 @@
+#!/usr/bin/env bash
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2011-2012 Michał Masłowski <mtjm@mtjm.eu>
+# Copyright (C) 2012 Daniel Molina (lluvia)
+#
+# License: GNU GPLv3+
+#
+# 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 3 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 Affero 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/>.
+
+set -e
+
+. libremessages
+. "$(librelib conf.sh)"
+load_files libretools
+check_vars libretools WORKDIR
+
+for arg in "$@" ; do
+ case "$arg" in
+ -h|--h|--he|--hel|--help|-\?)
+ {
+ print 'Usage: %s repo [arch]' "${0##*/}"
+ echo
+ prose "This script outputs a diff of package names and versions
+ in repo between pacman's sync db and abslibre checkout."
+ } >&2
+ exit 0
+ ;;
+ esac
+done
+
+# The repo to find missing packages in.
+repo=$1
+# The arch to check in Arch repos, other will have all arches checked.
+arch=${2:-mips64el}
+# A Python tuple of repos which don't have arch=any packages.
+archrepos='("core", "extra", "community")'
+
+diff -U0 \
+ <( (
+ cd /var/lib/pacman/sync
+ for f in $repo.db ; do
+ tar xOf $f | python -c 'import sys
+arch = None
+name = None
+version = None
+it = iter(sys.stdin)
+try:
+ while True:
+ line = next(it)
+ if line == "%ARCH%\n":
+ arch = next(it)
+ if arch == "'"$arch"'\n" or "'$repo'" not in '"$archrepos"':
+ print("%s-%s" % (name.strip(), version.strip()))
+ if line == "%NAME%\n":
+ name = next(it)
+ if line == "%VERSION%\n":
+ version = next(it)
+except StopIteration:
+ pass
+'
+ done
+ ) | sort ) \
+ <( (
+ cd "${WORKDIR}/abslibre"
+ # Needed to not include pkgnames specific to other arches.
+ CARCH=$arch
+ for f in $repo/* ; do
+ load_PKGBUILD "$f/PKGBUILD" || continue
+ is_here=false
+ for arc in ${arch[@]} ; do
+ if [[ "$arc" == "any" ]] || [[ "$arc" == "$CARCH" ]] ; then
+ is_here=true
+ break
+ fi
+ done
+ if [[ "$is_here" == "true" ]] ; then
+ for name in "${pkgname[@]}" ; do
+ if [[ -z "$epoch" ]] ; then
+ echo $name-$pkgver-$pkgrel
+ else
+ echo $name-$epoch:$pkgver-$pkgrel
+ fi
+ done
+ fi
+ done
+ ) | sort ) | sed -rn 's/^[+-][^+-].+$/&/p'
diff --git a/src/abslibre-tools/libredbdiff b/src/abslibre-tools/libredbdiff
new file mode 100755
index 0000000..09c7ad1
--- /dev/null
+++ b/src/abslibre-tools/libredbdiff
@@ -0,0 +1,360 @@
+#!/usr/bin/env bash
+name="Libredbdiff"
+
+# Copyright (C) 2014 Esteban Carnevale <alfplayer@mailoo.org>
+# Copyright (C) 2014 Luke Shumaker <lukeshu@sbcglobal.net>
+#
+# License: GNU GPLv3+
+#
+# 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 3 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/>.
+
+baseconfpath="/etc/libredbdiff"
+basedbpath="/var/lib/libredbdiff"
+
+conffile="$baseconfpath/pacman.conf.parabola"
+conffilearch="$baseconfpath/pacman.conf.archlinux"
+
+dbpath="$basedbpath/pacman.parabola"
+dbpatharch="$basedbpath/pacman.archlinux"
+
+mirrorlist="$baseconfpath/mirrorlist.parabola"
+mirrorlistarch="$baseconfpath/mirrorlist.archlinux"
+
+mirror='http://repo.parabola.nu/$repo/os/$arch'
+mirrorarch='http://mirrors.kernel.org/archlinux/$repo/os/$arch'
+
+repos="libre pcr libre-multilib nonprism"
+
+field_pkgname_parabola=30
+field_pkgname_arch=30
+
+
+. libremessages
+
+cmd="${0##*/}"
+
+arch_packages_tmp="/tmp/${cmd}.arch-packages"
+parabola_packages_tmp="/tmp/${cmd}.parabola-packages"
+
+field_pkgname_total="$((${field_pkgname_parabola} + ${field_pkgname_arch}))"
+printf_format="%s %-${field_pkgname_parabola}s%-${field_pkgname_arch}s %s | %s\n"
+printf_format_noarch="%s %-${field_pkgname_total}s %s\n"
+
+downloadfile() {
+ local outfile=$1
+ local url=$2
+ local mesg=("${@:3}")
+ if [[ ! -e $outfile ]] ; then
+ msg "${mesg[@]}"
+ if wget -q "$url" -O "$outfile"; then
+ return 255
+ else
+ die "Failed to download %q. Exiting." "$outfile"
+ fi
+ elif [[ $init ]]; then
+ warning "%q already exists. Skipping." "$outfile"
+ fi
+}
+
+enablerepo() {
+ repo="$1"
+ conffile_arg="$2"
+ msg2 "Enabling repo %q in %q" "$repo" "${conffile_arg}"
+ sed -i "s/\#\[$repo\]/[$repo]/" "${conffile_arg}"
+ sed -i "\/\[$repo\]/,+1 s/#Include/Include/" "${conffile_arg}"
+}
+
+createdir() {
+ local dir=$1
+ if [[ ! -e $dir ]] ; then
+ msg "Creating directory %q" "$dir"
+ mkdir -- "$1" || die "Failed to create directory %q. Exiting." "$dir"
+ elif [[ $init ]]; then
+ warning "%q already exists. Skipping." "$dir"
+ fi
+}
+
+setmirror() {
+ local distro="$1"
+ local mirror="$2"
+ local mirrorlist="$3"
+ if [[ $init ]] && [[ $mirror ]]; then
+ mirrorescaped="${mirror//./\\.}"
+ mirrorescaped="${mirrorescaped//\$/\\$}"
+ msg2 "Setting %s as the only enabled %s mirror." "${mirror}" "${distro}"
+ sed -i 's|^#\(Server = '"${mirrorescaped}"'\)$|\1|' "${mirrorlist}"
+ fi
+}
+
+filenotfound() {
+ local file=$1
+ if [[ ! -r $1 ]]; then
+ error "Could not read %q." "$file"
+ die "Nothing done. It may be necessary to run %q without \
+arguments as root to initialize %s." "$cmd" "$name"
+ fi
+}
+
+initialize() {
+ createdir "$baseconfpath"
+ createdir "$basedbpath"
+
+ downloadfile \
+ "${conffile}" \
+ "https://projects.parabola.nu/abslibre.git/plain/libre/pacman/pacman.conf.x86_64" \
+ "Downloading Parabola %q" \
+ pacman.conf
+ if [[ $? == 255 ]] ; then
+ msg2 "Setting DBPath in %q" "${conffile}"
+ sed -i "s|^#DBPath .*|DBPath = ${dbpath}|" "${conffile}"
+ enablerepo nonprism "${conffile}"
+ enablerepo pcr "${conffile}"
+ enablerepo libre-multilib "${conffile}"
+ enablerepo multilib "${conffile}"
+ fi
+
+ downloadfile \
+ "${conffilearch}" \
+ "https://projects.archlinux.org/svntogit/packages.git/plain/pacman/trunk/pacman.conf.x86_64" \
+ "Downloading Arch %q" \
+ pacman.conf
+ if [[ $? == 255 ]] ; then
+ msg2 "Setting DBPath in %q" "${conffilearch}"
+ sed -i "s|^#DBPath .*|DBPath = ${dbpatharch}|" "${conffilearch}"
+ msg2 "Setting Arch mirrorlist file in %q" "${conffilearch}"
+ sed -i "s|/etc/pacman\.d/mirrorlist$|$baseconfpath/mirrorlist.archlinux|" \
+ "${conffilearch}"
+ enablerepo multilib "${conffilearch}"
+ fi
+
+ downloadfile \
+ "${mirrorlist}" \
+ "https://repo.parabola.nu/mirrorlist.txt" \
+ "Downloading Parabola %q" \
+ mirrorlist
+ if [[ $? == 255 ]] ; then
+ sed -i 's|^Server|#Server|' "${mirrorlist}"
+ setmirror "Parabola" "$mirror" "$mirrorlist"
+ fi
+
+ downloadfile \
+ "${mirrorlistarch}" \
+ "https://projects.archlinux.org/svntogit/packages.git/plain/pacman-mirrorlist/trunk/mirrorlist" \
+ "Downloading Arch %q" \
+ mirrorlist
+ if [[ $? == 255 ]] ; then
+ setmirror "Arch" "$mirrorarch" "$mirrorlistarch"
+ fi
+}
+
+repo_test() {
+ for repo in ${repos} ; do
+ if [[ $repo == $1 ]] ; then
+ found=1
+ return 0
+ fi
+ done
+ if [[ $found != 1 ]] ; then
+ die "The specified Parabola repo \"%s\" cannot be compared. It's not in the list of repos in the configuration variable \"repos\"." "$1"
+ fi
+}
+
+compare_pkgs() {
+ local cmp
+ if [[ ${verarch[$pkgname]} ]] ; then
+ cmp=$(vercmp "${ver[$pkgname]}" "${verarch[$pkgname]}")
+ if [[ $cmp -lt 0 ]]; then
+ printf "${printf_format}" \
+ '=' \
+ "${pkgname}" \
+ "" \
+ "${ver[$pkgname]}" \
+ "${verarch[$pkgname]}"
+ fi
+ elif [[ ${provides[$pkgname]} ]]; then
+ for provide in "${provides[$pkgname]}"; do
+ if [[ ${verarch["$provide"]} ]]; then
+ cmp=$(vercmp "${ver[$pkgname]}" "${verarch[$provide]}")
+ if [[ $cmp -lt 0 ]]; then
+ printf "${printf_format}" \
+ 'p' \
+ "${pkgname}" \
+ "${provide}" \
+ "${ver[$pkgname]}" \
+ "${verarch[$provide]}"
+ fi
+ fi
+ done
+ else
+ printf "${printf_format_noarch}" \
+ 'o' \
+ "${pkgname}" \
+ "${ver[$pkgname]}"
+ fi
+}
+
+print_cmp() {
+ local repo="$1"
+ awk -F/ -v repo="$repo" \
+ '$1 == repo {print $2}' \
+ ${parabola_packages_tmp} | \
+ while read -a line ; do
+ ver["${line[0]}"]="${line[1]}"
+ provides[${line[0]}]="${line[@]:2}"
+ pkgname=${line[0]}
+ compare_pkgs
+ done
+}
+
+usage() {
+ print "Usage: %q [-n|-h]" "$cmd"
+ print 'Show packages that need to be updated from Arch repositories.'
+ echo
+ prose "Compares packages in Parabola repositories. Packages from
+ all configured Parabola repositories are compared. A Parabola
+ repository name can be specified as argument to compare only
+ packages in that repository."
+ echo
+ prose "The default mode of operation is to download/update all necessary
+ files for comparison, but not compare them. Specify the \`-n\`
+ flag to not download anything, but to compare already downloaded
+ files."
+ echo
+ print 'Options:'
+ flag '-n' "Don't update anything, just compare already downloaded files."
+ flag '-h' 'Show this message'
+ echo
+ print "Output format:"
+ print "type_character parabola_pkgname (arch_pkgname) parabola_pkgver - (arch_pkgver)"
+ echo
+ print "Type characters:"
+ flag '=' "Arch package with the same pkgname and greater pkgver was found"
+ flag 'p' "Arch package with pkgname equal to a provide and greater
+ pkgver was found In this case arch_pkgname is a provide of
+ parabola_pkgname"
+ flag 'o' "No Arch package with the same pkgname or with pkgname equal to
+ a provide was found"
+}
+
+main() {
+ local UPDATE=1
+ local arg
+ local repo_arg
+
+ for arg in "$@"; do
+ case "$arg" in
+ -n|--noupdate)
+ UPDATE=0
+ ;;
+ -h|--help)
+ usage
+ return 0
+ ;;
+ *)
+ repo_test "$arg"
+ repo_arg="$arg"
+ break
+ ;;
+ esac
+ done
+
+ if (( $UPDATE )) ; then
+ if [[ $EUID != 0 ]]; then
+ die "To initialize %s or update %s pacman databases, %s must be run as root (without arguments). Nothing done." \
+ "$name" \
+ "$name" \
+ "$cmd"
+ fi
+
+ if ! [[ -e "${conffile}" && \
+ -e "${conffilearch}" && \
+ -e "${mirrorlist}" && \
+ -e "${mirrorlist}" ]]; then
+ warning "At least one %s configuration file is missing." \
+ "${name}"
+ msg "Downloading and preparing missing configuration files."
+ init=1
+ fi
+
+ createdir "$baseconfpath"
+ createdir "$basedbpath"
+
+ initialize
+
+ if ! [[ -d "$dbpath" && \
+ -d "$dbpatharch" ]]; then
+ warning "At least one %s pacman DB directory is missing. Synchronizing %s DB files." \
+ "${name}" "${name}"
+ fi
+
+ createdir "$dbpath"
+ msg "Synchronizing %s pacman databases for Parabola" "$name"
+ pacman --config "${conffile}" -Sy ||
+ die "Failed to synchronize pacman database for Parabola. Exiting."
+
+ createdir "$dbpatharch"
+ msg "Synchronizing %s pacman databases for Arch" "$name"
+ pacman --config "${conffilearch}" -b "${dbpatharch}" -Sy ||
+ die "Failed to synchronize pacman database for Arch. Exiting."
+
+ msg "%s pacman databases are updated. %s is ready. Run %q -n to print results." \
+ "$name" "$name" "$cmd"
+ return 0
+ else
+ filenotfound "${dbpath}"
+ filenotfound "${dbpatharch}"
+ filenotfound "${conffile}"
+ filenotfound "${conffilearch}"
+ filenotfound "${mirrorlist}"
+ filenotfound "${mirrorlistarch}"
+
+ unset provides ver verarch
+ declare -gA provides ver verarch
+
+ if ! [[ -d "$dbpath" && \
+ -d "$dbpatharch" ]]; then
+ die "At least one %s pacman DB directory is missing. To update %s pacman databases, %s must be run as root. Nothing done." \
+ "$name" \
+ "$name" \
+ "$cmd"
+ fi
+
+ pacman --config "${conffilearch}" -Ss | \
+ grep -v '^ ' | \
+ awk -F/ '{print $2}' \
+ > ${arch_packages_tmp} || \
+ die "pacman command to get Arch package data has failed. Exiting."
+ chmod 777 ${arch_packages_tmp}
+
+ while read -a line; do
+ verarch["${line[0]}"]="${line[1]}"
+ done < ${arch_packages_tmp}
+
+ expac --config "${conffile}" -S '%r/%n %v %S' \
+ > ${parabola_packages_tmp} || \
+ die "expac command to get Parabola package data has failed. Exiting."
+ chmod 777 ${parabola_packages_tmp}
+
+ if [[ ${repo_arg} ]] ; then
+ print_cmp "${repo_arg}"
+ else
+ for repo in ${repos} ; do
+ echo "[$repo]"
+ print_cmp "$repo"
+ done
+ fi
+ fi
+}
+
+main "$@"
diff --git a/src/abslibre-tools/librerelease b/src/abslibre-tools/librerelease
new file mode 100755
index 0000000..b7a77d3
--- /dev/null
+++ b/src/abslibre-tools/librerelease
@@ -0,0 +1,257 @@
+#!/usr/bin/env bash
+# Librerelease
+# Uploads packages and releases them
+
+# Copyright (C) 2010-2012 Joshua Ismael Haase Hernández (xihh) <hahj87@gmail.com>
+# Copyright (C) 2010-2013 Nicolás Reynolds <fauno@parabola.nu>
+# Copyright (C) 2013 Michał Masłowski <mtjm@mtjm.eu>
+# Copyright (C) 2013-2014 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 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/>.
+
+# create_signature() is taken from pacman:makepkg, which is GPLv2+,
+# so we take the '+' to combine it with our GPLv3+.
+
+. libremessages
+. "$(librelib conf.sh)"
+
+dryrun=""
+upload_only=false
+readonly rsync_flags=(
+ --no-group
+ --no-perms
+ --copy-links
+ --hard-links
+ --partial
+ --human-readable
+ --progress
+ -e ssh
+)
+
+# Functions ####################################################################
+
+list0_files() {
+ find -L "${WORKDIR}/staging" -type f -not -name '*.lock' \
+ -exec realpath -z --relative-to="${WORKDIR}/staging" {} +
+}
+
+# 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
+ # The signature will be generated directly in ascii-friendly format
+ gpg --detach-sign --use-agent "${SIGNWITHKEY[@]}" "$filename" || ret=$?
+
+
+ if (( ! ret )); then
+ msg2 "Created signature file %s." "$filename.sig"
+ else
+ error "Failed to sign package file."
+ return $ret
+ fi
+}
+
+sign_packages() {
+ IFS=$'\n'
+ local files=($(find "${WORKDIR}/staging/" \
+ \( -type d -name "${ABSLIBREDEST##*/}" \) -prune \
+ -o \( -type f -not -iname '*.sig' \) -print))
+ local file
+ for file in "${files[@]}"; do
+ if [[ -f "${file}.sig" ]]; then
+ msg2 "File signature found, verifying..."
+
+ # Verify that the signature is correct, else remove for re-signing
+ if ! gpg --quiet --verify "${file}.sig" >/dev/null 2>&1; then
+ error "Failed! Re-signing..."
+ rm -f "${file}.sig"
+ fi
+ fi
+
+ if ! [[ -f "${file}.sig" ]]; then
+ create_signature "$file" || return 2
+ fi
+ done
+}
+
+# Clean everything if not in dry-run mode
+clean_files() {
+ local file_list=$1
+
+ local rmcmd=(rm -fv)
+ if [[ -n "${dryrun}" ]]; then
+ rmcmd=(printf "$(_ "removed '%s' (dry-run)")\n")
+ fi
+
+ msg "Removing files from local staging directory"
+ cd "${WORKDIR}/staging" && xargs -0r -a "$file_list" "${rmcmd[@]}"
+ cd "${WORKDIR}/staging" && find . -mindepth 1 -type d -empty \
+ -exec rmdir -p {} + 2>/dev/null
+}
+
+################################################################################
+
+usage() {
+ print "Usage: %s [OPTIONS]" "${0##*/}"
+ echo
+ prose 'This script uploads packages on $WORKDIR/staging
+ to the Parabola server.'
+ echo
+ print "Options:"
+ flag '-c' 'Clean; delete packages in $WORKDIR/staging'
+ flag '-l' "List; list packages but not upload them"
+ flag '-u' "Upload-only; do not run db-update on the server"
+
+ flag '-n' "Dry-run; don't actually do anything"
+ flag '-h' "Show this message"
+}
+
+main() {
+ if [[ -w / ]]; then
+ error "This program should be run as regular user"
+ return 1
+ fi
+
+ # Parse options
+ local mode="release_packages"
+ while getopts 'clunh' arg; do
+ case $arg in
+ c) mode=clean ;;
+ l) mode=pretty_print_packages ;;
+ u) upload_only=true ;;
+ n) dryrun="--dry-run" ;;
+ h) mode=usage ;;
+ *) usage >&2; return 1 ;;
+ esac
+ done
+ shift $(($OPTIND - 1))
+ if [[ $# != 0 ]]; then
+ usage >&2
+ return 1
+ fi
+
+ if [[ $mode == usage ]]; then
+ usage
+ return 0
+ fi
+
+ load_files makepkg
+ check_vars makepkg GPGKEY
+ load_files libretools
+ check_vars libretools WORKDIR REPODEST ABSLIBREDEST || return 1
+ REPODEST+='/staging/'
+ # The following settings are actually optional
+ #check_vars libretools HOOKPRERELEASE HOOKPOSTRELEASE || return 1
+
+ "$mode"
+}
+
+# The different modes (sans 'usage') ###########################################
+
+pretty_print_packages() {
+ find "$WORKDIR/staging/" -mindepth 1 -maxdepth 1 -type d -not -empty | sort |
+ while read -r path; do
+ msg2 "${path##*/}"
+ cd "$path"
+ find -L . -type f -not -name '*.lock' | sed 's|^\./| |' | sort
+ done
+}
+
+clean() {
+ lock 8 "${WORKDIR}/staging.lock" \
+ 'Waiting for an exclusive lock on the staging directory'
+
+ local file_list="$(mktemp -t ${0##*/}.XXXXXXXXXX)"
+ trap "$(printf 'rm -f -- %q' "$file_list")" EXIT
+ list0_files > "$file_list"
+
+ lock_close 8
+
+ clean_files "$file_list"
+}
+
+release_packages() {
+ if [[ -n $HOOKPRERELEASE ]]; then
+ msg "Running HOOKPRERELEASE..."
+ plain '%s' "${HOOKPRERELEASE}"
+ bash -c "${HOOKPRERELEASE}"
+ fi
+
+ lock 8 "${WORKDIR}/staging.lock" \
+ 'Waiting for an exclusive lock on the staging directory'
+
+ sign_packages || return 1
+
+ # Make the permissions of the packages 644 otherwise the user will get access
+ # denied error when they try to download (rsync --no-perms doesn't seem to
+ # work).
+ find "${WORKDIR}/staging" -type f -exec chmod 644 {} +
+ find "${WORKDIR}/staging" -type d -exec chmod 755 {} +
+
+ local file_list="$(mktemp -t ${0##*/}.XXXXXXXXXX)"
+ trap "$(printf 'rm -f -- %q' "$file_list")" EXIT
+ list0_files > "$file_list"
+
+ lock_close 8
+
+ msg "%s to upload" "$(cd "${WORKDIR}/staging" && du -hc --files0-from="$file_list" | sed -n '$s/\t.*//p')"
+ msg "Uploading packages..."
+ xargs -0r -a "$file_list" dirname -z | ssh "${REPODEST%%:*}" "$(printf 'mkdir -p -- %q && cd %q && xargs -0r mkdir -pv --' "${REPODEST#*:}"{,})"
+ if ! rsync ${dryrun} "${rsync_flags[@]}" \
+ -0 --files-from="$file_list" \
+ "${WORKDIR}/staging" \
+ "${REPODEST}/"
+ then
+ error "Sync failed, try again"
+ return 1
+ fi
+
+ clean_files "$file_list"
+
+ if $upload_only; then
+ return 0
+ fi
+
+ msg "Running db-update on repos"
+ ssh "${REPODEST%%:*}" "$(printf 'STAGING=%q dbscripts/db-update' "${REPODEST#*:}")"
+
+ if [[ -n $HOOKPOSTRELEASE ]]; then
+ msg "Running HOOKPOSTRELEASE..."
+ plain '%s' "${HOOKPOSTRELEASE}"
+ bash -c "${HOOKPOSTRELEASE}"
+ fi
+
+ return 0
+}
+
+main "$@"
diff --git a/src/abslibre-tools/librestage b/src/abslibre-tools/librestage
new file mode 100755
index 0000000..39523ac
--- /dev/null
+++ b/src/abslibre-tools/librestage
@@ -0,0 +1,154 @@
+#!/usr/bin/env bash
+# LibreStage
+# Prepares packages for upload
+
+# Copyright (C) 2010-2012 Nicolás Reynolds <fauno@parabola.nu>
+# Copyright (C) 2011 Joshua Ismael Haase Hernández (xihh) <hahj87@gmail.com>
+# Copyright (C) 2013-2014 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/>.
+
+. libremessages
+. "$(librelib conf.sh)"
+
+usage() {
+ print "Usage: %s [REPO]" "${0##*/}"
+ print "Stages the package(s) build by ./PKGBUILD for upload."
+ echo
+ prose "The package(s) are staged for the named repository, or the name
+ of the parent directory if a repository is not named."
+}
+
+main() {
+ if [[ -w / ]]; then
+ error "This program should be run as a regular user"
+ return 1
+ fi
+
+ # Parse options, set up
+ while getopts 'h' arg; do
+ case $arg in
+ h) usage; return 0;;
+ *) usage >&2; return 1;;
+ esac
+ done
+ local repo=
+ case $# in
+ 0) repo="$(basename "$(dirname "$PWD")")";;
+ 1) repo=$1;;
+ *) usage >&2; return 1;;
+ esac
+
+ if ! [[ -e ./PKGBUILD ]]; then
+ error "PKGBUILD not found"
+ return 1
+ fi
+
+ if ! xbs -b abslibre status; then
+ error "There are uncommitted changes in the current directory"
+ return 1
+ fi
+
+ # Load configuration
+ load_files libretools
+ # ABSLIBREDEST is used by xbs release-client
+ check_vars libretools WORKDIR ARCHES ABSLIBREDEST || return 1
+ load_files makepkg # for PKGDEST and SRCDEST, which are optional
+ load_files librefetch # for MIRRORS, which is optional
+
+ # Load the PKGBUILD
+ load_PKGBUILD
+
+ # Now for the main routine.
+ local staged=false
+ slock 8 "${WORKDIR}/staging.lock" \
+ 'Waiting for a shared lock on the staging directory'
+
+ # Look for makepkg output
+ local CARCH _pkgname pkgfile
+ for CARCH in "${ARCHES[@]}" any; do
+ for _pkgname in "${pkgname[@]}" "${pkgname[@]/%/-debug}"; do
+ if ! pkgfile=$(find_cached_package "$_pkgname" "$(get_full_version "$_pkgname")" "$CARCH"); then
+ continue
+ fi
+
+ msg 'Found package: %s' "${pkgfile##*/}"
+
+ # This little check is from devtools:commitpkg
+ if grep -q "packager = Unknown Packager" <(bsdtar -xOqf "$pkgfile" .PKGINFO); then
+ die "PACKAGER wes not set when building package"
+ fi
+
+ xbs -b abslibre release-client "$repo" "$CARCH"
+ mkdir -p "${WORKDIR}/staging/${repo}"
+ if cp "$pkgfile" "${WORKDIR}/staging/${repo}/${pkgfile##*/}"; then
+ msg2 "%s staged on [%s]" "$_pkgname" "$repo"
+ staged=true
+ else
+ error "Can't put %s on [%s]" "$_pkgname" "$repo"
+ return 1
+ fi
+ done
+ done
+
+ # Look for librefetch output
+ local netfile mirror path
+ local srcurl srcname srcpath
+ for netfile in "${source[@]}"; do
+ for mirror in "${MIRRORS[@]}"; do
+ srcurl=${netfile#*::}
+ if [[ "$srcurl" == "$mirror"* ]]; then
+ if [[ $netfile = *::* ]]; then
+ srcname=${netfile%%::*}
+ else
+ srcname=${netfile##*/}
+ fi
+
+ srcpath=''
+ for path in "./$srcname" "${SRCDEST:-.}/$srcname"; do
+ if [[ -f "$path" ]]; then
+ srcpath="$path"
+ break
+ fi
+ done
+ if [[ -n "$srcpath" ]]; then
+ msg "Found generated source file: %s" "$srcname"
+ local dest="${WORKDIR}/staging/other/${srcurl##"$mirror"}"
+ mkdir -p -- "${dest%/*}"
+ if cp "$srcpath" "$dest"; then
+ msg2 "%s staged on [%s]" "$srcname" other
+ staged=true
+ else
+ error "Can't put %s on [%s]" "$srcname" other
+ return 1
+ fi
+ fi
+ break
+ fi
+ done
+ done
+
+ if $staged ; then
+ return 0
+ else
+ error "Nothing was staged"
+ return 1
+ fi
+}
+
+main "$@"