diff options
118 files changed, 5257 insertions, 2948 deletions
@@ -1,2 +1,19 @@ *~ #* +*.pot +*.1 +*.2 +*.3 +*.4 +*.5 +*.6 +*.7 +*.8 +*.1.html +*.2.html +*.3.html +*.4.html +*.5.html +*.6.html +*.7.html +*.8.html @@ -1,2 +1,3 @@ Joshua Haase Nicolás Reynolds +Luke Shumaker diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..27139ae --- /dev/null +++ b/Makefile @@ -0,0 +1,51 @@ +topdir = . +include config.mk + +################################################################################ + +# these are the resulting packages +packages=doc libretools libretools-mips64el librelib libregit +# and which directories they contain +doc=doc +libretools=\ + src \ + src/abslibre-tools \ + src/chroot-tools \ + src/devtools \ + src/fullpkg \ + src/librefetch \ + src/toru +libretools-mips64el=src/mips64el-tools +librelib=src/lib +libregit=src/libregit + +################################################################################ + +all: PHONY build +copy: PHONY $(addprefix copy-, $(packages)) +build: PHONY $(addprefix build-, $(packages)) +install: PHONY $(addprefix install-,$(packages)) +clean: PHONY $(addprefix clean-, $(packages)) +check: + @cd test && ./testenv $(TESTENVFLAGS) roundup + +%/copy: PHONY % + $(MAKE) -C $* copy +%/build: PHONY % + $(MAKE) -C $* +%/install: PHONY % + $(MAKE) -C $* install +%/clean: PHONY % + $(MAKE) -C $* clean + +.SECONDEXPANSION: +$(addprefix copy-, $(packages)): copy-%: PHONY $$(addsuffix /copy, $$($$*)) +$(addprefix build-, $(packages)): build-%: PHONY $$(addsuffix /build, $$($$*)) +$(addprefix install-,$(packages)): install-%: PHONY $$(addsuffix /install,$$($$*)) +$(addprefix clean-, $(packages)): clean-%: PHONY $$(addsuffix /clean, $$($$*)) + +################################################################################ + +FORCE: PHONY +PHONY: +.PHONY: FORCE PHONY diff --git a/abslibre-commit b/abslibre-commit deleted file mode 100755 index bca64c0..0000000 --- a/abslibre-commit +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -# ABSLibreCommit -# Commits a PKGBUILD to ABSLibre.git - -# Copyright 2010 Nicolás Reynolds - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -for _pkg in ${@}; do - [[ ! -e ${_pkg}/PKGBUILD ]] && continue - - unset pkgbase pkgname - source ${_pkg}/PKGBUILD - -# use . instead of * will use .gitignore - git stage ${_pkg}/. - - git commit -m "${pkgbase:-$pkgname}-${pkgver}-${pkgrel}" -done - -exit 0 @@ -1,123 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2010 Nicolás Reynolds, Joshua Ismael - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -source /etc/libretools.conf -source /etc/abs.conf - -function usage { - echo "Usage: $0 pkgname-from-aur1 [pkgname-from-aur2 ...]" - echo - echo "This script will download packages from aur to the current dir" - echo "and check their license for nonfree issues." -} - -while getopts 'h' arg; do - case $arg in - h) usage; exit 0 ;; - *) usage; exit 1 ;; - esac -done - -missing_deps=() -for _pkg in ${@}; do - -# Remove the version - _pkg="${_pkg%%[<>=]*}" - - if [ -f "${_pkg}/PKGBUILD" ]; then - warning "${_pkg} already existed." - -# Check if we want to diff - if [ -z "${DIFFTOOL}" ]; then - continue - else -# Store our copy of the PKGBUILD dir - _diff="${PWD}/${_pkg}" - stdnull "pushd $(mktemp -d /tmp/${_pkg}.XXXX)" - msg2 "Downloading PKGBUILD into ${PWD} for diff" - fi - fi - - msg "Downloading $_pkg..." - wget -O - -q https://aur.archlinux.org/packages/$(echo $_pkg | sed "s/^../&\/&/")/$_pkg.tar.gz | \ - tar xzf - >/dev/null 2>&1 - - if [ $? -ne 0 ]; then - error "Couldn't get $_pkg" - continue - fi - - stdnull "pushd $_pkg" - - if [ ! -z "$_diff" ]; then - msg2 "Diffing files" -# Diff all files with our difftool - for file in *; do - ${DIFFTOOL} ${_diff}/${file} ${file} - done - -# Go back to our copy to continue working - stdnull "pushd ${_diff}" - fi - - source PKGBUILD - - if ! pkgbuild-check-nonfree; then - if [ $? -eq 15 ]; then - warning "This PKGBUILD links to known unfree packages" - fi - fi - - msg2 "Checking license..." - free=0 - for _license in ${license[@]}; do - if [ ! -d /usr/share/licenses/common/$_license ]; then - warning "License $_license is not a common license" - free=1 - fi - done - - if [ $free -eq 1 ]; then - plain "Please check that the license is included in the package and - *specially* that it respects your freedom." - fi - - for _dep in ${depends[@]} ${makedepends[@]}; do - _dep=${_dep/[<>=]*/} - if ! is_built $_dep; then - if ! find ${ABSROOT} -maxdepth 2 -type d -name "$_dep" | egrep "*" >/dev/null ; then - msg2 "$_dep will be get from AUR" - missing_deps+=($_dep) - fi - else - msg2 "$_dep is on repos" - fi - done - - stdnull popd - -done - -[[ ${#missing_deps[*]} -gt 0 ]] && { - msg2 "Retrieving missing deps: ${missing_deps[@]}" - $0 ${missing_deps[@]} -} - -exit 0 diff --git a/buildenv b/buildenv deleted file mode 100755 index 5caea0c..0000000 --- a/buildenv +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -trap "umount_all" 0 ERR TERM KILL - -user=${SUDO_USER:-${1}} - -umount_all() { - for mp in home/pkgdest home/srcdest home/${user}; do - msg "Umounting /$mp" - umount $CHROOTDIR/$CHROOT/$mp || error "Couldn't umount" - done -} - -source /etc/libretools.conf - -for mp in home/pkgdest home/srcdest home/${user} var/lib/toru; do - msg "Binding /$mp" - mount -o bind /$mp $CHROOTDIR/$CHROOT/$mp || exit 1 -done - -for etc in etc/makepkg.conf etc/abs.conf etc/mtab; do - msg "Copying config /$etc" - cp --remove-destination /$etc $CHROOTDIR/$CHROOT/$etc || exit 1 -done - -$(dirname $0)/librechroot $CHROOT - -exit $? diff --git a/chcleanup b/chcleanup deleted file mode 100755 index b1a02db..0000000 --- a/chcleanup +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash -# (c) Nicolás Reynolds <fauno@parabola.nu> -# Released under GPLv3 -# -# Performs chroot cleanup smartly, it only removes the unneeded packages or -# leaves you with a cleansystem -# -# See: HOOKPREBUILD - -set -e -DRYRUN=${DRYRUN:-false} - -source /etc/makepkg.conf -source /etc/libretools.conf -source ${HOME}/.makepkg.conf 2>/dev/null|| true - -msg "Cleaning chroot..." - -TMPDIR="$(mktemp -d /tmp/$(basename $0)-XXXXX)" -cleanup_log="${TMPDIR}"/libretools-cleanup.log - -cp -a /var/lib/pacman/sync "${TMPDIR}/" -touch ${cleanup_log} - -# If we're running makepkg -if [ -f PKGBUILD ]; then - source PKGBUILD || true - - check=(${depends[@]} ${makedepends[@]} ${checkdepends[@]}) - -fi - -# Get the full list of packages needed by dependencies, including the base system -sudo pacman -b "${TMPDIR}" \ - -Sp \ - --print-format "%n" \ - base base-devel sudo \ - ${CHROOTEXTRAPKG[@]} \ - ${check[@]} \ - >${cleanup_log} - -# Diff installed packages against a clean chroot then remove leftovers -packages=($(comm -23 <(pacman -Qq | sort) \ - <(sort -u ${cleanup_log}))) - -[ ${#packages[@]} -eq 0 ] && exit 0 - -msg2 "Removing %d packages" ${#packages[@]} - -# Only remove leftovers, -Rcs removes too much -${DRYRUN} || sudo pacman --noconfirm -Rn ${packages[@]} -${DRYRUN} && echo ${packages[@]} - -# Cleanup -${DRYRUN} || rm -fr ${TMPDIR} - -exit $? diff --git a/common.mk b/common.mk new file mode 100644 index 0000000..68b5d56 --- /dev/null +++ b/common.mk @@ -0,0 +1,144 @@ +topdir := $(dir $(lastword $(MAKEFILE_LIST))) +include $(topdir)/config.mk +pkgconfdir ?= $(sysconfdir)/libretools.d +pkglibexecdir ?= $(libexecdir)/libretools + +# Misc variables for use in recipes ############################################ + +# Usage: <INPUT $(edit) >OUTPUT +# Expand m4_include macros to use librelib +# This is used when using sources grabbed from devtools +edit = sed -e 's|m4_include(lib/\(.*\))|. $$(librelib \1)|' + +# Usage <INPUT $(pofmt) >OUTPUT +# Normalize a .po(t) file +pofmt = msguniq -Fi + +pot-remove-wrap = tr '\n' '\r' | sed 's/"\r\s*"//g' | tr '\r' '\n' +html-whitespace-collapse = sed -r -e 's/(\\n|\\t|\t)/ /g' -e 's/ +/ /g' +define xgettext-prose = + xgettext --omit-header --from-code=UTF-8 -L shell \ + -k \ + --keyword={prose,bullet,flag:2} \ + -o - $^ | $(pot-remove-wrap) | $(html-whitespace-collapse) | sed '/^#, sh-format/d' +endef +define xgettext-main = + xgettext --omit-header --from-code=UTF-8 -L shell \ + -k \ + --keyword={_,print} \ + --keyword={msg,msg2,warning,error,stat_busy} \ + --keyword={lock,slock}:3 \ + -o - $^ +endef + +# Usage: as a variable +# relative path to `/` from $(bindir) +# used for symlinking libexec files +rootdir = $(shell sed -r 's|^/||;s|[^/]+|..|g'<<<$(bindir)) + +# Detect things aboud the director we're in #################################### + +progs += $(filter-out $(no-progs),$(shell find . -maxdepth 1 -type f -executable -printf '%f\n')) +confs += $(filter-out $(no-conf) ,$(wildcard *.conf)) +mans += $(filter-out $(no-mans) ,$(patsubst %.ronn,%,$(wildcard *.ronn))) +docs += $(filter-out $(no-docs) ,$(wildcard *.md) $(wildcard *.ronn)) +libexecs += +libs += + +copy_files += +build_files += $(progs) $(confs) $(mans) $(patsubst %.in,%,$(copy_files)) +install_files += $(addprefix $(DESTDIR)$(bindir)/,$(progs)) \ + $(addprefix $(DESTDIR)$(pkgconfdir)/,$(confs)) \ + $(addprefix $(DESTDIR)$(pkglibexecdir)/,$(libexecs) $(libs)) \ + $(addprefix $(DESTDIR)$(docdir)/libretools/,$(docs)) \ + $(addprefix $(DESTDIR)$(mandir)/man1/,$(filter %.1,$(mans))) \ + $(addprefix $(DESTDIR)$(mandir)/man2/,$(filter %.2,$(mans))) \ + $(addprefix $(DESTDIR)$(mandir)/man3/,$(filter %.3,$(mans))) \ + $(addprefix $(DESTDIR)$(mandir)/man4/,$(filter %.4,$(mans))) \ + $(addprefix $(DESTDIR)$(mandir)/man5/,$(filter %.5,$(mans))) \ + $(addprefix $(DESTDIR)$(mandir)/man6/,$(filter %.6,$(mans))) \ + $(addprefix $(DESTDIR)$(mandir)/man7/,$(filter %.7,$(mans))) \ + $(addprefix $(DESTDIR)$(mandir)/man8/,$(filter %.8,$(mans))) +clean_files += $(patsubst %.in,%,$(copy_files)) $(copy_files) $(mans) $(wildcard *.pot) + +# Set the default target ####################################################### + +all: PHONY build + +# Copy (files from devtools) ################################################### + +copy: PHONY $(copy_files) + +%.in: $(devtoolsdir)/%.in + cp $< $@ +%.in: $(devtoolsdir)/lib/% + cp $< $@ + +# Build ######################################################################## + +build: PHONY $(build_files) + +%: %.ronn + ronn --roff $(RONNFLAGS) < '$<' > '$@' +%.html: %.ronn + ronn --html $(RONNFLAGS) < '$<' > '$@' +%: %.in + @echo "GEN $@" + @$(edit) <"$<" >"$@" || { rm -f -- '$@'; false; } + @chmod 755 "$@" || { rm -f -- '$@'; false; } + +%.pot: % + { $(xgettext-main); $(xgettext-prose); } | $(pofmt) > '$@' + +# Install ###################################################################### + +install: PHONY $(install_files) + +# We sort the explicit targets because sort also removes duplicates; in a few +# cases, a target could be listed twice, which is a warning. + +# bindir: $(progs) vs $(libexecs) +$(sort $(addprefix $(DESTDIR)$(bindir)/,$(filter-out $(libexecs),$(progs)))): $(DESTDIR)$(bindir)/%: % + install -Dm755 '$<' '$@' +$(sort $(addprefix $(DESTDIR)$(bindir)/,$(libexecs))): $(DESTDIR)$(bindir)/%: % + install -d '$(@D)' + ln -sf '$(rootdir)$(pkglibexecdir)/$(@F)' "$@" +# pkglibexecdir: $(libexecs) vs $(libs) +$(sort $(addprefix $(DESTDIR)$(pkglibexecdir)/,$(libexecs))): $(DESTDIR)$(pkglibexecdir)/%: % + install -Dm755 '$<' '$@' +$(sort $(addprefix $(DESTDIR)$(pkglibexecdir)/,$(libs))): $(DESTDIR)$(pkglibexecdir)/%: % + install -Dm644 '$<' '$@' +# everything else +$(DESTDIR)$(pkgconfdir)/%: % + install -Dm644 '$<' '$@' +$(DESTDIR)$(docdir)/libretools/%: % + install -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man1/%.1: %.1 + install -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man2/%.2: %.2 + install -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man3/%.3: %.3 + install -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man4/%.4: %.4 + install -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man5/%.5: %.5 + install -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man6/%.6: %.6 + install -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man7/%.7: %.7 + install -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man8/%.8: %.8 + install -Dm644 '$<' '$@' + +# Clean ######################################################################## + +clean: PHONY clean-hook + rm -f -- $(clean_files) + +clean-hook: PHONY + +# Boiler-plate ################################################################# + +FORCE: PHONY +PHONY: +.PHONY: FORCE PHONY diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..548d4d3 --- /dev/null +++ b/config.mk @@ -0,0 +1,25 @@ +# Configuration +# Note: $(topdir) is set to the directory containing this file. + +# Note: In the default version of this file, commented out values indicate what +# the GNU standards dictate, when our values differ. + +DESTDIR= + +#prefix=/usr/local +prefix=/usr +exec_prefix=$(prefix) +bindir=$(exec_prefix)/bin +#libexecdir=$(exec_prefix)/libexec +libexecdir=$(exec_prefix)/lib + +datarootdir=$(prefix)/share +datadir=$(datarootdir) +#sysconfdir=$(prefix)/etc +sysconfdir=/etc + +docdir=$(datarootdir)/doc +mandir=$(datarootdir)/man + +devtoolsdir=$(topdir)/../devtools-par +RONNFLAGS=--manual='libretools Manual' --organization='Parabola' diff --git a/diff-unfree b/diff-unfree deleted file mode 100755 index 7d75375..0000000 --- a/diff-unfree +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash -# This script will help you diff a *-libre PKGBUILD against the unfree one -# to check for updates. -# Copyright 2010 Nicolás Reynolds - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -source /etc/libretools.conf -custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf - -[[ "$1" == "--help" ]] && { - msg "Diff-Unfree helps you diff build scripts from ABSLibre against - (Unfree) ABS. Package name and repo will we guessed if you don't - specify them." - msg2 "Usage: $0 [community|packages] [unfree-package] [repo]" - exit 0 -} - -[[ ! -r PKGBUILD ]] && { - error "This is not a build dir." - exit 1 -} - -package_guess=$(basename $PWD) - -repo=${1:-$(basename $(dirname $PWD))} -package=${2:-${package_guess/-libre}} -trunk=${3:-trunk} - -tmp_dir=$(mktemp -d /tmp/${package}.XXXXXX) - -svnrepo="packages" -case $repo in - community*) - svnrepo="community" - ;; - multilib*) - svnrepo="community" - ;; - *) - ;; -esac - -unfree_dir="${tmp_dir}/${svnrepo}/${package}/${trunk}" - -[[ ! -d "${tmp_dir}" ]] && { - error "Can't create temp dir" - exit 1 -} - -stdnull 'pushd "${tmp_dir}"' - -msg "Getting diff from $repo/$package..." - -stdnull 'svn checkout --depth=empty svn://svn.archlinux.org/$svnrepo' - -cd ${svnrepo} -svn update ${package} - -# Back to start dir -stdnull popd - -msg "Diffing files" - -for _file in ${unfree_dir}/*; do - msg2 "$(basename "${_file}")" - ${DIFFTOOL} "$PWD/$(basename "${_file}")" "${_file}" -done - -exit $? diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..23f8a8f --- /dev/null +++ b/doc/Makefile @@ -0,0 +1 @@ +include ../common.mk diff --git a/doc/createworkdir b/doc/createworkdir deleted file mode 100644 index d74198a..0000000 --- a/doc/createworkdir +++ /dev/null @@ -1,62 +0,0 @@ -== CreateWorkDir - -This script recreates a proper dir tree for packaging. It's aim is to help -you be organized with the work you do as a packager, and stablish a -certain standard for packages' ubication, so you don't have to loose much -time with them. Just package and upload! - -It will create a dir tree like this: -workdir/ - abslibre/ - .git/ - libre/<PKGBUILDS> - libre-testing/<PKGBUILDS> - staging/ - libre/ - libre-testing/ - repos/ - libre/ - i686/ - x86_64/ - libre-testing/ - i686/ - x86_64/ - -*Related Variables* - - WORKDIR - - -=== staging/ - -This directory contains one dir for each repository, where the resulting -packages are in moved for syncing against the main repository on -Parabola's server. This dir is architecture independent. - -*Related Variables* - - REPOS - - -=== 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 - - -=== repos/ - -Contains the repo dir structure. Probably not useful for uploading -packages, but it will be for creating new repos for public access. - -It contains a dir for every repository, and inside them, a dir for every -supported architecture. - -*Related Variables* - - REPOS - - ARCHES diff --git a/doc/createworkdir.md b/doc/createworkdir.md new file mode 100644 index 0000000..2539920 --- /dev/null +++ b/doc/createworkdir.md @@ -0,0 +1,41 @@ +# CreateWorkDir + +This script recreates a proper directory tree for packaging. It's 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 loose 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. + +*Related Variables* + - REPOS + +## 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/doc/fullpkg b/doc/fullpkg.md index 5645fae..5645fae 100644 --- a/doc/fullpkg +++ b/doc/fullpkg.md diff --git a/doc/treepkg.markdown b/doc/treepkg.md index 7f7ece1..7f7ece1 100644 --- a/doc/treepkg.markdown +++ b/doc/treepkg.md diff --git a/doc/workflows.md b/doc/workflows.md new file mode 100644 index 0000000..f55ae7e --- /dev/null +++ b/doc/workflows.md @@ -0,0 +1,60 @@ +# Workflows + +Describe your packaging workflow here! + + +## fauno's way + +During packaging, I don't usually restart a build from scratch if I have to +make changes to the PKGBUILD. I use a lot of commenting out commands already +ran, `makepkg -R`, etc. When I used `libremakepkg` I ended up using a lot more +`librechroot` and working from inside the unconfigured chroot, because +`makechrootpkg` (the underlying technology for `libremakepkg`) tries to be too +smart. + +When I started writing `treepkg` I found that mounting what I need directly on +the chroot and working from inside it was much more comfortable and simple than +having a makepkg wrapper doing funny stuff (for instance, mangling makepkg.conf +and breaking everything.) + +This is how the chroot is configured: + +* Create the same user (with same uid) on the chroot that the one I use regularly. + +* Give it password-less sudo on the chroot. + +* Bind mount /home to /chroot/home, where I have the abslibre-mips64el clone. + +* Bind mount /var/cache/pacman/pkg to /chroot/var/cache/pacman/pkg + +* Put these on system's fstab so I don't have to do it everytime + +* Configure makepkg.conf to PKGDEST=CacheDir and SRCDEST to something on my home. + +Workflow: + +* Enter the chroot with `systemd-nspawn -D/chroot` and `su - fauno`. + +* From another shell (I use tmux) edit the abslibre or search for updates with + `git log --no-merges --numstat`. + +* Pick a package and run `treepkg` from its dir on the chroot, or retake + a build with `treepkg /tmp/package-treepkg-xxxx`. (Refer to doc/treepkg + here). + +What this allows: + +* Not having to worry about the state of the chroot. `chcleanup` removes and + adds packages in a smart way so shared dependencies stay and others move + along (think of installing and removing qt for a complete kde rebuild). + +* Building many packages in a row without recreating a chroot for every one of + them. + +* Knowing that any change you made to the chroot stays as you want (no one + touches your makepkg.conf) + +* Hability to run regular commands, not through a chroot wrapper. I can `cd` to + a dir and use `makepkg -whatever` on it and nothing breaks. + +* No extra code spent on wrappers. diff --git a/is_built b/is_built deleted file mode 100755 index d6aafd9..0000000 --- a/is_built +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -usage() { - echo "$0 " - echo - echo "Detect if a given package version is already in repos" - echo "Assuming you want greater or equal" - echo - echo "Example usage: is_built 'pcre' '20'" -} - -while getopts 'h' arg; do - case $arg in - h) usage; exit 0 ;; - *) usage; exit 1 ;; - esac -done - -ver=${2} -pkg=${1} -pver=$(LC_ALL=C pacman -Sddp --print-format "%v" "${pkg}" 2>/dev/null) - -# if pacman fails or returns nothing -r=$? -[ "${pver}" = " there is nothing to do" ] && r=1 - -result=$(vercmp "${pver}" "${ver}") - -# if vercmp > 1 means our version is bigger -if [ ${result} -ge 0 -a ${r} -eq 0 ]; then - exit 0 -else - exit 1 -fi - -# just in case -exit 1 diff --git a/is_unfree b/is_unfree deleted file mode 100755 index f32c193..0000000 --- a/is_unfree +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# Checks if a package is on blacklist - -# fail immediately on error -set -E - -blacklist="$XDG_CONFIG_HOME/libretools/blacklist.txt" - -egrep -q "^${1}:" "${blacklist}" - -exit $? @@ -1,16 +0,0 @@ -#!/bin/bash -# LibreTools wrapper -# License: GPLv3 - -source /etc/libretools.conf - -command=$1; shift - -[[ ! -x ~/l/libre"${command}" ]] && { - error "Command not found" - exit 1 -} - -~/l/libre${command} "$@" - -exit $? diff --git a/librechroot b/librechroot deleted file mode 100755 index c8e02b0..0000000 --- a/librechroot +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash -# LibreChRoot -# Enters a chroot - -# Copyright 2010 Nicolás Reynolds -# Copyright 2011 Joshua Haase - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -function usage { - - echo "" - echo "Usage: $0 [options] [chrootname]" - echo "Use it as root." - echo "" - echo "Default chroot name: $CHROOT" - echo "Default chrootdir: $CHROOTDIR" - echo "" - echo "OPTIONS:" - echo "" - echo " -c : clean the chroot using pacman" - echo " only 'base', 'base-devel' and 'sudo' on chroot" - echo " -d <chrootdir> : use <chrootdir> instead of default" - echo " -r : clean /repo on the chroot" - echo " -h : this message" - echo " -u : update the chroot" - echo "" - -} - -function clean_chroot { # Clean packages with pacman - cp -a "$(dirname $0)/chcleanup" "${CHROOTDIR}/${CHROOTNAME}/clean" - - mkarchroot -r "cd /build; /clean" "${CHROOTDIR}/${CHROOTNAME}" -} - -function clean_repo { - msg "Cleaning repo for chroot: ${CHROOTDIR}/${CHROOTNAME}" - if [ -d "${CHROOTDIR}/${CHROOTNAME}/repo" ]; then - find "${CHROOTDIR}/${CHROOTNAME}/repo/" -mindepth 1 -delete - else - mkdir -p "${CHROOTDIR}/${CHROOTNAME}/repo" - fi - bsdtar -czf "${CHROOTDIR}/${CHROOTNAME}/repo/repo.db.tar.gz" -T /dev/null - ln -s "repo.db.tar.gz" "${CHROOTDIR}/${CHROOTNAME}/repo/repo.db" -} -source /etc/libretools.conf - -if [ -e "$XDG_CONFIG_HOME/libretools/libretools.conf" ]; then - source "$XDG_CONFIG_HOME/libretools/libretools.conf" -fi - -CLEANCHROOT='false' -UPDATE='false' -CLEANREPO='false' -CHROOTNAME="${CHROOT:-${SUDO_USER:-root}}" - -while getopts 'hrcud:' arg; do - case $arg in - h) usage; exit 0 ;; - c) CLEANCHROOT='true' ;; - u) UPDATE='true' ;; - r) CLEANREPO='true' ;; - d) CHROOTDIR="$(readlink -e $OPTARG)" ;; - esac -done - -[[ "$UID" != "0" ]] && { - error "This script must be run as root." - exit 1 -} - -shift $(($OPTIND - 1)) - -if [ $# -eq 1 ]; then - CHROOTNAME="$1" -fi - -if "$CLEANREPO"; then - clean_repo -fi - -if "$CLEANCHROOT"; then - clean_chroot -elif "$UPDATE"; then - msg "Updating chroot: ${CHROOTDIR}/${CHROOTNAME}" - mkarchroot -u "${CHROOTDIR}/${CHROOTNAME}" -else - msg "Entering chroot: ${CHROOTDIR}/${CHROOTNAME}" - mkarchroot -r "bash" "${CHROOTDIR}/${CHROOTNAME}" -fi - -exit 0 diff --git a/librecommit b/librecommit deleted file mode 100755 index 1698bed..0000000 --- a/librecommit +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# Copyright 2010 Nicolás Reynolds - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -source /etc/libretools.conf - -usage () { - echo "cd to the dir with the PKGBUILD you are commiting and" - echo - echo "$0 [optionally files to commit]" - echo - echo "This script commits the package using name, pkgver and pkgrel" - echo - exit 1 -} - -msg="Commiting libre package \"\$pkg-\$pkgver-\$pkgrel\"" - -for opt in $@ ; do - case ${opt} in - -h) usage ;; - -m) shift; msg=${1}; shift ;; - *) files+="${1} " ; shift ;; - esac -done - -if [ ! -e PKGBUILD -o -z "$files" ]; then usage; fi - -source PKGBUILD - -pkg=${pkgbase:-${pkgname}} - -msg=$(eval echo $msg) - -if [ "$COMMITCMD" = 'git' ]; then - - ${COMMITCMD} add ${files} && ${COMMITCMD} commit -m "$(echo $msg)" - -elif [ "$COMMITCMD" = 'hg' ]; then - - ${COMMITCMD} commit ${files} -m "$msg" -v || exit 1 - -else - - error "COMMITCMD is not correctly set on libretools.conf" - -fi - -exit 0 diff --git a/librediff b/librediff deleted file mode 100755 index 1f39eb9..0000000 --- a/librediff +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# Generates a patch for a nonfree PKGBUILD -# -# Copyright 2010 Nicolás Reynolds - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -usage() { - echo "Usage: $0 <pkgname> [<pkgname2> ...]" - echo "Requirements:" - echo "* Have a <pkgname>/ directory with nonfree build scripts inside" - echo "* Have a <pkgname>-libre/ directory with libre build scripts inside" -} - -# Load custom config or system-wide config -custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf -if [ -e $custom_config ]; then - source $custom_config -else - source /etc/libretools.conf -fi - -# Print usage if no package has been given -[[ -z "$@" ]] && { - usage - exit 1 -} - - -for package in $@; do -# Continue on errors - [[ ! -d ./${package} || ! -d ./${package}-libre ]] && { - error "no matching ${package} and ${package}-libre found" - continue - } - - [[ ! -f ./${package}/PKGBUILD || ! -f ./${package}-libre/PKGBUILD ]] && { - error "no matching PKGBUILDs found for ${package}-libre" - continue - } - - source ./${package}-libre/PKGBUILD - [[ -z ${pkgbase} ]] && pkgbase=${pkgname} - -# Generate a diff file, no -r since we don't want to patch src/ nor pkg/ - diff -auN ${package} ${package}-libre > $PATCHDIR/${pkgbase}-${pkgver}-${pkgrel}.patch - -done - -exit 0 diff --git a/libremakepkg b/libremakepkg deleted file mode 100755 index f7924f6..0000000 --- a/libremakepkg +++ /dev/null @@ -1,126 +0,0 @@ -#!/bin/bash -# Copyright 2010 - 2011 Nicolás Reynolds -# Copyright 2011 Joshua Ismael Haase Hernández - -# ---------- GNU General Public License 3 ---------- - -# 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 -x # uncomment for debug - -function copy_log { # copy logs if they exist - - find "${CHROOTDIR}/${CHROOT}/build/" -maxdepth 1 -name "*\.log" -exec cp {} ./ \; - -} - - -function trap_exit { # End inmediately but print a useful message - - copy_log - error "$@" - exit 1 - -} - -# Trap signals from makepkg -set -E -trap 'trap_exit "(libremakepkg): TERM signal caught. Exiting..."' TERM HUP QUIT -trap 'trap_exit "(libremakepkg): Aborted by user! Exiting..."' INT -trap 'trap_exit "(libremakepkg): An unknown error has occurred. Exiting..."' ERR - -source /etc/libretools.conf - -CLEANFIRST="false" -UPDATEFIRST="false" -CHECKNONFREE="true" -LIBRECHROOT_ARGS="" -MAKEPKG_ARGS="" - -function usage { - - echo '' - echo 'cd to a dir containing a PKGBUILD and run:' - echo '$0 [options] [-- makechrootpkg args [-- makepkg args]]' - echo 'This script will build your package on a chroot.' - echo '' - echo 'OPTIONS:' - echo '' - echo ' -h : show this message.' - echo ' -c : clean the chroot before building.' - echo ' -u : update the chroot before building.' - echo ' -d <chrootdir> : use this dir instead of "$CHROOTDIR"' - echo ' -n <chrootname> : use this dir instead of "$CHROOT".' - echo ' -N : do not check freedom issues' # As fullpkg-check will do that before - echo '' - exit 1 - -} - -while getopts 'hcud:n:N' arg ; do - case "${arg}" in - h) usage ;; - c) CLEANFIRST="true" ;; - u) UPDATEFIRST="true" ;; - d) CHROOTDIR="$OPTARG" - LIBRECHROOT_ARGS='-d "$OPTARG"' ;; - n) CHROOT="$OPTARG" ;; - N) CHECKNONFREE="false" ;; - esac -done - -# Pass all arguments after -- right to makechrootpkg -MAKEPKG_ARGS="$makepkg_args ${*:$OPTIND}" - -if (( EUID )); then - error "This script must be run as root" - exit 1 -fi - -if [ ! -e PKGBUILD ]; then # Check if we are actually on a build directory. Do this early. - error "This isn't a build directory"; usage -fi - -msg "Checking PKGBUILD for non-free issues" -if "$CHECKNONFREE"; then - if ! pkgbuild-check-nonfree; then - - if [[ $? -eq 15 ]]; then # other errors mean fail, not nonfree - error "PKGBUILD contains non-free issues" - exit 15 - else - warning "PKGBUILD couldn't be check aganist non-free issues" - fi - fi -fi - -if "$CLEANFIRST"; then - librechroot -c "$LIBRECHROOT_ARGS" "$CHROOT" -fi - -if "$UPDATEFIRST"; then - librechroot -u "$LIBRECHROOT_ARGS" "$CHROOT" -fi - -unset CLEANFIRST UPDATEFIRST LIBRECHROOT_ARGS - -makechrootpkg -d -r "$CHROOTDIR" -l "$CHROOT" -- $MAKEPKG_ARGS -ev="$?" # exit value - -copy_log - -exit $ev diff --git a/libremessages b/libremessages deleted file mode 100755 index 68badb8..0000000 --- a/libremessages +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> -# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> -# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> -# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> -# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> -# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk> -# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org> -# Copyright (c) 2011 by Joshua Haase <hahj87@gmail.com> -# -# 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/>. - -# gettext initialization -export TEXTDOMAIN='libretools' -export TEXTDOMAINDIR='/usr/share/locale' - -# check if messages are to be printed using color -unset ALL_OFF BOLD BLUE GREEN RED YELLOW -if [[ -t 2 ]]; then - # prefer terminal safe colored and bold text when tput is supported - if tput setaf 0 &>/dev/null; then - ALL_OFF="$(tput sgr0)" - BOLD="$(tput bold)" - PURPLE="${ALL_OFF}$(tput setaf 5)" - BLUE="${BOLD}$(tput setaf 4)" - GREEN="${BOLD}$(tput setaf 2)" - RED="${BOLD}$(tput setaf 1)" - YELLOW="${BOLD}$(tput setaf 3)" - else - ALL_OFF="\e[1;0m" - BOLD="\e[1;1m" - BLUE="${BOLD}\e[1;34m" - GREEN="${BOLD}\e[1;32m" - RED="${BOLD}\e[1;31m" - YELLOW="${BOLD}\e[1;33m" - PURPLE="${BOLD}\033[1;30;40m" - fi -fi -readonly ALL_OFF BOLD BLUE GREEN RED YELLOW PURPLE - -stdnull() { - eval "$@ >/dev/null 2>&1" -} - -plain() { - local mesg=$1; shift - printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 -} - -msg() { - local mesg=$1; shift - printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 -} - -msg2() { - local mesg=$1; shift - printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 -} - -warning() { - local mesg=$1; shift - printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 -} - -error() { - local mesg=$1; shift - printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 -} - -stat_busy() { - local mesg=$1; shift - printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}...${ALL_OFF}" >&2 -} - -stat_done() { - printf "${BOLD}done${ALL_OFF}\n" >&2 -} - -# Set the terminal title -# TODO test on several terms - it works on screen/tmux -term_title() { - printf "\033k%s\033\\" "$@" -} - -# usage : in_array( $needle, $haystack ) -in_array() { - [[ $2 ]] || return 1 # Not found - - local needle=$1; shift - local item - - for item in "$@"; do - [[ ${item#@} = $needle ]] && return 0 # Found - done - - return 1 # Not Found -} diff --git a/libremkchroot b/libremkchroot deleted file mode 100755 index b576209..0000000 --- a/libremkchroot +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# LibreMkChroot -# Creates a chroot - -# Copyright 2011, 2012 Luke Shumaker - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -source /etc/libretools.conf - -if [ -e "$XDG_CONFIG_HOME/libretools/libretools.conf" ]; then - source "$XDG_CONFIG_HOME/libretools/libretools.conf" -fi - -cmd=${0##*/} -function usage { - echo "Usage: $cmd [OPTIONS]" - echo 'This script will create a chroot to build packages in.' - echo "Use \`librechroot' to interact with the chroot after it is created." - echo '' - echo 'Options:' - echo ' -h Show this message' - echo '' - echo ' -f Force overwrite of files in the working-dir' - echo '' - echo ' -d <chrootdir> Use this dir instead of "$CHROOTDIR".' - echo " -c <pacmandir> Location of pacman cache. Default: \`/var/cache/pacman/pkg'." - echo ' -C <file> Location of pacman config file.' - echo ' -M <file> Location of makepkg config file.' -} - -mkchroot_args=(); -while getopts 'hfd:c:C:M:' arg; do - case "$arg" in - h) usage; exit 0 ;; - f) mkchroot_args+=("-$arg");; - c|C|M) mkchroot_args+=("-$arg" "$OPTARG");; - d) CHROOTDIR=$OPTARG ;; - ?) usage; exit 1 ;; - esac -done - -if (( EUID )); then - error "This script must be run as root" - exit 1 -fi - -mkdir -p "${CHROOTDIR}" -xargs -d'\n' mkarchroot "${mkchroot_args[@]}" "${CHROOTDIR}/root" < /etc/libretools.d/cleansystem diff --git a/librerelease b/librerelease deleted file mode 100755 index efb698e..0000000 --- a/librerelease +++ /dev/null @@ -1,155 +0,0 @@ -#!/bin/bash -# Librerelease -# Uploads packages into [staging] - -# Copyright 2010 Nicolás Reynolds - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -source /etc/libretools.conf -custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf - -function usage { - echo "$(gettext "Usage: $0")" - echo - echo "$(gettext "This script uploads packages on $WORKDIR/stagging")" - echo "$(gettext "to parabola server.")" - echo - echo "$(gettext "OPTIONS:")" - echo "$(gettext " -h this message.")" - echo "$(gettext " -l only list packages but not upload them.")" - echo "$(gettext " -c clean packages on $WORKDIR/staging.")" - echo "$(gettext " -n dry-run")" -} - -function list_packages { - repos=($(find "$WORKDIR/staging/" -mindepth 1 -type d \! -empty -printf '%f ' 2>/dev/null)) - for _repo in ${repos[@]}; do - msg2 "$_repo" - find ${WORKDIR}/staging/${_repo} -type f -printf "%f\n" - done - unset repos -} - -function sign_packages { - if [ -z "${SIGEXT}" ]; then - SIGEXT=.sig - warning "Empty SIGEXT var, using default .sig" - fi - - if [ -z "${GPG_AGENT_INFO}" ]; then - warning "It's better to use gpg-agent to sign packages in batches" - fi - - packages=($(find "${WORKDIR}/staging/" -type f -iname '*.pkg.tar.?z')) - for package in ${packages[@]}; do - if [ -f "${package}${SIGEXT}" ]; then - - warning "Package signature found, verifying..." - -# Verify that the signature is correct, else remove for re-signing - if ! gpg --quiet --verify "${package}${SIGEXT}" >/dev/null 2>&1; then - error "Failed! Resigning..." - rm -f "${package}${SIGEXT}" - fi - fi - - msg2 "Signing ${package}..." - gpg --default-key "${SIGID}" --output "${package}${SIGEXT}" \ - --detach-sig "${package}" || { - error "Signing failed" - exit 2 - } - - done -} - -# Remove everything that's not a package or a signature -function clean_non_packages { - find $WORKDIR/staging/ -type f \ - \! -iname "*.pkg.tar.?z" -a \! -iname "*.pkg.tar.?z.sig" \ - -delete -} - -# Clean everything if not on dry-run mode -function clean { - [ -z ${dryrun} ] && \ - rm -f $@ -} - -if [ -w / ]; then - error "Run $0 as normal user" - exit 1 -fi - -while getopts 'hlcn' arg; do - case $arg in - h) usage; exit 0 ;; - l) list_packages; exit 0 ;; - c) clean; exit $? ;; - n) dryrun="--dry-run" ;; - esac -done - -[[ -e $custom_config ]] && source $custom_config - -[[ ! -z ${HOOKPRERELEASE} ]] && bash -c "${HOOKPRERELEASE}" - -clean_non_packages -if [ ! -z "${SIGID}" ]; then - sign_packages -else - error "Package signing is *required*, please set SIGID on your libretools.conf" - exit 1 -fi - -# 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 {} \; - -# Get the synced files -SYNCED_FILES=($(find ${WORKDIR}/staging -type f)) - -msg "%s to upload" $(du -h -d 0 ${WORKDIR}/staging | tr "\t" " " | cut -d" " -f1) -msg "Uploading packages..." -rsync --recursive \ - ${dryrun} \ - --no-group \ - --no-perms \ - --copy-links \ - --hard-links \ - --partial \ - --prune-empty-dirs \ - --human-readable \ - --progress \ - -e "ssh " \ - ${WORKDIR}/staging \ - ${PARABOLAHOST}:${LIBREDESTDIR}/ || { - error "Sync failed, try again" - exit 1 - } - -msg "Removing ${#SYNCED_FILES[@]} files from local [staging]" -clean ${SYNCED_FILES[@]} - -msg "Running db-update on repos" -ssh ${PARABOLAHOST} dbscripts/db-update - -exit 0 diff --git a/librerepkg b/librerepkg deleted file mode 100755 index d506003..0000000 --- a/librerepkg +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash -# Copyright 2011 Joshua Ismael Haase Hernandez - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -source /etc/libretools.conf -custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf -if [ -x $custom_config ]; then - source $custom_config; - unset $custom_config -fi - -[[ ! -r rePKGBUILD ]] && { - error "This build does not contains a rePKGBUILD." - exit 1 -} - -source /etc/makepkg.conf -source /etc/abs.conf -source rePKGBUILD - -usage() { - echo "cd to a dir with a rePKGBUILD and other file info and run" - echo "$0 [makepkg flags]" - echo - echo "This script will repackage an arch package without compiling" -} - -while getopts 'h' arg; do - case $arg in - h) usage; exit 0 ;; - esac -done - -makepkgflags=$@ - -tempdir=$(mktemp -d /tmp/$(basename $PWD).XXXXX) - -msg "Copying files" -cp ./* ${tempdir}/ - -for _arch in ${arch[@]}; do - - msg "Repackaging: $pkgname $pkgver-$pkgrel ($(date -u))" - - stdnull pushd ${tempdir} - - msg2 "Updating md5sums" - makepkg -gp rePKGBUILD >> rePKGBUILD - - echo "export CARCH=${_arch}" >> rePKGBUILD - - msg "Repackaging using makepkg" - makepkg -Lcdp rePKGBUILD ${makepkgflags} - - stdnull popd ${tempdir} -done diff --git a/librestage b/librestage deleted file mode 100755 index b474bb1..0000000 --- a/librestage +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/bash -# LibreStage -# Prepares packages for upload into [staging] - -# Copyright 2010 Nicolás Reynolds - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - - -source /etc/libretools.conf -custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf -[[ -e $custom_config ]] && source $custom_config - -if [ -w / ]; then - error "This script should be run as regular user" - exit 1 -fi - - -# End Config - -usage() { - cat <<EOU -LibreStage Copyright (C) 2011 Nicolás Reynolds -This program comes with ABSOLUTELY NO WARRANTY. -This is free software, and you are welcome to redistribute it -under the terms of the GNU General Public License version 3 or later. - - -Usage: $(basename $0) <repo> [<repo2> ... ] - -LibreRelease will stage for upload the package(s) built by the PKGBUILD on -the current directory to the specified repo(s). -EOU -} - -repos=$@ - -while getopts 'h' arg; do - case $arg in - h) usage; exit 0 ;; - esac -done - -if [ ${#repos} -eq 0 ]; then - usage - exit 1; -fi - -[[ ! -e ./PKGBUILD ]] && { - error "PKGBUILD not found" - exit 1 -} - -# Source the needed files -source /etc/makepkg.conf -[[ -e ~/.makepkg.conf ]] && source ~/.makepkg.conf -source ./PKGBUILD -[[ -e ./rePKGBUILD ]] && source ./rePKGBUILD - -# Default package location -PKGDEST=${PKGDEST:-.} -SRCPKGDEST=${SRCPKGDEST:-.} - -PKGEXT=".pkg.tar.?z" - -staged=false -# Copies the packages to the specified repos inside staging -for _arch in ${ARCHES[@]}; do - for pkg in ${pkgname[@]}; do - - pkgpath=$(find ${PKGDEST}/ -type f \ - -name "${pkg}-${pkgver}-${pkgrel}-${_arch}${PKGEXT}" -or \ - -name "${pkg}-${epoch}:${pkgver}-${pkgrel}-${_arch}${PKGEXT}") - - [[ -z ${pkgpath} ]] && continue - - pkgfile=$(basename ${pkgpath}) - -# TODO refactor this - if [ -e "${pkgpath}" ]; then - msg "Found ${pkgfile}" - - canonical="" - for _repo in ${repos[@]}; do - - if [ ! -d "${WORKDIR}/staging/${_repo}" ]; then - warning "[${_repo}] didn't exist, creating..." - mkdir -p "${WORKDIR}/staging/${_repo}" - fi - - if [ -z "$canonical" ]; then - canonical="${WORKDIR}/staging/${_repo}/${pkgfile}" - - cp "${pkgpath}" "${WORKDIR}/staging/${_repo}/" || { - error "Can't put ${pkgfile} on [staging]" - exit 1 - } && { - msg2 "${pkg} staged on [${_repo}]" - staged=true - } - - else - ln "${canonical}" "${WORKDIR}/staging/${_repo}/${pkgfile}" || { - error "Can't put ${pkgfile} on [staging]" - exit 1 - } && { - msg2 "${pkg} staged on [${_repo}]" - staged=true - } - - fi - done - fi - done -done - -if ! $staged ; then - error "No package was staged" - exit 1 -fi - -exit 0 diff --git a/libretools.conf b/libretools.conf deleted file mode 100644 index 8032397..0000000 --- a/libretools.conf +++ /dev/null @@ -1,122 +0,0 @@ -## Blacklist URL -BLACKLIST=http://repo.parabolagnulinux.org/docs/blacklist.txt - -# Diff tool (vimdiff, gvimdiff, meld, etc) -DIFFTOOL=vimdiff - -# The dir where you work on -WORKDIR=/home/$USER/packages -# The repos you'll be packaging for -# -# Tip: As early repos take precedence on $REPOS loops, you can use this as -# inverted order of precedence. Put testing repos first so fullpkg find new -# PKGBUILDs first, for instance. Toru-path uses reverse order to enforce repo -# precedence on the path cache (the last path added replaces the rest) -REPOS=('core' 'libre' 'extra' 'community' 'libre-testing' 'social' 'sugar') - -# The architectures -ARCHES=('i686' 'x86_64' 'mips64el' 'any') - -## The directory where the chroots are stored -CHROOTDIR=/home/chroot -# Extra packages to have installed on the chroot (besides base base-devel and sudo) -CHROOTEXTRAPKG=(distcc ccache tsocks tokyocabinet) - -## The working chroot -## A chroot is useful to build packages isolated from the current system and avoid -## unwanted (as in not in dependencies) automatic library linking -# CHROOT=$SUDO_USER -# CHROOT=root - -## Obtains CacheDir from pacman.conf -CACHEDIR=`grep "^#\?CacheDir" /etc/pacman.conf | cut -d'=' -f2` - -## Parabola hostname (should be the same used on ssh_config -PARABOLAHOST=parabola - -## Server destination of libre packages -# Don't change unless you know what you're doing and you won't screw -# anything ;) -LIBREDESTDIR=/srv/http/repo/public - -## ABSLibre -ABSLIBREGIT=http://projects.parabolagnulinux.org/abslibre.git - -## Commit Command -## Should be git or hg -## Uncomment only one of those -#COMMITCMD=git -#COMMITCMD=hg - -## Uncomment one of those or make one of your choice -# Normal fullpkg -FULLBUILDCMD="sudo libremakepkg -cuN" -# Cross compiling fullkpg -# FULLBUILDCMD="sudo libremakepkg -cuN -d '/path/to/cross-compiling/chroot'" -# Build from within the chroot (or host system) -# FULLBUILDCMD="makepkg -sL --noconfirm" - -# Run a command before releasing a package (ie. SSH connection, SSH tunnel, etc.) -HOOKPRERELEASE="ssh -fN parabola" - -# Run a command before running FULLBUILDCMD, usually to cleanup uneeded packages -# Note! chcleanup *is not* chroot aware, if you run it as it is it will cleanup -# your system -# HOOKPREBUILD="chcleanup" - -# Locally release the package or any other action after running FULLBUILDCMD -# succesfully -# HOOKLOCALRELEASE="" - -## Toru -# Section for toru's vars -TORUPATH=/var/lib/libretools/toru - -## Package signing -# Leave commented to disable signing -#SIGEXT=".sig" -#SIGID="0xYOURID" - -# Checks if vars aren't empty - -for VAR in CHROOTDIR CHROOT CACHEDIR PARABOLAHOST LIBREDESTDIR \ - BLACKLIST WORKDIR REPOS ARCHES ABSLIBREGIT \ - COMMITCMD DIFFTOOL FULLBUILDCMD; do - - ret=0 - [[ -z ${!VAR} ]] && { - echo "Configure $VAR var in /etc/libretools.conf" - ret=1 - } - [ $ret -ne 0 ] && exit 1 -done - -source /usr/bin/libremessages - -## These are architecture specific files. -## Uncomment them if you installed libretools-mips64el -# source /etc/libretools.d/mips64el.conf - -## Recommended SSH Config follows -# SSH host, it's better if you have it configured on ~/.ssh/config -# with ControlMaster auto (and a shell opened somewhere else) -# -# Example: -# Host * -# Protocol 2 -# ControlMaster auto -# ControlPath /tmp/ssh-%r@%h:%p -# -## Repo server -# Host parabola -# Port 22 -# HostName repo.parabolagnulinux.org -# User parabolavnx -# IdentityFile ~/.ssh/id_rsa -# -## Git server -# Host vparabola -# Port 1863 -# HostName parabolagnulinux.org -# User parabola -# IdentityFile ~/.ssh/id_rsa diff --git a/mips64el/mips64el.conf b/mips64el/mips64el.conf deleted file mode 100644 index 836b407..0000000 --- a/mips64el/mips64el.conf +++ /dev/null @@ -1,12 +0,0 @@ -## Arquitecture specific commands - -## Run a command for PKGBUILD modifications before building -## Like adding 'mips64el' to arch if it's not there -# HOOKPKGBUILDMOD="mips-add" - -## Run a command for local releasing of packages -# Useful for mass packaging (ie. mips port) -# Must accept the following parameters even if the command won't use them: -# $1 repo name -# $2+ packages -# HOOKLOCALRELEASE="mipsrelease" diff --git a/mips64el/mipsrelease b/mips64el/mipsrelease deleted file mode 100755 index 586adfc..0000000 --- a/mips64el/mipsrelease +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# Lic: GPLv3+ -# Author: Nicolas Reynolds <fauno@kiwwwi.com.ar> -# Local release of mips64el packages + clean ABS sync -# Called by HOOKLOCALRELEASE - -# $1 repo -# $2+ packages - -source /etc/makepkg.conf -source /etc/libretools.conf - -libretoolsdir="$(dirname $0)/../" - -usage() { - echo "$0 repo package1 [ package2 ... packageN ]" - echo - echo " release packages locally on ${PKGDEST}/stage3." - echo " and make a clean ABS sync " -} - -## -# usage : get_full_version( $epoch, $pkgver, $pkgrel ) -# return : full version spec, including epoch (if necessary), pkgver, pkgrel -## -get_full_version() { - if [[ $1 -eq 0 ]]; then - # zero epoch case, don't include it in version - echo $2-$3 - else - echo $1:$2-$3 - fi -} - -repo=$1; shift - -if [ -z "${repo}" ]; then - error "Empty repo" - exit 1 -fi - -# Get all needed sources -source PKGBUILD -fullver=$(get_full_version ${epoch:-0} ${pkgver} ${pkgrel}) -pkgs=() -makepkg --source -f --skippgpcheck -c - -msg "Adding packages to [stage3]..." -for name in ${pkgname[@]}; do - msg2 "${name} ${fullver}" - pkgs+=("${PKGDEST}/${name}-${fullver}-*.pkg.tar.*") -done - -repo-add ${PKGDEST}/stage3.db.tar.gz ${pkgs[@]} - -librestage ${repo} - - -mkdir -p ${WORKDIR}/abs/${CARCH}/${repo} >/dev/null - -pushd ${WORKDIR}/abs/${CARCH}/${repo} >/dev/null - tar xvf $SRCPKGDEST/${pkgbase:-${pkgname[0]}}-${fullver}${SRCEXT} -popd >/dev/null - -exit $? diff --git a/pkgbuild-check-nonfree b/pkgbuild-check-nonfree deleted file mode 100755 index df0ff36..0000000 --- a/pkgbuild-check-nonfree +++ /dev/null @@ -1,205 +0,0 @@ -#!/bin/bash -# pkgbuild-check-nonfree -# Copyright 2010 Joshua Ismael Haase Hernández, Joseph Graham - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -# function log_end { -# kill "$teepid" -# rm "$logpipe" -# } - -# function log { -# LOG="pkgbuild-check-nonfree-$(date -u +%Y%m%d).log" -# # ensure overridden package variables survive tee with split packages -# logpipe="$(mktemp -u "$startdir/logpipe.XXXXXXXX")" -# mkfifo "$logpipe" -# tee "$LOG" < "$logpipe" & -# teepid=$! -# trap log_end ERR EXIT -# } - - -function unset_pkgbuild { - - unset 'pkgbase' 'pkgname' 'pkgver' 'pkgrel' 'epoch' 'pkgdesc' \ - 'arch' 'url' 'license' 'groups' 'optdepends' 'provides' \ - 'conflicts' 'replaces' 'backup' 'options' 'install' \ - 'changelog' 'source' 'noextract' 'md5sums' 'build' \ - 'check' 'package' 'depends' 'makedepends' 'checkdepends' - -} - -function assert_pkgbuild { - - if [ -e "$1" ]; then - - source "$1" - if [ -n "${pkgname[0]}" ]; then - return 0 # valid PKGBUILD - fi - - fi - - error "$1 is not a valid PKGBUILD" - return 1 -} - -function check_replacement { - - [ $2 ] || return 0 # Free (not found) - local needle=$1; shift - local item - local rep - for line in $@; do - - item="$(echo "$line" | cut -d':' -f1)" - rep="$(echo "$line" | cut -s -d':' -f2)" - - if [ "$item" == "$needle" ]; then - if [ -z "$rep" ]; then - return 15 # Nonfree (found) - else - echo "$rep" - return 0 # Free (has replacement) - fi - fi - - done - return 0 # Free (not found) -} - -function get_blacklist { # Download the blacklist. - - pushd "$XDG_CONFIG_HOME/libretools" >/dev/null - - msg "Downloading the blacklist of proprietary software packages." - - if ! wget -N -q -O blacklist.txt "${BLACKLIST}" 2>/dev/null; then - - if [ -e "$XDG_CONFIG_HOME/libretools/blacklist.txt" ]; then - warning "Using local copy of blacklist" - else - error "Download failed, exiting" - fi - - fi - - popd > /dev/null -} - -function check_deps { # Check wheter a package depends on non-free - - unset_pkgbuild - - if ! assert_pkgbuild "$1"; then - return 1 # not PKGBUILD - fi - - msg2 "${pkgbase:-${pkgname[0]}} $pkgver $pkgrel ${epoch:-""}" # > "$logpipe" - - for pkg in ${pkgname[@]} ${depends[@]} ${makedepends[@]} ${checkdepends[@]}; do - - lines=($(grep "$pkg" "$XDG_CONFIG_HOME/libretools/blacklist.txt" | tr " " "_")) - - rep="$(check_replacement $pkg ${lines[@]})" - freedom=$? - - if [ "$freedom" -eq 15 ]; then - warning "found $pkg" # > "$logpipe" - ev=15 - continue - - elif [ -n "$rep" ]; then - - if [ "$rep" = "$pkg" ]; then - plain "$pkg is repackaged with the same name." # > "$logpipe" - continue - else - plain "$pkg -> $rep" # > "$logpipe" - continue - fi - - fi - - done - -} - -function usage { - # TODO: implement PKGBUILD arguments - echo "" - echo "$(basename $0) [options] [PKGBUILD1 PKGBUILD2 ...]" - echo "" - echo "OPTIONS" - echo "" - echo " -h : this message" - echo "" - echo "If no PKGBUILD is specified, one is searched on current directory" - - exit 1 -} - -while getopts 'h' arg; do - case "$arg" in - h) usage ;; - esac -done - -if [ -w / ]; then - error "Run as normal user" -fi - -source /etc/libretools.conf -if [ -e "$XDG_CONFIG_HOME/libretools/libretools.conf" ]; then - source "$XDG_CONFIG_HOME/libretools/libretools.conf" -fi - -if [ -z "${BLACKLIST}" ]; then - error "BLACKLIST variable is not set your libretools.conf file" - exit 1 -fi - -if [ ! -d "$XDG_CONFIG_HOME/libretools" ]; then - mkdir -p "$XDG_CONFIG_HOME/libretools" -fi - -startdir=`pwd` - -get_blacklist -# log - -shift $(( OPTIND - 1)) - -msg "Looking for unfree dependencies" - -if [ $# -ge 1 ]; then - - for p in $@; do - if [ -n "$p" ]; then - check_deps "$p" - fi - done - -else - - check_deps "`pwd`/PKGBUILD" - -fi - -exit $ev diff --git a/prtools/prfullpkg b/prtools/prfullpkg deleted file mode 100755 index bbb8d73..0000000 --- a/prtools/prfullpkg +++ /dev/null @@ -1,398 +0,0 @@ -#!/bin/bash - -source /etc/makepkg.conf -source /etc/abs.conf -source /etc/libretools.conf -source /etc/libretools.d/prtools.conf - -if [ -z $XDG_CONFIG_HOME ]; then # Avoid /libretools dir doesn't exist errors - - error "There's no XDG_CONFIG_HOME var set"; exit 1 - -elif [ -e $XDG_CONFIG_HOME/libretools/libretools.conf ]; then - - source $XDG_CONFIG_HOME/libretools/libretools.conf - -fi - - -function usage { - - echo "cd to a dir containing a PKGBUILD and run:" - echo "$0 [options]" - printf "This script will check dependencies, build them if possible " - printf "and stage the packages on it's repo." - echo - echo "OPTIONS:" - echo " -h : this message." - echo " -a absdir : set absdir as ABSROOT." - echo " -b build_dir : use a fullpkg build_dir and only build." - echo " -c : check deps only, do not build." - echo " -d build_dir : use this dir to build. Defaults to mktemp." - echo " -n : don't update pacman db." - echo " -m max_level : check deps until this level" - echo " -r \"command\" : use this instead of \"$FULLBUILDCMD\"" - echo - exit 1 - -} - -function remove_buildorder { # Removes a package from the buildorder -# $1 package name -# $2 buildorder file - - grep -Evw "${1}" ${2} > ${2}2 - mv -f ${2}2 ${2} - -} - -function guess_repo { # Get repo name. Asumes ${ABSROOT}/package/repo/PKGBUILD - - basename $(pwd) - -} - -function get_fullver { # return : full version spec, including epoch (if necessary), pkgver, pkgrel - -# usage : get_fullver( ${epoch:-0}, $pkgver, $pkgrel ) - - if [[ $1 -eq 0 ]]; then - # zero epoch case, don't include it in version - echo $2-$3 - else - echo $1:$2-$3 - fi - -} - -function cleanup { # Cleans the build_dir. - - [ ! -d "${build_dir}" -o "${build_only}" = 'y' ] && return 0 # Do nothing or already cleaned. - - - if [ $level -eq 0 ]; then # Only do cleanup on level 0. - msg "Cleaning up ${build_dir}" - rm -rf "$build_dir/*" - fi -} - -function find_deps { # Checks ABSROOT and look for target pkg deps. Adds them if not built or outdated. - - source PKGBUILD ## Check this level. - - local repo=${repo:-$(guess_repo)} - local pkgbase=${pkgbase:-${pkgname[0]}} - local epoch=${epoch:-0} - local fullver=$(get_fullver ${epoch} ${pkgver} ${pkgrel}) - - if is_built "${pkgbase}" "${fullver}"; then - exit 0 # pkg is built and updated - fi - - echo "${level}:${pkgbase}" >> "${build_dir}/BUILDORDER" # greater levels are built first - - if [ -d "${build_dir}/${pkgbase}" ]; then # PKGBUILD is already there - - exit 0 - - else # Copy dir to build_dir - - mkdir ${build_dir}/${pkgbase} - cp -r $(pwd)/* ${build_dir}/${pkgbase} - - echo "repo=$repo" > "${build_dir}/${pkgbase}/.INFO" # to identify repo later - fi - - msg2 "%${level}s${pkgbase}-${fullver}" # current package plus a space for every level - - declare -i next_level=$level+1 ## Check next deps level. - - deps=$(echo "${depends[@]} ${makedepends[@]}" | \ - sed "s/[=<>]\+[^ ]\+//g" | \ - tr ' ' "\n" | \ - sort -u) # All deps in separate line, only once, without version. - - for _dep in ${deps[@]}; do - - local found=false - - if [ -d "${ABSROOT}/${_dep}" ]; then # ABSROOT/package/repo - - for _repo in ${REPOS[@]}; do # Use PKGBUILD from repo in REPOS array order - - if [ -e "${ABSROOT}/${_dep}/${_repo}/PKGBUILD" ]; then - - pushd "${ABSROOT}/${_dep}/${_repo}" > /dev/null - $0 -c -d ${build_dir} -l ${next_level} # run this cmd on dep's PKGBUILD dir - [ $? -eq 20 ] && return 20 # probable circular deps - popd > /dev/null - local found=true - break 1 # found, go to next dep - fi - - done - - else # pkgsplit, needs guess - - for _repo in ${REPOS[@]}; do - - if _dir=($(find "$ABSROOT/" -type f \ - -wholename "*/${_repo}/PKGBUILD" -print0 2>/dev/null | \ - "xargs" -0 -e grep -HEw "pkgname=|pkgbase=|provides=" | \ - grep -w "$_dep" 2>&1)) ; - - then - - _dir=$(dirname $(echo $_dir | cut -d: -f1)) - plain "guess for $_dep -> $_dir" - - pushd "$_dir" > /dev/null - $0 -c -d ${build_dir} -l ${next_level} # run this cmd on dep's PKGBUILD dir - [ $? -eq 20 ] && return 20 # probable circular dep - popd > /dev/null - local found=true - break 1 # found, go to next dep - fi - - done - - fi - - if ( ${found} ); then - continue 1 # go to next dep - else - echo "dep_not_found:$_dep" >> $build_dir/log - fi - - done - - unset next_level dir - # unset PKGBUILD variables - unset pkgbase pkgname pkgver pkgrel epoch pkgdesc arch url license groups depends \ - makedepens checkdepends optdepends provides conflicts replaces backup \ - options install changelog source noextract md5sums build check package -} - -function __build () { - pushd ${build_dir} > /dev/null - - build_packages=($(sort -gr $buildorder | cut -d: -f2)) # greater levels must be built first - - while [ ${#build_packages[@]} -ge 1 ]; do - pushd $build_dir/${build_packages[0]} > /dev/null - source PKGBUILD - - msg2 "${pkgbase:-${pkgname[0]}} $pkgver-$pkgrel" - - msg2 "Checking for non free deps" - pkgbuild-check-nonfree || { - if [ $? -eq 15 ]; then # this error means nonfree others means fail. - - echo "nonfree:$(basename $PWD)" >> $build_dir/log - - remove_buildorder "$(basename $PWD)" $buildorder # take out package from $buildorder - - continue # build next package - fi - } - - msg2 "Building $(basename $PWD)" - - $FULLBUILDCMD; r=$? # this buildcmd is on libretools.conf - - case $r in - - 0) ## Succesfull build - - plain "The build was succesful." - if source .INFO && [ -n $repo ]; then - - if [ ! -z $HOOKLOCALRELEASE ]; then # Calls a local release script if it's used - find -name "*.pkg.tar.?z" -print0 | xargs -0 $HOOKLOCALRELEASE $repo - fi - - librestage $repo || echo "unstaged:$(basename $PWD)" >> $build_dir/log - - msg "Updating pacman db and packages" - sudo pacman -Sy || true - - fi - - echo "built:$(basename $PWD)" >> $build_dir/log - ;; - - *) ## Build failed - error "There were errors while trying to build the package." - echo "failed:$(basename $PWD)" >> $build_dir/log - ;; - esac - - remove_buildorder "${build_packages[0]}" $buildorder || true - - build_packages=($(sort -gr $buildorder | cut -d: -f2)) # which is next package? - popd > /dev/null - done - - pkgs=($(grep "nonfree:" $build_dir/log)) && { - error "Those packages contain nonfree deps:" - echo ${pkgs[@]} | tr " " "\n" | cut -d: -f2 - } - - pkgs=($(grep "built:" $build_dir/log)) && { - msg "Those packages were built and staged:" - echo ${pkgs[@]} | tr " " "\n" | cut -d: -f2 - } - - pkgs=($(grep "failed:" $build_dir/log)) && { - error "Those packages failed to build:" - echo ${pkgs[@]} | tr " " "\n" | cut -d: -f2 - } - - pkgs=($(grep "unstaged:" $build_dir/log)) && { - error "Those packages couldn't be staged because of missing reponame:" - echo ${pkgs[@]} | tr " " "\n" | cut -d: -f2 - } - - popd > /dev/null -} - -function trap_exit { # End inmediately but print a useful message - - error "$@" - warning "Leftover files left on $build_dir" - - exit 1 -} - -# Trap signals from makepkg -set -E -trap 'trap_exit "(prfullpkg:${level}) TERM signal caught. Exiting..."' TERM HUP QUIT -trap 'trap_exit "(prfullpkg:${level}) Aborted by user! Exiting..."' INT -trap 'trap_exit "(prfullpkg:${level}) An unknown error has occurred. Exiting..."' ERR - -ban_file=$XDG_CONFIG_HOME/libretools/ban -force_build="" -level=0 -noupdate='n' -build_only='n' -check_deps_only='n' -max_level=21 - -while getopts 'ha:b:cd:l:nm:r:' arg; do - case $arg in - h) usage ;; - a) ABSROOT="$OPTARG" ;; - b) build_only='y' - build_dir="$OPTARG" - if [ -z ${build_dir} ]; then - usage - fi - if [ ! -r ${build_dir}/BUILDORDER ] ; then - error "${build_dir}/BUILDORDER doesn't exist." - exit 1 - fi;; - c) check_deps_only='y' ;; - d) build_dir="$OPTARG" ;; - l) level=$OPTARG ;; # hidden option to know dep level. - n) noupdate='y';; - m) max_level=$OPTARG ;; - r) FULLBUILDCMD="$OPTARG" ;; - esac -done - -if [ ${build_only} == 'n' ]; then - - [ ! -r PKGBUILD ] && { # Check if we are actually on a build directory. Do this early. - error "This isn't a build directory" - usage - } - - if [ ! -z "$HOOKPKGBUILDMOD" ]; then - "$HOOKPKGBUILDMOD" - fi - -fi - -if [ $level -eq 0 ]; then - - if [ ! -d ${build_dir} ]; then # in case of custom -d option - mkdir -p ${build_dir} - else - cleanup # files already there can screw find_deps - fi - - build_dir=${build_dir:-$(mktemp -d /tmp/fullpkg.XXXXXX)} # use -d option or else mktemp - - touch ${build_dir}/{log,BUILDORDER} ${ban_file} # make files for log and buildorder - buildorder=${build_dir}/BUILDORDER - - if [ ${noupdate} = 'n' ]; then - - msg "Updating pacman db and packages" - sudo pacman -Syu --noconfirm || true - - fi - - if [ ${build_only} == 'y' ]; then - - msg "Build Packages" - - __build - - exit 0 - - fi - - msg "Checking dependencies" -fi - -[ $level -ge $max_level ] && exit 20 # Probable circular deps - -find_deps || { - - if [ $? -eq 20 ]; then # Probable circular deps - - if [ $level -eq 0 ]; then # Show error only on level 0 - error "Check for circular deps on $build_dir/BUILDORDER"; - fi - - fi - exit 20 # Pass message 20 -} - -[ $check_deps_only = 'y' -o $level -gt 0 ] && exit 0 # only build on level 0 - -if [ $level -eq 0 -a -d $build_dir ]; then # Sanity check - - if [ ! -w $ban_file -o ! -r $ban_file ]; then # Check ban_file permisions - - chmod a+rw $ban_file || error "Ban file is not readable/writable ($ban_file)" - - else - - rsync -e ssh -aq $PARABOLAHOST:mips64el/ban >/dev/null 2>&1 || { - - warning "Failed to get ban list" && [ -r ${ban_file} ] && { # use local copy if it exist - - search=$(cat ${ban_file} | tr "\n" "|") - - egrep -w "$search" ${buildorder} >> ${build_dir}/banned # Keep track of banned files - - egrep -vw "$search" ${buildorder} > ${buildorder}2 # Take banned packages out of buildorder - - mv -f ${buildorder}2 ${buildorder} - - unset search - } - } - fi -fi - -msg "Building packages:" - -__build # Build the packages - -echo -msg2 "Check if your system works fine and librerelease if it does" - -exit 0 diff --git a/prtools/prmipsrelease b/prtools/prmipsrelease deleted file mode 100755 index 1fbd696..0000000 --- a/prtools/prmipsrelease +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -# Lic: GPLv3+ -# Author: Nicolas Reynolds <fauno@kiwwwi.com.ar> -# Local release of mips64el packages + clean ABS sync -# Called by HOOKLOCALRELEASE - -# $1 repo -# $2+ packages - - source /etc/makepkg.conf - source /etc/libretools.conf - source /etc/libretools.d/prtools.conf - - usage() { - echo "$0 repo package1 [ package2 ... packageN ]" - echo - echo " release packages locally on ${PKGDEST}/stage3." - echo " and make a clean ABS sync " - } - -## -# usage : get_full_version( $epoch, $pkgver, $pkgrel ) -# return : full version spec, including epoch (if necessary), pkgver, pkgrel -## - get_full_version() { - if [[ $1 -eq 0 ]]; then - # zero epoch case, don't include it in version - echo $2-$3 - else - echo $1:$2-$3 - fi - } - - repo=$1; shift - repo-add "${PKGDEST}/stage3.db.tar.gz" $@ - -# Get all needed sources - source PKGBUILD - fullver=$(get_full_version ${epoch:-0} ${pkgver} ${pkgrel}) - pkgbase=${pkgbase:-$pkgname} - - msg "Adding packages to [stage3]..." - repo-add $@ - for name in ${pkgname[@]}; do - msg2 "${name} ${fullver}" - repo-add ${PKGDEST}/stage3.db.tar.gz ${PKGDEST}/${name}-${fullver}-*.pkg.tar.* - done - -# Copy PKGBUILD and sources - - msg "Adding clean source to $WORKDIR/abs/${CARCH}/$repo/$pkgbase" - dest_dir="$WORKDIR/abs/${CARCH}/$repo/$pkgbase" - mkdir -p ${dest_dir} >/dev/null - rm -rf ${dest_dir}/* # if package existed already there - - eval $(grep '^CARCH=' "$copydir/etc/makepkg.conf") # CARCH might be used in PKGBUILD to select sources. - export CARCH - source=($(. "PKGBUILD"; echo ${source[@]})) - cp --remove-destination "PKGBUILD" "${dest_dir}" || echo "copy 1" - for f in ${source[@]}; do - basef=$(echo $f | sed 's|::.*||' | sed 's|^.*://.*/||g') - if [ -f "$basef" ]; then - cp --remove-destination "$basef" "${dest_dir}" - fi - done - - ( . PKGBUILD - for i in 'changelog' 'install'; do - filelist=$(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD) - for file in $filelist; do - # evaluate any bash variables used - eval file=${file} - if [ -f "$file" ]; then - cp --remove-destination "$file" "${dest_dir}" - fi - done - done - ) -# END add clean abs - -# Commit the changes - - pushd "$dest_dir" >/dev/null - - source "${dest_dir}/PKGBUILD" - epoch=${epoch:-0} - fullver=$(get_full_version ${epoch} ${pkgver} ${pkgrel}) - pkgbase=${pkgbase:-${pkgname[0]}} - - git add "${dest_dir}/." # add using .gitignore - - git commit -m "${pkgbase}-${fullver} ${repo}" >/dev/null && msg2 "${pkgbase} ${fullver} ${repo}" - - popd >/dev/null - -# END commit - - exit $? diff --git a/prtools/prtools.conf b/prtools/prtools.conf deleted file mode 100644 index 5b41216..0000000 --- a/prtools/prtools.conf +++ /dev/null @@ -1,4 +0,0 @@ - -# Absroot for libretools-pr -ABSROOT=$WORKDIR/prabs -HOOKLOCALRELEASE="prmipsrelease"
\ No newline at end of file diff --git a/prtools/prtoru b/prtools/prtoru deleted file mode 100644 index 2898b66..0000000 --- a/prtools/prtoru +++ /dev/null @@ -1,173 +0,0 @@ -#!/bin/bash -# Queries the ABS -# License: GPL3 - -## TODO -# * Add license text -# * Create symlinks from pkgbase to pkgname[@] for easy package finding -# * Use lastsync to store processed packages - -## GOALS -# * Have a searchable database of PKGBUILD metadata -# * Have an interface for source-only builds -# * Possibility to hook up ABS dirs besides ABSROOT (low priority) -# * Tell updates and non available binary packages (working on this) - -source /etc/abs.conf -source /etc/libretools.conf -source /etc/libretools.d/prtools.conf - -# Stores the lastsync date -lastsync() { - [ -e ${lastsyncfile} -a ! -w ${lastsyncfile} ] && { - error "The sync date can't be saved. ${lastsyncfile} isn't writable." - return 1 - } - - date +%s > "$lastsyncfile" - touch "$lastsyncfile" -} - -## -# usage : get_full_version( $epoch, $pkgver, $pkgrel ) -# return : full version spec, including epoch (if necessary), pkgver, pkgrel -## -get_full_version() { - if [[ $1 -eq 0 ]]; then - # zero epoch case, don't include it in version - echo $2-$3 - else - echo $1:$2-$3 - fi -} - -# Outputs an ordered package-fullpkgver array -print_package_array() { - echo "$@" | tr " " "\n" | sort -V -u -} - - -# Gets repo.db contents -# $1 repo -get_db_contents() { - [ ! -r /var/lib/pacman/sync/$1.db ] && return 0 - - bsdtar -tf /var/lib/pacman/sync/$1.db | \ - cut -d'/' -f1 | \ - sort -V -u -} - - -extract_pkgname() { - echo "$@" | tr " " "\n" | sed "s/^\(.\+\)-[^-]\+-[^-]\+$/\1/" -} - -extract_fullpkgver() { - echo "$@" | tr " " "\n" | sed "s/^.\+-\([^-]\+-[^-]\+\)$/\1/" -} - - -# Updates the database by finding all PKGBUILDS -# Workflow: -# * Find all PKGBUILDs on the ABS repo specified -# * Get all packages already on package repos -# * Compare them -# Args: -update() { -# The PKGBUILDs found - local pkgbuilds=() -# The list of pkgname-fullpkgver - local packages_to_sync=() - local packages_in_sync=() - local needed_updates=() - local old_versions=() - -# Find all the PKGBUILDs newer than the last update -# Update newer, otherwise everything - if [ $force ] || [ ! -e ${lastsyncfile} ]; then - $quiet || msg "Forcing upgrade" - pkgbuilds=($(find ${@} -maxdepth 2 -type f -name 'PKGBUILD')) - else - pkgbuilds=($(find ${@} -maxdepth 2 -type f -name 'PKGBUILD' -newer ${lastsyncfile})) - fi - -# Inform how many PKGBUILDS were found and quit immediately if none - $quiet || msg "Found $((${#pkgbuilds[*]}-1)) packages to update" - [ ${#pkgbuilds[*]} -eq 1 ] && { - $quiet || msg2 "There's nothing to be done. Phew!" - exit 0 - } - - for _pkgbuild in ${pkgbuilds[@]}; do - -# The repo name is guessed -# You *must* use repo/pkgbase structure - _pkgpath=$(dirname "${_pkgbuild}") - _pkgbase=$(basename "${_pkgpath}") - _pkgrepo=$(basename $(dirname "${_pkgpath}")) - - source ${_pkgbuild} - - for _pkg in ${pkgname[@]}; do -# Fill the list of packages to find - packages_to_sync+=($_pkg-$(get_full_version ${epoch:-0} $pkgver $pkgrel)) - done - - unset pkgbase pkgname pkgver pkgrel source epoch - done - -# Get repo database contents - packages_in_sync=($(get_db_contents ${_pkgrepo})) - print_package_array "${packages_to_sync[@]}" > ${TMPDIR}/packages_to_sync - print_package_array "${packages_in_sync[@]}" > ${TMPDIR}/packages_in_sync - -# We've orderer the files! - needed_updates=($(comm --nocheck-order -32 ${TMPDIR}/packages_to_sync ${TMPDIR}/packages_in_sync)) - old_versions=($(comm --nocheck-order -31 ${TMPDIR}/packages_to_sync ${TMPDIR}/packages_in_sync)) - - $quiet || msg "This packages are available to update" - for _update in ${needed_updates[@]}; do - pkg=$(extract_pkgname $_update) - - $quiet && echo $pkg - $quiet || { - ver=$(extract_fullpkgver $_update) - oldver=$(extract_fullpkgver $(grep -w $pkg ${TMPDIR}/packages_in_sync)) - - msg2 "$pkg $oldver => $ver" - } - - done - -# lastsync - -} - -## MAIN -commands=() -repos=() -quiet=false -force=false -while getopts 'hqfu' arg; do - case $arg in - h) usage; exit 0 ;; - q) quiet=true ;; - f) force=true ;; - u) commands+=(update);; - esac - - shift $((OPTIND-1)) -done - -# This is the syncfile, stores the last date as content and mtime -lastsyncfile=${ABSROOT}/toru.lastsync - -TMPDIR=$(mktemp -d) - -[[ -z ${TMPDIR} ]] && exit 1 - -${commands[0]} ${@} - -rm -rf ${TMPDIR} - -exit $? diff --git a/rePKGBUILD.proto b/rePKGBUILD.proto deleted file mode 100644 index c8b19bf..0000000 --- a/rePKGBUILD.proto +++ /dev/null @@ -1,29 +0,0 @@ -# This is an example rePKGBUILD file. Use this as a start to creating your own, -# and remove these comments. For more information, see 'man PKGBUILD'. -# NOTE: Please fill out the license field for your package! If it is unknown, -# then please put 'unknown'. - -# Maintainer: Your Name <youremail@domain.com> -source PKGBUILD -unset build package md5sums source -_repo= # Put the repo here -_mirror=http://mirrors.kernel.org/archlinux # Put mirror here -source=(PKGBUILD - "${_mirror}/${_repo}/os/${CARCH}/${pkgname%-libre}-$pkgver-$pkgrel-$CARCH$PKGEXT" - # files for pkg modifications below this line - ) - -build() { - cd "${srcdir}/" - rm .{INSTALL,PKGINFO} - # put actions for package modifications below this line - -} - -package() { - find ${srcdir} -maxdepth 1 -type l -delete - cp -a ${srcdir}/* ${pkgdir} -} - - -# vim:set ts=2 sw=2 et: diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..63f7782 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,2 @@ +pkgconfdir=$(sysconfdir) +include ../common.mk diff --git a/src/abslibre-tools/Makefile b/src/abslibre-tools/Makefile new file mode 100644 index 0000000..2c76089 --- /dev/null +++ b/src/abslibre-tools/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/createworkdir b/src/abslibre-tools/createworkdir index 6a4de10..99214ab 100755 --- a/createworkdir +++ b/src/abslibre-tools/createworkdir @@ -21,9 +21,10 @@ # You should have received a copy of the GNU General Public License # along with Parabola. If not, see <http://www.gnu.org/licenses/>. -source /etc/libretools.conf -custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf -[[ -e $custom_config ]] && source $custom_config +. libremessages +. $(librelib conf.sh) +load_files libretools +check_vars libretools WORKDIR REPOS ABSLIBREGIT || exit 1 [[ ! -d ${WORKDIR} ]] && { # Create the WORKDIR @@ -34,7 +35,7 @@ custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf } -for _repo in ${REPOS[@]}; do # Create the staging dirs +for _repo in "${REPOS[@]}"; do # Create the staging dirs [[ ! -d ${WORKDIR}/staging/${_repo} ]] && { mkdir -p ${WORKDIR}/staging/${_repo} || { diff --git a/src/abslibre-tools/diff-unfree b/src/abslibre-tools/diff-unfree new file mode 100755 index 0000000..07f2ca2 --- /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 2010 Nicolás Reynolds + +# ---------- GNU General Public License 3 ---------- + +# 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 DIFFTOOL || exit 1 + +cmd=${0##*/} + +usage() { + echo "Usage: $cmd [community|packages] [unfree-package] [repo]" + echo "Usage: $cmd --help" + echo "Helps you diff build scripts from ABSLibre against (Unfree) ABS." + echo "" + echo "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 $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 "$(basename "${_file}")" + ${DIFFTOOL} "$PWD/$(basename "${_file}")" "${_file}" + done +} + +main "$@" diff --git a/libreaddiff b/src/abslibre-tools/libreaddiff index 98646a2..03d0ad0 100755 --- a/libreaddiff +++ b/src/abslibre-tools/libreaddiff @@ -1,4 +1,5 @@ -#!/bin/bash +#!/usr/bin/env bash +set -e # -*- coding: utf-8 -*- # Copyright (C) 2011, 2012 Michał Masłowski <mtjm@mtjm.eu> # @@ -15,12 +16,9 @@ # 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 - -. /etc/libretools.conf -custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf -[ -e $custom_config ] && . $custom_config +. $(librelib conf.sh) +load_files libretools +check_vars libretools WORKDIR for arg in "$@" ; do case "$arg" in @@ -71,12 +69,7 @@ except StopIteration: # Needed to not include pkgnames specific to other arches. CARCH=$arch for f in $repo/* ; do - unset pkgname - unset epoch - unset pkgver - unset pkgrel - unset arch - . $f/PKGBUILD || continue + load_PKGBUILD "$f/PKGBUILD" || continue is_here=false for arc in ${arch[@]} ; do if [ "$arc" = "any" -o "$arc" = "$CARCH" ] ; then diff --git a/src/abslibre-tools/librerelease b/src/abslibre-tools/librerelease new file mode 100755 index 0000000..5913670 --- /dev/null +++ b/src/abslibre-tools/librerelease @@ -0,0 +1,212 @@ +#!/usr/bin/env bash +# Librerelease +# Uploads packages into [staging] + +# Copyright 2010 Nicolás Reynolds +# Copyright 2013 Luke Shumaker +# For just the create_signature() function: +# Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> +# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> +# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> +# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> +# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk> +# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org> +# Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> +# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> +# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> +# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> +# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk> +# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org> +# +# 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) + +function usage { + print "Usage: %s [OPTIONS]" "${0##*/}" + echo + print 'This script uploads packages on $WORKDIR/stagging' + print "to parabola server." + echo + print "Options:" + print ' -c Clean packages on $WORKDIR/staging' + print " -l Only list packages but not upload them" + print " -n Dry-run; don't actually do anything" + print " -h Show this message" +} + +function list_packages { + find "$WORKDIR/staging/" -mindepth 1 -type d -not -empty -printf '%f\n' | sort | + while read -r repo; do + msg2 "$repo" + find "${WORKDIR}/staging/${repo}" -type f -printf "%f\n" | sort + done +} + +# This function is taken almost verbatim from makepkg +create_signature() { + local ret=0 + local filename="$1" + msg "$(gettext "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" &>/dev/null || ret=$? + + + if (( ! ret )); then + msg2 "$(gettext "Created signature file %s.")" "$filename.sig" + else + error "$(gettext "Failed to sign package file.")" + return $ret + fi +} + +function sign_packages { + if [ -z "${GPG_AGENT_INFO}" ]; then + warning "It's better to use gpg-agent to sign packages in batches" + fi + + for package in $(find "${WORKDIR}/staging/" -type f -iname '*.pkg.tar.?z'); do + if [ -f "${package}.sig" ]; then + msg2 "Package signature found, verifying..." + + # Verify that the signature is correct, else remove for re-signing + if ! gpg --quiet --verify "${package}.sig" >/dev/null 2>&1; then + error "Failed! Re-signing..." + rm -f "${package}.sig" + fi + fi + + if ! [ -f "${package}.sig" ]; then + create_signature "$package" || return 2 + fi + done +} + +# Remove everything that's not a package or a signature +function clean_non_packages { + find $WORKDIR/staging/ -type f \ + \! -iname "*.pkg.tar.?z" -a \! -iname "*.pkg.tar.?z.sig" \ + -delete +} + +# Clean everything if not on dry-run mode +function clean { + if [[ -n "${dryrun}" ]]; then + : + else + msg "Removing files from local staging directory" + # use '-exec rm' instead of '-delete' to be verbose + find "${WORKDIR}/staging" -type f -exec rm -fv {} + + fi +} + +function main { + if [ -w / ]; then + error "This program should be run as regular user" + return 1 + fi + + # Parse options + local dryrun="" + local mode="release_packages" + while getopts 'clnh' arg; do + case $arg in + c) mode=clean ;; + l) mode=list_packages ;; + n) dryrun="--dry-run" ;; + h) mode=usage ;; + *) usage >/dev/stderr; return 1 ;; + esac + done + shift $(($OPTIND - 1)) + if [[ $# != 0 ]]; then + usage >/dev/stderr + 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 || return 1 + # The following variables are actually optional + #check_vars libretools HOOKPRERELEASE HOOKPOSTRELEASE || return 1 + + lock 10 "${WORKDIR}/staging.lock" 'Waiting for an exclusive lock on the staging directory' + "$mode" +} + +function release_packages { + if [[ -n $HOOKPRERELEASE ]]; then + msg "Running HOOKPRERELEASE..." + bash -c "${HOOKPRERELEASE}" + fi + + clean_non_packages + 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 {} \; + + msg "%s to upload" $(du -h -d 0 ${WORKDIR}/staging | tr "\t" " " | cut -d" " -f1) + msg "Uploading packages..." + if ! rsync --recursive \ + ${dryrun} \ + --no-group \ + --no-perms \ + --copy-links \ + --hard-links \ + --partial \ + --prune-empty-dirs \ + --human-readable \ + --progress \ + -e "ssh " \ + ${WORKDIR}/staging \ + ${REPODEST}/ + then + error "Sync failed, try again" + return 1 + fi + + clean + + msg "Running db-update on repos" + ssh ${REPODEST%%:*} dbscripts/db-update + + if [[ -n $HOOKPOSTRELEASE ]]; then + msg "Running 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..57846fc --- /dev/null +++ b/src/abslibre-tools/librestage @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# LibreStage +# Prepares packages for upload + +# Copyright 2010-2011 Nicolás Reynolds +# Copyright 2013 Luke Shumaker +# +# 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) + +cmd=${0##*/} +usage() { + print "Usage: %s REPO [REPO2 REPO3...]" "$cmd" + print "Stages the package(s) build by ./PKGBUILD for upload." + echo + print "The package(s) are staged for the named repositories." + print "It is in general a bad idea to stage a package on multiple" + print "repositories, but it supported by this tool." +} + +main() { + if [[ -w / ]]; then + error "This program should be run as regular user" + return 1 + fi + + # Parse options, set up + while getopts 'h' arg; do + case $arg in + h) usage; return 0;; + *) usage >/dev/stderr; return 1;; + esac + done + repos=("$@") + if [[ ${#repos[@]} -eq 0 ]]; then + usage >>/dev/stderr + return 1; + fi + + [[ ! -e ./PKGBUILD ]] && { + error "PKGBUILD not found" + return 1 + } + + # Load configuration + load_files libretools + check_vars libretools WORKDIR ARCHES || return 1 + load_files makepkg # for PKGDEST, which is optional + + # Load the PKGBUILD + load_PKGBUILD + + # Now for the main routine. + staged=false + slock 10 "${WORKDIR}/staging.lock" 'Waiting for a shared lock on the staging directory' + for CARCH in "${ARCHES[@]}" any; do + for _pkgname in "${pkgname[@]}"; do + pkgfile=${_pkgname}-$(get_full_version $_pkgname)-${CARCH}${PKGEXT} + pkgpath="$(find . "${PKGDEST:-.}" -maxdepth 1 -type f -name "$pkgfile"|sed 1q)" + + if [[ ! -f "${pkgpath}" ]]; then + continue + else + pkgpath="$(readlink -f "$pkgpath")" + fi + + msg "Found ${pkgfile}" + + canonical="" # is empty for the first iteration, set after that + for repo in "${repos[@]}"; do + mkdir -p "${WORKDIR}/staging/${repo}" + if [[ -z $canonical ]]; then + canonical="${WORKDIR}/staging/${repo}/${pkgfile}" + cmd=(cp "$pkgpath" "$canonical") + else + cmd=(ln "$canonical" "${WORKDIR}/staging/${repo}/${pkgfile}") + fi + if "${cmd[@]}"; 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 + done + + if $staged ; then + return 0 + else + error "No package was staged" + return 1 + fi +} + +main "$@" @@ -0,0 +1,163 @@ +#!/usr/bin/env bash +# Copyright 2010 Joshua Ismael +# Copyright 2010 Nicolás Reynolds +# Copyright 2013 Luke Shumaker +# +# 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 + +cmd=${0##*/} +usage() { + echo "Usage: $cmd [-h] pkgname-from-aur1 [pkgname-from-aur2 ...]" + echo + echo "This script will download packages from AUR to the current" + echo "directory and check their license for nonfree issues. This does" + echo "not mean that they are free; they may be incorrectly labeled, or" + echo "have other freedom issues. It's a tool to help Parabola" + echo "packagers, not to help users install things directly from AUR." +} + +main() { + while getopts 'h' arg; do + case $arg in + h) usage; return 0;; + *) usage >&2; return 1;; + esac + done + if [[ $# -lt 1 ]]; then + usage >&2 + return 1 + fi + + . $(librelib conf.sh) + load_files libretools + check_vars libretools DIFFTOOL || exit 1 + + local startdir="$(pwd)" + local missing_deps=() + local ret=0 + local pkg + local copy_new + local copy_old + for pkg in "$@"; do + pkg="${pkg%%[<>=]*}" # remove the version + msg "Processing package: %s" "$pkg" + copy_new="$startdir/$pkg" + copy_old= + + if [[ -f "${copy_new}/PKGBUILD" ]]; then + warning "%s already exists, will compare with new version." "$pkg" + + # Store our copy of the PKGBUILD dir + copy_old=$copy_new + copy_new="$(mktemp --tmpdir -d aur-${pkg}.new.XXXX)/$pkg" + cd "${copy_new%/*}" + fi + + msg2 "Downloading" + local url="https://aur.archlinux.org/packages/${pkg:0:2}/$pkg/$pkg.tar.gz" + set -o pipefail + if ! wget -O- -q "$url" | bsdtar xf -; then + ret=$(($ret|2)) + error "Couldn't get %s" "$pkg" + continue + fi + set +o pipefail + + if [[ -n $copy_old ]]; then + msg2 "Diffing files" + cd "$copy_new" + + # Diff all files with our difftool + local diffed=false + for file in *; do + if ! cmp -s "${copy_old}/${file}" "${copy_new}/${file}" ; then + warning "%s != %s" "${copy_old}/${file}" "${copy_new}/${file}" + diffed=true + "${DIFFTOOL}" "${copy_old}/${file}" "${copy_new}/${file}" + fi + done + if $diffed; then + read -p "Press enter to continue." + fi + + # Go back to our copy to continue working + cd "$copy_old" + rm -rf -- "${copy_new%/*}" + else + cd "$copy_new" + fi + + load_PKGBUILD + + ################################################################ + + pkgbuild-check-nonfree -c + case $? in + 0) :;; + 15) warning "This PKGBUILD links to known unfree packages";; + *) warning "pkgbuild-check-nonfree failed to run";; + esac + + ################################################################ + + local s=0 + pkgbuild-check-licenses || s=$? + for i in 1 2 4; do + if [[ $i -eq $(($s & $i)) ]]; then + case $i in + 1) warning "pkgbuild-check-licenses encountered an error";; + 2) warning "This PKGBUILD has an uncommon license";; + 4) warning "This PKGBUILD has a known nonfree license";; + esac + fi + done + unset s + + ################################################################ + + local _deps=( + # depends + "${depends[@]}" "${makedepends[@]}" "${checkdepends[@]}" + # mksource depends + "${mkdepends[@]}" + ) + local _dep + msg2 "Checking dependencies" + for _dep in "${_deps[@]}"; do + _dep=${_dep/[<>=]*/} + if ! is_built $_dep; then + if ! pacman -Sddp "$_dep" &>/dev/null ; then + plain "%s: will be downloaded from AUR" "$_dep" + missing_deps+=($_dep) + fi + else + plain "%s: is on repos" "$_dep" + fi + done + cd "$startdir" + done + + if [[ ${#missing_deps[*]} -gt 0 ]]; then + msg "Retrieving missing deps: %s" "${missing_deps[*]}" + "$0" "${missing_deps[@]}" + ret=$(($ret|$?)) + fi + return $ret; +} + +main "$@" diff --git a/src/chroot-tools/.gitignore b/src/chroot-tools/.gitignore new file mode 100644 index 0000000..80e1000 --- /dev/null +++ b/src/chroot-tools/.gitignore @@ -0,0 +1,5 @@ +makechrootpkg.sh* +!makechrootpkg.sh.patch + +arch-nspawn* +mkarchroot* diff --git a/src/chroot-tools/Makefile b/src/chroot-tools/Makefile new file mode 100644 index 0000000..0540636 --- /dev/null +++ b/src/chroot-tools/Makefile @@ -0,0 +1,44 @@ +# These files are coming from devtools +copy_files = makechrootpkg.sh.in mkarchroot.in arch-nspawn.in +# These are programs that we will use internally, but shouldn't be in PATH +libexecs = mkarchroot arch-nspawn distcc-tool chcleanup +no-progs = $(libexecs) +# These are the shell libraries we will use +libs = makechrootpkg.sh $(wildcard hooks-*.sh) + +pkglibexecdir = $(libexecdir)/libretools/chroot +clean_files = makechrootpkg.sh.ugly* *~ +include ../../common.mk + +# Usage: $(call indent,FILENAME) +# Command to auto-indent a file. +indent = emacs --batch $1 \ + --eval '(setq sh-basic-offset 8)' \ + --eval '(indent-region (point-min) (point-max) nil)' \ + -f save-buffer &>/dev/null + +# makechrootpkg.sh is special, we patch it and do fancy stuff +# The flow is: +# $(devtoolsdir)/*.in -> *.sh.in + *.sh.patch -> *.sh.ugly -> *.sh + +makechrootpkg.sh.in: %.sh.in: $(devtoolsdir)/%.in + cp $< $@ +makechrootpkg.sh.ugly: %.ugly: %.in %.patch Makefile + cp $*.in $@ + @echo 'PATCH $@ $*.patch'; patch $@ $*.patch || { rm -f -- '$@'; false; } +makechrootpkg.sh: %: %.ugly Makefile + @echo 'EDIT < $< > $@'; $(edit) <'$<' >'$@' || { rm -f -- '$@'; false; } + @echo 'INDENT $@'; $(call indent,$@) || { rm -f -- '$@'; false; } + +mkarchroot: mkarchroot.in Makefile + @echo '< $< M4_EDIT | SED > $@' + @<'$<' $(edit) | sed 's|arch-nspawn|$$(librelib chroot/&)|' >'$@' || { rm -f -- '$@'; false; } + @echo 'CHMOD $<'; chmod 755 "$@" || { rm -f -- '$@'; false; } + +archroot: %: %.in Makefile + @echo "GEN $@" + @$(edit) <"$<" >"$@" || { rm -f -- '$@'; false; } + @chmod 755 "$@" || { rm -f -- '$@'; false; } + +distcc-tool.pot: distcc-tool + xgettext --omit-header -i --from-code=UTF-8 -L shell --keyword={error,errusage} -o $@ $< diff --git a/src/chroot-tools/chcleanup b/src/chroot-tools/chcleanup new file mode 100755 index 0000000..a43065b --- /dev/null +++ b/src/chroot-tools/chcleanup @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +set -eE +# (c) Nicolás Reynolds <fauno@parabola.nu> +# Released under GPLv3 +# +# Performs chroot cleanup smartly, it only removes the unneeded packages or +# leaves you with a cleansystem +# +# See: HOOKPREBUILD + +DRYRUN=${DRYRUN:-false} + +################################################################################ +# Define these here to avoid having dependencies on outside files + +if type gettext &>/dev/null; then + _() { gettext "$@"; } +else + _() { echo "$@"; } +fi + +plain() { + local mesg="$(_ "$1")"; shift + printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 +} + +msg() { + local mesg="$(_ "$1")"; shift + printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 +} + +msg2() { + local mesg="$(_ "$1")"; shift + printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 +} + +warning() { + local mesg="$(_ "$1")"; shift + printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 +} + +error() { + local mesg="$(_ "$1")"; shift + printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 +} + +################################################################################ + +if [[ ! -f /.arch-chroot ]] && ! ${DRYRUN}; then + error "(chcleanup): Must be run inside of a chroot" + exit 1 +fi + +source /etc/libretools.d/chroot.conf +# If we're running makepkg +if [ -f PKGBUILD ]; then + export CARCH="$(. /etc/makepkg.conf; printf '%s' "$CARCH")" + source PKGBUILD + CHROOTEXTRAPKG+=("${depends[@]}" + "${makedepends[@]}" + "${checkdepends[@]}") +fi + +msg "Cleaning chroot..." +msg2 "Fetching updated package lists..." +pacman -Sy || { + warning "There was an error updating package lists, ignoring." +} + +# Setup the temporary directory +TEMPDIR="$(mktemp --tmpdir -d $(basename $0).XXXXX)" +trap "rm -rf '$TEMPDIR'" EXIT + +cp -a /var/lib/pacman/sync "${TEMPDIR}/" +pkglist="${TEMPDIR}"/pkglist.txt + +# Get the full list of packages needed by dependencies, including the base system +msg2 "Creating a full list of packages..." +pacman -b "${TEMPDIR}" \ + -Sp --print-format "%n" base-devel "${CHROOTEXTRAPKG[@]}" >"$pkglist" || { + ret=$? + error "Could not create a full list of packages, exiting." + plain "This is likely caused by a dependency that could not be found." + exit $ret +} + +# Diff installed packages against a clean chroot then remove leftovers +packages=($(comm -23 <(pacman -Qq | sort -u) \ + <(sort -u "${pkglist}"))) + +if [[ ${#packages[@]} = 0 ]]; then + msg2 "No packages to remove" +else + msg2 "Removing %d packages" ${#packages[@]} + + if ${DRYRUN}; then + echo "${packages[*]}" + else + # Only remove leftovers, -Rcs removes too much + pacman --noconfirm -Rn "${packages[@]}" + fi +fi diff --git a/src/chroot-tools/chroot.conf b/src/chroot-tools/chroot.conf new file mode 100644 index 0000000..3b3c445 --- /dev/null +++ b/src/chroot-tools/chroot.conf @@ -0,0 +1,13 @@ +# The full path to the chroot is +# $CHROOTDIR/$CHROOT/$COPY +# where $COPY is set at runtime. +# See `librechroot help` for details. +CHROOTDIR=/var/lib/archbuild +CHROOT=default + +# Extra packages to have installed on the chroot. +# This is in addition to CHROOTPKG=(base-devel) +CHROOTEXTRAPKG=() +#CHROOTEXTRAPKG+=(distcc-nozeroconf socat) # for BUILDENV+=(distcc) +#CHROOTEXTRAPKG+=(ccache) # for BUILDENV+=(ccache) +#CHROOTEXTRAPKG+=(libretools) # for running libremakepkg inside the chroot diff --git a/src/chroot-tools/distcc-tool b/src/chroot-tools/distcc-tool new file mode 100755 index 0000000..7633029 --- /dev/null +++ b/src/chroot-tools/distcc-tool @@ -0,0 +1,244 @@ +#!/usr/bin/env bash +# -*- tab-width: 4; sh-basic-offset: 4 -*- +# distcc-tool + +# Copyright 2013 Luke Shumaker +# +# 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/>. + +# This program has very few dependencies: +# - bash: I don't know what version, I use fairly modern features +# - socat +# - cat: any version +# - rm: any version +# - sed: any version +# On Parabola, this means the packages: +# bash, coreutils, sed, socat + +if ! type gettext &>/dev/null; then + gettext() { echo "$@"; } +fi + +panic() { + echo "$(gettext 'panic: malformed call to internal function')" >&2 + exit 1 +} + +error() { + mesg="$(gettext "$1")"; shift + printf "$(gettext 'ERROR:') $mesg\n" "$@" >&2 + exit 1 +} + +print() { + local mesg=$1 + shift + printf -- "$(gettext "$mesg")\n" "$@" +} + +usage() { + print "Usage: $0 COMMAND [COMMAND-ARGS]" + print "Tool for using distcc within a networkless chroot" + echo + print "Commands:" + print ' help print this message' + print ' odaemon CHROOTPATH daemon to run outside of the chroot' + print ' idaemon DISTCC_HOSTS daemon to run inside of the chroot' + print ' rewrite DISTCC_HOSTS prints a rewritten version of DISTCC_HOSTS' + print ' client HOST PORT connects stdio to TCP:$HOST:$PORT' + print 'Commands: for internal use' + print ' server counterpart to client; spawned by odaemon' +} + +errusage() { + if [[ $# -gt 0 ]]; then + fmt="$(gettext "$1")"; shift + printf "$(gettext 'ERROR:') $fmt\n" "$@" >&2 + fi + usage >&2 + exit 1 +} + +main() { + local cmd=$1 + shift + case "$cmd" in + help) + [[ $# -eq 0 ]] || errusage '%s: invalid number of arguments' "$cmd" + usage;; + odaemon|idaemon|rewrite) + [[ $# -eq 1 ]] || errusage '%s: invalid number of arguments' "$cmd" + $cmd "$@";; + client) + [[ $# -eq 2 ]] || errusage '%s: invalid number of arguments' "$cmd" + $cmd "$@";; + server) + [[ $# -eq 0 ]] || errusage '%s: invalid number of arguments' "$cmd" + $cmd "$@";; + *) errusage 'unknown subcommand: %s' "$cmd";; + esac +} + +################################################################################ +# DISTCC_HOSTS parser # +################################################################################ + +# usage: parse_DISTCC_HOSTS true|false DISTCC_HOSTS +# parses DISTCC_HOSTS and: +# $1==true : It sets up port forwarding for inside the choot, sleep forever +# $1==false: Prints a modified version of DISTCC_HOSTS that uses the forwarded +# ports that were set up when $1==true. +parse_DISTCC_HOSTS() { + { [[ $# -eq 2 ]] && { [[ $1 == true ]] || [[ $1 == false ]]; }; } || panic + local forward_ports=$1 + local DISTCC_HOSTS=$2 + + local pids=() # child pids + local newhosts=() + local newport=8000 # next port to be used for port forwarding + + # This is based on the grammar specified in distcc(1) + local HOSTSPEC + for HOSTSPEC in $(sed 's/#.*//' <<<"$DISTCC_HOSTS"); do + case "$HOSTSPEC" in + # LOCAL_HOST + localhost|localhost/*|--localslots=*|--localslots_cpp=*) + # "localhost" runs commands directly, not talking to distccd at + # localhost, use an IP or real hostname for that. + # So, just pass these through. + newhosts+=("$HOSTSPEC") + ;; + # SSH_HOST + *@*) + # SSH_HOST doesn't allow custom port numbers, and even if it + # did, ssh would complain about MITM. Instead, we'll count on + # ssh ProxyCommand being configured to used `client`. + newhosts+=("$HOSTSPEC") + ;; + # GLOBAL_OPTION + --*) + # pass these through + newhosts+=("$HOSTSPEC") + ;; + # ZEROCONF + +zeroconf) + error "%s does not support the +zeroconf option" "$0" + exit 1 + ;; + # TCP_HOST or OLDSTYLE_TCP_HOST + *) + declare HOSTID= PORT= LIMIT= OPTIONS= + if [[ $HOSTSPEC =~ ^([^:/]+)(:([0-9]+))?(/([0-9]+))?(,.*)?$ ]]; then + # TCP_HOST + HOSTID=${BASH_REMATCH[1]} + PORT=${BASH_REMATCH[3]} + LIMIT=${BASH_REMATCH[5]} + OPTIONS=${BASH_REMATCH[6]} + elif [[ $HOSTSPEC =~ ^([^:/]+)(/([0-9]+))?(:([0-9]+))?(,.*)?$ ]]; then + # OLDSTYLE_TCP_HOST + HOSTID=${BASH_REMATCH[1]} + LIMIT=${BASH_REMATCH[3]} + PORT=${BASH_REMATCH[5]} + OPTIONS=${BASH_REMATCH[6]} + else + error "Could not parse HOSTSPEC: %s" "$HOSTSPEC" + fi + + # set up port forwaring + if $forward_ports; then + socat TCP-LISTEN:${newport},fork SYSTEM:"$0 client $HOSTID ${PORT:-3632}" & + pids+=($!) + fi + + # add the forwarded port + local newhost="127.0.0.1:$newport" + [[ -z $LIMIT ]] || newhost+="/$LIMIT" + [[ -z $OPTIONS ]] || newhost+="$OPTIONS" + newhosts+=("$newhost") + : $((newport++)) + ;; + esac + done + if $forward_ports; then + if [[ -z "${pids[*]}" ]]; then + # listen on port 8000, but immediatly close, just so that we are + # listening on something + socat TCP-LISTEN:${newport},fork SYSTEM:true & + pids+=($!) + fi + trap "kill -- ${pids[*]}" EXIT + wait "${pids[@]}" + else + printf '%s\n' "${newhosts[*]}" + fi +} + +################################################################################ +# Port forwarding primitives # +################################################################################ + +# Usage: server +# Reads "host port" from the first line of stdin, then connects stdio to the +# specified TCP socket. +server() { + [[ $# -eq 0 ]] || panic + while read -r host port; do + socat STDIO TCP:"$host:$port" + break + done +} + +# Usage: client HOST PORT +# For usage inside of a chroot. It talks through the UNIX-domain socket to an +# instance of `server` outside, in order to connect stdio to the specified TCP +# socket. +client() { + [[ $# -eq 2 ]] || panic + local file=/socket + { printf '%s\n' "$*"; cat; } | socat UNIX-CONNECT:"$file" STDIO +} + +################################################################################ +# High-level routines # +################################################################################ + +# Usage: odaemon CHROOTPATH +# Listens on "$CHROOTPATH/socket" and spawns a `server` for each new connection. +odaemon() { + [[ $# -eq 1 ]] || panic + local chrootpath=$1 + + umask 111 + socat UNIX-LISTEN:"$chrootpath/socket",fork SYSTEM:"$0 server" & + trap "kill -- $!; rm -f '$chrootpath/socket'" EXIT + wait +} + +# Usage: idaemon DISTCC_HOSTS +# Sets things up inside of the chroot to forward distcc hosts out. +idaemon() { + [[ $# -eq 1 ]] || panic + parse_DISTCC_HOSTS true "$1" +} + +# Usage: rewrite DISTCC_HOSTS +# Prints a modified version of DISTCC_HOSTS for inside the chroot. +rewrite() { + [[ $# -eq 1 ]] || panic + parse_DISTCC_HOSTS false "$1" +} + +main "$@" diff --git a/src/chroot-tools/hooks-chcleanup.sh b/src/chroot-tools/hooks-chcleanup.sh new file mode 100644 index 0000000..09e6dd9 --- /dev/null +++ b/src/chroot-tools/hooks-chcleanup.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -euE + +hooks_pre_build+=("clean_chroot") + +clean_chroot() ( + set +x + local copydir=$1 + if $INCHROOT; then + cd /build + sudo -u nobody "$(librelib chroot/chcleanup)" + else + librechroot -l "$copydir" clean-pkgs + fi + r=$?; echo clean_chroot returning $r; return $r +) diff --git a/src/chroot-tools/hooks-check.sh b/src/chroot-tools/hooks-check.sh new file mode 100644 index 0000000..e8120b8 --- /dev/null +++ b/src/chroot-tools/hooks-check.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -euE + +hook_check_pkgbuild+=("check_pkgbuild_dependencies") +check_pkgbuild_dependencies() { + local s=0 + sudo -EH -u "$LIBREUSER" pkgbuild-check-nonfree -f || s=$? + case $s in + 0) :;; + 15) error "This PKGBUILD links to known unfree packages"; return 1;; + *) warning "pkgbuild-check-nonfree failed to run";; + esac +} + +hook_check_pkgbuild+=("check_pkgbuild_license") +check_pkgbuild_license() { + local s=0 + sudo -EH -u "$LIBREUSER" pkgbuild-check-licenses -f || s=$? + for i in 1 2 4; do + if [[ $i -eq $(($s & $i)) ]]; then + case $i in + 1) warning "pkgbuild-check-licenses encountered an error";; + 2) warning "This PKGBUILD has an uncommon license";; + 4) error "This PKGBUILD has a known nonfree license"; ret=1;; + esac + fi + done +} + +#hook_check_pkgbuild+=("check_pkgbuild_namcap") +check_pkgbuild_namcap() { + sudo -EH -u "$LIBREUSER" namcap PKGBUILD +} + +#hook_check_pkg+=("check_pkg") +check_pkg() { + # TODO + : +} diff --git a/src/chroot-tools/hooks-distcc.sh b/src/chroot-tools/hooks-distcc.sh new file mode 100644 index 0000000..9e42242 --- /dev/null +++ b/src/chroot-tools/hooks-distcc.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +set -euE + +hook_pre_build+=("distcc_start") +hook_post_build+=("distcc_stop") + +_distcc_check() { + local copydir=$1 + local home=$2 + + local files=( + "$copydir/bin/distcc-tool" + "$copydir/run/distcc-tool.pid" + "$home/.makepkg.conf" + "$home/.ssh/config" + ) + + local file_err=false + for files in "${files[@]}"; do + if [[ -f $file ]]; then + file_err=true + error "Auto-generated file already exists, remove it: %s" "$file" + fi + done + if $file_err; then + exit 1 + fi +} + +distcc_start() { + local copydir=$1 + + # Because /{,usr/}{,s}bin are all symlinked together for + # fileystem 2013.05-2 and up, I can take shortcuts when checking for + # existance of programs. + if $NONET && [[ -f "$copydir/bin/socat" && -f "$copydir/bin/distcc" ]]; then + local home + if $INCHROOT; then + home=$LIBREHOME + else + home="$copydir/build" + fi + + _distcc_check + + local _distcc_tool=$(librelib chroot/distcc-tool) + install -m755 "$_distcc_tool" "$copydir/bin/distcc-tool" + + mkdir -p "$home/.ssh" + + printf '%s\n' \ + '/bin/distcc-tool idaemon "$DISTCC_HOSTS" &' \ + 'DISTCC_HOSTS="$(/bin/distcc-tool rewrite "$DISTCC_HOSTS")"' \ + > "$home/.makepkg.conf" + + printf '%s\n' \ + 'Host *' \ + ' ProxyCommand /bin/distcc-tool client %h %p' \ + > "$home/.ssh/config" + + "$_distcc_tool" odaemon "$copydir" & + echo $! > "$copydir/run/distcc-tool.pid" + fi +} + +distcc_stop() { + local copydir=$1 + + local home + if $INCHROOT; then + home=$LIBREHOME + else + home="$copydir/build" + fi + + if [[ -f "$copydir/run/distcc-tool.pid" ]]; then + + odaemon=$(cat "$copydir/distcc-tool.pid") + kill -- "$odaemon" + + rm -f -- \ + "$home/.makepkg.conf" \ + "$home/.ssh/config" \ + "$copydir/bin/distcc-tool" \ + "$copydir/run/distcc-tool.pid" + fi +} diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot new file mode 100755 index 0000000..0b3ad43 --- /dev/null +++ b/src/chroot-tools/librechroot @@ -0,0 +1,325 @@ +#!/usr/bin/env bash +set -euE +# librechroot + +# Copyright 2010 Nicolás Reynolds +# Copyright 2011 Joshua Haase +# Copyright 2012-2013 Luke Shumaker +# +# 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/>. + +# HACKING: if a command is added or removed, it must be changed in 3 places: +# - the usage() text +# - the commands=() array +# - the case statement in main() + +. $(librelib conf) +load_files chroot + +. libremessages + +shopt -s nullglob +umask 0022 + +readonly _arch_nspawn=$(librelib chroot/arch-nspawn) +readonly _mkarchroot=$(librelib chroot/mkarchroot) +readonly _makechrootpkg=$(librelib chroot/makechrootpkg.sh) + +# Because the makechrootpkg.sh library functions don't work with -euE +_makechrootpkg() ( + set +euE + . "$_makechrootpkg" + "$@" +) + +# Usage: make_empty_repo $copydir +make_empty_repo() { + local copydir=$1 + mkdir -p "${copydir}/repo" + bsdtar -czf "${copydir}/repo/repo.db.tar.gz" -T /dev/null + ln -s "repo.db.tar.gz" "${copydir}/repo/repo.db" +} + +# Usage: chroot_add_to_local_repo $copydir $pkgfiles... +chroot_add_to_local_repo() { + local copydir=$1; shift + mkdir -p "$copydir/repo" + local pkgfile + for pkgfile in "$@"; do + cp "$pkgfile" "$copydir/repo" + pushd "$copydir/repo" >/dev/null + repo-add repo.db.tar.gz "${pkgfile##*/}" + popd >/dev/null + done +} + +usage() { + eval "$(calculate_directories)" + print "Usage: %s [OPTIONS] COMMAND [ARGS...]" "${0##*/}" + print 'Interacts with an archroot (arch chroot).' + echo + prose 'This is configured with `chroot.conf`, either in + `/etc/libretools.d/`, or `$XDG_CONFIG_HOME/libretools/`. + The variables you may set are $CHROOTDIR, $CHROOT, and + $CHROOTEXTRAPKG.' + echo + prose 'There may be multiple chroots; they are stored in $CHROOTDIR.' + echo + prose 'Each chroot is named; the default is configured with $CHROOT.' + echo + prose 'Each named chroot has a master clean copy (named `root`), and any + number of other named copies; the copy used by default is the + current username (or $SUDO_USER, or `copy` if root).' + echo + prose 'The full path to the chroot copy is "$CHROOTDIR/$CHROOT/$COPY", + unless the copy name is manually specified as an absolute path, + in which case, that path is used.' + echo + prose 'The current settings for the above varibles are:' + printf ' CHROOTDIR : %s\n' "${CHROOTDIR:-$(_ 'ERROR: NO SETTING')}" + printf ' CHROOT : %s\n' "${CHROOT:-$(_ 'ERROR: NO SETTING')}" + printf ' COPY : %s\n' "$COPY" + printf ' rootdir : %s\n' "${rootdir:-$(_ 'ERROR')}" + printf ' copydir : %s\n' "${copydir:-$(_ 'ERROR')}" + echo + prose 'If the chroot, or copy does not exist, it will be created + automatically. A chroot by default contains the packages in the + group "base-devel", and any packages named in $CHROOTEXTRAPKG. + Unless the `-C` or `-M` flags are used, the configuration files + that this program installs are the stock versions supplied in the + packages, not the versions from your host system. Other tools + (such as libremakepkg) may alter the configuration.' + echo + prose 'This command will make the following configuration changes in the + chroot:' + bullet 'overwrite `/etc/libretools.d/chroot.conf`' + bullet 'overwrite `/etc/pacman.d/mirrorlist`' + bullet 'set `CacheDir` in `/etc/pacman.conf`' + prose 'If a new `pacman.conf` is inserted with the `-C` flag, the change + is made after the file is copied in; the `-C` flag doesn'\''t + stop the change from being effective.' + echo + prose 'Creating a copy, deleting a copy, or syncing a copy can be fairly + slow; but are very fast if $CHROOTDIR is on a btrfs partition.' + echo + print 'Options:' + flag "-n <$(_ CHROOT)>" 'Name of the chroot to use' + flag "-l <$(_ COPY)>" 'Name of, or absolute path to, the copy to use' + flag '-N' 'Disable networking in the chroot' + flag "-C <$(_ FILE)>" 'Copy this file to `$copydir/etc/pacman.conf`' + flag "-M <$(_ FILE)>" 'Copy this file to `$copydir/etc/makepkg.conf`' + flag "-w <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read/write' + flag "-r <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read-only' + echo + print 'Commands:' + print ' Create/copy/delete:' + flag 'noop|make' 'Do not do anything, but still creates the chroot + copy if it does not exist' + flag 'sync' 'Sync the copy with the clean (`root`) copy' + flag 'delete' 'Delete the chroot copy' + print ' Dealing with packages:' + flag "install-file $(_ FILES...)" 'Like `pacman -U FILES...`' + flag "install-name $(_ NAMES...)" 'Like `pacman -S NAMES...`' + flag 'update' 'Like `pacman -Syu`' + flag 'clean-pkgs' 'Remove all packages from the chroot copy that + are not in base-devel, $CHROOTEXTRAPKG, or named + as a dependency in the file `/build/PKGBUILD` in + the chroot copy' + print ' Other:' + flag "run $(_ CMD...)" 'Run CMD in the chroot copy' + flag 'enter' 'Enter an interactive shell in the chroot copy' + flag 'clean-repo' 'Clean /repo in the chroot copy' + flag 'help' 'Show this message' +} +readonly commands=( + noop make sync delete + install-file install-name update clean-pkgs + run enter clean-repo help +) + +# set $rootdir and $copydir; blank them on error +calculate_directories() { + # Don't assume that CHROOTDIR or CHROOT are set, + # but assume that COPY is set. + local rootdir copydir + + if [[ -n ${CHROOTDIR:-} ]] && [[ -n ${CHROOT:-} ]]; then + rootdir="${CHROOTDIR}/${CHROOT}/root" + else + rootdir='' + fi + + if [[ ${COPY:0:1} = / ]]; then + copydir=$COPY + elif [[ -n ${CHROOTDIR:-} ]] && [[ -n ${CHROOT:-} ]]; then + copydir="${CHROOTDIR}/${CHROOT}/${COPY}" + else + copydir='' + fi + + declare -p rootdir + declare -p copydir +} + +arch_nspawn_flags=() +sysd_nspawn_flags=() +arch-nspawn() { + local copydir=$1; shift + set +u # if an array is empty, it counts as unbound + "$_arch_nspawn" "${arch_nspawn_flags[@]}" "$copydir" "${sysd_nspawn_flags[@]}" -- "$@" + set -u +} + +# Globals: $CHROOTDIR, $CHROOT, $COPY, $rootdir and $copydir +main() { + COPY=$LIBREUSER + [[ $COPY != root ]] || COPY=copy + + local mode=enter + while getopts 'n:l:NC:M:w:r:' opt; do + case $opt in + n) CHROOT=$OPTARG;; + l) COPY=$OPTARG;; + N) sysd_nspawn_flags+=(--private-network);; + C|M) arch_nspawn_flags+=(-$opt "$OPTARG");; + w) sysd_nspawn_flags+=("--bind=$OPTARG");; + r) sysd_nspawn_flags+=("--bind-ro=$OPTARG");; + *) usage >/dev/stderr; return 1;; + esac + done + shift $(($OPTIND - 1)) + if [[ $# -lt 1 ]]; then + error "Must specify a command" + usage >/dev/stderr + return 1 + fi + mode=$1 + if ! in_array "$mode" "${commands[@]}"; then + error "Unrecognized command: %s" "$mode" + usage >/dev/stderr + return 1 + fi + shift + + if [[ $mode == help ]]; then + usage + return 0 + fi + + check_vars chroot CHROOTDIR CHROOT + eval "$(calculate_directories)" + + readonly LIBREUSER LIBREHOME + readonly CHROOTDIR CHROOT COPY + readonly rootdir copydir + readonly mode + + ######################################################################## + + if (( EUID )); then + error "This program must be run as root." + return 1 + fi + + umask 0022 + + # Keep this lock as long as we are running + # Note that '9' is the same FD number as in mkarchroot et al. + lock 9 "$copydir.lock" \ + "Waiting for existing lock on chroot copy to be released: [%s]" "$COPY" + + if [[ ! -d $rootdir ]]; then + msg "Creating 'root' copy for chroot [%s]" "$CHROOT" + set +u # if an array is empty, it counts as unbound + "$_mkarchroot" "${arch_nspawn_flags[@]}" "$rootdir" base-devel + set -u + make_empty_repo "$rootdir" + fi + + if [[ ! -d $copydir ]] || [[ $mode == sync ]]; then + msg "Syncing copy [%s] with root copy" "$COPY" + _makechrootpkg sync_chroot "$CHROOTDIR/$CHROOT" "$COPY" + fi + + mkdir -p "$copydir/etc/libretools.d" + { + if [[ -n ${CHROOTEXTRAPKG[*]:-} ]]; then + declare -p CHROOTEXTRAPKG | sed -r 's/declare( -.)* //' + else + printf 'CHROOTEXTRAPKG=()\n' + fi + } > "$copydir"/etc/libretools.d/chroot.conf + + if [[ $mode != delete ]]; then + # "touch" the chroot first + # this will + # - overwrite \`/etc/pacman.d/mirrorlist'" + # - set \`CacheDir' in \`/etc/pacman.conf'" + # - apply -C or -M flags + arch-nspawn "$copydir" true + arch_nspawn_flags=() # XXX dirty hack, don't apply -C or -M again + fi + + ######################################################################## + + case "$mode" in + # Creat/copy/delete + noop|make|sync) :;; + delete) + if [[ -d $copydir ]]; then + _makechrootpkg delete_chroot "$copydir" "$COPY" + fi + ;; + + # Dealing with packages + install-file) + _makechrootpkg install_packages "$copydir" "$@" + chroot_add_to_local_repo "$copydir" "$@" + ;; + install-name) + arch-nspawn "$copydir" pacman -Sy "$@" + ;; + update) + arch-nspawn "$copydir" pacman -Syu --noconfirm + ;; + clean-pkgs) + trap "rm -f '$copydir'/bin/chcleanup '$copydir'/chrootexec" EXIT + install -m755 "$(librelib chroot/chcleanup)" "$copydir/bin/chcleanup" + printf '%s\n' \ + '#!/bin/bash' \ + 'mkdir -p /build' \ + 'cd /build' \ + '/bin/chcleanup' \ + > "$copydir/chrootexec" + chmod 755 "$copydir/chrootexec" + arch-nspawn "$copydir" /chrootexec + ;; + + # Other + run) + arch-nspawn "$copydir" "$@" + ;; + enter) + arch-nspawn "$copydir" bash + ;; + clean-repo) + rm -rf "${copydir}"/repo/* + make_empty_repo "$copydir" + ;; + esac +} + +main "$@" diff --git a/src/chroot-tools/libremakepkg b/src/chroot-tools/libremakepkg new file mode 100755 index 0000000..a59315b --- /dev/null +++ b/src/chroot-tools/libremakepkg @@ -0,0 +1,249 @@ +#!/usr/bin/env bash +set -euE +# libremakepkg + +# Copyright 2010-2011 Nicolás Reynolds +# Copyright 2011 Joshua Ismael Haase Hernández +# Copyright 2012-2013 Luke Shumaker +# +# 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/>. + +. $(librelib conf) +. $(librelib messages) +. $(librelib chroot/makechrootpkg.sh) + +shopt -s nullglob +umask 0022 + +# Global variables: +readonly INCHROOT=$([[ -f /.arch-chroot ]] && echo true || echo false) +NONET=true # can be changed with the -N flag +# {SRC,LOG,PKG}DEST set at runtime by makepkg.conf +# MAKEFLAGS, PACKAGER set at runtime by makepkg.conf +# LIBREUSER, LIBREHOME are set by conf.sh + +# Hooks ######################################################################## + +hook_pre_build=(:) +hook_post_build=(:) +hook_check_pkgbuild=(:) +hook_check_pkg=(:) +. $(librelib chroot/hooks-chcleanup.sh) +. $(librelib chroot/hooks-check.sh) +. $(librelib chroot/hooks-distcc.sh) + +# Boring/mundane functions ##################################################### + +# Usage: exit_copy $copydir $src_owner +# End immediately, but copy log files out +exit_copy() { + local copydir=$1 + local src_owner=$2 + if ! $INCHROOT; then + msg "Copying log and package files out of the chroot..." + move_products "$copydir" "$src_owner" + fi +} + +# Usage; run_hook $hookname $args... +run_hook() { + local hookname=$1; shift + local hookvar="hook_${hookname}[@]" + local fails=() + msg "Running hook: %s" "$hookname" + for hook in "${!hookvar}"; do + msg2 'hook: %s' "$hook" + "$hook" "$@" || { error "result: %s" $?; fails+=("$hook"); } + done + if [[ ${#fails[@]} -gt 0 ]]; then + error "Failure(s) in %s: %s" "$hookname" "${fails[*]}" + return 1 + fi + return 0 +} + +# Usage: add_to_local_repo $copydir $pkgfiles... +add_to_local_repo() { + local copydir=$1; shift + mkdir -p "$copydir/repo" + local pkgfile + for pkgfile in "$@"; do + cp "$pkgfile" "$copydir/repo" + pushd "$copydir/repo" >/dev/null + repo-add repo.db.tar.gz "${pkgfile##*/}" + popd >/dev/null + done +} + +build() ( + local copydir=$1; shift + local cmd=(/chrootbuild "$@") + + run_hook pre_build "$copydir" + trap "run_hook post_build '$copydir'" EXIT + + local netflag='' + if $INCHROOT; then + ! $NONET || netflag='-n' + unshare $netflag -- "${cmd[@]}" + else + ! $NONET || netflag='-N' + librechroot $netflag \ + -r "$PWD:/startdir_host" \ + -r "$SRCDEST:/srcdest_host" \ + -l "$copydir" \ + run "${cmd[@]}" + fi +) + +# The main program ############################################################# + +usage() { + print "Usage: %s [options] [-- makepkg args]" "${0##*/}" + print 'This program will build your package.' + echo + prose 'If run from outside of a chroot, command will make the following + configuration changes in the chroot:' + bullet 'whatever changes `librechroot` makes.' + bullet 'set `PKGDEST` and `SRCDEST` in `/etc/makepkg.conf`' + bullet 'set `PACKAGER` in `/etc/makepkg.conf` to reflect the value + outside of the chroot.' + bullet '(maybe) delete `/build/.makepkg.conf`' + bullet '(maybe) delete `/build/.ssh/config`' + prose 'If run from inside of a chroot, this command will:' + bullet '(maybe) delete `~/.makepkg.conf`' + bullet '(maybe) delete `~/.ssh/config`' + prose 'The above "maybe"s happen as part of the workarounds to make + distcc work in a network-less environment. They will happen if + both `socat` and `distcc` are installed in the chroot.' + echo + prose 'The `-n` and `-l` options behave identically to librechroot, see + the documentation there.' + echo + print 'Options:' + flag "-n <$(_ CHROOT)>" 'Name of the chroot to use' + flag "-l <$(_ COPY)>" 'Name of, or absolute path to, the chroot copy to use' + flag '-N' "Don't disable networking during build() and + package(). PLEASE don't use this unless you + have a special reason, its use is a violation + of Parabola policy." + flag '-R' 'Repackage contents of the package without rebuilding' + flag '-h' 'Show this message' +} + +# Convenience method for use in option parsing +err_chflag() { + local flag=$1 + error 'The -%s flag does not make sense inside of a chroot' "$flag" + return 1 +} + +main() { + # Initial variable values ############################################## + local copy=$([[ $LIBREUSER == root ]] && echo copy || echo "$LIBREUSER") + local makepkg_args=(-s --noconfirm -L) + local repack=false + local chroot='' + + # Parse command line options ########################################### + while getopts 'n:l:NRh' flag ; do + case "${flag}" in + n) if $INCHROOT; then err_chflag "$flag"; else chroot=$OPTARG; fi;; + l) if $INCHROOT; then err_chflag "$flag"; else copy=$OPTARG; fi;; + N) NONET=false;; + R) repack=true; makepkg_args+=(-R);; + h) usage; return 0;; + *) usage >&2; return 1;; + esac + done + shift $(($OPTIND - 1)) + # Pass all arguments after -- right to makepkg + makepkg_args+=("$@") + + # Resolve the chroot path ############################################## + local copydir + if $INCHROOT; then + copydir='/' + else + load_files chroot + check_vars chroot CHROOTDIR CHROOT + [[ -z ${chroot} ]] || CHROOT=$chroot + if [[ ${copy:0:1} = / ]]; then + copydir=$copy + else + copydir="${CHROOTDIR}/${CHROOT}/${copy}" + fi + unset CHROOTDIR CHROOTEXTRAPKG + fi + unset chroot + + # Quick sanity check ################################################### + + if (( EUID )); then + error "This program must be run as root" + exit 1 + fi + + if [[ ! -f PKGBUILD ]]; then + # This is the message used by makepkg + error "PKGBUILD does not exist." + exit 1 + fi + + # Load makepkg configuration ########################################### + # Note that all of these are globals + SRCDEST="$(get_conf_makepkg SRCDEST "$PWD")" + PKGDEST="$(get_conf_makepkg PKGDEST "$PWD")" + LOGDEST="$(get_conf_makepkg LOGDEST "$PWD")" + mkdir -p "$SRCDEST" "$PKGDEST" "$LOGDEST" + MAKEFLAGS="$(get_conf_makepkg MAKEFLAGS '')" + PACKAGER="$(get_conf_makepkg PACKAGER '')" + + # OK, we are starting now ############################################## + + if $INCHROOT; then + lock 9 "/build/.lock" \ + "Waiting for existing lock on build directory to be released" + else + # Obtain a lock on the chroot + lock 9 "$copydir.lock" \ + "Waiting for existing lock on chroot copy to be released: [%s]" "$copy" + # Create the chroot if it does not exist + librechroot -n "$CHROOT" -l "$copy" make + fi + + # Set target CARCH + # note that we waited until after locking/creating the chroot to do this + export CARCH="$(MAKEPKG_CONF=$copydir/etc/makepkg.conf get_conf_makepkg CARCH)" + + # Pre-build + run_hook check_pkgbuild + download_sources "$copydir" "$LIBREUSER" + prepare_chroot "$copydir" "$LIBREHOME" "$repack" false + clean_chroot "$copydir" + + # Build + trap "exit_copy '$copydir' '$LIBREUSER'" EXIT + warning 'Entering build...' + build "$copydir" "${makepkg_args[@]}" + # Post-build + warning 'Entering hook check_pkg...' + run_hook check_pkg + warning 'Entering add_to_local_repo ...' + add_to_local_repo "$copydir" "$copydir"/pkgdest/*.pkg.tar* +} + +main "$@" diff --git a/src/chroot-tools/makechrootpkg.sh.patch b/src/chroot-tools/makechrootpkg.sh.patch new file mode 100644 index 0000000..f5b8ed7 --- /dev/null +++ b/src/chroot-tools/makechrootpkg.sh.patch @@ -0,0 +1,303 @@ +--- makechrootpkg.sh.in 2013-09-08 23:01:20.000000000 -0400 ++++ makechrootpkg.sh.ugly 2013-09-09 15:43:06.000000000 -0400 +@@ -12,6 +12,7 @@ + + shopt -s nullglob + ++init_variables() { + _makepkg_args=(-s --noconfirm -L --holdver) + makepkg_args=("${_makepkg_args[@]}") + repack=false +@@ -26,9 +27,10 @@ + declare -i ret=0 + + copy=$USER +-[[ -n $SUDO_USER ]] && copy=$SUDO_USER ++[[ -n ${SUDO_USER:-} ]] && copy=$SUDO_USER + [[ -z "$copy" || $copy = root ]] && copy=copy + src_owner=${SUDO_USER:-$USER} ++} + + usage() { + echo "Usage: ${0##*/} [options] -r <chrootdir> [--] [makepkg args]" +@@ -62,6 +64,7 @@ + exit 1 + } + ++parse_options_init() { + while getopts 'hcur:I:l:nT' arg; do + case "$arg" in + h) usage ;; +@@ -86,9 +89,6 @@ + [[ ! -d $chrootdir ]] && die "No chroot dir defined, or invalid path '%s'" "$passeddir" + [[ ! -d $chrootdir/root ]] && die "Missing chroot dir root directory. Try using: mkarchroot %s/root base-devel" "$chrootdir" + +-# Detect chrootdir filesystem type +-chroottype=$(stat -f -c %T "$chrootdir") +- + if [[ ${copy:0:1} = / ]]; then + copydir=$copy + else +@@ -103,30 +103,47 @@ + repack=true + fi + +-if [[ -n $SUDO_USER ]]; then ++if [[ -n ${SUDO_USER:-} ]]; then + USER_HOME=$(eval echo ~$SUDO_USER) + else + USER_HOME=$HOME + fi ++} + + # {{{ functions ++# Usage: load_vars $makepkg_conf ++# Globals: ++# - SRCDEST ++# - LOGDEST ++# - PKGDEST ++# - MAKEFLAGS ++# - PACKAGER + load_vars() { + local makepkg_conf="$1" var + + [[ -f $makepkg_conf ]] || return 1 + + for var in {SRC,PKG,LOG}DEST MAKEFLAGS PACKAGER; do +- [[ -z ${!var} ]] && eval $(grep "^${var}=" "$makepkg_conf") ++ [[ -z ${!var:-} ]] && eval $(grep "^${var}=" "$makepkg_conf") + done + + return 0 + } + +-create_chroot() { +- # Lock the chroot we want to use. We'll keep this lock until we exit. +- lock 9 "$copydir.lock" "Locking chroot copy [%s]" "$copy" ++# Usage: sync_chroot $CHROOTDIR/$CHROOT <$CHROOTCOPY|$copydir> ++sync_chroot() { ++ local chrootdir=$1 ++ local copy=$2 ++ local copydir='' ++ if [[ ${copy:0:1} = / ]]; then ++ copydir=$copy ++ else ++ copydir="$chrootdir/$copy" ++ fi ++ ++ # Detect chrootdir filesystem type ++ local chroottype=$(stat -f -c %T "$chrootdir") + +- if [[ ! -d $copydir ]] || $clean_first; then + # Get a read lock on the root chroot to make + # sure we don't clone a half-updated chroot + slock 8 "$chrootdir/root.lock" "Locking clean chroot" +@@ -147,10 +164,15 @@ + + # Drop the read lock again + lock_close 8 +- fi + } + +-clean_temporary() { ++# Usage: delete_chroot $copydir [$copy] ++delete_chroot() { ++ local copydir=$1 ++ local copy=${2:-$copydir} ++ # Detect chrootdir filesystem type ++ local chroottype=$(stat -f -c %T "$copydir") ++ + stat_busy "Removing temporary copy [%s]" "$copy" + if [[ "$chroottype" == btrfs ]]; then + btrfs subvolume delete "$copydir" >/dev/null || +@@ -166,9 +188,14 @@ + stat_done + } + ++# Usage: install_packages $copydir $pkgs... + install_packages() { ++ local copydir=$1 ++ local install_pkgs=("${@:2}") ++ declare -i ret=0 + local pkgname + ++ local install_pkg + for install_pkg in "${install_pkgs[@]}"; do + pkgname="${install_pkg##*/}" + cp "$install_pkg" "$copydir/$pkgname" +@@ -179,11 +206,19 @@ + rm "$copydir/$pkgname" + done + +- # If there is no PKGBUILD we are done +- [[ -f PKGBUILD ]] || exit $ret ++ return $ret + } + ++# Usage: prepare_chroot $copydir $HOME $repack $run_namcap ++# Globals: ++# - MAKEFLAGS ++# - PACKAGER + prepare_chroot() { ++ local copydir=$1 ++ local USER_HOME=$2 ++ local repack=$3 ++ local run_namcap=$4 ++ + $repack || rm -rf "$copydir/build" + + mkdir -p "$copydir/build" +@@ -217,12 +252,12 @@ + + chown -R nobody "$copydir"/{build,pkgdest,logdest,srcdest,startdir} + +- if [[ -n $MAKEFLAGS ]]; then ++ if [[ -n ${MAKEFLAGS:-} ]]; then + sed -i '/^MAKEFLAGS=/d' "$copydir/etc/makepkg.conf" + echo "MAKEFLAGS='${MAKEFLAGS}'" >> "$copydir/etc/makepkg.conf" + fi + +- if [[ -n $PACKAGER ]]; then ++ if [[ -n ${PACKAGER:-} ]]; then + sed -i '/^PACKAGER=/d' "$copydir/etc/makepkg.conf" + echo "PACKAGER='${PACKAGER}'" >> "$copydir/etc/makepkg.conf" + fi +@@ -235,6 +270,14 @@ + chmod 440 "$copydir/etc/sudoers.d/nobody-pacman" + fi + ++ if ! grep -q '^\[repo\]' "$copydir/etc/pacman.conf"; then ++ cat >> "$copydir/etc/pacman.conf" <<EOF ++[repo] ++SigLevel = Optional TrustAll ++Server = file:///repo ++EOF ++ fi ++ + # This is a little gross, but this way the script is recreated every time in the + # working copy + printf $'#!/bin/bash\n%s\n_chrootbuild %q "$@"' "$(declare -f _chrootbuild)" \ +@@ -242,13 +285,19 @@ + chmod +x "$copydir/chrootbuild" + } + ++# Usage: download_sources $copydir $src_owner ++# Globals: ++# - SRCDEST + download_sources() { ++ local copydir=$1 ++ local src_owner=$2 ++ + local builddir="$(mktemp -d)" + chmod 1777 "$builddir" + + # Ensure sources are downloaded +- if [[ -n $SUDO_USER ]]; then +- sudo -u $SUDO_USER env SRCDEST="$SRCDEST" BUILDDIR="$builddir" \ ++ if [[ $USER != $src_owner ]]; then ++ sudo -u $src_owner env SRCDEST="$SRCDEST" BUILDDIR="$builddir" \ + makepkg --config="$copydir/etc/makepkg.conf" --verifysource -o + else + ( export SRCDEST BUILDDIR="$builddir" +@@ -258,7 +307,7 @@ + (( $? != 0 )) && die "Could not download sources." + + # Clean up garbage from verifysource +- rm -rf $builddir ++ rm -rf "$builddir" + } + + _chrootbuild() { +@@ -295,6 +344,7 @@ + + # Safety check + if [[ ! -w PKGBUILD ]]; then ++ # XXX: internationalize this message + echo "Can't write to PKGBUILD!" + exit 1 + fi +@@ -312,12 +362,24 @@ + exit 0 + } + ++# Usage: move_products $copydir $owner ++# Globals: ++# - PKGDEST ++# - LOGDEST + move_products() { ++ local copydir=$1 ++ local src_owner=$2 ++ ++ local pkgfile + for pkgfile in "$copydir"/pkgdest/*; do + chown "$src_owner" "$pkgfile" + mv "$pkgfile" "$PKGDEST" ++ if [[ $PKGDEST != $PWD ]]; then ++ ln -sf "$PKGDEST/${pkgfile##*/}" . ++ fi + done + ++ local l + for l in "$copydir"/logdest/*; do + chown "$src_owner" "$l" + mv "$l" "$LOGDEST" +@@ -325,6 +387,10 @@ + } + # }}} + ++main() { ++init_variables ++parse_options_init ++ + umask 0022 + + load_vars /etc/makepkg.conf +@@ -335,27 +401,37 @@ + [[ -d $SRCDEST ]] || SRCDEST=$PWD + [[ -d $LOGDEST ]] || LOGDEST=$PWD + +-create_chroot ++# Lock the chroot we want to use. We'll keep this lock until we exit. ++lock 9 "$copydir.lock" "Locking chroot copy [%s]" "$copy" ++ ++if [[ ! -d $copydir ]] || $clean_first; then ++ sync_chroot "$chrootdir" "$copy" ++fi + + $update_first && arch-nspawn "$copydir" pacman -Syu --noconfirm + +-[[ -n ${install_pkgs[*]} ]] && install_packages ++if [[ -n ${install_pkgs[*]:-} ]]; then ++ install_packages "$copydir" "${install_pkgs[@]}" ++ ret=$? ++ # If there is no PKGBUILD we have done ++ [[ -f PKGBUILD ]] || exit $ret ++fi + +-prepare_chroot ++prepare_chroot "$copydir" "$USER_HOME" "$repack" + +-download_sources ++download_sources "$copydir" "$src_owner" + + if arch-nspawn "$copydir" \ + --bind-ro="$PWD:/startdir_host" \ + --bind-ro="$SRCDEST:/srcdest_host" \ + /chrootbuild "${makepkg_args[@]}" + then +- move_products ++ move_products "$copydir" "$src_owner" + else + (( ret += 1 )) + fi + +-$temp_chroot && clean_temporary ++$temp_chroot && delete_chroot "$copydir" "$copy" + + if (( ret != 0 )); then + if $temp_chroot; then +@@ -366,3 +442,4 @@ + else + true + fi ++} diff --git a/src/devtools/.gitignore b/src/devtools/.gitignore new file mode 100644 index 0000000..097fcde --- /dev/null +++ b/src/devtools/.gitignore @@ -0,0 +1,3 @@ +* +!Makefile +!.gitignore diff --git a/src/devtools/Makefile b/src/devtools/Makefile new file mode 100644 index 0000000..3fc5d70 --- /dev/null +++ b/src/devtools/Makefile @@ -0,0 +1,8 @@ +progs = checkpkg find-libdeps finddeps lddd +copy_files = $(addsuffix .in,$(progs)) +install_files = $(DESTDIR)$(bindir)/find-libprovides +include ../../common.mk + +$(DESTDIR)$(bindir)/find-libprovides: + install -d $(@D) + ln -sf find-libdeps $@ diff --git a/src/fullpkg/Makefile b/src/fullpkg/Makefile new file mode 100644 index 0000000..2c76089 --- /dev/null +++ b/src/fullpkg/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/fullpkg b/src/fullpkg/fullpkg index 9a03b82..1d4388c 100755 --- a/fullpkg +++ b/src/fullpkg/fullpkg @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # set -x # uncomment for debug # Builds packages from ABS recursively. It tries to find dependencies that # aren't built or need update and then makepkg them in order. @@ -20,7 +20,7 @@ usage() { } -while getopts 'haA:l:nm:' arg; do +while getopts 'h' arg; do case "$arg" in h) usage ;; esac diff --git a/fullpkg-build b/src/fullpkg/fullpkg-build index b497db5..1771d83 100755 --- a/fullpkg-build +++ b/src/fullpkg/fullpkg-build @@ -1,17 +1,17 @@ -#!/bin/bash +#!/usr/bin/env bash # set -x # uncomment for debug # Builds packages from ABS recursively. It tries to find dependencies that # aren't built or need update and then makepkg them in order. # TODO move __build to chroot -source /etc/makepkg.conf -source /etc/libretools.conf - -if [ -e $XDG_CONFIG_HOME/libretools/libretools.conf ]; then - source $XDG_CONFIG_HOME/libretools/libretools.conf -fi - +. libremessages +. $(librelib conf.sh) +load_files makepkg +load_files libretools +check_vars libretools FULLBUILDCMD || exit 1 +# The following variables are actually optional +#check_vars libretools HOOKPKGBUILDMOD HOOKLOCALRELEASE || exit 1 ## List packages on log that are on status ## usage: list_pkgs <status> <message> @@ -25,18 +25,6 @@ list_pkgs() { } } -# return : full version spec, including epoch (if necessary), pkgver, pkgrel -# usage : get_fullver( ${epoch:-0}, $pkgver, $pkgrel ) -get_fullver() { - if [[ $1 -eq 0 ]]; then -# zero epoch case, don't include it in version - echo $2-$3 - else - echo $1:$2-$3 - fi - -} - ## Check all build_dir, fails if one PKGBUILD is nonfree check_nonfree() { find "$build_dir" -name PKGBUILD \ @@ -67,11 +55,9 @@ succesfull_build() { if source .INFO && [ -n "$repo" ]; then if [ ! -z "$HOOKLOCALRELEASE" ]; then - find -name "*.pkg.tar.?z" -print0 | xargs -0 "$HOOKLOCALRELEASE" "$repo" + "$HOOKLOCALRELEASE" "$repo" fi - librestage $repo || echo "unstaged:$(basename $PWD)" >>$build_dir/log - msg "Updating pacman db and packages" sudo pacman -Sy || true @@ -189,10 +175,6 @@ if "$CHECKNONFREE"; then check_nonfree fi -if [ -z "$FULLBUILDCMD" ]; then - error "Set your FULLBUILDCMD on libretools.conf" -fi - msg "$MESSAGE" __build diff --git a/fullpkg-find b/src/fullpkg/fullpkg-find index e188ec8..a927782 100755 --- a/fullpkg-find +++ b/src/fullpkg/fullpkg-find @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # set -x # uncomment for debug # Builds packages from ABS recursively. It tries to find dependencies that # aren't built or need update and then makepkg them in order. @@ -11,18 +11,8 @@ guess_repo() { basename $(dirname $(pwd)) } -# return : full version spec, including epoch (if necessary), pkgver, pkgrel -# usage : get_fullver( ${epoch:-0}, $pkgver, $pkgrel ) -get_fullver() { - if [[ $1 -eq 0 ]]; then -# zero epoch case, don't include it in version - echo $2-$3 - else - echo $1:$2-$3 - fi - -} - +# This function is stolen from makechrootpkg. +# That probably has some copyright/licensing implications. copy_files() { local copydir="$build_dir/${pkgbase:-${pkgname[0]}}" @@ -31,7 +21,7 @@ copy_files() { # Copy PKGBUILD and sources cp PKGBUILD "$copydir" ( - source PKGBUILD + load_PKGBUILD for file in "${source[@]}"; do file="${file%%::*}" file="${file##*://*/}" @@ -56,12 +46,10 @@ copy_files() { # Checks ABSROOT and look for target pkg deps. Adds them if not built or outdated. find_deps() { # Check this level - source /etc/makepkg.conf - source PKGBUILD + load_PKGBUILD local repo="${repo:-$(guess_repo)}" local pkgbase="${pkgbase:-${pkgname[0]}}" - local fullver="$(get_fullver ${epoch:-0} ${pkgver} ${pkgrel})" if ! pkgbuild-check-nonfree > /dev/null 2> /dev/null; then if [ "$?" -eq 15 ]; then @@ -74,7 +62,7 @@ find_deps() { # be always considered outdated: there is no package built named kdebase. # TODO: maybe check for the package requested in case of recursive calls, # instead of the first one listed? - if is_built "${pkgname[0]}" "${fullver}"; then + if is_built "${pkgname[0]}" "$(get_full_version "${pkgname[0]}")"; then exit 0 # pkg is built and updated fi @@ -92,7 +80,7 @@ find_deps() { fi # current package plus a space for every level - msg2 "%${LEVEL}s${pkgbase}-${fullver}" + msg2 "%${LEVEL}s${pkgbase}-$(get_full_version)" ## Check next levels declare -i next_level=$LEVEL+1 @@ -130,11 +118,9 @@ find_deps() { unset next_level dir } -source /etc/libretools.conf - -if [ -e $XDG_CONFIG_HOME/libretools/libretools.conf ]; then - source $XDG_CONFIG_HOME/libretools/libretools.conf -fi +. libremessages +. $(librelib conf.sh) +load_files makepkg LEVEL=0 MAXLEVEL=20 @@ -206,7 +192,6 @@ if [ "$LEVEL" -eq 0 ]; then msg "Checking dependencies" fi -# Find the dependencies on the ABS itself find_deps exit 0 diff --git a/src/is_built b/src/is_built new file mode 100755 index 0000000..80d0719 --- /dev/null +++ b/src/is_built @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +cmd=${0##*/} +usage() { + echo "Usage: $cmd [-h] pkgname [pkgver]" + echo + echo "Detect if a given package version is already in repos" + echo "Assuming you want greater or equal." + echo + echo "Example usage: $cmd 'pcre' '20'" + echo + echo "Exit status:" + echo " 0: The package is built" + echo " 1: The package has not built" + echo " >1: There was an error" +} + +while getopts 'h' arg; do + case $arg in + h) usage; exit 0 ;; + *) usage >&2; exit 2 ;; + esac +done +if [[ $# -ne 1 ]] && [[ $# -ne 2 ]]; then + usage >&2 + exit 2 +fi + +pkg=${1} +ver=${2:-0} +pver=$(LC_ALL=C pacman -Sddp --print-format '%v' "${pkg}" 2>/dev/null) + +# if pacman fails or returns nothing +r=$? + +result=$(vercmp "${pver}" "${ver}") +# result: +# -1 : pver < ver +# 0 : pver = ver +# 1 : pver > ver + +if [[ $result -ge 0 ]] && [[ $r -eq 0 ]]; then + exit 0 +else + exit 1 +fi diff --git a/src/lib/.gitignore b/src/lib/.gitignore new file mode 100644 index 0000000..9a0c402 --- /dev/null +++ b/src/lib/.gitignore @@ -0,0 +1,3 @@ +common.sh +common.sh.in +common.sh.top diff --git a/src/lib/Makefile b/src/lib/Makefile new file mode 100644 index 0000000..45fd330 --- /dev/null +++ b/src/lib/Makefile @@ -0,0 +1,30 @@ +copy_files = common.sh.in +libexecs = $(filter-out librelib,$(wildcard libre*)) +# include common.sh in libs explicitly, because it might not exist yet +# when the wildcard is performed +libs = $(sort $(wildcard *.sh) common.sh) +include ../../common.mk + +# Build ############################################################## + +common.sh: %: %.in %.top Makefile + @echo "GEN $@" + @{ \ + cat '$*.top' && \ + echo && \ + sed -r -e '/encoding problem/d;/LANG=/d' -e 's/mesg=\$$(.)/mesg="$$(_ "$$\1")"/' '$*.in' && \ + echo && \ + cat '$*.bottom' && \ + :; } > '$@' + +# Translate ########################################################## + +pot: libreblacklist.pot common.sh.pot librelib.pot + +libreblacklist.pot: libreblacklist + { \ + sed -n '/^# Usage:/,/()/{ /^#/ { =; p; } }' $< | sed -r -e 's/^# (.*)/msgid "\1"/' -e 's/^[0-9]*$$/#. embedded usage text\n#: $<:&/'; \ + sed -rn '/print /{ =; s/\s*print "([^"]*)".*/msgid "\1"/p; }' $< | sed 's/^[0-9]*$$/#. print\n#: $<:&/' ; \ + } | sed 's/^msgid .*/&\nmsgstr ""\n/' > $@ +common.sh.pot: common.sh + xgettext --omit-header -i --from-code=UTF-8 -L shell -o $@ $< diff --git a/src/lib/common.sh.bottom b/src/lib/common.sh.bottom new file mode 100644 index 0000000..e133fad --- /dev/null +++ b/src/lib/common.sh.bottom @@ -0,0 +1 @@ +fi diff --git a/src/lib/common.sh.top b/src/lib/common.sh.top new file mode 100644 index 0000000..054301b --- /dev/null +++ b/src/lib/common.sh.top @@ -0,0 +1,26 @@ +#!/bin/bash # non-executable, but put this there as a hint to text editors +# This may be included with or without `set -euE` + +# This file is included by libremessages. +# You should probably use libremessages instead of this. + +# 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; version 2 of the License. +# +# 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. + +if [[ -z ${_INCLUDE_COMMON_SH:-} ]]; then +_INCLUDE_COMMON_SH=true + +export TEXTDOMAIN='libretools' +export TEXTDOMAINDIR='/usr/share/locale' + +if type gettext &>/dev/null; then + _() { gettext "$@"; } +else + _() { echo "$@"; } +fi diff --git a/src/lib/conf.sh b/src/lib/conf.sh new file mode 100644 index 0000000..f96af26 --- /dev/null +++ b/src/lib/conf.sh @@ -0,0 +1,190 @@ +#!/bin/bash # non-executable, but put this there as a hint to text editors +# This may be included with or without `set -euE` + +# Copyright (c) 2012-2013 by Luke Shumaker <lukeshu@sbcglobal.net> +# +# 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/>. + +LIBREUSER="${SUDO_USER:-$USER}" +if [[ $LIBREUSER == $USER ]]; then + LIBREHOME=$HOME +else + LIBREHOME="$(eval echo ~$LIBREUSER)" +fi +if [[ -z ${XDG_CONFIG_HOME:-} ]]; then + export XDG_CONFIG_HOME="${LIBREHOME}/.config" +fi +if [[ -z ${XDG_CACHE_HOME:-} ]]; then + export XDG_CACHE_HOME="${LIBREHOME}/.cache" +fi + +# Generic functions ############################################################ + +# Usage: list_files $slug +# Lists the configuration files to be considered for $slug. +# Later files should take precedence over earlier files. +list_files() { + local slug=$1 + case $slug in + abs) + echo /etc/$slug.conf + echo "$LIBREHOME/.$slug.conf" + ;; + makepkg) + if [[ ${MAKEPKG_CONF:-} != /etc/$slug.conf && -r ${MAKEPKG_CONF:-} ]]; then + echo "$MAKEPKG_CONF" + else + echo /etc/$slug.conf + echo "$LIBREHOME/.$slug.conf" + fi + ;; + libretools) + echo /etc/$slug.conf + echo "$XDG_CONFIG_HOME/libretools/$slug.conf" + ;; + *) + echo /etc/libretools.d/$slug.conf + echo "$XDG_CONFIG_HOME/libretools/$slug.conf" + ;; + esac +} + +# Usage: list_envvars $slug +# Lists the environmental variables that take precidence over the configuration +# files for $slug. +list_envvars() { + local slug=$1 + case $slug in + makepkg) + printf '%s\n' \ + PKGDEST SRCDEST SRCPKGDEST LOGDEST \ + BUILDDIR \ + PKGEXT SRCEXT \ + GPGKEY PACKAGER + ;; + *) :;; + esac +} + +# Usage: load_files $slug +# Loads the configuration files for $slug in the proper order. +load_files() { + local slug=$1 + local var + local file + + # Save the existing versions at _VARNAME + for var in $(list_envvars $slug); do + [[ -n ${!var:-} ]] && eval "_$var=\${$var}" + done + + # Load the files + for file in $(list_files $slug); do + if [[ -r $file ]]; then + . "$file" || return 1 + fi + done + + # Restore the _SAVED versions + for var in $(list_envvars $slug); do + eval "$var=\${_$var:-\${$var:-}}" + done +} + +# Usage: check_vars $slug VAR1 VAR2... +# Check whether the variables listed are properly set. +# If not, it prints a message saying to set them in the configuration file(s) +# for $slug. +check_vars() { + local slug=$1; shift + + local ret=0 + + local VAR + for VAR in "$@"; do + if [[ -z ${!VAR:-} ]]; then + type print &>/dev/null || . libremessages + if [[ $(list_files $slug|wc -l) -gt 1 ]]; then + print "Configure '%s' in one of:" "$VAR" + list_files $slug | sed 's/./ -> &/' + else + print "Configure '%s' in '%s'" "$VAR" "$(list_files $slug)" + fi + ret=1 + fi + done >&2 + + if [[ $ret != 0 ]]; then + return 1 + fi +} + +# makepkg configuration ######################################################## + +# Usage: get_conf_makepkg <var_name> <default_value> +get_conf_makepkg() ( + set +euE + local setting=$1 + local default=$2 + load_files makepkg + printf '%s\n' "${!setting:-${default}}" +) + +set_conf_makepkg() { + local key=$1 + local val=$2 + local file + for file in $(list_files makepkg|tac); do + if [[ -w $file ]]; then + sed -i "/^\s*$key=/d" "$file" + printf '%s=%q\n' "$key" "$val" >> "$file" + return 0 + fi + done + return 1 +} + +# PKGBUILD (not configuration, per se) ######################################### + +unset_PKGBUILD() { + # This routine is based primarily off of the PKGBUILD(5) man-page, + # version 4.1.2, dated 2013-06-18. + + # From the "OPTIONS AND DIRECTIVES" section (in order of mention) + unset -v pkgname pkgver + unset -f pkgver + unset -v pkgrel pkgdesc epoch url license install changelog source + unset -v noextract md5sums sha{1,256,384,512}sums groups arch backup + unset -v depends makedepends checkdepends optdepends conflicts provides + unset -v replaces options + + # From the "PACKAGING FUNCTIONS" section (in order of mention) + unset -f package prepare build check + + # From the "PACKAGE SPLITTING" section + unset -f $(declare -f|sed -n 's/^\(package_\S*\) ()\s*$/\1/p') + unset -v pkgbase + + # These are used by the `librefetch` program + unset -v mksource mknoextract mkmd5sums mksha{1,256,384,512}sums + unset -v mkdepends + unset -f mksource +} + +load_PKGBUILD() { + local file=${1:-./PKGBUILD} + unset_PKGBUILD + CARCH="$(get_conf_makepkg CARCH "`uname -m`")" + . "$file" +} diff --git a/src/lib/libreblacklist b/src/lib/libreblacklist new file mode 100755 index 0000000..5db1a3f --- /dev/null +++ b/src/lib/libreblacklist @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +# This may be included with or without `set -euE` +# When run directly, it does `set -euE` + +# Copyright (c) 2013 by Luke Shumaker <lukeshu@sbcglobal.net> +# +# 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/>. + +# make sure XDG_CACHE_HOME is set +. $(librelib conf) + +# Usage: blacklist-normalize <$file +# Normalizes the syntax of the blacklist on stdin. +blacklist-normalize() { + sed -e 's/^[^:]*$/&::/' -e 's/^[^:]*:[^:]*$/&:/' +} + +# Usage: blacklist-cat +# Prints the blacklist. +# Uses the cache, but downloads it if it doesn't exist. Also normalizes the blacklist for easier parsing. +blacklist-cat() { + local file="$XDG_CACHE_HOME/libretools/blacklist.txt" + if ! [[ -e $file ]]; then + # exit on failure, whether set -e or not + blacklist-update || return $? + fi + blacklist-normalize < "$file" +} + +# Usage: blacklist-update +# Updates (or creates) the cached copy of the blacklist. +blacklist-update() ( + . libremessages + load_files libretools || return 1 + check_vars libretools BLACKLIST || return 1 + + local remote_blacklist="$BLACKLIST" + local local_blacklist="$XDG_CACHE_HOME/libretools/blacklist.txt" + + stat_busy "Downloading blacklist of proprietary software packages" + + mkdir -p "${local_blacklist%/*}" + if wget -N -q -O "${local_blacklist}.part" "$remote_blacklist" 2>/dev/null; then + stat_done + mv -f "${local_blacklist}.part" "$local_blacklist" + else + stat_done + rm "${local_blacklist}.part" + if [[ -e "$local_blacklist" ]]; then + warning "Using local copy of blacklist" + else + error "Download failed, exiting" + return 1 + fi + + fi +) + +# Usage: blacklist-cat | blacklist-lookup $pkgname +# Filters to obtain the line for $pkgname from the blacklist on stdin. +# Exits successfully whether a line is found or not. +blacklist-lookup() { + local pkg=$1 + # we accept that $pkg contains no regex-nes + blacklist-normalize | grep "^$pkg:" || true +} + +# Usage: blacklist-cat | blacklist-get-pkg +# Prints only the package name field of the blacklist line(s) on stdin. +blacklist-get-pkg() { + blacklist-normalize | cut -d: -f1 +} + +# Usage: blacklist-cat | blacklist-get-rep +# Prints only the replacement package field of the blacklist line(s) on stdin. +blacklist-get-rep() { + blacklist-normalize | cut -d: -f2 +} + +# Usage: blacklist-cat | blacklist-get-reason +# Prints only the reason field of the blacklist line(s) on stdin. +blacklist-get-reason() { + blacklist-normalize | cut -d: -f3- +} + +if [[ "${0##*/}" == libreblacklist ]]; then + set -euE + usage-outside() { + sed -n '/^# Usage:/,/()/p' "$0" | + tr '\n' '\r' | sed 's/\s*()\s*[{(]/\n/g' + } + # The output format of this is: + # - The first line is "Usage:" + # - The second line is a brief description + # - The last line is the command name (prefixed with "blacklist-") + # - The in-between lines are the extended description. + usage-inside() { + sed 's/\r/\n/g'<<<"$1"|sed -e '/^$/d' -e 's/^# //' + } + usage() { + . $(librelib messages) + if [[ $# -eq 0 ]]; then + print "Usage: %s [-h] COMMAND [ARGUMENTS]" "${0##*/}" + print "Tool for working with the nonfree software blacklist" + echo + print "Commands:" + usage-outside | while read -r sec; do sec="$(usage-inside "$sec")" + cmd=$(<<<"$sec" sed -n '$s/^blacklist-//p') + desc="$(_ "$(sed -n 2p <<<"$sec")")" + flag "$cmd" "${desc//blacklist-/${0##*/} }" + done + else + usage-outside | while read -r sec; do sec="$(usage-inside "$sec")" + cmd=$(<<<"$sec" sed -n '$s/^blacklist-//p') + if [[ "$cmd" == "$1" ]]; then + <<<"$sec" sed '$d' | + while read -r line; do print "$line"; done | + sed "s/blacklist-/${0##*/} /g" | + fmt -us + return 0 + fi + done + fi + } + + if [[ $# -eq 0 ]]; then + usage >/dev/stderr + exit 1 + fi + _blacklist_cmd=$1 + shift + if [[ $_blacklist_cmd == -h ]]; then + usage "$@" + else + "blacklist-$_blacklist_cmd" "$@" + fi +fi diff --git a/src/lib/librelib b/src/lib/librelib new file mode 100755 index 0000000..2dc9314 --- /dev/null +++ b/src/lib/librelib @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +# Copyright (c) 2013 by Luke Shumaker <lukeshu@sbcglobal.net> +# +# 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/>. + +default_libdir=/usr/lib/libretools + +if ! type gettext &>/dev/null; then + gettext() { echo "$@"; } +fi + +print() { + mesg=$1 + shift + printf -- "$(gettext "$mesg")\n" "$@" +} + +prose() { + print "$@" | fmt -su +} + +cmd=${0##*/} +usage() { + . libremessages + print 'Usage: . $(%s LIBRARY)' "$cmd" + print "Finds a shell library file" + echo + prose "While some libraries can be sourced just by their name because + they are installed in PATH (like libremessages), some are not + installed there (like conf.sh), so a path must be given. + Hardcoding that path is the way of the dark side." + echo + prose 'By default, it looks for the files in `%s`, but this can be + changed with the environmental variable LIBRETOOLS_LIBDIR.' "$default_libdir" + echo + print "Example usage:" + printf ' . $(%s conf.sh)\n' "$cmd" +} + +main() { + if [[ $# != 1 ]]; then + usage >&2 + return 2 + fi + if [[ $1 == '-h' ]]; then + usage + return 0; + fi + + if [[ -z $LIBRETOOLS_LIBDIR ]]; then + export LIBRETOOLS_LIBDIR=$default_libdir + fi + + lib=$1 + lib=${lib#libre} + lib=${lib%.sh} + + for file in ${lib} libre${lib} ${lib}.sh libre${lib}.sh; do + if [[ -f "$LIBRETOOLS_LIBDIR/$file" ]]; then + printf '%s\n' "$LIBRETOOLS_LIBDIR/$file" + return 0; + fi + done + print '%s: could not find library: %s' "$cmd" "$lib" >> /dev/stderr + return 1 +} + +main "$@" diff --git a/src/lib/libremessages b/src/lib/libremessages new file mode 100755 index 0000000..c6d08e2 --- /dev/null +++ b/src/lib/libremessages @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +# This may be included with or without `set -euE` +# When run directly, it does `set -euE` + +# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> +# Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> +# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> +# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk> +# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org> +# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> +# Copyright (c) 2011 by Joshua Haase <hahj87@gmail.com> +# Copyright (c) 2012-2013 by Luke Shumaker <lukeshu@sbcglobal.net> +# +# 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/>. + +################################################################################ +# Inherit most functions from devtools # +################################################################################ + +. $(librelib common.sh) + +################################################################################ +# Own functions # +################################################################################ + +panic() { + echo "$(_ 'panic: malformed call to internal function')" >&2 + exit 1 +} + +# Usage: print MESG ARG1 ARG2... +# Like printf, but gettext-aware, and prints a trailing newline +print() { + [[ $# -ge 1 ]] || panic + local mesg="$(_ "$1")" + shift + printf -- "$mesg\n" "$@" +} + +# Do HTML-style whitespace collapsing on standard IO. It considers newline, +# tab, and space to be whitespace. +_html_whitespace_collapse() { + [[ $# == 0 ]] || panic + tr '\n' ' ' | sed -r -e 's/\t/ /g' -e 's/ +/ /g' +} + + +# Usage: prose MESG +# Do HTML-style whitespace collapsing on the first argument, translate it +# (gettext), then word-wrap it to 75 columns. +# This is useful for printing a paragraph of prose in --help text. +prose() { + [[ $# -ge 1 ]] || panic + local mesg="$(_ "$(_html_whitespace_collapse <<<"$1")")"; shift + printf -- "$mesg" "$@" | fmt -u +} + +# Usage: bullet MESG +# Like prose, but print a bullet "-" before the first line, and indent the +# remaining lines. +bullet() { + [[ $# -ge 1 ]] || panic + local mesg="$(_ "$(_html_whitespace_collapse <<<"$1")")"; shift + # Wrap the text to 71 columns; 75 (the default) minus a 4 column indent + printf -- "$mesg" "$@" | fmt -u -w 71 | sed -e '1s/^/ - /' -e '2,$s/^/ /' +} + +# Usage: flag FLAG DESCRIPTION +# Print a flag and description formatted for --help text. +# ex: flag '-C <FILE>' 'Use this file instead of pacman.conf' +# The description is fed through gettext, the flag is not, so if part of the +# flag needs to be translated, you must do that yourself: +# ex: flag "-C <$(_ FILE)>" 'Use this file instead of pacman.conf' +# If you want to line-break the description in the source, so it isn't +# crazy-long, feel free, it is reflowed/wrapped the same way as prose and +# bullet. +flag() { + [[ $# == 2 ]] || panic + local n=' +' + local flag=$1 + local desc="$(_ "$(_html_whitespace_collapse <<<"$2")")" + + declare -i indent=13 + while [[ $indent -le ${#flag} ]]; do + indent=$((indent+8)) + done + + local lines + IFS=$n lines=($(fmt -u -w $((73-indent)) <<<"$desc")) + local line + for line in "${lines[@]}"; do + printf " %-${indent}s %s\n" "$flag" "$line" + flag='' + done +} + +# Usage: term_title This will be the term title +# Sets the terminal title +term_title() { + [[ $# -ge 1 ]] || panic + local fmt='' + case "$TERM" in + screen|tmux) fmt='\ek%s\e\\';; + xterm*|rxvt*) fmt='\e]0;%s\a';; + esac + printf "$fmt" "$*" +} + +################################################################################ +# Run one of the defined functions if invoked directly # +################################################################################ + +if [[ "${0##*/}" == libremessages ]]; then + set -euE + _libremessages_cmd=$1 + shift + "$_libremessages_cmd" "$@" +fi diff --git a/src/librefetch/Makefile b/src/librefetch/Makefile new file mode 100644 index 0000000..2c76089 --- /dev/null +++ b/src/librefetch/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/src/librefetch/librefetch b/src/librefetch/librefetch new file mode 100755 index 0000000..086a5e9 --- /dev/null +++ b/src/librefetch/librefetch @@ -0,0 +1,331 @@ +#!/usr/bin/env bash +# 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/>. + +. $(librelib conf.sh) +. libremessages + +declare -r tempdir="$(mktemp -d --tmpdir ${0##*/}.XXXXXXXXXXX)" +cleanup() { rm -rf -- "$tempdir"; } +trap cleanup EXIT + +cmd=${0##*/} +usage() { + print "Usage: %s [options] <source-url> [<output-file>]" "$cmd" + print "Usage: %s -[g|P|V|h]" "$cmd" + print "Downloads or creates a liberated source tarball." + echo + print "The default mode is to create <output-file>, first by trying download" + print "mode, then create mode." + echo + print "If <output-file> isn't specified, it defaults to the non-directory" + print "part of <source-url>, in the current directory." + echo + print "In download mode, the glob '*://' is stripped from the beginning of" + print "<source-url>, and the resulting path is attempted to be downloaded" + print "from the configured mirror." + echo + print "In create mode, it looks at a build script, and uses that to create" + print "the source tarball. <source-url> is ignored, except that it is used" + print "to set the default value of <output-file>." + echo + print "The default build script is 'PKGBUILD', or 'SRCBUILD' if it exists." + echo + print "Unrecognized options are passed straight to makepkg." + echo + print "Example usage:" + print ' $ %s libre://mypackage-1.0.tar.gz' "$cmd" + echo + print "Options:" + print " Settings:" + 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 " Alternate modes:" + print " -g, --geninteg Generage integrity checks for source files" + print " -P, --print Print the effective build script (SRCBUILD)" + print " -V, --version Show version information" + print " -h, --help Show this message" +} + +version() { + print "librefetch (libretools) beta 4" + 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." +} + +main() { + BUILDFILE="$(readlink -m PKGBUILD)" + makepkg_opts=() + extra_opts=() + mode=download-create + parse_options "$@" + + # Mode: version, help ################################################## + + if [[ $mode =~ version ]]; then + version + return 0 + fi + if [[ $mode =~ help ]]; then + usage + return 0 + fi + + ######################################################################## + + local BUILDFILEDIR="${BUILDFILE%/*}" + if [[ -f "${BUILDFILEDIR}/SRCBUILD" ]]; then + BUILDFILE="${BUILDFILEDIR}/SRCBUILD" + srcbuild="$(modified_srcbuild "$BUILDFILE")" + else + srcbuild="$(modified_pkgbuild "$BUILDFILE")" + fi + makepkg="$(modified_makepkg "$(which makepkg)")" + + # Mode: checksums ###################################################### + + if [[ $mode =~ checksums ]]; then + if [[ ${#extra_opts[@]} != 0 ]]; then + print "%s: found extra non-flag arguments: %s" "$cmd" "${extra_opts[*]}" >> /dev/stderr + usage >> /dev/stderr + return 1 + fi + "$makepkg" "${makepkg_opts[@]}" -g -p "$srcbuild" | + case ${BUILDFILE##*/} in + PKGBUILD) sed -e 's/^[a-z]/mk&/' -e 's/^\s/ &/';; + SRCBUILD) cat;; + esac + return 0 + fi + + # Mode: print ########################################################## + + if [[ $mode =~ print ]]; then + if [[ ${#extra_opts[@]} != 0 ]]; then + print "%s: found extra non-flag arguments: %s" "$cmd" "${extra_opts[*]}" >> /dev/stderr + usage >> /dev/stderr + return 1 + fi + cat "$srcbuild" + return 0 + fi + + ######################################################################## + + local src dst + case ${#extra_opts[@]} in + 1) + src="${extra_opts[0]#*://}" + dst="$(readlink -m -- "${src##*/}")" + ;; + 2) + src="${extra_opts[0]#*://}" + dst="$(readlink -m -- "${extra_opts[1]}")" + ;; + *) + print "%s: %d non-flag arguments found, expected 1 or 2: %s" "$cmd" ${#extra_opts[@]} >> /dev/stderr + usage >> /dev/stderr + return 1 + esac + + # Mode: download ####################################################### + + if [[ $mode =~ download ]]; then + load_files librefetch + check_vars librefetch MIRROR DOWNLOADER || return 1 + + local url="${MIRROR}/${src}" + + local dlcmd="${DOWNLOADER}" + dlcmd="${dlcmd//\%o/\"$dst\"}" + dlcmd="${dlcmd//\%u/\"$url\"}" + { eval "$dlcmd"; } >> /dev/stderr && return 0 + fi + + # Mode: create ######################################################### + + if [[ $mode =~ create ]]; then + PKGEXT=${dst##*/} + export PKGEXT=${PKGEXT%.part} + export PKGDEST=${dst%/*} + export pkg_file=$dst + + cd "$BUILDFILEDIR" + "$makepkg" "${makepkg_opts[@]}" -p "$srcbuild" >> /dev/stderr || return $? + 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 [[ $# -gt 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|--print) mode=print;; + -p) BUILDFILE="$(readlink -m -- "$opt")";; + -V|--version) mode=version;; + -h|--help) mode=help;; + -*) + makepkg_opts+=("$arg") + $have_opt && makepkg_opts+=("$opt") + ;; + --) shift; break;; + *) extra_opts+=("$arg");; + esac + shift + done + extra_opts+=("$@") +} + +# Modify makepkg ############################################################### + +# an ERE +makepkg_modify=' +/create_package\(\) \{/,/^\}$/ { + /pkg_file=/d # allow us to set pkg_file + s/"?\$\{comp_files\[@\]\}"?// # do not include .{PKGINFO,INSTALL,CHANGELOG} + s/bsdtar /&--format=ustar / # ustar, not pax + s/create_signature .*/&; return $?/ # do not procede to create symlinks +} + +/tidy_install\(\) \{/,/^\}$/ { + /for .*PURGE_TARGETS/itidy_install_purge + /for .*PURGE_TARGETS/,/done/d + /^\}$/ifind . -exec touch --date="1990-01-01 0:0:0 +0" {} + +} + +s|srcdir=.*|&-libre| +s|pkgdirbase=.*|&-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 +} + +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 [[ ${#pkgname[@]} -gt 1 ]]; then + if [[ -n $pkgbase ]]; then + pkgname=("$pkgbase") + else + pkgname=("$pkgname") + fi +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/ .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="$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 '/PKGEXT=/d' < "$orig" > "$new" + printf '%s\n' "$new" +} + +main "$@" diff --git a/src/librefetch/librefetch.8.ronn b/src/librefetch/librefetch.8.ronn new file mode 100644 index 0000000..7fa15d4 --- /dev/null +++ b/src/librefetch/librefetch.8.ronn @@ -0,0 +1,162 @@ +librefetch(8) -- downloads or creates a liberated source tarball +================================================================ + +## SYNOPSIS + +`librefetch` [options] <source-url> [<output-file>]<br> +`librefetch` -[g|V|h] + +## DESCRIPTION + +`librefetch` is a program to streamline creation of custom source +tarballs for `PKGBUILD(5)` files. + +To automatically use `librefetch` to download or create a source +tarball, you can add `libre://FILENAME.tar.gz` to the source array in +your `PKGBUILD`. This works because a post-install script for the +package adds `librefetch` as a download agent for `libre://` to +`makepkg.conf`. Because of this, it is almost never necessary to call +`librefetch` manually. + +There are 7 modes: + + * `download-create`: The default mode. First try `download` mode, + then `create` mode. + * `download`: Download the tarball from the configured mirror. + * `create`: Create the tarball from a `PKGBUILD`/`SRCBUILD`. + * `checksums`: Generate integrity checks for source files. + * `print`: Print the effective build script. + * `version`: Print `librefetch` version information. + * `help`: Print `librefetch` usage information. + +## 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. + * `-P` | `--print`: Use `print` mode: print the effective build script. + * `-V` | `--version`: Use `version` mode: Show version information. + * `-h` | `--help`: Use `help` mode: Show useage information. + +## CREATE MODE + +The principle of `create` mode is that a special `PKGBUILD(5)`, called +a `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, +then fed to a modified version of `makepkg(8)`. + +The purpose of the modified `makepkg` is so that the resulting tarball +doesn't contain package metadata, doesn't end with a .pkg file +extension, and always produces an identicle tarball. + +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 `print` 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 temorary 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, sha256, sha384, sha512) + depends = <empty> + checkdepends = <empty> + makedepends = mkdepends + 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=()` + * Declare a `mksource()` function to make modifications to the + source, if nescessary. + +Other changes: + + * `pkgname` is set to `pkgbase`, or the first element of the + `pkgname` array. + * `options=()` is set have `makepkg` avoid making changes to + `$pkgdir`. The exact change is: + + options+=(!strip docs libtool 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 "1990-01-01 0:0:0 +0", so that + the resulting tarball will be the same, regardless of when it was + created. + * append `-libre` to `$srcdir` + * append `-libre` to `$pkgbasedir` (which becomes `$pkgdir`) + * Don't check if the package has already been built. + +## 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) 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' diff --git a/src/librefetch/librefetch.conf.5.ronn b/src/librefetch/librefetch.conf.5.ronn new file mode 100644 index 0000000..3d80ab5 --- /dev/null +++ b/src/librefetch/librefetch.conf.5.ronn @@ -0,0 +1,36 @@ +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 precidence 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 + + * `MIRROR='https://repo.parabolagnulinux.org/sources/'`: + The location to download pre-built source tarball in download + mode. + * `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. + +## SEE ALSO + +librefetch(8) diff --git a/src/libregit/Makefile b/src/libregit/Makefile new file mode 100644 index 0000000..2c76089 --- /dev/null +++ b/src/libregit/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/src/libregit/libregit b/src/libregit/libregit new file mode 100755 index 0000000..8687d2f --- /dev/null +++ b/src/libregit/libregit @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# Copyright (c) 2012-2013 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (c) 2012-2013 Luke Shumaker <lukeshu@sbcglobal.net> +# +# 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/>. + +. libremessages + +cd_safe() { + if ! cd "$1"; then + error "Failed to change to directory %s" "$1" + plain "Aborting..." + exit 1 + fi +} + +download_git() { + if [[ ! -d "$dir/.git" ]] ; then + msg2 "Cloning %s %s repo..." "${repo}" "git" + if ! git clone "$repo" "$dir"; then + error "Failure while downloading %s %s repo" "${repo}" "git" + plain "Aborting..." + exit 1 + fi + else + cd_safe "$dir" + # Make sure we are fetching the right repo + if [[ "$repo" != "$(git config --get remote.origin.url)" ]] ; then + error "%s is not a clone of %s" "$dir" "$repo" + plain "Aborting..." + exit 1 + fi + msg2 "Updating %s %s repo..." "${repo}" "git" + if ! git pull origin "$ref"; then + # only warn on failure to allow offline builds + warning "Failure while updating %s %s repo" "${repo}" "git" + fi + fi +} + +usage() { + print 'Usage: %s repo ref dir' "${0##*/}" + echo + print "Clones or pulls from the git URL 'repo', and checks out the git ref" + print "'ref' to the directory 'dir'." + echo + print "It does safety checks, figures out whether to clone or pull, and other" + print "helpful things. This exists because the same 'download_git' function" + print "from makepkg was being copied again and again." +} + +main() { + [[ $# == 3 ]] || { usage >&2; return 1; } + repo=$1 + ref=$2 + dir=$3 + + [[ -d "${dir%/*}" ]] || mkdir -p "${dir%/*}" + download_git +} + +main "$@" diff --git a/src/libretools.conf b/src/libretools.conf new file mode 100644 index 0000000..593aed6 --- /dev/null +++ b/src/libretools.conf @@ -0,0 +1,83 @@ +#!/bin/bash # non-executable, but put this there as a hint to text editors + +################################################################################ +# misc # +################################################################################ + +# The dir where you work on +WORKDIR=/home/$LIBREUSER/packages + +## Blacklist URL +BLACKLIST=https://repo.parabolagnulinux.org/docs/blacklist.txt + +## Diff tool (vimdiff, gvimdiff, meld, etc) +## Used by `aur`, `diff-unfree` +DIFFTOOL=`which kdiff3 meld gvimdiff vimdiff colordiff diff 2>/dev/null|sed 's/\s.*//;1q'` + +## The repos you'll be packaging for +## Used by `toru`, `createworkdir` +# Tip: As early repos take precedence on $REPOS loops, you can use this as +# inverted order of precedence. Put testing repos first so fullpkg find new +# PKGBUILDs first, for instance. Toru-path uses reverse order to enforce repo +# precedence on the path cache (the last path added replaces the rest) +REPOS=('core' 'libre' 'extra' 'community' 'libre-testing' 'social' 'sugar' 'pcr' 'java') + +## The architectures you'll be packaging for +## Used by `librestage` +ARCHES=('x86_64' 'i686' 'mips64el') + +## ABSLibre +#ABSLIBREGIT=http://projects.parabolagnulinux.org/abslibre.git +ABSLIBREGIT=ssh://git@projects.parabolagnulinux.org:1863/srv/git/abslibre.git + +################################################################################ +# librerelease # +################################################################################ + +## Where to upload packages to +# Don't change unless you know what you're doing and you won't screw +# anything ;) +REPODEST=repo@repo:/srv/http/repo/public +## Assumes something similar in your .ssh/config: +# Host repo +# Port 1863 +# HostName repo.parabolagnulinux.org + +## These are run before and after uploading packages +HOOKPRERELEASE="ssh -fN ${REPODEST%%:*}" +HOOKPOSTRELEASE="sudo librechroot clean-repo" + +################################################################################ +# fullpkg/treepkg # +################################################################################ + +# Note: fullpkg accepts HOOK* settings not being set, treepkg requires them to +# be set. + +# NOTE: fullpkg ONLY +#HOOKPKGBUILDMOD="mips-add" + +# Run a command before running FULLBUILDCMD, usually to cleanup uneeded packages +# Note: Recent versions of libremakepkg run chcleanup for you. +# NOTE: treepkg ONLY +HOOKPREBUILD=":" +#HOOKPREBUILD="chcleanup" + +## Uncomment one of those or make one of your choice +# Normal +FULLBUILDCMD="sudo libremakepkg" +# Cross compiling +#FULLBUILDCMD="sudo libremakepkg -n cross-compile-chroot" +# Don't use a chroot +#FULLBUILDCMD="makepkg -sL --noconfirm" + +# Locally release the package or any other action after running FULLBUILDCMD +# succesfully. When run, it is given a repository name as a single argument. +HOOKLOCALRELEASE="librestage" +#HOOKLOCALRELEASE="mipsrelease" + +################################################################################ +# toru # +################################################################################ + +TORUPATH=/var/lib/libretools/toru diff --git a/src/mips64el-tools/Makefile b/src/mips64el-tools/Makefile new file mode 100644 index 0000000..2c76089 --- /dev/null +++ b/src/mips64el-tools/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/add-mips64el b/src/mips64el-tools/add-mips64el index 17b167b..17b167b 100755 --- a/add-mips64el +++ b/src/mips64el-tools/add-mips64el diff --git a/librebasebuilder b/src/mips64el-tools/librebasebuilder index f7d3a25..6b8c8bb 100755 --- a/librebasebuilder +++ b/src/mips64el-tools/librebasebuilder @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # -*- coding: utf-8 -*- # Copyright (C) 2012 Michał Masłowski <mtjm@mtjm.eu> # @@ -45,7 +45,7 @@ done tempdir=/home/chroot/base outdir=$(pwd) -mkarchroot -n $tempdir mkinitcpio base sudo parted nano zile vi ed openssh +archroot -n $tempdir mkinitcpio base sudo parted nano zile vi ed openssh cd $tempdir diff --git a/mips64el/mips-add b/src/mips64el-tools/mips-add index da9b431..402036e 100644..100755 --- a/mips64el/mips-add +++ b/src/mips64el-tools/mips-add @@ -1,7 +1,8 @@ -#!/bin/bash -source /etc/libretools.conf +#!/usr/bin/env bash +. libremessages if ! grep mips64el PKGBUILD >/dev/null; then # Add mips64el in ${arch} array if it isn't 'any' warning "Adding mips64el arch" sed -i "s/^\(arch=([^)anym]\+\))/\1 'mips64el')/" "PKGBUILD" - librecommit PKGBUILD + git add PKGBUILD + git commit fi diff --git a/src/mips64el-tools/mipsrelease b/src/mips64el-tools/mipsrelease new file mode 100755 index 0000000..de17651 --- /dev/null +++ b/src/mips64el-tools/mipsrelease @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# Lic: GPLv3+ +# Author: Nicolas Reynolds <fauno@kiwwwi.com.ar> +# Local release of mips64el packages + clean ABS sync +# Called by HOOKLOCALRELEASE + +# $1 repo +# $2+ packages + +. libremessages +. $(librelib conf.sh) +load_files makepkg +check_vars makepkg CARCH PKGDEST PKGEXT || exit 1 +load_files libretools +check_vars libretools WORKDIR || exit 1 + +usage() { + echo "$0 repo" + echo + echo " release packages locally on \${PKGDEST}/stage3." + echo " and make a clean ABS sync " +} + +main() { + if [[ $# != 1 ]]; then + usage + exit 1 + fi + + repo=$1 + + if [ -z "${repo}" ]; then + error "Empty repo" + exit 1 + fi + + # Get all needed sources + load_PKGBUILD + pkgs=() + makepkg --source -f --skippgpcheck -c + + msg "Adding packages to [stage3]..." + for name in "${pkgname[@]}"; do + msg2 "${name} $(get_full_version $name)" + pkgs+=(${PKGDEST}/${name}-$(get_full_version $name)-*.pkg.tar.*) + done + + repo-add ${PKGDEST}/stage3.db.tar.gz "${pkgs[@]}" + + librestage ${repo} + + mkdir -p ${WORKDIR}/abs/${CARCH}/${repo} >/dev/null + + pushd ${WORKDIR}/abs/${CARCH}/${repo} >/dev/null + tar xvf $SRCPKGDEST/${pkgbase:-${pkgname[0]}}-$(get_full_version)${SRCEXT} + popd >/dev/null + + exit $? +} + +main "$@" diff --git a/src/pkgbuild-check-licenses b/src/pkgbuild-check-licenses new file mode 100755 index 0000000..85ca2c3 --- /dev/null +++ b/src/pkgbuild-check-licenses @@ -0,0 +1,126 @@ +#!/usr/bin/env bash +# pkgbuild-check-licenses + +# Copyright 2010 Haase Hernández +# Copyright 2010 Joseph Graham +# Copyright 2010 Joshua Ismael +# Copyright 2010 Nicolás Reynolds +# Copyright 2012-2013 Luke Shumaker +# +# 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) + +# Usage: check_deps $pkgbuild +# Check whether a PKGBUILD package depends on non-free packages +check_licenses() ( + # Note that we use () instead of {} for this function; so that variables + # from the PKBUILD don't bubble up + local pkgbuild=$1 + load_PKGBUILD "$pkgbuild" + if [[ -z $pkgname ]]; then + return $_E_ERROR # not a PKGBUILD + fi + if [[ -z "${license[*]}" ]]; then + error "license array of %s %s is not set" "${pkgbase:-${pkgname[0]}}" "$(get_full_version)" + return $_E_ERROR + fi + + msg2 "Looking at license array of %s %s" "${pkgbase:-${pkgname[0]}}" "$(get_full_version)" + + local ret=$_E_OK + for _license in "${license[@]}"; do + if [[ ! -e "/usr/share/licenses/common/$_license" ]]; then + local s=$_E_OK + case "${_license#custom:}" in + WTFPL) + # accept as common, I think it should be in the licenses package + :;; + BSD1|BSD2|BSD3|MIT|X11) + # accept these as common; they can't be included in the + # 'licenses' package because some text must be customized + :;; + BSD4) + warning "The 4-clause BSD license is free but has practical problems.";; + BSD) + warning "License 'BSD' is ambiguous, use 'BSD{1..4}' to specify the number of clauses." + s=$_E_UNCOMMON + ;; + JSON) + error "License '%s' is a known non-free license." "$_license" + s=$_E_NONFREE + ;; + *) + warning "License '%s' is not a common license." "$_license" + s=$_E_UNCOMMON + ;; + esac + ret=$(($ret|$s)) + fi + done + return $ret +) + +usage() { + print "Usage: %s [OPTIONS] [PKGBUILD1 PKGBUILD2 ...]" "${0##*/}" + echo + prose 'If no PKGBUILD is specified, `./PKGBUILD` is implied.' + echo + print "Exit status (add them for combinations):" + print " 0: Everything OK, no freedom issues" + print " 1: Ran with error" + print " 2: Uses uncommon licenses, check them" + print " 4: Uses known unacceptable licenses" + echo + print "Options:" + flag '-f' 'Allow running as root user' + flag '-h' 'Show this message' +} +_E_OK=0 +_E_ERROR=1 +_E_UNCOMMON=2 +_E_NONFREE=4 + +main() { + local asroot=false + while getopts 'fh' arg; do + case "$arg" in + f) asroot=true;; + h) usage; return $_E_OK;; + *) usage; return $_E_ERROR;; + esac + done + shift $(($OPTIND - 1)) + if [[ $# -lt 1 ]]; then + pkgbuilds=("`pwd`/PKGBUILD") + else + pkgbuilds=("$@") + fi + + if [[ -w / ]] && ! $asroot; then + error "Run as normal user, or use the -f option to run as root." + return 1 + fi + + local ret=0 + for pkgbuild in "${pkgbuilds[@]}"; do + check_licenses "$pkgbuild" || ret=$(($ret|$?)) + done + return $ret +} + +main "$@" diff --git a/src/pkgbuild-check-nonfree b/src/pkgbuild-check-nonfree new file mode 100755 index 0000000..1cc0d9b --- /dev/null +++ b/src/pkgbuild-check-nonfree @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +# pkgbuild-check-nonfree + +# Copyright 2010 Haase Hernández +# Copyright 2010 Joseph Graham +# Copyright 2010 Joshua Ismael +# Copyright 2012-2013 Luke Shumaker +# +# 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 +. libreblacklist +. $(librelib conf) + +# Usage: check_deps $pkgbuild +# Check whether a PKGBUILD package depends on non-free packages +check_deps() ( + # Note that we use () instead of {} for this function; so that variables + # from the PKBUILD don't bubble up + local pkgbuild=$1 + load_PKGBUILD "$pkgbuild" + if [[ -z "$pkgname" ]]; then + exit 1 # not a PKGBUILD + fi + + msg2 'Looking for unfree dependencies of %s %s' "${pkgbase:-${pkgname[0]}}" "$(get_full_version)" + + local pkgs=( + # packages being built + "${pkgname[@]}" + # depends + "${depends[@]}" "${makedepends[@]}" "${checkdepends[@]}" "${optdepends[@]%%:*}" + # mksource depends + "${mkdepends[@]}" + ) + local ret=0 + for pkg in "${pkgs[@]}"; do + local line="$(blacklist-cat|blacklist-lookup "$pkg")" + local rep="$(blacklist-get-rep <<<"$line")" + if [[ -z $line ]]; then + # not mentioned in blacklist; free + plain '%s: not blacklisted' "$pkg" + continue + elif [[ -z $rep ]]; then + # non-free with no replacement + plain '%s: blacklisted' "$pkg" + ret=1 + else + # non-free with free replacement + if [[ "$rep" == "$pkg" ]]; then + plain '%s: repackaged with the same name' "$pkg" + else + plain '%s: replaced by %s' "$pkg" "$rep" + fi + fi + done + return $ret +) + +usage() { + print "Usage: %s [OPTIONS] [PKGBUILD1 PKGBUILD2 ...]" "${0##*/}" + echo + prose 'If no PKGBUILD is specified, `./PKGBUILD` is implied.' + echo + print "Exit status:" + print " 0: Everything OK, no freedom issues" + print " 1: Ran with error" + print " 15: Depends on non-free packages" + echo + print "Options:" + flag '-c' 'Use the cached blacklist, do not try downloading.' + flag '-f' 'Allow running as root user' + flag '-h' 'Show this message' +} + +main() { + local asroot=false + local cache=false + while getopts 'cfh' arg; do + case "$arg" in + c) cache=true;; + f) asroot=true;; + h) usage; return 0;; + *) usage; return 1;; + esac + done + shift $(($OPTIND - 1)) + if [[ $# -lt 1 ]]; then + pkgbuilds=("`pwd`/PKGBUILD") + else + pkgbuilds=("$@") + fi + + if [[ -w / ]] && ! $asroot; then + error "Run as normal user, or use the -f option to run as root." + return 1 + fi + + $cache || blacklist-update || return 1 + + local ret=0 + for pkgbuild in "${pkgbuilds[@]}"; do + check_deps "$pkgbuild" || ret=15 + done + return $ret +} + +main "$@" diff --git a/repo-diff b/src/repo-diff index 7527381..bfa1968 100755 --- a/repo-diff +++ b/src/repo-diff @@ -2,7 +2,7 @@ # Shows a diff between repo databases if test $# -eq 0; then - printf "$(gettext "Compares two repo databases using distro/repo/architecture format + printf "$(gettext "Compares two repo databases using distro/repo/architecture format Usage: \t%s arch/core/i686 parabola/core/i686 @@ -10,21 +10,21 @@ Usage: Shortcuts: \tarch \texpands to archlinux repo url repo \tparabola\texpands to parabola repo url\n")" ${0##*/} - exit 0 + exit 0 fi b() { bsdtar ztf $1 | cut -d "/" -f1 | sort -u ; } n() { echo "$1".db | tr "/" "-"; } # hopefully simple way to convert -# parabola/libre/i686 -# to +# parabola/libre/i686 +# to # http://repo.parabolagnulinux.org/libre/os/i686/libre.db # add more distros here g() { - echo "$1" | sed -e "s,^\([^/]\+\)/\([^/]\+\)/\([^/]\+\)$,\1/\2/os/\3/\2.db," \ - -e "s,^parabola/,http://repo.parabolagnulinux.org/," \ - -e "s,^arch\(linux\)\?/,http://mirrors.kernel.org/archlinux/," + echo "$1" | sed -e "s,^\([^/]\+\)/\([^/]\+\)/\([^/]\+\)$,\1/\2/os/\3/\2.db," \ + -e "s,^parabola/,http://repo.parabolagnulinux.org/," \ + -e "s,^arch\(linux\)\?/,http://mirrors.kernel.org/archlinux/," } mkdir ${0##*/}.$$ @@ -32,20 +32,20 @@ pushd ${0##*/}.$$ >/dev/null d="" for i in $1 $2; do - n=$(n "$i") + n=$(n "$i") - test -z "$n" && exit 1 + test -z "$n" && exit 1 - wget -O "$n" -nv $(g "$i") - b "$n" >${n}.orig + wget -O "$n" -nv $(g "$i") + b "$n" >${n}.orig - d+=" ${n}.orig" + d+=" ${n}.orig" done { - printf "$(gettext "Difference between %s and %s")\n---\n" $1 $2 - which diffstat &>/dev/null && diff -auN ${d[@]} | diffstat - diff -auN ${d[@]} + printf "$(gettext "Difference between %s and %s")\n---\n" $1 $2 + which diffstat &>/dev/null && diff -auN ${d[@]} | diffstat + diff -auN "${d[@]}" } >../${n}.diff popd >/dev/null diff --git a/src/toru/Makefile b/src/toru/Makefile new file mode 100644 index 0000000..2c76089 --- /dev/null +++ b/src/toru/Makefile @@ -0,0 +1 @@ +include ../../common.mk @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Queries the ABS # License: GPL3 @@ -12,7 +12,7 @@ # * Possibility to hook up ABS dirs besides ABSROOT (low priority) # * Tell updates and non available binary packages (working on this) -source $(dirname $(command -v $0))/toru-utils +source toru-utils # Saves contents on a named cache # $1 cache name (repo) @@ -35,19 +35,6 @@ read_cache() { return $? } -## -# usage : get_full_version( $epoch, $pkgver, $pkgrel ) -# return : full version spec, including epoch (if necessary), pkgver, pkgrel -## -get_full_version() { - if [[ $1 -eq 0 ]]; then - # zero epoch case, don't include it in version - echo $2-$3 - else - echo $1:$2-$3 - fi -} - # Outputs an ordered package-fullpkgver array print_package_array() { echo "$@" | tr " " "\n" | sort -u @@ -167,7 +154,7 @@ update() { # Keep removing unneeded stuff unset package_${_pkg} >/dev/null 2>&1 || true # Fill the list of packages to find - packages_in_abs+=($_pkg-$(get_full_version ${epoch:-0} $pkgver $pkgrel)) + packages_in_abs+=($_pkg-$(get_full_version $_pkg)) package_paths+=($_pkg:$_pkgpath) done # end pkgnames diff --git a/toru-info b/src/toru/toru-info index 523f682..d73d2ad 100755 --- a/toru-info +++ b/src/toru/toru-info @@ -1,12 +1,13 @@ -#!/bin/bash +#!/usr/bin/env bash # Prints info about a given pkgname -source /etc/libretools.conf +. libremessages +. $(librelib conf) for _pkg in $@; do _pkgbuild="$(toru-where $_pkg)" if [ -f "$_pkgbuild/PKGBUILD" ]; then - source "$_pkgbuild/PKGBUILD" 2>/dev/null || { + load_PKGBUILD "$_pkgbuild/PKGBUILD" 2>/dev/null || { warning "Errors on %s" $_pkg continue } @@ -14,8 +15,6 @@ for _pkg in $@; do deps="${depends[@]} ${makedepends[@]} ${checkdepends[@]}" repo="$(basename $(dirname "$_pkgbuild"))" - unset build package depends makedepends checkdepends optdepends source md5sums - msg "%s/%s %s-%s" $repo $_pkg $pkgver $pkgrel msg2 "$pkgdesc" msg2 "$url" @@ -23,6 +22,4 @@ for _pkg in $@; do else warning "%s doesn't exist" $_pkg fi - - unset pkgname pkgver pkgrel pkgdesc url done diff --git a/toru-path b/src/toru/toru-path index 957f49b..6c86e88 100755 --- a/toru-path +++ b/src/toru/toru-path @@ -1,6 +1,6 @@ -#!/bin/bash +#!/usr/bin/env bash -source $(dirname $(command -v $0))/toru-utils +source toru-utils TORUPATH=${T:-${TORUPATH}} VERBOSE=${V:-false} @@ -22,6 +22,8 @@ fi fullrepos=() for (( i = ${#REPOS[@]}-1 ; i >= 0 ; i-- )); do ${VERBOSE} && msg "Processing [%s]" ${REPOS[$i]} + + [ -d "${ABSROOT}${REPOS[$i]}" ] && \ fullrepos+=("${ABSROOT}${REPOS[$i]}") done pkgbuilds=($(get_pkgbuilds ${fullrepos[@]})) @@ -30,7 +32,7 @@ msg "Updating path cache" msg2 "${#pkgbuilds[@]} PKGBUILDs to update" for _pkgbuild in ${pkgbuilds[@]}; do # plain "$_pkgbuild" - source ${_pkgbuild} >/dev/null 2>&1 || { + load_PKGBUILD "${_pkgbuild}" >/dev/null 2>&1 || { error "${_pkgbuild} contains errors, skipping" continue } @@ -41,8 +43,6 @@ for _pkgbuild in ${pkgbuilds[@]}; do $VERBOSE && msg2 "${_pkg} -> ${fullpath}" tcamgr put ${PATHFILE} ${_pkg/[<>=]*} ${fullpath} done - - unset pkgbase pkgname provides done lastsync ${LASTSYNCFILE} diff --git a/toru-utils b/src/toru/toru-utils index 316e6b8..96aa35e 100755 --- a/toru-utils +++ b/src/toru/toru-utils @@ -1,27 +1,15 @@ -#!/bin/bash +#!/usr/bin/env bash -source /etc/abs.conf -source /etc/libretools.conf +. libremessages +. $(librelib conf.sh) +load_files libretools +check_vars libretools TORUPATH || exit 1 LASTSYNCFILE=${TORUPATH}/lastsync FORCE=false QUIET=false DEBUG=false -# usage : in_array( $needle, $haystack ) -function in_array { - [[ $2 ]] || return 1 # Not found - - local needle=$1; shift - local item - - for item in "$@"; do - [[ ${item#@} = $needle ]] && return 0 # Found - done - - return 1 # Not Found -} - # Stores the lastsync date lastsync() { local lastsyncfile diff --git a/toru-where b/src/toru/toru-where index 0cbba6f..4b3ff1b 100755 --- a/toru-where +++ b/src/toru/toru-where @@ -1,6 +1,8 @@ #!/usr/bin/env bash # Locates a PKGBUILD dir on toru's path cache -source /etc/libretools.conf +. $(librelib conf.sh) +load_files libretools +check_vars libretools TORUPATH || exit 1 PATHFILE=${TORUPATH}/paths.tch diff --git a/src/treepkg b/src/treepkg new file mode 100755 index 0000000..a1b4e38 --- /dev/null +++ b/src/treepkg @@ -0,0 +1,231 @@ +#!/usr/bin/env bash +#set -x +# (c) 2012 Nicolás Reynolds <fauno@parabola.nu> +# +# 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/>. + +source libremessages +source $(librelib conf.sh) + +load_files libretools +check_vars libretools HOOKPREBUILD FULLBUILDCMD HOOKLOCALRELEASE +load_files makepkg + +term_title "$(basename $0)" + +# End inmediately but print an useful message +trap_exit() { + term_title "error!" + error "($(basename $0)) $@ (leftovers on ${BUILDDIR})" + exit 1 +} + +# Trap signals from makepkg +set -E +trap 'trap_exit "TERM signal caught. Exiting..."' TERM HUP QUIT +trap 'trap_exit "Aborted by user! Exiting..."' INT +trap 'trap_exit "An unknown error has occurred. Exiting..."' ERR + +# Add line to build order cache in CSV format +# *must* be run from the PKGBUILD path +# status;depth;pkgbase;[epoch:]pkgver-pkgrel;path;repo +# $1 status +# $2 pkgname +add_order() { + echo "${1};${DEPTH};${2:-${pkgbase}};$(get_full_version ${2});${PWD};$(guess_repo "$PWD")" >> "${BUILDORDER}" + ${VERBOSE} && msg2 "%${DEPTH}s${2:-${pkgbase}} [${1}]" || true +} + +# Bury a package deeper in the tree +# $1 pkgbase +# $2 nextdepth +bury() { + # Bury only if we are going to build the dep + # Get it's current depth and dir name + local current_depth=$(grep "build;[0-9]\+;${1};" "${BUILDORDER}" | cut -d ';' -f 2) + local current_name="$(printf "%03d" ${current_depth})_${1}" + + # If there's a depth or the package is not the root of the build tree (which + # can lead to funny chicken-and-egg problems), update the depth to the current + # package next-depth and rename the dir too + if [ -z "${current_depth}" ]; then return; fi + if [ -z "${current_name}" ]; then return; fi + if [ ${current_depth} -eq 0 ]; then return; fi + if [ ${current_depth} -ge $2 ]; then return; fi + + ${VERBOSE} && msg "Burying ${1} from ${current_depth} to ${2}" + + { + sed -i "s|^\(build;\)\([0-9]\+\)\(;${1};.*\)$|\1${2}\3|" "${BUILDORDER}" && \ + mv "${BUILDDIR}/${current_name}" "${BUILDDIR}/$(printf "%03d" ${2})_${1}" + } || return 1 +} + +# Guess the repo from the pkgbase path +# $1 path, pwd or toru-where +guess_repo() { + basename "$(dirname "${1}")" +} + +if [ ! -f PKGBUILD ]; then + error "Missing PKGBUILD ($PWD)" + exit 1 +fi + +if ! load_PKGBUILD ; then + error "Can't source PKGBUILD" + exit 1 +fi + +# Save resources +unset pkgdesc arch license groups backup install md5sums sha1sums \ + sha256sums source options >/dev/null 2>&1 + +unset build package >/dev/null 2>&1 + +for _pkg in "${pkgname[@]}"; do + unset package_${_pkg} >/dev/null 2>&1 || true +done +## + +# Get useful values +pkgbase="${pkgbase:-${pkgname[0]}}" + +# Get or set the work dir +BUILDDIR="${1:-$(mktemp -d /tmp/${pkgbase}-treepkg-XXXx)}" +BUILDORDER="${BUILDDIR}/BUILDORDER" +DEPTH=${2:-0} +NEXTDEPTH=$((${DEPTH} + 1)) +# This can be set as env vars (ie: $ V=false B=false treepkg) +# TODO Turn into flags? +VERBOSE=${V:-true} +BUILD=${B:-true} +CLEANUP=${C:-true} +# Skip BUILDORDER creation and build anything on BUILDDIR +BUILDNOW=${N:-false} +IGNORE=${I:-} + +if [[ ! -z $1 ]] && [[ $DEPTH -eq 0 ]]; then + BUILDNOW=true +fi + +if ! ${BUILDNOW}; then + # ensure it exists + touch "${BUILDORDER}" + + # If this package is already built quit silently + for _pkg in "${pkgname[@]}"; do + + if in_array "${_pkg}" "${IGNORE[@]}"; then + add_order "ignore" + exit 0 + fi + + if is_built "${_pkg}" "$(get_full_version ${_pkg})"; then + add_order "ignore" + exit 0 + fi + done + + # Ignore if already in build order + egrep -q ";${pkgbase};" "${BUILDORDER}" && exit 0 + + # Add pkgbase to build order + add_order "build" + + # Copy the directory to the build dir + # TODO run makepkg --source to avoid moving garbage around? + cp -r "${PWD}" "${BUILDDIR}/$(printf "%03d" ${DEPTH})_${pkgbase}" + + # Cleanup dep versioning + deps=($(echo "${depends[@]} ${makedepends[@]}" | \ + sed "s/[=<>]\+[^ ]\+//g" | \ + tr ' ' "\n" | \ + sort -u)) + + # NOTE: getting depends from package() is a PITA + for _dep in "${deps[@]}"; do + # Move deps deeper in the tree if + # pkgbase - dep1 + # \ dep2 - dep1 + # dep1 should be depth + 1 + egrep -q ";${_dep};" "${BUILDORDER}" && bury "${_dep}" ${NEXTDEPTH} + + # Ask toru where's a PKGBUILD + depdir="$(toru-where ${_dep})" + + if [[ -z ${depdir} ]] || [[ ! -d ${depdir} ]]; then + # We specify the pkgname because we can't source the dep PKGBUILD + # Normally 'any' packages are missing from our work ABS + add_order "missing" "${_dep}" + continue + fi + + pushd "${depdir}" >/dev/null + + # Run itself over dependencies + $0 "${BUILDDIR}" ${NEXTDEPTH} + + done + # End BUILD now +fi + +# Only build at the end +if [ ${DEPTH} -eq 0 ]; then + ${VERBOSE} && msg "Starting build" || true + + if ${BUILD}; then + ${VERBOSE} && msg "Build tree stored in ${BUILDORDER}" || true + + # Build everything sorting the build dir + # The reverse order ensures we start by the deepest packages + for _pkg in $(ls -r "${BUILDDIR}"); do + # Ignore if there's no PKGBUILD + if [ ! -f "${BUILDDIR}/${_pkg}/PKGBUILD" ]; then continue; fi + # Skip if already built (faster than calling is_build again) + if [ -f "${BUILDDIR}/${_pkg}/built_ok" ]; then continue; fi + + ${VERBOSE} && msg "Building ${_pkg/_/ }" || true + + # Remove leading zeros and space if any + term_title "$(echo ${_pkg/_/ } | sed "s/^0\+ \?//")" + + # Run build command + pushd "${BUILDDIR}/${_pkg}" >/dev/null + sudo -E pacman -Syu --noconfirm + + ${HOOKPREBUILD} + + ${FULLBUILDCMD} + # Run local release hook with $1 = $repo + ${HOOKLOCALRELEASE} $(egrep ";${_pkg#*_};" "${BUILDORDER}" | cut -d';' -f6) + + touch built_ok + popd >/dev/null + done + + else + # Just print the working dir + ${VERBOSE} || echo "${BUILDORDER}" || true + fi + + if (( CLEANUP )) ; then + msg2 "Removing ${BUILDDIR}" + rm -rf "${BUILDDIR}" + fi + +fi + +term_title "done" +exit $? diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..2226ac6 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +.roundup.* diff --git a/test/aur-test.sh b/test/aur-test.sh new file mode 100644 index 0000000..1fbe659 --- /dev/null +++ b/test/aur-test.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env roundup + +describe aur + +. ./test-common.sh + +before() { + _before +} + +after() { + _after +} + +it_displays_help() { + LANG=C aur -h >$tmpdir/stdout 2>$tmpdir/stderr + + [[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} + +it_fails_with_0_args() { + aur >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} + +# TODO: Actually test diff --git a/test/is_built-test.sh b/test/is_built-test.sh new file mode 100644 index 0000000..62847e5 --- /dev/null +++ b/test/is_built-test.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env roundup + +describe is_built + +. ./test-common.sh + +before() { + _before +} + +after() { + _after +} + +it_displays_help() { + LANG=C is_built -h >$tmpdir/stdout 2>$tmpdir/stderr + + [[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} + +it_fails_with_0_args() { + is_built >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat -gt 1 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} + +it_succeeds_with_1_arg() { + is_built sh >$tmpdir/stdout 2>$tmpdir/stderr + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} + +it_returns_1_for_non_existent_package() { + is_built phony-ne-package 100 >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat == 1 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} + +it_returns_1_for_future_packages() { + # If emacs ever goes rapid release, we might need to change this :P + is_built emacs 100 >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat == 1 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} + +it_returns_0_for_past_packages() { + # If emacs ever goes rapid release, we might need to change this :P + is_built emacs 1 >$tmpdir/stdout 2>$tmpdir/stderr + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} diff --git a/test/lib-blacklist-test.sh b/test/lib-blacklist-test.sh new file mode 100644 index 0000000..c496167 --- /dev/null +++ b/test/lib-blacklist-test.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env roundup + +describe libreblacklist + +. ./test-common.sh + +before() { + _before +} + +after() { + _after +} + +it_works_with_just_pkgname() { + v="$(libreblacklist normalize <<<skype)"; [[ $v == 'skype::' ]] + v="$(libreblacklist get-pkg <<<skype)"; [[ $v == skype ]] + v="$(libreblacklist get-rep <<<skype)"; [[ -z $v ]] + v="$(libreblacklist get-reason <<<skype)"; [[ -z $v ]] +} + +it_works_with_everything_set() { + line='linux:linux-libre:nonfree blobs and firmwares' + v="$(libreblacklist normalize <<<"$line")"; [[ $v == "$line" ]] + v="$(libreblacklist get-pkg <<<"$line")"; [[ $v == 'linux' ]] + v="$(libreblacklist get-rep <<<"$line")"; [[ $v == 'linux-libre' ]] + v="$(libreblacklist get-reason <<<"$line")"; [[ $v == 'nonfree blobs and firmwares' ]] +} + +it_normalizes_correctly() { + v="$(libreblacklist normalize <<<pkg)"; [[ $v == 'pkg::' ]] + v="$(libreblacklist normalize <<<pkg:)"; [[ $v == 'pkg::' ]] + v="$(libreblacklist normalize <<<pkg::)"; [[ $v == 'pkg::' ]] + v="$(libreblacklist normalize <<<pkg:rep)"; [[ $v == 'pkg:rep:' ]] + v="$(libreblacklist normalize <<<pkg:rep:)"; [[ $v == 'pkg:rep:' ]] + v="$(libreblacklist normalize <<<pkg:rep:reason)"; [[ $v == 'pkg:rep:reason' ]] + v="$(libreblacklist normalize <<<pkg:rep:reason:)"; [[ $v == 'pkg:rep:reason:' ]] +} + +it_works_with_colons_in_reason() { + line='package:replacement:my:reason' + v="$(libreblacklist normalize <<<"$line")"; [[ $v == "$line" ]] + v="$(libreblacklist get-pkg <<<"$line")"; [[ $v == 'package' ]] + v="$(libreblacklist get-rep <<<"$line")"; [[ $v == 'replacement' ]] + v="$(libreblacklist get-reason <<<"$line")"; [[ $v == 'my:reason' ]] +} + +it_fails_update_when_there_is_no_blacklist_or_network() { + mkdir -p $XDG_CONFIG_HOME/libretools + echo "BLACKLIST='phony://example.com'" >$XDG_CONFIG_HOME/libretools/libretools.conf + + libreblacklist update >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} + +it_fails_cat_when_there_is_no_blacklist_or_network() { + mkdir -p $XDG_CONFIG_HOME/libretools + echo "BLACKLIST='phony://example.com'" >$XDG_CONFIG_HOME/libretools/libretools.conf + + libreblacklist cat >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} + +it_fails_update_when_BLACKLIST_is_unset() { + mkdir -p $XDG_CONFIG_HOME/libretools + echo "BLACKLIST=" >$XDG_CONFIG_HOME/libretools/libretools.conf + + libreblacklist update >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} + +it_fails_cat_when_syntax_error_in_conf() { + mkdir -p $XDG_CONFIG_HOME/libretools + # there is a stray single quote in there + echo "BLACKLIST='https://repo.parabolagnulinux.org/docs/blacklist.txt" >$XDG_CONFIG_HOME/libretools/libretools.conf + + libreblacklist cat >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} + +it_downloads_the_blacklist_as_needed() { + require network || return 0 + mkdir -p $XDG_CONFIG_HOME/libretools + echo "BLACKLIST=https://repo.parabolagnulinux.org/docs/blacklist.txt" >$XDG_CONFIG_HOME/libretools/libretools.conf + + libreblacklist cat >$tmpdir/stdout 2>$tmpdir/stderr + + [[ -n "$(cat $tmpdir/stdout)" ]] +} + +it_downloads_the_blacklist_repeatedly() { + require network || return 0 + mkdir -p $XDG_CONFIG_HOME/libretools + echo "BLACKLIST=https://repo.parabolagnulinux.org/docs/blacklist.txt" >$XDG_CONFIG_HOME/libretools/libretools.conf + + libreblacklist update + libreblacklist update +} + +it_displays_help_and_fails_with_no_args() { + LANG=C libreblacklist >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ "$(sed 1q $tmpdir/stderr)" =~ 'Usage: libreblacklist ' ]] +} + +it_displays_help_when_given_h() { + LANG=C libreblacklist -h >$tmpdir/stdout 2>$tmpdir/stderr + + [[ "$(sed 1q $tmpdir/stdout)" =~ 'Usage: libreblacklist ' ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} + +it_displays_help_when_given_h_cat() { + LANG=C libreblacklist -h cat >$tmpdir/stdout 2>$tmpdir/stderr + + [[ "$(sed 1q $tmpdir/stdout)" == 'Usage: libreblacklist cat' ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} diff --git a/test/lib-conf-test.sh b/test/lib-conf-test.sh new file mode 100644 index 0000000..0d028b8 --- /dev/null +++ b/test/lib-conf-test.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env roundup + +describe lib/conf.sh + +. ./test-common.sh + +before() { + _before test-conf.sh +} + +after() { + _after +} + +it_sets_makepkg_vars_in_custom_file() { + unset PKGDEST + touch "$tmpdir/makepkg.conf" + . $(librelib conf.sh) + MAKEPKG_CONF="$tmpdir/makepkg.conf" set_conf_makepkg PKGDEST /pkgdest + . "$tmpdir/makepkg.conf" + [[ $PKGDEST == /pkgdest ]] +} + +it_figures_out_HOME_when_root() { + require sudo || return 0 + # This one is tricky, because it does the job too well, it will find + # the actual HOME, instead of the test environment HOME. Therefore, we + # will just check that [[ $HOME != /root ]] + cd "$tmpdir" + echo '. $(librelib conf.sh); echo "$LIBREHOME"' > test.sh + LIBREHOME=$(testsudo bash ./test.sh) + [[ $LIBREHOME != /root ]] +} + +it_respects_custom_HOME() { + cd "$tmpdir" + echo '. $(librelib conf.sh); echo "$LIBREHOME"' > test.sh + + export HOME=/foo + LIBREHOME=$(bash ./test.sh) + + [[ $LIBREHOME == /foo ]] +} diff --git a/test/lib-messages-test.sh b/test/lib-messages-test.sh new file mode 100644 index 0000000..826556b --- /dev/null +++ b/test/lib-messages-test.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env roundup + +describe libremessages + +. ./test-common.sh + +before() { + _before +} + +after() { + _after +} + +it_can_be_included_twice() ( + . libremessages + . libremessages +) + +it_can_be_included_with_set_euE() ( + set -euE + . libremessages +) + +it_works_with_no_color_and_set_euE() ( + ( + unset TERM + set -euE + . libremessages + msg Foo + ) >$tmpdir/stdout 2>$tmpdir/stderr + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +) + +it_can_be_called_without_including() { + libremessages msg Foo >$tmpdir/stdout 2>$tmpdir/stderr + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} + +it_fails_with_msg_and_no_args() { + ret=0 + libremessages msg || ret=$? + [[ $ret != 0 ]] +} diff --git a/test/librechroot-test.sh b/test/librechroot-test.sh new file mode 100644 index 0000000..76afb56 --- /dev/null +++ b/test/librechroot-test.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env roundup + +describe librechroot + +. ./test-common.sh + +before() { + _before librechroot + mkdir -p "$XDG_CONFIG_HOME"/libretools + echo "CHROOTDIR='$tmpdir/chrootdir'" > "$XDG_CONFIG_HOME"/libretools/chroot.conf + echo "CHROOT='default'" >> "$XDG_CONFIG_HOME"/libretools/chroot.conf + echo "CHROOTEXTRAPKG=()" >> "$XDG_CONFIG_HOME"/libretools/chroot.conf +} + +after() { + _after_sudo +} + +it_creates_repo_for_new_chroots() { + require network sudo || return 0 + libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty + testsudo librechroot run test -r /repo/repo.db +} + +it_cleans_the_local_repo_correctly() { + require network sudo || return 0 + libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty + testsudo librechroot make + testsudo librechroot clean-repo + testsudo librechroot run test -r /repo/repo.db + # TODO: inspect /repo/* more +} + +it_displays_help_as_normal_user() { + rm -rf "$XDG_CONFIG_HOME" + LANG=C librechroot help >$tmpdir/stdout 2>$tmpdir/stderr + + [[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} + +it_otherwise_fails_as_normal_user() { + librechroot run true >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} + +it_displays_help_and_fails_with_0_args() { + LANG=C librechroot >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ "$(sed 1q $tmpdir/stderr)" =~ Usage:.* ]] +} + +# requires sudo so we know it's not failing because it needs root +it_fails_for_unknown_commands() { + require sudo || return 0 + testsudo librechroot phony >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} + +# requires sudo so we know it's not failing because it needs root +it_fails_for_unknown_flags() { + require sudo || return 0 + testsudo librechroot -q >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} diff --git a/test/librelib-test.sh b/test/librelib-test.sh new file mode 100644 index 0000000..e86dffe --- /dev/null +++ b/test/librelib-test.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env roundup + +describe librelib + +. ./test-common.sh + +before() { + _before +} + +after() { + _after +} + +it_displays_help_and_fails_with_0_args() { + ret=0 + librelib >$tmpdir/stdout 2>$tmpdir/stderr || ret=$? + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ "$(sed 1q $tmpdir/stderr)" =~ Usage:.* ]] + [[ $ret != 0 ]] +} + +it_fails_with_2_args() { + ret=0 + librelib a b >$tmpdir/stdout 2>$tmpdir/stderr || ret=$? + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] + [[ $ret != 0 ]] +} + +it_displays_usage_text() { + librelib -h >$tmpdir/stdout 2>$tmpdir/stderr + + [[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} + +# libremessages is executable +it_finds_messages() { + v1=$(librelib messages) + v2=$(librelib libremessages) + v3=$(librelib messages.sh) + v4=$(librelib libremessages.sh) + + [[ -x "$v1" ]] + [[ "$v1" == "$v2" ]] + [[ "$v1" == "$v3" ]] + [[ "$v1" == "$v4" ]] +} + +# conf.sh is non-executable +it_finds_conf() { + v1=$(librelib conf) + v2=$(librelib libreconf) + v3=$(librelib conf.sh) + v4=$(librelib libreconf.sh) + + [[ -r "$v1" && ! -x "$v1" ]] + [[ "$v1" == "$v2" ]] + [[ "$v1" == "$v3" ]] + [[ "$v1" == "$v4" ]] +} + +it_fails_to_find_phony() { + ret=0 + librelib phony >$tmpdir/stdout 2>$tmpdir/stderr || ret=$? + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] + [[ $ret != 0 ]] +} diff --git a/test/libremakepkg-test.sh b/test/libremakepkg-test.sh new file mode 100644 index 0000000..be19e17 --- /dev/null +++ b/test/libremakepkg-test.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env roundup + +describe libremakepkg + +. ./test-common.sh + +before() { + _before libremakepkg + + mkdir -p "$XDG_CONFIG_HOME"/libretools + + echo "BLACKLIST=https://repo.parabolagnulinux.org/docs/blacklist.txt" >"$XDG_CONFIG_HOME"/libretools/libretools.conf + + echo "CHROOTDIR='$tmpdir/chrootdir'" > "$XDG_CONFIG_HOME"/libretools/chroot.conf + echo "CHROOT='default'" >> "$XDG_CONFIG_HOME"/libretools/chroot.conf + echo "CHROOTEXTRAPKG=()" >> "$XDG_CONFIG_HOME"/libretools/chroot.conf +} + +after() { + _after_sudo +} + +it_builds_a_trivial_package() { + require network sudo || return 0 + cp libremakepkg.d/PKGBUILD-hello "$tmpdir/PKGBUILD" + cd "$tmpdir" + + libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty + testsudo libremakepkg + + [[ -f $(echo libretools-hello-1.0-1-any.pkg.tar.?z) ]] +} + +it_handles_PKGDEST_not_existing() { + require network sudo || return 0 + cp libremakepkg.d/PKGBUILD-hello "$tmpdir/PKGBUILD" + cd "$tmpdir" + + libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty + testsudo env PKGDEST="$tmpdir/dest/pkgdest" libremakepkg + + [[ -f $(echo dest/pkgdest/libretools-hello-1.0-1-any.pkg.tar.?z) ]] +} + +it_displays_help_as_normal_user() { + rm -rf "$XDG_CONFIG_HOME" + LANG=C libremakepkg -h >$tmpdir/stdout 2>$tmpdir/stderr + + [[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]] + [[ -z "$(cat $tmpdir/stderr)" ]] +} + +it_otherwise_fails_as_normal_user() { + # I do this to give it a chance of passing + cp libremakepkg.d/PKGBUILD-hello "$tmpdir/PKGBUILD" + cd "$tmpdir" + + libremakepkg >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] +} diff --git a/test/libremakepkg.d/PKGBUILD-hello b/test/libremakepkg.d/PKGBUILD-hello new file mode 100644 index 0000000..706cb24 --- /dev/null +++ b/test/libremakepkg.d/PKGBUILD-hello @@ -0,0 +1,19 @@ +pkgname='libretools-hello' +pkgver=1.0 +license=('GPL') +url='https://parabolagnulinux.org' + +pkgrel=1 +arch=(any) +depends=(sh) + +build() { + cd "$srcdir" + echo '#!/bin/sh' > hello.sh + echo 'echo Hello, world!' >> hello.sh +} + +package() { + cd "$srcdir" + install -Dm755 hello.sh "$pkgdir"/usr/bin/libretools-hello +} diff --git a/test/librestage-test.sh b/test/librestage-test.sh new file mode 100644 index 0000000..849a68c --- /dev/null +++ b/test/librestage-test.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env roundup + +describe librestage + +. ./test-common.sh + +before() { + _before + + mkdir -p $XDG_CONFIG_HOME/libretools + echo "WORKDIR='$tmpdir/workdir'" >$XDG_CONFIG_HOME/libretools/libretools.conf + echo "ARCHES=('x86_64' 'i686' 'misp64el')" >>$XDG_CONFIG_HOME/libretools/libretools.conf + + export HOME=$XDG_CONFIG_HOME + echo 'PKGEXT=.pkg.tar.gz' > $HOME/.makepkg.conf + echo "PKGDEST='$tmpdir/workdir/pkgdest'" >> $HOME/.makepkg.conf + mkdir -p "$tmpdir/workdir/pkgdest" +} + +after() { + _after +} + +it_displays_usage_text() { + rm -rf "$XDG_CONFIG_HOME" + LANG=C librestage -h >$tmpdir/stdout 2>$tmpdir/stderr + + [[ "$(sed 1q "$tmpdir/stdout")" =~ Usage:.* ]] + [[ -z "$(cat "$tmpdir/stderr")" ]] +} + +it_fails_with_0_args() { + librestage >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat "$tmpdir/stdout")" ]] + [[ -n "$(cat "$tmpdir/stderr")" ]] +} + +it_fails_with_invalid_args() { + librestage -q >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ $stat != 0 ]] + [[ -z "$(cat "$tmpdir/stdout")" ]] + [[ -n "$(cat "$tmpdir/stderr")" ]] +} + +# This was an actual bug I hit with md/emacs-mdmua a long time ago; solution was +# to use $(get_full_version) +it_stages_split_packages_with_different_versions() { + cp librestage.d/PKGBUILD-split "$tmpdir/PKGBUILD" + cd "$tmpdir" + + makepkg + librestage '~lukeshu' + + # peak at the PKGBUILD to get this info + [[ -f $tmpdir/workdir/staging/~lukeshu/md-0.81-4-any.pkg.tar.gz ]] + [[ -f $tmpdir/workdir/staging/~lukeshu/emacs-mdmua-0.72-4-any.pkg.tar.gz ]] +} + +it_stages_packages_to_multiple_repos() { + cp librestage.d/PKGBUILD-hello "$tmpdir/PKGBUILD" + cd "$tmpdir" + + makepkg + librestage repo1 repo2 repo3 + + [[ -f $tmpdir/workdir/staging/repo1/libretools-hello-1.0-1-any.pkg.tar.gz ]] + [[ -f $tmpdir/workdir/staging/repo2/libretools-hello-1.0-1-any.pkg.tar.gz ]] + [[ -f $tmpdir/workdir/staging/repo3/libretools-hello-1.0-1-any.pkg.tar.gz ]] +} + + +it_stages_packages_without_PKGDEST() { + echo "PKGDEST=''" >> $HOME/.makepkg.conf + + cp librestage.d/PKGBUILD-hello "$tmpdir/PKGBUILD" + cd "$tmpdir" + + makepkg + librestage repo1 + + [[ -f $tmpdir/workdir/staging/repo1/libretools-hello-1.0-1-any.pkg.tar.gz ]] +} diff --git a/test/librestage.d/PKGBUILD-hello b/test/librestage.d/PKGBUILD-hello new file mode 100644 index 0000000..706cb24 --- /dev/null +++ b/test/librestage.d/PKGBUILD-hello @@ -0,0 +1,19 @@ +pkgname='libretools-hello' +pkgver=1.0 +license=('GPL') +url='https://parabolagnulinux.org' + +pkgrel=1 +arch=(any) +depends=(sh) + +build() { + cd "$srcdir" + echo '#!/bin/sh' > hello.sh + echo 'echo Hello, world!' >> hello.sh +} + +package() { + cd "$srcdir" + install -Dm755 hello.sh "$pkgdir"/usr/bin/libretools-hello +} diff --git a/test/librestage.d/PKGBUILD-split b/test/librestage.d/PKGBUILD-split new file mode 100644 index 0000000..a8ec1ef --- /dev/null +++ b/test/librestage.d/PKGBUILD-split @@ -0,0 +1,42 @@ +# Maintainer: Luke Shumaker <lukeshu@sbcglobal.net> + +pkgname=("md" "emacs-mdmua") +pkgver=0.81 +pkgrel=4 +arch=('any') +url="https://github.com/nicferrier/$_pkgname" +license=('GPL3') + +#makedepends=(python-distribute) + +#__gitbranch=1d69744 # This is the commit that is 0.81 +__gitbranch=455b6b4 # this is currently HEAD (has bugfixes) +#source=("nicferrier-md-${__gitbranch}.tar.gz::https://github.com/nicferrier/$pkgname/tarball/${__gitbranch}") + +#build() { +# cd "${srcdir}/nicferrier-md-${__gitbranch}" +# +# # fix typo +# sed -i 's/pyprofyfs/pyproxyfs/' setup.py +#} + +package_md() { + pkgdesc="A maildir client and library." + depends=('python' 'python-pyproxyfs') + +# cd "${srcdir}/nicferrier-md-${__gitbranch}" +# python setup.py install --root="$pkgdir/" --optimize=1 +} + +package_emacs-mdmua() { + pkgdesc="An Emacs mail user agent (MUA) build around md." + pkgver='0.72' + depends=("md=0.81" 'emacs>=24') + +# cd "${srcdir}/nicferrier-md-${__gitbranch}" +# cd useragents/emacs +# install -d ${pkgdir}/usr/share/emacs/site-lisp +# install -m 644 *.el ${pkgdir}/usr/share/emacs/site-lisp +} + +#md5sums=('452727348df2f51d7eddade709aceb1c') diff --git a/test/pkgbuild-check-licenses-test.sh b/test/pkgbuild-check-licenses-test.sh new file mode 100644 index 0000000..220ef6b --- /dev/null +++ b/test/pkgbuild-check-licenses-test.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env roundup + +# avoid carpel tunnel +pcl=pkgbuild-check-licenses + +describe $pcl + +. ./test-common.sh + +before() { + _before +} + +after() { + _after +} + +it_displays_usage_text() { + # This test seems silly, but it makes sure that it is executable, + # syntactically correct, and loading libraries works. + LANG=C $pcl -h >$tmpdir/stdout 2>$tmpdir/stderr + stat=$? + + [[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]] + [[ -z "$(cat $tmpdir/stderr)" ]] + [[ $stat == 0 ]] +} diff --git a/test/pkgbuild-check-nonfree-test.sh b/test/pkgbuild-check-nonfree-test.sh new file mode 100644 index 0000000..d547e24 --- /dev/null +++ b/test/pkgbuild-check-nonfree-test.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env roundup + +# avoid carpel tunnel +pcn=pkgbuild-check-nonfree + +describe $pcn + +. ./test-common.sh + +before() { + _before + + mkdir -p $XDG_CONFIG_HOME/libretools + echo "BLACKLIST='phony://example.com'" >$XDG_CONFIG_HOME/libretools/libretools.conf + + local blacklist=$XDG_CACHE_HOME/libretools/blacklist.txt + mkdir -p "${blacklist%/*}" + echo 'linux:linux-libre:nonfree blobs and firmwares' >$blacklist + echo 'skype' >>$blacklist +} + +after() { + _after +} + +it_displays_usage_text() { + # This test seems silly, but it makes sure that it is executable, + # syntactically correct, and loading libraries works. + LANG=C $pcn -h >$tmpdir/stdout 2>$tmpdir/stderr + stat=$? + + [[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]] + [[ -z "$(cat $tmpdir/stderr)" ]] + [[ $stat == 0 ]] +} + +it_succeeds_for_free_depends() { + $pcn $pcn.d/PKGBUILD.free >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] + [[ $stat == 0 ]] +} + +it_succeeds_for_nonfree_depend_with_replacement() { + $pcn $pcn.d/PKGBUILD.nonfree-replacement >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] + [[ $stat == 0 ]] +} + +it_fails_with_15_for_nonfree_depend() { + $pcn $pcn.d/PKGBUILD.nonfree >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] + [[ $stat == 15 ]] +} + +it_fails_when_there_is_no_blacklist() { + mkdir -p $XDG_CONFIG_HOME/libretools + echo "BLACKLIST='phony://example.com'" >$XDG_CONFIG_HOME/libretools/libretools.conf + rm $XDG_CACHE_HOME/libretools/blacklist.txt + + $pcn $pcn.d/PKGBUILD.free >$tmpdir/stdout 2>$tmpdir/stderr || stat=$? + + [[ -z "$(cat $tmpdir/stdout)" ]] + [[ -n "$(cat $tmpdir/stderr)" ]] + [[ $stat != 0 ]] && [[ $stat != 15 ]] +} diff --git a/test/pkgbuild-check-nonfree.d/PKGBUILD.free b/test/pkgbuild-check-nonfree.d/PKGBUILD.free new file mode 100644 index 0000000..4b8f0dd --- /dev/null +++ b/test/pkgbuild-check-nonfree.d/PKGBUILD.free @@ -0,0 +1,18 @@ +pkgname=wmii +pkgver=3.9.2 +pkgrel=3 +pkgdesc="A small, dynamic window manager for X11" +arch=('i686' 'x86_64') +license=('MIT') +url="http://wmii.suckless.org/" +depends=('libxft' 'libxrandr' 'libxinerama' 'dash') +source=() +md5sums=() + +build() { + : +} + +package() { + : +} diff --git a/test/pkgbuild-check-nonfree.d/PKGBUILD.nonfree b/test/pkgbuild-check-nonfree.d/PKGBUILD.nonfree new file mode 100644 index 0000000..3a7afa4 --- /dev/null +++ b/test/pkgbuild-check-nonfree.d/PKGBUILD.nonfree @@ -0,0 +1,18 @@ +pkgname=wmii +pkgver=3.9.2 +pkgrel=3 +pkgdesc="A small, dynamic window manager for X11" +arch=('i686' 'x86_64') +license=('MIT') +url="http://wmii.suckless.org/" +depends=('skype') # random non-free package with no other information +source=() +md5sums=() + +build() { + : +} + +package() { + : +} diff --git a/test/pkgbuild-check-nonfree.d/PKGBUILD.nonfree-replacement b/test/pkgbuild-check-nonfree.d/PKGBUILD.nonfree-replacement new file mode 100644 index 0000000..7855bdc --- /dev/null +++ b/test/pkgbuild-check-nonfree.d/PKGBUILD.nonfree-replacement @@ -0,0 +1,18 @@ +pkgname=wmii +pkgver=3.9.2 +pkgrel=3 +pkgdesc="A small, dynamic window manager for X11" +arch=('i686' 'x86_64') +license=('MIT') +url="http://wmii.suckless.org/" +depends=('linux') # random non-free package with a replacement +source=() +md5sums=() + +build() { + : +} + +package() { + : +} diff --git a/test/test-common.sh b/test/test-common.sh new file mode 100644 index 0000000..01b1b35 --- /dev/null +++ b/test/test-common.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +if [[ $HOME == "$(eval echo ~$USER)" ]]; then + libremessages error "\$HOME is the default for %s; use testenv: %s" "$USER" "$HOME" + exit 1 +fi + +_before() { + tmpdir="$(mktemp -d --tmpdir "test-${roundup_desc//\//-}.XXXXXXXXXXXX")" + stat=0 +} + +_after() { + rm -rf -- "$tmpdir" "$XDG_CONFIG_HOME" "$XDG_CACHE_HOME" +} + +_after_sudo() { + if [[ $SUDO ]]; then + sudo rm -rf -- "$tmpdir" "$XDG_CONFIG_HOME" "$XDG_CACHE_HOME" + else + rm -rf -- "$tmpdir" "$XDG_CONFIG_HOME" "$XDG_CACHE_HOME" + fi +} + +require() { + local missing=() + if libremessages in_array "network" "$@" && ! [[ $NETWORK ]]; then + missing+=('networking') + fi + if libremessages in_array "sudo" "$@" && ! [[ $SUDO ]]; then + missing+=('sudo') + fi + if (( ${#missing[@]} )); then + libremessages warning "Next test requires %s; Skipping (passing)..." "$(echo "${missing[*]}"|sed 's/ /, /g')" &>/dev/tty + return 1 + fi + return 0; +} diff --git a/test/testenv b/test/testenv new file mode 100755 index 0000000..e6c882f --- /dev/null +++ b/test/testenv @@ -0,0 +1,60 @@ +#!/bin/bash + +# Parse the arguments +NETWORK=true +SUDO=true +while [[ $# -gt 0 ]]; do + case "$1" in + --no-network) shift; unset NETWORK;; + --network) shift; NETWORK=true;; + --no-sudo) shift; unset SUDO;; + --sudo) shift; SUDO=true;; + --) shift; break;; + *) break;; + esac +done +export NETWORK SUDO + +# Set up the working directory, and add the hook to clean it up +export TMPDIR="$(mktemp --tmpdir -d libretools-test.XXXXXXXXXX)" +trap "rm -rf '$TMPDIR'" EXIT + +# Set up the install to work with +destdir=$TMPDIR/destdir + +old_pwd="$(pwd)" +if [[ -f $0 ]]; then + cd "${0%/*}" +fi +make -C .. install DESTDIR=$destdir &>/dev/null || { + echo 'error creating local install, cannot run tests' + exit 1 +} +cd "$old_pwd" + +# Set up the environment +export PATH="$destdir/usr/bin:$PATH" +export LIBRETOOLS_LIBDIR="$destdir/usr/lib/libretools" +export HOME=$TMPDIR/home +export XDG_CACHE_HOME="$HOME/.cache" +export XDG_CONFIG_HOME="$HOME/.config" + +# Hack to respect our variables in sudo +_sudo() { + local vars=(TMPDIR PATH LIBRETOOLS_LIBDIR XDG_CACHE_HOME XDG_CONFIG_HOME) + local args=() + local var + for var in "${vars[@]}"; do + args+=("$var=${!var}") + done + sudo env "${args[@]}" "$@" +} +printf '%s\n' \ + '#!/bin/bash' \ + "$(declare -f _sudo)" \ + '_sudo "$@"' \ + > "$destdir/usr/bin/testsudo" +chmod 755 "$destdir/usr/bin/testsudo" + +# Run the tests +eval "$@" diff --git a/treepkg b/treepkg deleted file mode 100755 index dc2575d..0000000 --- a/treepkg +++ /dev/null @@ -1,244 +0,0 @@ -#!/usr/bin/env bash -#set -x -# (c) 2012 Nicolás Reynolds <fauno@parabola.nu> -# -# 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/>. - -source /etc/libretools.conf -source $XDG_CONFIG_HOME/libretools/libretools.conf >/dev/null 2>&1|| true - -term_title "$(basename $0)" - -# Get system variables -source /etc/makepkg.conf -source $HOME/makepkg.conf >/dev/null 2>&1|| true - -# End inmediately but print an useful message -trap_exit() { - term_title "error!" - error "($(basename $0)) $@ (leftovers on ${BUILDDIR})" - exit 1 -} - -# Trap signals from makepkg -set -E -trap 'trap_exit "TERM signal caught. Exiting..."' TERM HUP QUIT -trap 'trap_exit "Aborted by user! Exiting..."' INT -trap 'trap_exit "An unknown error has occurred. Exiting..."' ERR - -# return : full version spec, including epoch (if necessary), pkgver, pkgrel -# usage : get_fullver( ${epoch:-0}, $pkgver, $pkgrel ) -get_fullver() { - if [ $1 -eq 0 ]; then -# zero epoch case, don't include it in version - echo $2-$3 - else - echo $1:$2-$3 - fi - -} - -# Add line to build order cache in CSV format -# *must* be run from the PKGBUILD path -# status;depth;pkgbase;[epoch:]pkgver-pkgrel;path;repo -# $1 status -# $2 pkgname -add_order() { - echo "${1};${DEPTH};${2:-${pkgbase}};${fullver};${PWD};$(guess_repo "$PWD")" >> "${BUILDORDER}" - ${VERBOSE} && msg2 "%${DEPTH}s${2:-${pkgbase}} [${1}]" || true -} - -# Bury a package deeper in the tree -# $1 pkgbase -# $2 nextdepth -bury() { -# Bury only if we are going to build the dep -# Get it's current depth and dir name - local current_depth=$(grep "build;[0-9]\+;${1};" "${BUILDORDER}" | cut -d ';' -f 2) - local current_name="$(printf "%03d" ${current_depth})_${1}" - -# If there's a depth or the package is not the root of the build tree (which -# can lead to funny chicken-and-egg problems), update the depth to the current -# package next-depth and rename the dir too - if [ -z "${current_depth}" ]; then return; fi - if [ -z "${current_name}" ]; then return; fi - if [ ${current_depth} -eq 0 ]; then return; fi - if [ ${current_depth} -ge $2 ]; then return; fi - - ${VERBOSE} && msg "Burying ${1} from ${current_depth} to ${2}" - - { - sed -i "s|^\(build;\)\([0-9]\+\)\(;${1};.*\)$|\1${2}\3|" "${BUILDORDER}" && \ - mv "${BUILDDIR}/${current_name}" "${BUILDDIR}/$(printf "%03d" ${2})_${1}" - } || return 1 -} - -# Guess the repo from the pkgbase path -# $1 path, pwd or toru-where -guess_repo() { - basename "$(dirname "${1}")" -} - -if [ ! -f PKGBUILD ]; then - error "Missing PKGBUILD ($PWD)" - exit 1 -fi - -if ! source PKGBUILD ; then - error "Can't source PKGBUILD" - exit 1 -fi - -# Save resources -unset pkgdesc arch license groups backup install md5sums sha1sums \ - sha256sums source options >/dev/null 2>&1 - -unset build package >/dev/null 2>&1 - -for _pkg in ${pkgname[@]}; do - unset package_${_pkg} >/dev/null 2>&1 || true -done -## - -# Get useful values -pkgbase="${pkgbase:-${pkgname[0]}}" -fullver=$(get_fullver ${epoch:-0} ${pkgver} ${pkgrel}) - -# Get or set the work dir -BUILDDIR="${1:-$(mktemp -d /tmp/${pkgbase}-treepkg-XXXx)}" -BUILDORDER="${BUILDDIR}/BUILDORDER" -DEPTH=${2:-0} -NEXTDEPTH=$((${DEPTH} + 1)) -# This can be set as env vars (ie: $ V=false B=false treepkg) -# TODO Turn into flags? -VERBOSE=${V:-true} -BUILD=${B:-true} -CLEANUP=${C:-true} -# Skip BUILDORDER creation and build anything on BUILDDIR -BUILDNOW=${N:-false} -IGNORE=${I} - -if [ ! -z "${1}" -a ${DEPTH} -eq 0 ]; then - BUILDNOW=true -fi - -if ! ${BUILDNOW}; then -# ensure it exists - touch "${BUILDORDER}" - -# If this package is already built quit silently - for _pkg in ${pkgname[@]}; do - - echo "${IGNORE[@]}" | grep -q ${_pkg} && { - add_order "ignore" - exit 0 - } - - if is_built "${_pkg}" "${fullver}"; then - add_order "ignore" - exit 0 - fi - done - -# Ignore if already in build order - egrep -q ";${pkgbase};" "${BUILDORDER}" && exit 0 - -# Add pkgbase to build order - add_order "build" - -# Copy the directory to the build dir -# TODO run makepkg --source to avoid moving garbage around? - cp -r "${PWD}" "${BUILDDIR}/$(printf "%03d" ${DEPTH})_${pkgbase}" - -# Cleanup dep versioning - deps=($(echo "${depends[@]} ${makedepends[@]}" | \ - sed "s/[=<>]\+[^ ]\+//g" | \ - tr ' ' "\n" | \ - sort -u)) - -# NOTE: getting depends from package() is a PITA - for _dep in ${deps[@]}; do -# Move deps deeper in the tree if -# pkgbase - dep1 -# \ dep2 - dep1 -# dep1 should be depth + 1 - egrep -q ";${_dep};" "${BUILDORDER}" && bury "${_dep}" ${NEXTDEPTH} - -# Ask toru where's a PKGBUILD - depdir="$(toru-where ${_dep})" - - if [ -z "${depdir}" -o ! -d "${depdir}" ]; then -# We specify the pkgname because we can't source the dep PKGBUILD -# Normally 'any' packages are missing from our work ABS - add_order "missing" "${_dep}" - continue - fi - - pushd "${depdir}" >/dev/null - -# Run itself over dependencies - $0 "${BUILDDIR}" ${NEXTDEPTH} - - done -# End BUILD now -fi - -# Only build at the end -if [ ${DEPTH} -eq 0 ]; then - ${VERBOSE} && msg "Starting build" || true - - if ${BUILD}; then - ${VERBOSE} && msg "Build tree stored in ${BUILDORDER}" || true - -# Build everything sorting the build dir -# The reverse order ensures we start by the deepest packages - for _pkg in $(ls -r "${BUILDDIR}"); do -# Ignore if there's no PKGBUILD - if [ ! -f "${BUILDDIR}/${_pkg}/PKGBUILD" ]; then continue; fi -# Skip if already built (faster than calling is_build again) - if [ -f "${BUILDDIR}/${_pkg}/built_ok" ]; then continue; fi - - ${VERBOSE} && msg "Building ${_pkg/_/ }" || true - -# Remove leading zeros and space if any - term_title "$(echo ${_pkg/_/ } | sed "s/^0\+ \?//")" - -# Run build command - pushd "${BUILDDIR}/${_pkg}" >/dev/null - sudo -E pacman -Syu --noconfirm - - ${HOOKPREBUILD} - - ${FULLBUILDCMD} -# Run local release hook with $1 = $repo - ${HOOKLOCALRELEASE} $(egrep ";${_pkg#*_};" "${BUILDORDER}" | cut -d';' -f6) - - touch built_ok - popd >/dev/null - done - - else -# Just print the working dir - ${VERBOSE} || echo "${BUILDORDER}" || true - fi - -if (( CLEANUP )) ; then - msg2 "Removing ${BUILDDIR}" - rm -rf "${BUILDDIR}" -fi - -fi - -term_title "done" -exit $? diff --git a/update-cleansystem b/update-cleansystem deleted file mode 100755 index 6bec742..0000000 --- a/update-cleansystem +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -# Updates the cleansystem file -# Creates a fake Parabola root and writes to cleansystem all -# packages installable from base and base-devel plus extras. - -set -e -# Copyright 2012 Nicolás Reynolds, Luke Shumaker - -# ---------- GNU General Public License 3 ---------- - -# 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 -e - -# libretools.conf gives us libremessages -source /etc/libretools.conf - -cleansystem=/etc/libretools.d/cleansystem - -cmd=${0##*/} -usage() { - echo "Usage: $cmd [<EXTRA_PACKAGES>]" - echo " $cmd -h" - echo "Creates a fake Parabola root and writes to \`$cleansystem' all" - echo "packages installable from base and base-devel plus extras." - echo '' - echo 'Options:' - echo ' -h Show this message' -} - -if [ "$1" == '-h' ]; then - usage - exit 0 -fi - -if [ ! -w "$cleansystem" ]; then - error 'This script must be run as root' - exit 1 -fi - -# Maintain a clean database in the system -db_dir="${DB:-/var/lib/libretools/clean}" -[ ! -d "${db_dir}" ] && mkdir -p "${db_dir}" - -# We sync first because updating info gets printed to stdout too -pacman -b "${db_dir}" --config /etc/pacman.conf -Sy 2>/dev/null -pacman -b "${db_dir}" \ - --config /etc/pacman.conf \ - -Sp --print-format "%n" \ - base base-devel sudo $@ | sort > "$cleansystem" - -# Ensures everything's installed -pacman -Sy --needed --noconfirm base base-devel sudo $@ - -exit $? diff --git a/updateabslibre b/updateabslibre deleted file mode 100755 index 76f964a..0000000 --- a/updateabslibre +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -# UpdateABSLibre -# Updates the ABSLibre git repo - -# Copyright 2010 Nicolás Reynolds - -# ---------- GNU General Public License 3 ---------- - -# 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/>. - -source /etc/libretools.conf -custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf -[[ -e $custom_config ]] && source $custom_config - -# Send every output to /dev/null - -msg "Updating ABSLibre..." - -pushd ${WORKDIR}/abslibre ${stdnull} - git pull ${ABSLIBREGIT} || { - error "Failed pull" - exit 1 -} -stdnull "popd" - -exit 0 |