summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HACKING.md223
-rw-r--r--INSTALL119
-rw-r--r--Makefile10
-rw-r--r--common.mk40
-rw-r--r--doc/treepkg.md10
-rw-r--r--doc/workflows.md4
-rwxr-xr-xsrc/abslibre-tools/createworkdir54
-rwxr-xr-xsrc/abslibre-tools/diff-unfree22
-rwxr-xr-xsrc/abslibre-tools/libreaddiff18
-rwxr-xr-xsrc/abslibre-tools/librerelease215
-rwxr-xr-xsrc/abslibre-tools/librestage61
-rwxr-xr-xsrc/aur69
-rw-r--r--src/chroot-tools/Makefile21
-rwxr-xr-xsrc/chroot-tools/chcleanup13
-rwxr-xr-xsrc/chroot-tools/distcc-tool16
-rw-r--r--src/chroot-tools/hooks-chcleanup.sh7
-rw-r--r--src/chroot-tools/hooks-check.sh25
-rw-r--r--src/chroot-tools/hooks-distcc.sh2
-rwxr-xr-xsrc/chroot-tools/indent35
-rwxr-xr-xsrc/chroot-tools/librechroot132
-rwxr-xr-xsrc/chroot-tools/libremakepkg146
-rw-r--r--src/chroot-tools/makechrootpkg.sh.patch120
-rw-r--r--src/fullpkg/Makefile2
-rwxr-xr-xsrc/fullpkg/fullpkg37
-rwxr-xr-xsrc/fullpkg/fullpkg-build180
-rwxr-xr-xsrc/fullpkg/fullpkg-find328
-rw-r--r--src/gitget/Makefile (renamed from src/libregit/Makefile)0
-rwxr-xr-xsrc/gitget/gitget220
-rwxr-xr-xsrc/gitget/libregit40
-rwxr-xr-xsrc/is_built21
-rw-r--r--src/lib/Makefile25
l---------src/lib/blacklist.sh.3.ronn1
-rw-r--r--src/lib/common.sh.3.ronn16
-rw-r--r--src/lib/common.sh.top10
-rw-r--r--src/lib/conf.sh49
-rw-r--r--src/lib/conf.sh.3.ronn128
-rwxr-xr-xsrc/lib/libreblacklist12
-rw-r--r--src/lib/libreblacklist.1.ronn23
-rwxr-xr-xsrc/lib/librelib39
-rw-r--r--src/lib/librelib.1.ronn55
-rw-r--r--src/lib/librelib.7.ronn50
-rwxr-xr-xsrc/lib/libremessages43
-rw-r--r--src/lib/libremessages.1.ronn220
l---------src/lib/messages.sh.3.ronn1
-rwxr-xr-xsrc/librefetch/librefetch212
-rw-r--r--src/librefetch/librefetch.8.ronn55
-rw-r--r--src/librefetch/librefetch.conf5
-rw-r--r--src/librefetch/librefetch.conf.5.ronn16
-rwxr-xr-xsrc/libregit/libregit74
-rw-r--r--src/libretools.conf14
-rwxr-xr-xsrc/mips64el-tools/mipsrelease2
-rwxr-xr-xsrc/pkgbuild-check-licenses126
-rwxr-xr-xsrc/pkgbuild-check-nonfree309
-rwxr-xr-xsrc/pkgbuild-summarize-nonfree88
-rwxr-xr-xsrc/treepkg40
-rw-r--r--test/aur-test.sh8
-rw-r--r--test/is_built-test.sh28
-rw-r--r--test/lib-blacklist-test.sh34
-rw-r--r--test/lib-conf-test.sh2
-rw-r--r--test/lib-messages-test.sh8
-rw-r--r--test/librechroot-test.sh79
-rw-r--r--test/librefetch-test.sh48
-rw-r--r--test/librefetch.d/PKGBUILD15
-rw-r--r--test/librefetch.d/list.txt2
-rw-r--r--test/librelib-test.sh12
-rw-r--r--test/libremakepkg-test.sh78
-rw-r--r--test/libremakepkg.d/PKGBUILD-netbuild17
-rw-r--r--test/libremakepkg.d/PKGBUILD-netpackage12
-rw-r--r--test/libremakepkg.d/PKGBUILD-netprepare17
-rw-r--r--test/libremakepkg.d/PKGBUILD-testpkg119
-rw-r--r--test/libremakepkg.d/PKGBUILD-testpkg219
-rw-r--r--test/librerelease-test.sh56
-rw-r--r--test/librestage-test.sh12
-rw-r--r--test/pkgbuild-check-licenses-test.sh27
-rw-r--r--test/pkgbuild-check-nonfree-test.sh31
-rw-r--r--test/test-common.sh44
-rwxr-xr-xtest/testenv5
77 files changed, 3158 insertions, 1218 deletions
diff --git a/HACKING.md b/HACKING.md
new file mode 100644
index 0000000..ebe595b
--- /dev/null
+++ b/HACKING.md
@@ -0,0 +1,223 @@
+This document is a little all over the place--I've been working on it
+for a while, but I keep refactoring it as I move pieces of it into man
+pages and whatnot. It's mostly a brain dump, sorry.
+
+There are three parts to this; procedures, "content" guidelines and
+"style" guidelines. The style guidelines are less strict; as long as
+things are consistent at the file-level, I'm pretty happy.
+
+Contributing
+============
+
+I'd love to have your patches! Code should be hackable; if you want
+to modify something, but can't figure out how: 1) ping me for help, 2)
+it probably means the code was too complicated in the first place.
+
+Patches should be sent to <dev@lists.parabolagnulinux.org>; please put
+"[PATCH]" and "libretools" in the subject line. If you have commit
+access, but want me to look over it first, feel free to create a new
+branch in git, and I will notice it. Try to avoid pushing to the
+"master" branch unless it's a trivial change; it makes it easier to
+review things; though I *will* look over every commit before I do a
+release, so don't think you can sneak something in :)
+
+I'd love to discuss possible changes on IRC (I'm lukeshu), either on
+irc.freenode.net#parabola or in personal messages. My account may be
+online even if I'm not; I will eventually see your it, I do a search
+for mentions of "luke" on #parabola every time I get on.
+
+Code content
+============
+
+Be aware of the `librelib(7)` library suite, which lives `src/lib`.
+It is a suite of Bash libraries that will help you out. Most of the
+people looking at the libretools code are familiar with the `messages`
+part of it, which actually contains a much of utility routines, not
+just message printing. There is also a library for dealing with
+`blacklist.txt`, and one for loading configuration files and
+PKGBUILDs. These are common tasks, but are tricky to handle
+consistently--the libraries are there to make things easier. Take a
+look at the man pages.
+
+Message printing: All of the message printing routines, except for
+`term_title` and `flag`, take printf-type arguments. Take advantage
+of that; don't use string interpolation (don't do `"foo ${var}
+bar"`). The reason for this is that if you don't do string
+interpolation, messages can be automatically internationalized.
+(Internationalization is incomplete at the momement)
+
+Message printing: The in `--help`/`-h` text, use `print` to print
+lines that should not wrap, `echo` to print blank lines, `prose` to
+print paragraphs, `bullet` to print bullet points, and `flag` to print
+option flags. The text should follow this general format:
+
+ print "Usage: %s [OPTIONS] VARS_ARE_UNDERSCORE_AND_CAPITAL" "${program_name}"
+ print "One line description of program, no period"
+ echo
+ prose "More details. This is a paragraph."
+ echo
+ print "Options:"
+ flag "-h" "Show this message"
+
+In the "Usage:" line, use printf `%s` and the value `"${0##*/}"` to
+determine the program name at runtime.
+
+There used to be guidelines for how to align the option flags and
+descriptions, but now the `flag` command exists takes care of it for
+you. Yay for things being easier!
+
+When using `set -u`, `set -e`, or `trap`, you should also use `set -E`
+to have the error handling be passed down to subshells.
+
+Feel free to use `set -e` (fail on error), but be careful of the
+caveats (there are a bunch of them); don't assume all errors are
+checked because of it.
+
+Use `set -u` if you can; it makes using an unset variable an error.
+ - If a variable not being set is valid (perhaps a configuration
+ option), use `${var:-}` when accessing it to suppress the error.
+ - An empty array counts as unset, so if you have an array that may be
+ empty, use `set +u` before accessing it.
+ - The reason for this is that a normal string variable is basically
+ an array with length=1; an unset variable looks like an array
+ with length=0. Weird stuff.
+
+In the shebang, use `#!/usr/bin/env bash`. This allows us to not
+hardcode the location of bash (I'm not sure why this is useful for
+something distro-dependent like libretools, but fauno seems to have a
+use-case for it).
+
+In the shebang, don't pass flags to bash, besides breaking `env`
+(above), it means people will make mistakes when debugging, and
+running things with `bash FILENAME`. Instead, use `set` to adjust the
+flags inside of the program.
+
+Obey `$TMPDIR`. It's usually as easy as passing `--tmpdir` to
+`mktemp`.
+
+Use `trap` to clean up your temporary files. This way, even if your
+program terminates early, things will be cleaned up.
+
+Bash best practices
+===================
+
+Basically, know what you are doing, and be safe with it. The problem
+is that most people don't know about safe bash scripting.
+
+A lot of people look at the "Advanced Bash Scripting" ebook--DO NOT do
+that, it is trash... though it contains a "reference card" page that
+may be useful and isn't trash.
+
+Take a look at Gentoo's Bash guidelines
+<http://devmanual.gentoo.org/tools-reference/bash/index.html>.
+They're pretty good, and cover most of the "gotcha's" about Bash
+syntax. It mentions but discourages the use of Bash 3
+features... why? Who still uses Bash 2? Feel free to use Bash 4
+features!
+
+I wrote an article on Bash arrays
+<https://lukeshu.com/blog/bash-arrays.html>. A lot of people think
+they're tricky, but they're simple once you know how they work. It's
+short enough that you should read the whole thing. Know the
+difference between `"${array[@]}"` and `"${array[*]}"`. And I'll say
+it again here, ALWAYS wrap those in double quotes; there is no reason
+I can think of that the unquoted behavior would ever be the correct
+thing.
+
+My brief rules of thumb:
+
+ - Quote every variable.
+ - That includes arrays: `"${array[@]}"` and `"${array[*]}"`.
+ - In most (but not all!) cases inside of `[[ ... ]]` conditions,
+ variables don't need to be quoted. When in doubt, quote them.
+ - When assigning one variable to another, you don't need quotes;
+ you don't need quotes for `foo=$bar`
+ - Try to avoid global variables; declare all variables in functions
+ with `local`.
+ - Or `declare`; inside of a function, unless you pass the `-g`
+ flag, `declare` makes the variable local.
+ - Use `local VAR` before a `for VAR in LIST` loop--the variable is created in the
+ current scope, not the scope of the loop.
+ - Feeding input to `while` loops is weird because of how subshells
+ work:
+
+ # Input from a file
+ # BAD
+ cat file | while read line; do
+ ...
+ done
+ # GOOD
+ while read line; do
+ ...
+ done <file
+
+ # Input from a program
+ # BAD
+ prog | while read line; do
+ ...
+ done
+ # GOOD
+ while read line; do
+ ...
+ done < <(prog)
+
+
+Style guidelines
+================
+
+Unless you have a good reason, use `[[ ... ]]` instead of `[ ... ]`;
+they work similarly, but `[[ ... ]]` is sometimes more readable (fine,
+rarely, but never less), and is harder to make mistakes with quoting,
+because it is syntactic magic, as opposed to `[ ... ]` which is an
+executable which just happens to be implemented as a builtin.
+
+Use a litteral tab for indent. When indenting line-wrapped text, such
+as that for `prose`, do it like this: (» indicates tab, · indicates
+space)
+
+ func() {
+ » prose "This is the first line. This paragraph is going to be
+ » ·······wrapped."
+ }
+
+The `; then` and `; do` should go on the same line as
+`if`/`elif`/`for`/`while`. Also, there is no space before the `;`.
+
+Prefer the `for VAR in LIST` syntax over the `for ((init; cond; inc))`
+syntax, when possible. For example (heh, `for` example):
+
+ local i
+ for (( i = 1 ; i <= 10 ; i++ )); do
+
+should be
+
+ local i
+ for i in {1..10}; do
+
+Of course, if the upper bound is a variable, the C-like syntax is
+the better option, as otherwise you would have to use `seq` (calling
+an external), or `eval` (gross, easy to mess up royally).
+
+Indent comments like you would code; don't leave them at the beginning
+of the line. Example:
+
+ for item in "${list[@]}"; do
+ if [[ $item == foo ]]; then
+ # BAD
+ foobar
+ fi
+ if [[ $item == bar ]]; then
+ # GOOD
+ barbaz
+ fi
+ done
+
+Fauno, I'm sorry. But I don't know how you can read your own code :P.
+
+Some people argue in favor of the useless use of cat, because data
+should flow from left to right. However, the input redirection
+doesn't have to go on the right side of a command:
+
+ cat file | program # useless use of cat
+ program < file # data flows right to left
+ < file program # just right
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..f25c466
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,119 @@
+Installation of libretools is pretty straight-forward. The only
+tricky thing is the weird dependence on the devtools-par source code.
+
+The build system will by default look at `$(topdir)/../devtools-par`
+for the devtools-par source code. This can be changed by adjusting
+the `devtoolsdir` configuration variable, see "Configuration" below.
+
+Once you have the devtools source taken care of, you can have the
+default everything-included install by running:
+
+ $ make
+ # make install
+
+Dependencies
+------------
+
+Unlike a lot of software, run-time dependencies are not required at
+build-time.
+
+Libretools is mostly shell scripts. It very specifically targets
+Parabola GNU/Linux-libre; there are a lot of dependencies, most of
+which are undocumented. Switching away from a GNU user-land is bound
+to cause issues.
+
+## Build dependencies
+
+The "unusual" build-time dependencies are:
+
+ - GNU Make -- other `make`s will not work.
+ - GNU sed -- must support `-r` for ERE; BSD sed uses `-E` for this purpose.
+ - Emacs -- `emacs --batch` is used use Emacs Lisp to process some text.
+ - ronn -- A markdown-to-manpage converter
+
+At this time, the build system dos not support not building the
+documentation; ronn is required.
+
+Additionally, other usual "core utilities" are required:
+
+ cat, chmod, cp, echo, false, find, install, ln, msguniq, rm, tr,
+ xgettext
+
+Also, `/bin/sh` must support `{brace,expansion}`. If it doesn't, find
+a shell that does, and configure `make` to use it. Though, because
+libretools is mostly shell scripts, if you deviate too much from a GNU
+command-line environment, I suspect that you will run into more
+issues. If I were targeting anything other than Parabola, this would
+be a bigger issue.
+
+## Test suite dependencies
+
+If you wish to run the test suite, you will need the "roundup" shell
+unit testing program. On Parabola GNU/Linux-libre it is called
+"sh-roundup". If your operating system doesn't have it, it is
+available at <http://bmizerany.github.io/roundup/>.
+
+## Run-time dependencies
+
+Being mostly shell scripts, many external program are used. Anything
+that is included when installing the `base` package group on Parabola
+GNU/Linux, I consider an implicit dependency. If something isn't used
+now, that doesn't mean it won't be in the future.
+
+On top of that, the following dependencies are also needed:
+
+librelib subpackage:
+ - wget
+gitget subpackage:
+ - librelib (provided)
+ - git
+main libretools subpackage:
+ - librelib (provided)
+ - gitget (provided, only needed for `createworkdir`)
+ - arch-install-scripts
+ - ssh client (OpenSSH, only needed for `librerelease`
+ - rsync
+ - subversion
+ - tokyocabinet
+libretools-mips64el subpackage:
+ - libretools (provided)
+ - git
+
+Configuration
+-------------
+
+This is not a GNU package, there is no `./configure` script.
+
+There are two ways to set configuration variables:
+ 1. Edit config.mk
+ 2. Pass `VARIABLE=VALUE` to `make`
+
+The configuration variables mostly match GNU packages, but default
+values differ; libretools installs to `prefix=/usr` by default instead
+of GNU's `prefix=/usr/local`.
+
+Building and installing subpackages
+-----------------------------------
+
+There are several subpackages you can build and install. This is done
+by running:
+
+ $ make build-${package}
+ # make install-${package}
+
+respectively. In addition to `build` and `install`, the activities
+you can do are:
+
+ - `copy` -- copy necessary files from the devtools-par source code
+ - `build` -- build all programs and files
+ - `install` -- install everything
+ - `clean` -- remove generated files
+ - `pot` -- generate gettext portable object template files.
+
+The subpackages you can run these on are:
+
+ - doc -- The non-manpage documentation
+ - libretools -- The main libretools package
+ - libretools-mips64el -- Programs useful for porting to mips64el
+ - librelib -- generic libraries included
+ - gitget -- A git downloader
diff --git a/Makefile b/Makefile
index 27139ae..feff83f 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ include config.mk
################################################################################
# these are the resulting packages
-packages=doc libretools libretools-mips64el librelib libregit
+packages=doc libretools libretools-mips64el librelib gitget
# and which directories they contain
doc=doc
libretools=\
@@ -17,7 +17,7 @@ libretools=\
src/toru
libretools-mips64el=src/mips64el-tools
librelib=src/lib
-libregit=src/libregit
+gitget=src/gitget
################################################################################
@@ -26,23 +26,25 @@ copy: PHONY $(addprefix copy-, $(packages))
build: PHONY $(addprefix build-, $(packages))
install: PHONY $(addprefix install-,$(packages))
clean: PHONY $(addprefix clean-, $(packages))
+pot: PHONY $(addprefix pot-, $(filter-out doc,$(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
+%/pot: PHONY %
+ $(MAKE) -C $* pot
.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, $$($$*))
+$(addprefix pot-, $(packages)): pot-%: PHONY $$(addsuffix /pot, $$($$*))
################################################################################
diff --git a/common.mk b/common.mk
index 68b5d56..deb64c7 100644
--- a/common.mk
+++ b/common.mk
@@ -14,22 +14,16 @@ edit = sed -e 's|m4_include(lib/\(.*\))|. $$(librelib \1)|'
# Normalize a .po(t) file
pofmt = msguniq -Fi
+xgettext-keywords-sh += --keyword={_,print}
+xgettext-keywords-sh += --keyword={msg,msg2,warning,error,stat_busy,die}
+xgettext-keywords-sh += --keyword={lock,slock}:3
+
+xgettext-sh = xgettext --omit-header --from-code=UTF-8 -L shell -o -
+xgettext-sh-std = $(xgettext-sh) $(xgettext-keywords-sh) $^
+
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
+xgettext-sh-prose = $(xgettext-sh) -k --keyword={prose,bullet,flag:2} $^ | $(pot-remove-wrap) | $(html-whitespace-collapse) | sed '/^\#, sh-format/d'
# Usage: as a variable
# relative path to `/` from $(bindir)
@@ -61,6 +55,9 @@ install_files += $(addprefix $(DESTDIR)$(bindir)/,$(progs)) \
$(addprefix $(DESTDIR)$(mandir)/man8/,$(filter %.8,$(mans)))
clean_files += $(patsubst %.in,%,$(copy_files)) $(copy_files) $(mans) $(wildcard *.pot)
+pots += $(filter-out $(no-pots) ,$(progs))
+pot_files += $(addsuffix .pot,$(pots))
+
# Set the default target #######################################################
all: PHONY build
@@ -84,11 +81,18 @@ build: PHONY $(build_files)
ronn --html $(RONNFLAGS) < '$<' > '$@'
%: %.in
@echo "GEN $@"
- @$(edit) <"$<" >"$@" || { rm -f -- '$@'; false; }
- @chmod 755 "$@" || { rm -f -- '$@'; false; }
+ @$(edit) <"$<" >"$@"
+ @chmod 755 "$@"
+
+# Build ########################################################################
+
+pot: everything.pot
+
+everything.pot: $(pot_files)
+ cat $^ | $(pofmt) > '$@'
%.pot: %
- { $(xgettext-main); $(xgettext-prose); } | $(pofmt) > '$@'
+ { $(xgettext-sh-std); $(xgettext-sh-prose); } | $(pofmt) > '$@'
# Install ######################################################################
@@ -142,3 +146,5 @@ clean-hook: PHONY
FORCE: PHONY
PHONY:
.PHONY: FORCE PHONY
+
+.DELETE_ON_ERROR:
diff --git a/doc/treepkg.md b/doc/treepkg.md
index 7f7ece1..1e30e33 100644
--- a/doc/treepkg.md
+++ b/doc/treepkg.md
@@ -67,18 +67,18 @@ Your HOOKLOCALRELEASE script should look like this:
source PKGBUILD
unset build package check
-
+
fullver=$(full_version ${epoch:-0} ${pkgver} ${pkgrel})
pkgs=()
-
+
# Generate canonical package paths
msg "Adding packages to [stage3]..."
for name in ${pkgname[@]}; do
msg2 "${name} ${fullver}"
pkgs+=("${PKGDEST}/${name}-${fullver}-*.pkg.tar.*")
done
-
- # Add the packages to a local
+
+ # Add the packages to a local
repo-add ${PKGDEST}/stage3.db.tar.gz ${pkgs[@]}
# Stage the packages for later releasing
@@ -109,7 +109,7 @@ current one. Thus this will become the build path:
> a really long build tree with some circular dependencies you may find
> packages buried several times and queued to build before their actuals deps.
-## Tips
+## Tips
`treepkg` accepts two arguments: 1) the temporary work dir and 2) the next
depth level it should use (if current equals 0, it'll pass 1). You don't need
diff --git a/doc/workflows.md b/doc/workflows.md
index f55ae7e..fe3c12e 100644
--- a/doc/workflows.md
+++ b/doc/workflows.md
@@ -28,7 +28,7 @@ This is how the chroot is configured:
* 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:
@@ -50,7 +50,7 @@ What this allows:
* 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)
diff --git a/src/abslibre-tools/createworkdir b/src/abslibre-tools/createworkdir
index 99214ab..27b285c 100755
--- a/src/abslibre-tools/createworkdir
+++ b/src/abslibre-tools/createworkdir
@@ -1,8 +1,10 @@
#!/usr/bin/env bash
+set -euE
# CreateWorkDir
# Creates a dir structure for working with Parabola packages
-# Copyright 2010 Nicolás Reynolds
+# Copyright (C) 2010 Nicolás Reynolds
+# Copyright (C) 2013 Luke Shumaker
# ---------- GNU General Public License 3 ----------
@@ -24,41 +26,27 @@
. libremessages
. $(librelib conf.sh)
load_files libretools
-check_vars libretools WORKDIR REPOS ABSLIBREGIT || exit 1
+check_vars libretools WORKDIR REPOS ABSLIBRERECV ABSLIBRESEND
-[[ ! -d ${WORKDIR} ]] && { # Create the WORKDIR
+trap 'error "Aborting..."' EXIT
- msg "Creating WORKDIR on ${WORKDIR}"
- mkdir -p ${WORKDIR} ||{
- error "Could not create ${WORKDIR}"; exit 1
- }
+msg "Creating WORKDIR at %s..." "$WORKDIR"
+mkdir -p "$WORKDIR"
-}
+msg "Creating staging directory in WORKDIR..."
+mkdir -p "$WORKDIR/staging"
-for _repo in "${REPOS[@]}"; do # Create the staging dirs
+cmd=(gitget -f -p "$ABSLIBRESEND" checkout "$ABSLIBRERECV" "$WORKDIR/abslibre")
+if ! "${cmd[@]}"; then
+ error "Could not clone ABSLibre"
+ plain "Try running this command:"
+ echo
+ printf '%q ' "${cmd[@]}"
+ echo
+ exit 1
+fi
- [[ ! -d ${WORKDIR}/staging/${_repo} ]] && {
- mkdir -p ${WORKDIR}/staging/${_repo} || {
- error "Can't create ${WORKDIR}/staging/${_repo}"
- exit 1
- }
- }
+msg "Finished, your packaging directory tree looks like this now:"
+ls --color=always "${WORKDIR}"/*
-done
-
-[[ ! -d ${WORKDIR}/abslibre/.git ]] && {
- msg "Cloning into ABSLibre"
- CMD="git clone ${ABSLIBREGIT} ${WORKDIR}/abslibre"
- ${CMD} || {
- error "Could not clone ABSLibre"
- plain "Try running this command:"
- echo
- plain "${CMD}"
- exit 1
- }
-}
-
-msg "Finished, your packaging dir tree looks like this now:"
-ls --color=always ${WORKDIR}/*/*
-
-exit 0
+trap -- EXIT
diff --git a/src/abslibre-tools/diff-unfree b/src/abslibre-tools/diff-unfree
index 07f2ca2..af5bbe5 100755
--- a/src/abslibre-tools/diff-unfree
+++ b/src/abslibre-tools/diff-unfree
@@ -1,7 +1,7 @@
#!/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
+# Copyright (C) 2010 Nicolás Reynolds
# ---------- GNU General Public License 3 ----------
@@ -23,16 +23,14 @@
. libremessages
. $(librelib conf.sh)
load_files libretools
-check_vars libretools DIFFTOOL || exit 1
-
-cmd=${0##*/}
+check_vars libretools DIFFPROG || exit 1
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."
+ print "Usage: %s [community|packages] [unfree-package] [repo]" "${0##*/}"
+ print "Usage: %s --help" "${0##*/}"
+ prose "Helps you diff build scripts from ABSLibre against (Unfree) ABS."
+ echo
+ prose "Package name and repo will we guessed if you don't specify them."
}
main() {
@@ -68,7 +66,7 @@ main() {
pushd "${tmp_dir}" &>/dev/null
- msg "Getting diff from $repo/$package..."
+ msg "Getting diff from %s..." "$repo/$package"
svn checkout --depth=empty svn://svn.archlinux.org/$svnrepo &>/dev/null
@@ -81,8 +79,8 @@ main() {
msg "Diffing files"
for _file in ${unfree_dir}/*; do
- msg2 "$(basename "${_file}")"
- ${DIFFTOOL} "$PWD/$(basename "${_file}")" "${_file}"
+ msg2 "%s" "$(basename "${_file}")"
+ ${DIFFPROG} "$PWD/$(basename "${_file}")" "${_file}"
done
}
diff --git a/src/abslibre-tools/libreaddiff b/src/abslibre-tools/libreaddiff
index 03d0ad0..ebd749d 100755
--- a/src/abslibre-tools/libreaddiff
+++ b/src/abslibre-tools/libreaddiff
@@ -23,10 +23,12 @@ check_vars libretools WORKDIR
for arg in "$@" ; do
case "$arg" in
-h|--h|--he|--hel|--help|-\?)
- echo 'Usage: libreaddiff repo [arch]
-
-This script outputs a diff of package names and versions in repo
-between pacman'\''s sync db and abslibre checkout.' >&2
+ {
+ print 'Usage: %s repo [arch]' "${0##*/}"
+ echo
+ prose "This script outputs a diff of package names and versions
+ in repo between pacman's sync db and abslibre checkout."
+ } >&2
exit 0
;;
esac
@@ -72,14 +74,14 @@ except StopIteration:
load_PKGBUILD "$f/PKGBUILD" || continue
is_here=false
for arc in ${arch[@]} ; do
- if [ "$arc" = "any" -o "$arc" = "$CARCH" ] ; then
+ if [[ "$arc" == "any" ]] || [[ "$arc" == "$CARCH" ]] ; then
is_here=true
break
fi
done
- if [ "$is_here" = "true" ] ; then
- for name in ${pkgname[@]} ; do
- if [ -z "$epoch" ] ; then
+ if [[ "$is_here" == "true" ]] ; then
+ for name in "${pkgname[@]}" ; do
+ if [[ -z "$epoch" ]] ; then
echo $name-$pkgver-$pkgrel
else
echo $name-$epoch:$pkgver-$pkgrel
diff --git a/src/abslibre-tools/librerelease b/src/abslibre-tools/librerelease
index 5913670..8b1e05f 100755
--- a/src/abslibre-tools/librerelease
+++ b/src/abslibre-tools/librerelease
@@ -2,23 +2,23 @@
# Librerelease
# Uploads packages into [staging]
-# Copyright 2010 Nicolás Reynolds
-# Copyright 2013 Luke Shumaker
+# Copyright (C) 2010 Nicolás Reynolds
+# Copyright (C) 2013-2014 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>
+# 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.
#
@@ -38,25 +38,24 @@
. 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
+dryrun=""
+upload_only=false
+readonly rsync_flags=(
+ --no-group
+ --no-perms
+ --copy-links
+ --hard-links
+ --partial
+ --human-readable
+ --progress
+ -e ssh
+)
+
+# Functions ####################################################################
+
+list0_files() {
+ find -L "${WORKDIR}/staging" -type f \
+ -exec realpath -z --relative-to="${WORKDIR}/staging" {} +
}
# This function is taken almost verbatim from makepkg
@@ -70,7 +69,7 @@ create_signature() {
SIGNWITHKEY="-u ${GPGKEY}"
fi
# The signature will be generated directly in ascii-friendly format
- gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$?
+ gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" || ret=$?
if (( ! ret )); then
@@ -81,67 +80,81 @@ create_signature() {
fi
}
-function sign_packages {
- if [ -z "${GPG_AGENT_INFO}" ]; then
- warning "It's better to use gpg-agent to sign packages in batches"
+sign_packages() {
+ if [[ -z "${GPG_AGENT_INFO}" ]]; then
+ warning "It's better to have \`%s\` running to sign packages in batches" 'gpg-agent --daemon'
fi
- for package in $(find "${WORKDIR}/staging/" -type f -iname '*.pkg.tar.?z'); do
- if [ -f "${package}.sig" ]; then
- msg2 "Package signature found, verifying..."
+ for file in $(find "${WORKDIR}/staging/" -type f -not -iname '*.sig'); do
+ if [[ -f "${file}.sig" ]]; then
+ msg2 "File signature found, verifying..."
# Verify that the signature is correct, else remove for re-signing
- if ! gpg --quiet --verify "${package}.sig" >/dev/null 2>&1; then
+ if ! gpg --quiet --verify "${file}.sig" >/dev/null 2>&1; then
error "Failed! Re-signing..."
- rm -f "${package}.sig"
+ rm -f "${file}.sig"
fi
fi
- if ! [ -f "${package}.sig" ]; then
- create_signature "$package" || return 2
+ if ! [[ -f "${file}.sig" ]]; then
+ create_signature "$file" || 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 {
+clean_files() {
+ local file_list=$1
+
+ local rmcmd=(rm -fv)
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 {} +
+ rmcmd=(printf "$(_ "removed '%s' (dry-run)")\n")
fi
+
+ msg "Removing files from local staging directory"
+ cd "${WORKDIR}/staging" && xargs -0r -a "$file_list" "${rmcmd[@]}"
+ cd "${WORKDIR}/staging" && find . -mindepth 1 -type d -empty \
+ -exec rmdir -p {} + 2>/dev/null
}
-function main {
- if [ -w / ]; then
+################################################################################
+
+usage() {
+ print "Usage: %s [OPTIONS]" "${0##*/}"
+ echo
+ prose 'This script uploads packages on $WORKDIR/stagging
+ to parabola server.'
+ echo
+ print "Options:"
+ flag '-c' 'Clean; delete packages in $WORKDIR/staging'
+ flag '-l' "List; list packages but not upload them"
+ flag '-u' "Upload-only; do not run db-update on the server"
+
+ flag '-n' "Dry-run; don't actually do anything"
+ flag '-h' "Show this message"
+}
+
+main() {
+ if [[ -w / ]]; then
error "This program should be run as regular user"
return 1
fi
# Parse options
- local dryrun=""
local mode="release_packages"
- while getopts 'clnh' arg; do
+ while getopts 'clunh' arg; do
case $arg in
c) mode=clean ;;
- l) mode=list_packages ;;
+ l) mode=pretty_print_packages ;;
+ u) upload_only=true ;;
n) dryrun="--dry-run" ;;
h) mode=usage ;;
- *) usage >/dev/stderr; return 1 ;;
+ *) usage >&2; return 1 ;;
esac
done
shift $(($OPTIND - 1))
if [[ $# != 0 ]]; then
- usage >/dev/stderr
+ usage >&2
return 1
fi
@@ -154,41 +167,66 @@ function main {
check_vars makepkg GPGKEY
load_files libretools
check_vars libretools WORKDIR REPODEST || return 1
- # The following variables are actually optional
+ REPODEST+='/staging/'
+ # The following settings 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 {
+# The different modes (sans 'usage') ###########################################
+
+pretty_print_packages() {
+ find "$WORKDIR/staging/" -mindepth 1 -maxdepth 1 -type d -not -empty | sort |
+ while read -r path; do
+ msg2 "${path##*/}"
+ cd "$path"
+ find -L . -type f | sed 's|^\./| |' | sort
+ done
+}
+
+clean() {
+ lock 10 "${WORKDIR}/staging.lock" \
+ 'Waiting for an exclusive lock on the staging directory'
+
+ local file_list="$(mktemp -t ${0##*/}.XXXXXXXXXX)"
+ trap "$(printf 'rm -f -- %q' "$file_list")" EXIT
+ list0_files > "$file_list"
+
+ lock_close 10
+
+ clean_files "$file_list"
+}
+
+release_packages() {
if [[ -n $HOOKPRERELEASE ]]; then
msg "Running HOOKPRERELEASE..."
+ plain '%s' "${HOOKPRERELEASE}"
bash -c "${HOOKPRERELEASE}"
fi
- clean_non_packages
+ lock 10 "${WORKDIR}/staging.lock" \
+ 'Waiting for an exclusive lock on the staging directory'
+
sign_packages || return 1
# Make the permissions of the packages 644 otherwise the user will get access
# denied error when they try to download (rsync --no-perms doesn't seem to
# work).
- find ${WORKDIR}/staging -type f -exec chmod 644 {} \;
- find ${WORKDIR}/staging -type d -exec chmod 755 {} \;
+ find ${WORKDIR}/staging -type f -exec chmod 644 {} +
+ find ${WORKDIR}/staging -type d -exec chmod 755 {} +
+
+ local file_list="$(mktemp -t ${0##*/}.XXXXXXXXXX)"
+ trap "$(printf 'rm -f -- %q' "$file_list")" EXIT
+ list0_files > "$file_list"
- msg "%s to upload" $(du -h -d 0 ${WORKDIR}/staging | tr "\t" " " | cut -d" " -f1)
+ lock_close 10
+
+ msg "%s to upload" "$(cd "${WORKDIR}/staging" && du -hc --files0-from="$file_list" | sed -n '$s/\t.*//p')"
msg "Uploading packages..."
- if ! rsync --recursive \
- ${dryrun} \
- --no-group \
- --no-perms \
- --copy-links \
- --hard-links \
- --partial \
- --prune-empty-dirs \
- --human-readable \
- --progress \
- -e "ssh " \
+ xargs -0r -a "$file_list" dirname -z | ssh ${REPODEST%%:*} "$(printf 'mkdir -p -- %q && cd %q && xargs -0r mkdir -pv --' "${REPODEST#*:}" "${REPODEST#*:}")"
+ if ! rsync ${dryrun} "${rsync_flags[@]}" \
+ -0 --files-from="$file_list" \
${WORKDIR}/staging \
${REPODEST}/
then
@@ -196,13 +234,18 @@ function release_packages {
return 1
fi
- clean
+ clean_files "$file_list"
+
+ if $upload_only; then
+ return 0
+ fi
msg "Running db-update on repos"
- ssh ${REPODEST%%:*} dbscripts/db-update
+ ssh ${REPODEST%%:*} "$(printf 'STAGING=%q dbscripts/db-update' "${REPODEST#*:}")"
if [[ -n $HOOKPOSTRELEASE ]]; then
msg "Running HOOKPOSTRELEASE..."
+ plain '%s' "${HOOKPOSTRELEASE}"
bash -c "${HOOKPOSTRELEASE}"
fi
diff --git a/src/abslibre-tools/librestage b/src/abslibre-tools/librestage
index 57846fc..610de50 100755
--- a/src/abslibre-tools/librestage
+++ b/src/abslibre-tools/librestage
@@ -2,8 +2,8 @@
# LibreStage
# Prepares packages for upload
-# Copyright 2010-2011 Nicolás Reynolds
-# Copyright 2013 Luke Shumaker
+# Copyright (C) 2010-2011 Nicolás Reynolds
+# Copyright (C) 2013-2014 Luke Shumaker
#
# This file is part of Parabola.
#
@@ -23,14 +23,13 @@
. libremessages
. $(librelib conf.sh)
-cmd=${0##*/}
usage() {
- print "Usage: %s REPO [REPO2 REPO3...]" "$cmd"
+ print "Usage: %s REPO [REPO2 REPO3...]" "${0##*/}"
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."
+ prose "The package(s) are staged for the named repositories.
+ It is in general a bad idea to stage a package on multiple
+ repositories, but it supported by this tool."
}
main() {
@@ -43,12 +42,12 @@ main() {
while getopts 'h' arg; do
case $arg in
h) usage; return 0;;
- *) usage >/dev/stderr; return 1;;
+ *) usage >&2; return 1;;
esac
done
repos=("$@")
if [[ ${#repos[@]} -eq 0 ]]; then
- usage >>/dev/stderr
+ usage >&2
return 1;
fi
@@ -60,14 +59,16 @@ main() {
# Load configuration
load_files libretools
check_vars libretools WORKDIR ARCHES || return 1
- load_files makepkg # for PKGDEST, which is optional
+ load_files makepkg # for PKGDEST and SRCDEST, which are optional
+ load_files librefetch # for MIRRORS, which is optional
# Load the PKGBUILD
load_PKGBUILD
# Now for the main routine.
staged=false
- slock 10 "${WORKDIR}/staging.lock" 'Waiting for a shared lock on the staging directory'
+ 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}
@@ -79,7 +80,7 @@ main() {
pkgpath="$(readlink -f "$pkgpath")"
fi
- msg "Found ${pkgfile}"
+ msg 'Found package: %s' "${pkgfile}"
canonical="" # is empty for the first iteration, set after that
for repo in "${repos[@]}"; do
@@ -101,10 +102,44 @@ main() {
done
done
+ for netfile in "${source[@]}"; do
+ for mirror in "${MIRRORS[@]}"; do
+ srcurl=${netfile#*::}
+ if [[ "$srcurl" == "$mirror"* ]]; then
+ if [[ $netfile = *::* ]]; then
+ srcname=${netfile%%::*}
+ else
+ srcname=${netfile##*/}
+ fi
+
+ srcpath=''
+ for path in "./$srcname" "${SRCDEST:-.}/$srcname"; do
+ if [[ -f "$path" ]]; then
+ srcpath="$path"
+ break
+ fi
+ done
+ if [[ -n "$srcpath" ]]; then
+ msg "Found generated source file: %s" "$srcname"
+ dest="${WORKDIR}/staging/other/${srcurl##"$mirror"}"
+ mkdir -p -- "${dest%/*}"
+ if cp "$srcpath" "$dest"; then
+ msg2 "%s staged on [%s]" "$srcname" other
+ staged=true
+ else
+ error "Can't put %s on [%s]" "$srcname" other
+ return 1
+ fi
+ fi
+ break
+ fi
+ done
+ done
+
if $staged ; then
return 0
else
- error "No package was staged"
+ error "Nothing was staged"
return 1
fi
}
diff --git a/src/aur b/src/aur
index 08de67e..988d33f 100755
--- a/src/aur
+++ b/src/aur
@@ -1,34 +1,34 @@
#!/usr/bin/env bash
-# Copyright 2010 Joshua Ismael
-# Copyright 2010 Nicolás Reynolds
-# Copyright 2013 Luke Shumaker
+# Copyright (C) 2010 Joshua Ismael
+# Copyright (C) 2010 Nicolás Reynolds
+# Copyright (C) 2013-2014 Luke Shumaker
#
-# This file is part of Parabola.
+# 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.
+# 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/>.
+# 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 ...]"
+ print "Usage: %s [-h] PKGNAME [PKGNAME2 PKGNAME3...]" "${0##*/}"
+ print "Downloads packages from the AUR, and does basic freedom checks."
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."
+ prose "This script will download packages from AUR to the current
+ directory and check their license for nonfree issues. This does
+ not mean that they are free; they may be incorrectly labeled, or
+ have other freedom issues. It's a tool to help Parabola
+ packagers, not to help users install things directly from AUR."
}
main() {
@@ -45,7 +45,7 @@ main() {
. $(librelib conf.sh)
load_files libretools
- check_vars libretools DIFFTOOL || exit 1
+ check_vars libretools DIFFPROG || exit 1
local startdir="$(pwd)"
local missing_deps=()
@@ -88,7 +88,7 @@ main() {
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}"
+ "${DIFFPROG}" "${copy_old}/${file}" "${copy_new}/${file}"
fi
done
if $diffed; then
@@ -107,26 +107,7 @@ main() {
################################################################
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
+ pkgbuild-summarize-nonfree $?
################################################################
diff --git a/src/chroot-tools/Makefile b/src/chroot-tools/Makefile
index 0540636..97ca688 100644
--- a/src/chroot-tools/Makefile
+++ b/src/chroot-tools/Makefile
@@ -1,11 +1,13 @@
# 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
+libexecs = mkarchroot arch-nspawn distcc-tool chcleanup indent
no-progs = $(libexecs)
# These are the shell libraries we will use
libs = makechrootpkg.sh $(wildcard hooks-*.sh)
+pots = $(libexecs) $(libs)
+
pkglibexecdir = $(libexecdir)/libretools/chroot
clean_files = makechrootpkg.sh.ugly* *~
include ../../common.mk
@@ -25,20 +27,19 @@ 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; }
+ @echo 'PATCH $@ $*.patch'; patch $@ $*.patch
makechrootpkg.sh: %: %.ugly Makefile
- @echo 'EDIT < $< > $@'; $(edit) <'$<' >'$@' || { rm -f -- '$@'; false; }
- @echo 'INDENT $@'; $(call indent,$@) || { rm -f -- '$@'; false; }
+ @echo 'EDIT < $< > $@'; $(edit) <'$<' >'$@'
+ @echo 'INDENT $@'; $(call indent,$@)
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; }
+ @<'$<' $(edit) | sed -e 's|arch-nspawn|$$(librelib chroot/&)|' -e 's/pacstrap/env -i &/' >'$@'
+ @echo 'CHMOD $<'; chmod 755 "$@"
archroot: %: %.in Makefile
@echo "GEN $@"
- @$(edit) <"$<" >"$@" || { rm -f -- '$@'; false; }
- @chmod 755 "$@" || { rm -f -- '$@'; false; }
+ @$(edit) <"$<" >"$@"
+ @chmod 755 "$@"
-distcc-tool.pot: distcc-tool
- xgettext --omit-header -i --from-code=UTF-8 -L shell --keyword={error,errusage} -o $@ $<
+distcc-tool.pot: xgettext-keywords-sh+=--keyword=errusage
diff --git a/src/chroot-tools/chcleanup b/src/chroot-tools/chcleanup
index a43065b..9ad121e 100755
--- a/src/chroot-tools/chcleanup
+++ b/src/chroot-tools/chcleanup
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
set -eE
-# (c) Nicolás Reynolds <fauno@parabola.nu>
+# Copyright (C) Nicolás Reynolds <fauno@parabola.nu>
# Released under GPLv3
#
# Performs chroot cleanup smartly, it only removes the unneeded packages or
@@ -53,19 +53,18 @@ fi
source /etc/libretools.d/chroot.conf
# If we're running makepkg
-if [ -f PKGBUILD ]; then
+if [[ -f PKGBUILD ]]; then
export CARCH="$(. /etc/makepkg.conf; printf '%s' "$CARCH")"
- source PKGBUILD
+ 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."
-}
+
+# Sync the local repo with pacman
+cp /repo/repo.db /var/lib/pacman/sync/repo.db
# Setup the temporary directory
TEMPDIR="$(mktemp --tmpdir -d $(basename $0).XXXXX)"
diff --git a/src/chroot-tools/distcc-tool b/src/chroot-tools/distcc-tool
index 7633029..9f78ead 100755
--- a/src/chroot-tools/distcc-tool
+++ b/src/chroot-tools/distcc-tool
@@ -2,7 +2,7 @@
# -*- tab-width: 4; sh-basic-offset: 4 -*-
# distcc-tool
-# Copyright 2013 Luke Shumaker
+# Copyright (C) 2013-2014 Luke Shumaker
#
# This file is part of Parabola.
#
@@ -32,6 +32,8 @@ if ! type gettext &>/dev/null; then
gettext() { echo "$@"; }
fi
+q0="$(printf '%q' "$0")" # quoted $0
+
panic() {
echo "$(gettext 'panic: malformed call to internal function')" >&2
exit 1
@@ -50,7 +52,7 @@ print() {
}
usage() {
- print "Usage: $0 COMMAND [COMMAND-ARGS]"
+ print "Usage: %s COMMAND [COMMAND-ARGS]" "$q0"
print "Tool for using distcc within a networkless chroot"
echo
print "Commands:"
@@ -125,7 +127,7 @@ parse_DISTCC_HOSTS() {
*@*)
# 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`.
+ # ssh ProxyCommand being configured to use `client`.
newhosts+=("$HOSTSPEC")
;;
# GLOBAL_OPTION
@@ -135,7 +137,7 @@ parse_DISTCC_HOSTS() {
;;
# ZEROCONF
+zeroconf)
- error "%s does not support the +zeroconf option" "$0"
+ error "%s does not support the +zeroconf option" "$q0"
exit 1
;;
# TCP_HOST or OLDSTYLE_TCP_HOST
@@ -159,7 +161,7 @@ parse_DISTCC_HOSTS() {
# set up port forwaring
if $forward_ports; then
- socat TCP-LISTEN:${newport},fork SYSTEM:"$0 client $HOSTID ${PORT:-3632}" &
+ socat TCP-LISTEN:${newport},fork SYSTEM:"$q0 client $HOSTID ${PORT:-3632}" &
pids+=($!)
fi
@@ -222,8 +224,8 @@ odaemon() {
local chrootpath=$1
umask 111
- socat UNIX-LISTEN:"$chrootpath/socket",fork SYSTEM:"$0 server" &
- trap "kill -- $!; rm -f '$chrootpath/socket'" EXIT
+ socat UNIX-LISTEN:"$chrootpath/socket",fork SYSTEM:"$q0 server" &
+ trap "kill -- $!; rm -f -- $(printf '%q' "$chrootpath/socket")" EXIT
wait
}
diff --git a/src/chroot-tools/hooks-chcleanup.sh b/src/chroot-tools/hooks-chcleanup.sh
index 09e6dd9..86c872c 100644
--- a/src/chroot-tools/hooks-chcleanup.sh
+++ b/src/chroot-tools/hooks-chcleanup.sh
@@ -1,16 +1,15 @@
#!/usr/bin/env bash
set -euE
-hooks_pre_build+=("clean_chroot")
+hook_pre_build+=("clean_chroot")
clean_chroot() (
set +x
local copydir=$1
if $INCHROOT; then
- cd /build
+ cd /startdir
sudo -u nobody "$(librelib chroot/chcleanup)"
else
- librechroot -l "$copydir" clean-pkgs
+ librechroot "${librechroot_flags[@]}" 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
index e8120b8..2702f95 100644
--- a/src/chroot-tools/hooks-check.sh
+++ b/src/chroot-tools/hooks-check.sh
@@ -1,30 +1,11 @@
#!/usr/bin/env bash
set -euE
-hook_check_pkgbuild+=("check_pkgbuild_dependencies")
-check_pkgbuild_dependencies() {
+hook_check_pkgbuild+=("check_pkgbuild_nonfree")
+check_pkgbuild_nonfree() {
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
+ pkgbuild-summarize-nonfree $s
}
#hook_check_pkgbuild+=("check_pkgbuild_namcap")
diff --git a/src/chroot-tools/hooks-distcc.sh b/src/chroot-tools/hooks-distcc.sh
index 9e42242..d8d708a 100644
--- a/src/chroot-tools/hooks-distcc.sh
+++ b/src/chroot-tools/hooks-distcc.sh
@@ -75,7 +75,7 @@ distcc_stop() {
if [[ -f "$copydir/run/distcc-tool.pid" ]]; then
- odaemon=$(cat "$copydir/distcc-tool.pid")
+ odaemon=$(< "$copydir/distcc-tool.pid")
kill -- "$odaemon"
rm -f -- \
diff --git a/src/chroot-tools/indent b/src/chroot-tools/indent
new file mode 100755
index 0000000..0e2d0e0
--- /dev/null
+++ b/src/chroot-tools/indent
@@ -0,0 +1,35 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+use constant BUFFER_SIZE => 40;
+binmode(STDIN);
+binmode(STDOUT);
+
+exit(1) if ($#ARGV != 0);
+my $indent = $ARGV[0];
+
+my $print_indent = 1;
+my $buffer;
+my $size;
+my $c;
+while (1) {
+ $size = sysread(STDIN, $buffer, BUFFER_SIZE);
+ last if ($size < 1);
+ for (0..$size-1) {
+ $c = substr($buffer, $_, 1);
+ if ($c eq "\n") {
+ syswrite(STDOUT, $indent) if ($print_indent);
+ # XXX: SYSTEMD-STDOUT HACK
+ #syswrite(STDOUT, $c, 1);
+ syswrite(STDOUT, "\r\n", 2);
+ $print_indent = 1;
+ } elsif ($c eq "\r") {
+ syswrite(STDOUT, $c, 1);
+ $print_indent = 1;
+ } else {
+ syswrite(STDOUT, $indent) if ($print_indent);
+ syswrite(STDOUT, $c, 1);
+ $print_indent = 0;
+ }
+ }
+}
diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot
index 0b3ad43..051148d 100755
--- a/src/chroot-tools/librechroot
+++ b/src/chroot-tools/librechroot
@@ -2,9 +2,9 @@
set -euE
# librechroot
-# Copyright 2010 Nicolás Reynolds
-# Copyright 2011 Joshua Haase
-# Copyright 2012-2013 Luke Shumaker
+# Copyright (C) 2010 Nicolás Reynolds
+# Copyright (C) 2011 Joshua Haase
+# Copyright (C) 2012-2014 Luke Shumaker
#
# This file is part of Parabola.
#
@@ -21,10 +21,11 @@ set -euE
# 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:
+# HACKING: if a command is added or removed, it must be changed in 4 places:
# - the usage() text
# - the commands=() array
-# - the case statement in main()
+# - the case statement in main() that checks the number of arguments
+# - the case statement in main() that runs them
. $(librelib conf)
load_files chroot
@@ -88,16 +89,16 @@ usage() {
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:'
+ prose 'The current settings for the above variables 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
+ 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.
+ 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
@@ -136,8 +137,8 @@ usage() {
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'
+ as a dependency in the file `/startdir/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'
@@ -150,7 +151,7 @@ readonly commands=(
run enter clean-repo help
)
-# set $rootdir and $copydir; blank them on error
+# Print code to 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.
@@ -174,12 +175,37 @@ calculate_directories() {
declare -p copydir
}
+check_mountpoint() {
+ local file=$1
+ local mountpoint="$(df -P "$file"|sed '1d;s/.*\s//')"
+ local mountopts=($(LC_ALL=C mount|awk "{ if (\$3==\"$mountpoint\") { gsub(/[(,)]/, \" \", \$6); print \$6 } }"))
+ ! in_array nosuid "${mountopts[@]}" && ! in_array noexec "${mountopts[@]}"
+}
+
arch_nspawn_flags=()
sysd_nspawn_flags=()
arch-nspawn() {
local copydir=$1; shift
+ # XXX: SYSTEMD-STDOUT HACK
+ if [[ -t 1 ]]; then
+ cmd=("$@")
+ else
+ # This perl script is similar to `sed 's|\n|\r\n|g'`, (or, more
+ # correctly, `sed 's|$|\r|'`) but it does't line-buffer.
+ local perlcmd='
+my $size;
+my $buffer;
+while(1) {
+ $size=sysread(STDIN, $buffer, 40);
+ last if ($size < 1);
+ $buffer =~ s/\n/\r\n/g;
+ syswrite(STDOUT, $buffer);
+}'
+ cmd=(bash --noprofile --norc -c "set -o pipefail; $(printf '%q ' "$@") |& perl -e $(printf '%q' "$perlcmd")")
+ fi
+
set +u # if an array is empty, it counts as unbound
- "$_arch_nspawn" "${arch_nspawn_flags[@]}" "$copydir" "${sysd_nspawn_flags[@]}" -- "$@"
+ "$_arch_nspawn" "${arch_nspawn_flags[@]}" "$copydir" "${sysd_nspawn_flags[@]}" -- "${cmd[@]}"
set -u
}
@@ -197,22 +223,65 @@ main() {
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;;
+ *) usage >&2; return 1;;
esac
done
shift $(($OPTIND - 1))
if [[ $# -lt 1 ]]; then
error "Must specify a command"
- usage >/dev/stderr
+ usage >&2
return 1
fi
mode=$1
if ! in_array "$mode" "${commands[@]}"; then
error "Unrecognized command: %s" "$mode"
- usage >/dev/stderr
+ usage >&2
return 1
fi
shift
+ case "$mode" in
+ noop|make|sync|delete|update|enter|clean-pkgs|clean-repo)
+ if [[ $# -gt 0 ]]; then
+ error 'Command `%s` does not take any arguments: %s' "$mode" "$*"
+ usage >&2
+ return 1
+ fi
+ :;;
+ install-file)
+ if [[ $# -lt 1 ]]; then
+ error 'Command `%s` requires at least one file' "$mode"
+ usage >&2
+ return 1
+ else
+ local missing=()
+ local file
+ for file in "$@"; do
+ if ! [[ -f $file ]]; then
+ missing+=("$file")
+ fi
+ done
+ if [[ ${#missing[@]} -gt 0 ]]; then
+ error "%s: file(s) not found: %s" "$mode" "${missing[*]}"
+ return 1
+ fi
+ fi
+ :;;
+ install-name)
+ if [[ $# -lt 1 ]]; then
+ error 'Command `%s` requires at least one package name' "$mode"
+ usage >&2
+ return 1
+ fi
+ :;;
+ run)
+ if [[ $# -lt 1 ]]; then
+ error 'Command `%s` requires at least one argument' "$mode"
+ usage >&2
+ return 1
+ fi
+ :;;
+ esac
+
if [[ $mode == help ]]; then
usage
@@ -236,11 +305,28 @@ main() {
umask 0022
+ # XXX: SYSTEMD-STDIN HACK
+ if ! [[ -t 0 ]]; then
+ error "Input is not a TTY"
+ plain "https://labs.parabola.nu/issues/420"
+ plain "https://bugs.freedesktop.org/show_bug.cgi?id=70290"
+ prose "Due to a bug in systemd-nspawn, redirecting stdin is not
+ supported. We have been able to mitigate the problems
+ with redirecting stdout, but until the bug is fixed,
+ redirecting stdin will only end in pain." >&2
+ return 1
+ fi
+
# 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 ! check_mountpoint "$copydir.lock"; then
+ error "Chroot copy is mounted with nosuid or noexec options: [%s]" "$COPY"
+ return 1
+ fi
+
if [[ ! -d $rootdir ]]; then
msg "Creating 'root' copy for chroot [%s]" "$CHROOT"
set +u # if an array is empty, it counts as unbound
@@ -256,10 +342,12 @@ main() {
mkdir -p "$copydir/etc/libretools.d"
{
- if [[ -n ${CHROOTEXTRAPKG[*]:-} ]]; then
- declare -p CHROOTEXTRAPKG | sed -r 's/declare( -.)* //'
+ if [[ ${#CHROOTEXTRAPKG[*]} -eq 0 ]]; then
+ echo 'CHROOTEXTRAPKG=()'
else
- printf 'CHROOTEXTRAPKG=()\n'
+ printf 'CHROOTEXTRAPKG=('
+ printf '%q ' "${CHROOTEXTRAPKG[@]}"
+ printf ')\n'
fi
} > "$copydir"/etc/libretools.d/chroot.conf
@@ -293,15 +381,17 @@ main() {
arch-nspawn "$copydir" pacman -Sy "$@"
;;
update)
- arch-nspawn "$copydir" pacman -Syu --noconfirm
+ # umount resolv.conf so that it can be upgraded, if nescessary
+ # this disables DNS, so fetch everything first
+ arch-nspawn "$copydir" bash -c 'pacman -Syuw --noconfirm && umount /etc/resolv.conf && pacman -Su --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' \
+ 'mkdir -p /startdir' \
+ 'cd /startdir' \
'/bin/chcleanup' \
> "$copydir/chrootexec"
chmod 755 "$copydir/chrootexec"
diff --git a/src/chroot-tools/libremakepkg b/src/chroot-tools/libremakepkg
index a59315b..26080bc 100755
--- a/src/chroot-tools/libremakepkg
+++ b/src/chroot-tools/libremakepkg
@@ -2,9 +2,9 @@
set -euE
# libremakepkg
-# Copyright 2010-2011 Nicolás Reynolds
-# Copyright 2011 Joshua Ismael Haase Hernández
-# Copyright 2012-2013 Luke Shumaker
+# Copyright (C) 2010-2011 Nicolás Reynolds
+# Copyright (C) 2011 Joshua Ismael Haase Hernández
+# Copyright (C) 2012-2014 Luke Shumaker
#
# This file is part of Parabola.
#
@@ -25,15 +25,18 @@ set -euE
. $(librelib messages)
. $(librelib chroot/makechrootpkg.sh)
+set -o pipefail
shopt -s nullglob
umask 0022
# Global variables:
+readonly _indent="$(librelib chroot/indent)"
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
+# {PKG,SRC,SRCPKG,LOG}DEST set at runtime by makepkg.conf
# MAKEFLAGS, PACKAGER set at runtime by makepkg.conf
# LIBREUSER, LIBREHOME are set by conf.sh
+librechroot_flags=()
# Hooks ########################################################################
@@ -47,6 +50,25 @@ hook_check_pkg=(:)
# Boring/mundane functions #####################################################
+indent() {
+ "$_indent" ' | '
+}
+
+# Usage: _check_perms_dir $directory
+# Make sure that $directory is readable and executable (searchable) by 'nobody'
+check_directory_permissions() (
+ local dir=$1
+ # `cd` to the directory, then test `.`; that way if parent
+ # directories aren't readable, we aren't testing for that. We
+ # only need the last element in `$dir`.
+ cd "$dir"
+ if ! sudo -u nobody test -r . -a -x .; then
+ error "Directory '%s' must be readable by user 'nobody'" "$dir"
+ return 1
+ fi
+ return 0
+)
+
# Usage: exit_copy $copydir $src_owner
# End immediately, but copy log files out
exit_copy() {
@@ -62,17 +84,18 @@ exit_copy() {
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
+ "$hook" "$@" || fails+=("$hook")
+ done |& indent
+
if [[ ${#fails[@]} -gt 0 ]]; then
error "Failure(s) in %s: %s" "$hookname" "${fails[*]}"
return 1
+ else
+ return 0
fi
- return 0
}
# Usage: add_to_local_repo $copydir $pkgfiles...
@@ -88,25 +111,32 @@ add_to_local_repo() {
done
}
+hook_post_build+=('cleanup')
+cleanup() {
+ local copydir=$1
+ rm -f -- "$copydir"/chroot{prepare,build}
+}
+
build() (
local copydir=$1; shift
- local cmd=(/chrootbuild "$@")
+ local repack=$1; shift
- run_hook pre_build "$copydir"
- trap "run_hook post_build '$copydir'" EXIT
-
- local netflag=''
+ local run_ynet=()
+ local run_nnet=()
if $INCHROOT; then
- ! $NONET || netflag='-n'
- unshare $netflag -- "${cmd[@]}"
+ run_ynet=(unshare)
+ run_nnet=(unshare -n)
else
- ! $NONET || netflag='-N'
- librechroot $netflag \
- -r "$PWD:/startdir_host" \
- -r "$SRCDEST:/srcdest_host" \
- -l "$copydir" \
- run "${cmd[@]}"
+ run_ynet=(librechroot "${librechroot_flags[@]}" run)
+ run_nnet=(librechroot "${librechroot_flags[@]}" -N run)
fi
+ $NONET || run_nnet=("${run_ynet[@]}")
+
+ prepare_chroot "$copydir" "$LIBREHOME" "$repack" false
+ "${run_ynet[@]}" /chrootprepare false "$@" |& indent
+ run_hook pre_build "$copydir"
+ trap "run_hook post_build '$copydir'" EXIT
+ "${run_nnet[@]}" /chrootbuild false "$@" |& indent
)
# The main program #############################################################
@@ -118,7 +148,7 @@ usage() {
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 `{PKG,SRC,SRCPKG,LOG}DEST` 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`'
@@ -134,8 +164,12 @@ usage() {
the documentation there.'
echo
print 'Options:'
+ print ' %s options:' librechroot
flag "-n <$(_ CHROOT)>" 'Name of the chroot to use'
flag "-l <$(_ COPY)>" 'Name of, or absolute path to, the chroot copy to use'
+ flag "-w <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read/write'
+ flag "-r <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read-only'
+ print ' %s options:' libremakepkg
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
@@ -159,10 +193,14 @@ main() {
local chroot=''
# Parse command line options ###########################################
- while getopts 'n:l:NRh' flag ; do
+ while getopts 'n:l:w:r: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) if $INCHROOT; then err_chflag "$flag"; else
+ chroot=$OPTARG; fi;;
+ l) if $INCHROOT; then err_chflag "$flag"; else
+ copy=$OPTARG; fi;;
+ w|r) if $INCHROOT; then err_chflag "$flag"; else
+ librechroot_flags+=(-$flag "$OPTARG"); fi;;
N) NONET=false;;
R) repack=true; makepkg_args+=(-R);;
h) usage; return 0;;
@@ -190,6 +228,15 @@ main() {
fi
unset chroot
+ # Load makepkg configuration ###########################################
+ # Note that all of these are globals
+ PKGDEST="$(get_var makepkg PKGDEST "$PWD")"
+ SRCDEST="$(get_var makepkg SRCDEST "$PWD")"
+ SRCPKGDEST="$(get_var makepkg SRCPKGDEST "$PWD")"
+ LOGDEST="$(get_var makepkg LOGDEST "$PWD")"
+ MAKEFLAGS="$(get_var makepkg MAKEFLAGS '')"
+ PACKAGER="$(get_var makepkg PACKAGER '')"
+
# Quick sanity check ###################################################
if (( EUID )); then
@@ -203,14 +250,17 @@ main() {
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 '')"
+ # Make sure that the various *DEST directories exist
+ mkdir -p -- "$PKGDEST" "$SRCDEST" "$SRCPKGDEST" "$LOGDEST"
+ # Check the permissions for $startdir and $SRCDEST
+ (
+ declare -i ret=0
+ check_directory_permissions "$PWD" || ret=1
+ if ! [[ "$PWD" -ef "$SRCDEST" ]]; then
+ check_directory_permissions "$SRCDEST" || ret=1
+ fi
+ exit $ret
+ )
# OK, we are starting now ##############################################
@@ -218,32 +268,40 @@ main() {
lock 9 "/build/.lock" \
"Waiting for existing lock on build directory to be released"
else
+ librechroot_flags+=(
+ -r "$PWD:/startdir_host"
+ -r "$SRCDEST:/srcdest_host"
+ -n "$CHROOT"
+ -l "$copy"
+ )
+
# 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
+ msg 'Initializing the chroot...'
+ librechroot "${librechroot_flags[@]}" make |& indent
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)"
+ export CARCH="$(MAKEPKG_CONF=$copydir/etc/makepkg.conf get_var makepkg CARCH)"
# Pre-build
+ msg 'Starting pre-build activities...'
run_hook check_pkgbuild
- download_sources "$copydir" "$LIBREUSER"
- prepare_chroot "$copydir" "$LIBREHOME" "$repack" false
- clean_chroot "$copydir"
+ msg 'Downloading sources...'
+ download_sources "$copydir" "$LIBREUSER" |& indent
# Build
+ msg 'Starting to build the package...'
trap "exit_copy '$copydir' '$LIBREUSER'" EXIT
- warning 'Entering build...'
- build "$copydir" "${makepkg_args[@]}"
+ build "$copydir" "$repack" "${makepkg_args[@]}"
+
# Post-build
- warning 'Entering hook check_pkg...'
+ msg 'Starting post-build activities...'
run_hook check_pkg
- warning 'Entering add_to_local_repo ...'
- add_to_local_repo "$copydir" "$copydir"/pkgdest/*.pkg.tar*
+ add_to_local_repo "$copydir" "$copydir"/pkgdest/*.pkg.tar* |& indent
}
main "$@"
diff --git a/src/chroot-tools/makechrootpkg.sh.patch b/src/chroot-tools/makechrootpkg.sh.patch
index f5b8ed7..540e6ba 100644
--- a/src/chroot-tools/makechrootpkg.sh.patch
+++ b/src/chroot-tools/makechrootpkg.sh.patch
@@ -1,5 +1,5 @@
---- makechrootpkg.sh.in 2013-09-08 23:01:20.000000000 -0400
-+++ makechrootpkg.sh.ugly 2013-09-09 15:43:06.000000000 -0400
+--- makechrootpkg.sh.in 2014-01-05 18:51:41.463720929 -0500
++++ makechrootpkg.sh.ugly 2014-02-09 20:20:25.021630727 -0500
@@ -12,6 +12,7 @@
shopt -s nullglob
@@ -8,8 +8,8 @@
_makepkg_args=(-s --noconfirm -L --holdver)
makepkg_args=("${_makepkg_args[@]}")
repack=false
-@@ -26,9 +27,10 @@
- declare -i ret=0
+@@ -29,9 +30,10 @@
+ bindmounts_rw=()
copy=$USER
-[[ -n $SUDO_USER ]] && copy=$SUDO_USER
@@ -20,15 +20,15 @@
usage() {
echo "Usage: ${0##*/} [options] -r <chrootdir> [--] [makepkg args]"
-@@ -62,6 +64,7 @@
+@@ -67,6 +69,7 @@
exit 1
}
+parse_options_init() {
- while getopts 'hcur:I:l:nT' arg; do
+ while getopts 'hcur:I:l:nTD:d:' arg; do
case "$arg" in
h) usage ;;
-@@ -86,9 +89,6 @@
+@@ -93,9 +96,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"
@@ -38,9 +38,9 @@
if [[ ${copy:0:1} = / ]]; then
copydir=$copy
else
-@@ -103,30 +103,47 @@
- repack=true
- fi
+@@ -115,30 +115,48 @@
+ esac
+ done
-if [[ -n $SUDO_USER ]]; then
+if [[ -n ${SUDO_USER:-} ]]; then
@@ -54,8 +54,9 @@
+# Usage: load_vars $makepkg_conf
+# Globals:
+# - SRCDEST
-+# - LOGDEST
++# - SRCPKGDEST
+# - PKGDEST
++# - LOGDEST
+# - MAKEFLAGS
+# - PACKAGER
load_vars() {
@@ -63,7 +64,7 @@
[[ -f $makepkg_conf ]] || return 1
- for var in {SRC,PKG,LOG}DEST MAKEFLAGS PACKAGER; do
+ for var in {SRC,SRCPKG,PKG,LOG}DEST MAKEFLAGS PACKAGER; do
- [[ -z ${!var} ]] && eval $(grep "^${var}=" "$makepkg_conf")
+ [[ -z ${!var:-} ]] && eval $(grep "^${var}=" "$makepkg_conf")
done
@@ -92,7 +93,7 @@
# 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 @@
+@@ -159,11 +177,16 @@
# Drop the read lock again
lock_close 8
@@ -100,6 +101,7 @@
}
-clean_temporary() {
+- stat_busy "Removing temporary copy [%s]" "$copy"
+# Usage: delete_chroot $copydir [$copy]
+delete_chroot() {
+ local copydir=$1
@@ -107,10 +109,11 @@
+ # Detect chrootdir filesystem type
+ local chroottype=$(stat -f -c %T "$copydir")
+
- stat_busy "Removing temporary copy [%s]" "$copy"
- if [[ "$chroottype" == btrfs ]]; then
++ stat_busy "Removing chroot copy [%s]" "$copy"
+ if [[ "$chroottype" == btrfs ]] && ! mountpoint -q "$copydir"; then
btrfs subvolume delete "$copydir" >/dev/null ||
-@@ -166,9 +188,14 @@
+ die "Unable to delete subvolume %s" "$copydir"
+@@ -178,9 +201,14 @@
stat_done
}
@@ -125,7 +128,7 @@
for install_pkg in "${install_pkgs[@]}"; do
pkgname="${install_pkg##*/}"
cp "$install_pkg" "$copydir/$pkgname"
-@@ -179,11 +206,19 @@
+@@ -193,11 +221,19 @@
rm "$copydir/$pkgname"
done
@@ -147,9 +150,9 @@
$repack || rm -rf "$copydir/build"
mkdir -p "$copydir/build"
-@@ -217,12 +252,12 @@
+@@ -236,12 +272,12 @@
- chown -R nobody "$copydir"/{build,pkgdest,logdest,srcdest,startdir}
+ chown -R nobody "$copydir"/{build,pkgdest,srcpkgdest,logdest,srcdest,startdir}
- if [[ -n $MAKEFLAGS ]]; then
+ if [[ -n ${MAKEFLAGS:-} ]]; then
@@ -162,22 +165,26 @@
sed -i '/^PACKAGER=/d' "$copydir/etc/makepkg.conf"
echo "PACKAGER='${PACKAGER}'" >> "$copydir/etc/makepkg.conf"
fi
-@@ -235,6 +270,14 @@
+@@ -254,20 +290,38 @@
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]
++ local line=$(grep -n '^\[' "$copydir/etc/pacman.conf" |grep -Fv ':[options]'|sed 's/:.*//;1q')
++ local ins='[repo]
+SigLevel = Optional TrustAll
+Server = file:///repo
-+EOF
++'
++ sed -i "${line}i${ins//$'\n'/\n}" "$copydir/etc/pacman.conf"
+ 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_chrootprepare "$@"' "$(declare -f _chrootprepare)" \
++ > "$copydir/chrootprepare"
++ chmod +x "$copydir/chrootprepare"
printf $'#!/bin/bash\n%s\n_chrootbuild %q "$@"' "$(declare -f _chrootbuild)" \
-@@ -242,13 +285,19 @@
+ "$run_namcap" >"$copydir/chrootbuild"
chmod +x "$copydir/chrootbuild"
}
@@ -199,7 +206,7 @@
makepkg --config="$copydir/etc/makepkg.conf" --verifysource -o
else
( export SRCDEST BUILDDIR="$builddir"
-@@ -258,7 +307,7 @@
+@@ -277,10 +331,10 @@
(( $? != 0 )) && die "Could not download sources."
# Clean up garbage from verifysource
@@ -207,8 +214,20 @@
+ rm -rf "$builddir"
}
- _chrootbuild() {
-@@ -295,6 +344,7 @@
+-_chrootbuild() {
++_chrootprepare() {
+ # This function isn't run in makechrootpkg,
+ # so no global variables
+ local run_namcap="$1"; shift
+@@ -291,6 +345,7 @@
+ shopt -s nullglob
+
+ # XXX: Workaround makepkg disliking read-only dirs
++ rm -rf -- /srcdest/* /startdir/*
+ ln -sft /srcdest /srcdest_host/*
+ ln -sft /startdir /startdir_host/*
+
+@@ -316,11 +371,29 @@
# Safety check
if [[ ! -w PKGBUILD ]]; then
@@ -216,7 +235,30 @@
echo "Can't write to PKGBUILD!"
exit 1
fi
-@@ -312,12 +362,24 @@
+
+- sudo -u nobody makepkg "${makepkg_args[@]}" || exit 1
++ # Sync deps now, as networking may be disabled during _chrootbuild
++ cp /repo/repo.db /var/lib/pacman/sync/repo.db
++ sudo -u nobody makepkg "${makepkg_args[@]}" -o
++}
++
++_chrootbuild() {
++ # This function isn't run in makechrootpkg,
++ # so no global variables
++ local run_namcap="$1"; shift
++ local makepkg_args=("$@")
++
++ . /etc/profile
++ export HOME=/build
++ shopt -s nullglob
++
++ cd /startdir
++
++ sudo -u nobody makepkg "${makepkg_args[@]}" -e || exit 1
+
+ if $run_namcap; then
+ pacman -S --needed --noconfirm namcap
+@@ -333,12 +406,24 @@
exit 0
}
@@ -239,9 +281,9 @@
+ local l
for l in "$copydir"/logdest/*; do
+ [[ $l == */logpipe.* ]] && continue
chown "$src_owner" "$l"
- mv "$l" "$LOGDEST"
-@@ -325,6 +387,10 @@
+@@ -352,6 +437,10 @@
}
# }}}
@@ -252,9 +294,9 @@
umask 0022
load_vars /etc/makepkg.conf
-@@ -335,27 +401,37 @@
- [[ -d $SRCDEST ]] || SRCDEST=$PWD
- [[ -d $LOGDEST ]] || LOGDEST=$PWD
+@@ -363,30 +452,45 @@
+ [[ -d $SRCPKGDEST ]] || SRCPKGDEST=$PWD
+ [[ -d $LOGDEST ]] || LOGDEST=$PWD
-create_chroot
+# Lock the chroot we want to use. We'll keep this lock until we exit.
@@ -264,7 +306,9 @@
+ sync_chroot "$chrootdir" "$copy"
+fi
- $update_first && arch-nspawn "$copydir" pacman -Syu --noconfirm
+ $update_first && arch-nspawn "$copydir" \
+ "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
+ pacman -Syu --noconfirm
-[[ -n ${install_pkgs[*]} ]] && install_packages
+if [[ -n ${install_pkgs[*]:-} ]]; then
@@ -283,6 +327,12 @@
if arch-nspawn "$copydir" \
--bind-ro="$PWD:/startdir_host" \
--bind-ro="$SRCDEST:/srcdest_host" \
+ "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
++ /chrootprepare &&
++ arch-nspawn "$copydir" \
++ --bind-ro="$PWD:/startdir_host" \
++ --bind-ro="$SRCDEST:/srcdest_host" \
++ "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
/chrootbuild "${makepkg_args[@]}"
then
- move_products
@@ -296,7 +346,7 @@
if (( ret != 0 )); then
if $temp_chroot; then
-@@ -366,3 +442,4 @@
+@@ -397,3 +501,4 @@
else
true
fi
diff --git a/src/fullpkg/Makefile b/src/fullpkg/Makefile
index 2c76089..ee9c395 100644
--- a/src/fullpkg/Makefile
+++ b/src/fullpkg/Makefile
@@ -1 +1,3 @@
include ../../common.mk
+
+fullpkg-build.pot: xgettext-keywords-sh+=--keyword=list_pkgs:2
diff --git a/src/fullpkg/fullpkg b/src/fullpkg/fullpkg
index 1d4388c..978cf7b 100755
--- a/src/fullpkg/fullpkg
+++ b/src/fullpkg/fullpkg
@@ -4,31 +4,32 @@
# aren't built or need update and then makepkg them in order.
usage() {
-
- echo "cd to a dir containing a PKGBUILD and run:"
- echo "$0 [build_dir]"
- echo ""
- echo "This script will check dependencies, build them if possible "
- echo "and stage the packages on it's repo."
- echo ""
- echo "OPTIONS:"
- echo " -h : this message."
- echo ""
- echo "Wrapper for \`fullpkg-find' and \`fullpkg-build'"
- echo ""
- exit 1
-
+ print "Usage: %s [OPTIONS] [BUILD_DIR]" "${0##*/}"
+ print "A (libre)makepkg wrapper that will also build dependencies"
+ echo
+ prose "More directly, it wraps fullpkg-find and fullpkg-build;
+ fullpkg-find finds the dependencies, and sets them up in
+ BUILD_DIR; then fullpkg-build builds them."
+ echo
+ prose "This script will check dependencies, build them if possible and
+ stage the packages on its repo."
+ echo
+ prose "If no BUILD_DIR is specified, it will create a temporary
+ directory."
+ echo
+ print "Options:"
+ flag '-h' "Show this message"
}
while getopts 'h' arg; do
- case "$arg" in
- h) usage ;;
- esac
+ case "$arg" in
+ h) usage; exit 0 ;;
+ esac
done
shift $(( OPTIND - 1 ))
-build_dir="${1:-$(mktemp -d /tmp/fullpkg.XXXXXX)}"
+build_dir="${1:-$(mktemp --tmpdir -d fullpkg.XXXXXXXXXX)}"
fullpkg-find "$build_dir" && fullpkg-build -N "$build_dir"
exit 0
diff --git a/src/fullpkg/fullpkg-build b/src/fullpkg/fullpkg-build
index 1771d83..e824c2e 100755
--- a/src/fullpkg/fullpkg-build
+++ b/src/fullpkg/fullpkg-build
@@ -18,101 +18,98 @@ check_vars libretools FULLBUILDCMD || exit 1
#
## status: nonfree, built, failed, unstaged
list_pkgs() {
- msg="$2"
- local pkgs=($(grep "$1:" $build_dir/log)) && {
- msg "$2"
- echo ${pkgs[@]} | tr " " "\n" | cut -d: -f2
- }
+ msg="$2"
+ local pkgs=($(grep "$1:" $build_dir/log)) && {
+ msg "$2"
+ printf '%s\n' "${pkgs[@]}" | cut -d: -f2
+ }
}
## Check all build_dir, fails if one PKGBUILD is nonfree
check_nonfree() {
- find "$build_dir" -name PKGBUILD \
- -exec pkgbuild-check-nonfree {} +
- if [ "$?" -eq 15 ]; then
- error "Some PKGBUILD have nonfree problems"
- exit 15
- fi
-
+ find "$build_dir" -name PKGBUILD \
+ -exec pkgbuild-check-nonfree {} +
+ local s=$?
+ pkgbuild-summarize-nonfree -q $s || return $s
}
# Removes a package from the buildorder
# $1 package name
# $2 buildorder file
remove_buildorder() {
- grep -Evw "${1}" ${2} > ${2}2
- mv -f ${2}2 ${2}
+ grep -Evw "${1}" ${2} > ${2}2
+ mv -f ${2}2 ${2}
- return $?
+ return $?
}
succesfull_build() {
- if [ "$RUN" != "$FULLBUILDCMD" ]; then
- return 0 # Custom command or download sources
- fi
+ if [[ "$RUN" != "$FULLBUILDCMD" ]]; then
+ return 0 # Custom command or download sources
+ fi
- if source .INFO && [ -n "$repo" ]; then
+ if source .INFO && [[ -n "$repo" ]]; then
- if [ ! -z "$HOOKLOCALRELEASE" ]; then
- "$HOOKLOCALRELEASE" "$repo"
- fi
+ if [[ ! -z "$HOOKLOCALRELEASE" ]]; then
+ "$HOOKLOCALRELEASE" "$repo"
+ fi
- msg "Updating pacman db and packages"
- sudo pacman -Sy || true
+ msg "Updating pacman db and packages"
+ sudo pacman -Sy || true
- fi
+ fi
- echo "built:$(basename $PWD)" >>$build_dir/log
+ echo "built:$(basename $PWD)" >>$build_dir/log
}
build_description() {
- list_pkgs "nonfree" "Those packages contain nonfree deps:"
- list_pkgs "built" "Those packages were built and staged:"
- list_pkgs "failed" "Those packages failed to build:"
- list_pkgs "unstaged" "Those packages couldn't be staged (missing reponame):"
+ list_pkgs "nonfree" "Those packages contain nonfree deps:"
+ list_pkgs "built" "Those packages were built and staged:"
+ list_pkgs "failed" "Those packages failed to build:"
+ list_pkgs "unstaged" "Those packages couldn't be staged (missing reponame):"
}
__build() {
- pushd ${build_dir} >/dev/null
+ pushd ${build_dir} >/dev/null
- build_packages=($(sort -gr $buildorder | cut -d: -f2)) # greater levels must be built first
+ build_packages=($(sort -gr $buildorder | cut -d: -f2)) # greater levels must be built first
- while [ ${#build_packages[@]} -ge 1 ]; do
+ while [[ ${#build_packages[@]} -ge 1 ]]; do
- pushd "$build_dir/${build_packages[0]}" >/dev/null
+ pushd "$build_dir/${build_packages[0]}" >/dev/null
- if [ -n "${HOOKPKGBUILDMOD}" ]; then
- ${HOOKPKGBUILDMOD} || true
- fi
+ if [[ -n "${HOOKPKGBUILDMOD}" ]]; then
+ ${HOOKPKGBUILDMOD} || true
+ fi
- eval "$RUN"; r=$?
+ eval "$RUN"; r=$?
- case $r in
+ case $r in
- 0) succesfull_build ;;
+ 0) succesfull_build ;;
- *) error "There were errors while trying to build the package."
- echo "failed:$(basename $PWD)" >>$build_dir/log
- ;;
- esac
+ *) 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
+ remove_buildorder "${build_packages[0]}" $buildorder || true
-# which is next package?
- build_packages=($(sort -gr $buildorder | cut -d: -f2))
- popd > /dev/null
- done
+ # which is next package?
+ build_packages=($(sort -gr $buildorder | cut -d: -f2))
+ popd > /dev/null
+ done
- popd >/dev/null
+ popd >/dev/null
}
# End inmediately but print a useful message
trap_exit() {
- error "$@"
- warning "Leftover files left on $build_dir"
- mv .BUILDORDER BUILDORDER
- exit 1
+ error "$@"
+ warning "Leftover files left on $build_dir"
+ mv .BUILDORDER BUILDORDER
+ exit 1
}
# Trap signals from makepkg
@@ -124,66 +121,63 @@ trap 'trap_exit "(fullpkg-build) An unknown error has occurred. Exiting..."' ERR
CLEANUP="false"
CHECKNONFREE="true"
RUN="$FULLBUILDCMD"
-MESSAGE="Building packages"
+MESSAGE="$(_ 'Building packages')"
usage() {
-
- echo ""
- echo "$(basename $0) [options] <build_dir>"
- echo ""
- echo "Builds packages from build_dir, create a build_dir using:"
- echo "'fullpkg-find <build_dir>'"
- echo ""
- echo "If no <build_dir> is specified, it uses the current directory."
- echo ""
- echo "OPTIONS:"
- echo " -h : this message."
- echo " -c : clean <build_dir> on succesfull build"
- echo " -N : don't check for freedom issues." #Also made by fullpkg-find
- echo " -r \"command\" : use this instead of \"$FULLBUILDCMD\"."
- echo " -g : get sources for building packages on build_dir."
- echo ""
- exit 1
-
+ print "Usage: %s [OPTIONS] [BUILD_DIR]" "${0##*/}"
+ print "Builds packages in BUILD_DIR, as set up by fullpkg-find"
+ echo
+ prose "Builds packages from BUILD_DIR; create BUILD_DIR using:"
+ print ' $ fullpkg-find BUILD_DIR'
+ echo
+ prose "If no BUILD_DIR is specified, it uses the current directory."
+ echo
+ print "Options:"
+ flag "-c" "Clean BUILD_DIR on succesfull build"
+ flag "-N" "Don't check for freedom issues." #Also made by fullpkg-find
+ flag "-r $(_ CMD)" "Use CMD instead of \${FULLBUILDCMD}"
+ flag "-g" "Get sources for building packages on BUILD_DIR"
+ flag "-h" "Show this message"
}
while getopts 'hNr:g' arg; do
- case $arg in
- h) usage ;;
- c) CLEAN ;;
- N) CHECKNONFREE="false" ;;
- r) RUN="$OPTARG"
- MESSAGE="Executing custom action";;
- g) RUN='makepkg -g > /dev/null'
- MESSAGE="Downloading packages";;
- esac
+ case $arg in
+ h) usage; exit 0 ;;
+ c) CLEAN ;;
+ N) CHECKNONFREE="false" ;;
+ r) RUN="$OPTARG"
+ MESSAGE="$(_ 'Executing custom action')";;
+ g) RUN='makepkg -g > /dev/null'
+ MESSAGE="$(_ 'Downloading packages')";;
+ esac
done
shift $(( OPTIND - 1 ))
build_dir="${1:-`pwd`}"
buildorder="${build_dir}/BUILDORDER"
-if [ ! -e "$buildorder" ]; then
- error "This is not a build_dir. Make one using fullpkg."
- usage
+if [[ ! -e "$buildorder" ]]; then
+ error "This is not a build_dir. Make one using fullpkg."
+ usage
+ exit 1
else
-# backup BUILDORDER
- cp "$buildorder" "$build_dir/.BUILDORDER"
+ # backup BUILDORDER
+ cp "$buildorder" "$build_dir/.BUILDORDER"
fi
if "$CHECKNONFREE"; then
- check_nonfree
+ check_nonfree
fi
msg "$MESSAGE"
__build
-if [ "$RUN" != "$FULLBUILDCMD" ]; then
- # Used for downloading or custom command
- mv "$build_dir/.BUILDORDER" "$buildorder"
- exit 0
+if [[ "$RUN" != "$FULLBUILDCMD" ]]; then
+ # Used for downloading or custom command
+ mv "$build_dir/.BUILDORDER" "$buildorder"
+ exit 0
elif "$CLEANUP"; then
- find "$build_dir" -mindepth 1 -delete
+ find "$build_dir" -mindepth 1 -delete
fi
build_description
diff --git a/src/fullpkg/fullpkg-find b/src/fullpkg/fullpkg-find
index a927782..8bd630c 100755
--- a/src/fullpkg/fullpkg-find
+++ b/src/fullpkg/fullpkg-find
@@ -1,5 +1,48 @@
#!/usr/bin/env bash
# set -x # uncomment for debug
+
+# Copyright (C) 2011-2012 Joshua I. Haase H. (xihh) <hahj87@gmail.com>
+# Copyright (C) 2011-2012 Nicolás Reynolds <fauno@kiwwwi.com.ar>
+# Copyright (C) 2012 Michał Masłowski <mtjm@mtjm.eu>
+# Copyright (C) 2012-2014 Luke Shumaker <LukeShu@sbcglobal.net>
+#
+# The copy_files() function is taken from makechrootpkg:
+# Copyright (C) 2007 Armin Luntzer <armin@archlinuxppc.org>
+# Copyright (C) 2007 Jason Chu <jchu@xentac.net>
+# Copyright (C) 2007, 2011 Dan McGee <dan@archlinux.org>
+# Copyright (C) 2007-2008 Travis Willard <travis@archlinux.org>
+# Copyright (C) 2007-2009 Aaron Griffin <aaronmgriffin@gmail.com>
+# Copyright (C) 2008 Simo Leone <simo@archlinux.org>
+# Copyright (C) 2009 Biru Ionut <biru.ionut@gmail.com>
+# Copyright (C) 2009 Biru Ionut <ionut@archlinux.ro>
+# Copyright (C) 2009 Evangelos Foutras <foutrelis@gmail.com>
+# Copyright (C) 2009 Francois Charette <francois@samarqand.localdomain>
+# Copyright (C) 2009 Nezmer <Nezmer@allurelinux.org>
+# Copyright (C) 2009 Ronald van Haren <pressh@gmail.com>
+# Copyright (C) 2009-2011 Andrea Scarpino <andrea@archlinux.org>
+# Copyright (C) 2009-2012 Allan McRae <allan@archlinux.org>
+# Copyright (C) 2009-2012 Eric Bélanger <snowmaniscool@gmail.com>
+# Copyright (C) 2009-2012 Pierre Schmitz <pierre@archlinux.de>
+# Copyright (C) 2010 Byron Clark <byron@theclarkfamily.name>
+# Copyright (C) 2011 Ionut Biru <ibiru@archlinux.org>
+# Copyright (C) 2011 Lukas Fleischer <archlinux@cryptocrack.de>
+# Copyright (C) 2011-2012 Florian Pritz <bluewind@xinu.at>
+# Copyright (C) 2011-2013 Jan Alexander Steffens (heftig) <jan.steffens@gmail.com>
+# Copyright (C) 2013 Sébastien Luttringer <seblu@seblu.net>
+#
+# Because of the code from makechrootpkg, this file is GPLv2, instead of GPLv3
+# like most of libretools.
+#
+# 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.
+
+
# Builds packages from ABS recursively. It tries to find dependencies that
# aren't built or need update and then makepkg them in order.
@@ -8,114 +51,108 @@
# Get repo name. Asumes ${ABSROOT}/repo/package/PKGBUILD
guess_repo() {
- basename $(dirname $(pwd))
+ basename "$(dirname "$(pwd)")"
}
# This function is stolen from makechrootpkg.
-# That probably has some copyright/licensing implications.
copy_files() {
- local copydir="$build_dir/${pkgbase:-${pkgname[0]}}"
- mkdir -p "$copydir"
-
- # Copy PKGBUILD and sources
- cp PKGBUILD "$copydir"
- (
- load_PKGBUILD
- for file in "${source[@]}"; do
- file="${file%%::*}"
- file="${file##*://*/}"
- if [[ -f $file ]]; then
- cp "$file" "$copydir/"
- elif [[ -f $SRCDEST/$file ]]; then
- cp "$SRCDEST/$file" "$copydir/"
- fi
- done
-
- # Find all changelog and install files, even inside functions
- for i in 'changelog' 'install'; do
- while read -r file; do
- # evaluate any bash variables used
- eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
- [[ -f $file ]] && cp "$file" "$copydir"
- done < <(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD)
- done
- )
+ local copydir="$build_dir/${pkgbase:-${pkgname[0]}}"
+ mkdir -p "$copydir"
+
+ # Copy PKGBUILD and sources
+ cp PKGBUILD "$copydir"
+ (
+ load_PKGBUILD
+ for file in "${source[@]}"; do
+ file="${file%%::*}"
+ file="${file##*://*/}"
+ if [[ -f $file ]]; then
+ cp "$file" "$copydir/"
+ elif [[ -f $SRCDEST/$file ]]; then
+ cp "$SRCDEST/$file" "$copydir/"
+ fi
+ done
+
+ # Find all changelog and install files, even inside functions
+ for i in 'changelog' 'install'; do
+ while read -r file; do
+ # evaluate any bash variables used
+ eval file=\"$(sed "s/^\\(['\"]\\)\\(.*\\)\\1\$/\\2/" <<< "$file")\"
+ [[ -f $file ]] && cp "$file" "$copydir"
+ done < <(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD)
+ done
+ )
}
# Checks ABSROOT and look for target pkg deps. Adds them if not built or outdated.
find_deps() {
-# Check this level
- load_PKGBUILD
-
- local repo="${repo:-$(guess_repo)}"
- local pkgbase="${pkgbase:-${pkgname[0]}}"
-
- if ! pkgbuild-check-nonfree > /dev/null 2> /dev/null; then
- if [ "$?" -eq 15 ]; then
- error "pkgbase" has nonfree issues
- return 15
- fi
- fi
-
- # Checking any package built, since otherwise e.g. kdebase would
- # 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]}" "$(get_full_version "${pkgname[0]}")"; then
- exit 0 # pkg is built and updated
- fi
-
-# greater levels are built first
- echo "${LEVEL}:${pkgbase}" >>"$build_dir/BUILDORDER"
-# PKGBUILD is already there
- if [ -d "${build_dir}/${pkgbase}" ]; then
- exit 0
-# Copy dir to build_dir
- else
- copy_files
-
-# to identify repo later
- echo "repo=$repo" > "${build_dir}/${pkgbase}/.INFO"
- fi
-
-# current package plus a space for every level
- msg2 "%${LEVEL}s${pkgbase}-$(get_full_version)"
-
-## Check next levels
- declare -i next_level=$LEVEL+1
-
-# All deps in separate line, only once, without version.
- deps=($(echo "${depends[@]} ${makedepends[@]}" | \
- sed "s/[=<>]\+[^ ]\+//g" | \
- tr ' ' "\n" | \
- sort -u))
-
- for _dep in ${deps[@]}; do
-
- local found=false
- # May fail, e.g. since abslibre-mips64el doesn't include
- # arch=any packages.
- local pkgdir=$(toru -p ${_dep}) || true
-
- if [ -n "$pkgdir" -a -d "${pkgdir}" ]; then
- found=true
-
- pushd "${pkgdir}" > /dev/null
-# runs itself on dep's PKGBUILD dir
- $0 -l ${next_level} ${build_dir} || return $?
- popd > /dev/null
- fi
-
- if ! (( found )); then
- echo "dep_not_found:$_dep" >>$build_dir/log
- fi
-
- done
-
-## End variable block
-
- unset next_level dir
+ # Check this level
+ load_PKGBUILD
+
+ local repo="${repo:-$(guess_repo)}"
+ local pkgbase="${pkgbase:-${pkgname[0]}}"
+
+ # Checking any package built, since otherwise e.g. kdebase would
+ # 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]}" "$(get_full_version "${pkgname[0]}")"; then
+ exit 0 # pkg is built and updated
+ fi
+
+ # greater levels are built first
+ echo "${LEVEL}:${pkgbase}" >>"$build_dir/BUILDORDER"
+ # PKGBUILD is already there
+ if [[ -d "${build_dir}/${pkgbase}" ]]; then
+ exit 0
+ # Copy dir to build_dir
+ else
+ copy_files
+
+ # to identify repo later
+ echo "repo=$repo" > "${build_dir}/${pkgbase}/.INFO"
+ fi
+
+ # current package plus a space for every level
+ msg2 "%${LEVEL}s%s" '' "${pkgbase}-$(get_full_version)"
+
+ ## Check next levels
+ declare -i next_level=$LEVEL+1
+
+ # All deps
+ local deps=("${depends[@]}" "${makedepends[@]}" "${checkdepends[@]}")
+ # Strip version specifiers
+ deps=("${deps[@]%%[=<>]*}")
+ # Filter out duplicates
+ read -d $'\n' -a deps <<<"$(printf '%s\n' "${deps[@]}"|sort -u)"
+
+ local _dep
+ for _dep in "${deps[@]}"; do
+
+ local found=false
+ # May fail, e.g. since abslibre-mips64el doesn't include
+ # arch=any packages.
+ local pkgdir=$(toru -p ${_dep}) || true
+
+ if [[ -n "$pkgdir" ]] && [[ -d "${pkgdir}" ]; then
+ found=true
+
+ pushd "${pkgdir}" > /dev/null
+ # runs itself on dep's PKGBUILD dir
+ "$0" -l "${next_level}" "${build_dir}" || return $?
+ popd > /dev/null
+ fi
+
+ if ! (( found )); then
+ echo "dep_not_found:$_dep" >>$build_dir/log
+ fi
+
+ done
+
+ ## End variable block
+
+ unset next_level dir
}
. libremessages
@@ -128,68 +165,67 @@ CLEANFIRST='false'
UPDATEDB='true'
usage() {
-
- echo ""
- echo "cd to a dir containing a PKGBUILD and run:"
- echo "$(basename $0) [options] <build_dir>"
- echo ""
- echo "This script will create a build_dir for recursive building"
- echo "it tries to find dependencies that aren't built or need update."
- echo ""
- echo "If no <build_dir> is specified, the script works on a tempdir"
- echo ""
- echo "OPTIONS:"
- echo " -h : this message."
- echo " -A <absroot> : use this ABSROOT."
- echo " -c : clean <build_dir> before working."
- echo " -m <max_level> : check deps until this level"
- echo " -n : don't update pacman db."
- echo ""
- exit 1
-
+ print "Usage: %s [OPTIONS] [BUILD_DIR]" "${0##*/}"
+ print "Finds package dependencies and sets up a build order"
+ echo
+ prose "Run this from a directory containing a PKGBUILD."
+ echo
+ prose "This script will create a BUILD_DIR for recursive building; it
+ tries to find dependencies that aren't built or need update."
+ echo
+ prose "If no BUILD_DIR is specified, it will create a temporary
+ directory."
+ echo
+ print "Options:"
+ flag "-h" "Show this message"
+ flag "-A <$(_ ABSROOT)>" "Use ABSROOT as the root of the ABS tree"
+ flag "-c" "Clean BUILD_DIR before working."
+ flag "-m <$(_ MAX_LEVEL)>" "Limit the depth of the dependency recursion"
+ flag "-n" "Don't update pacman DB"
}
while getopts 'hA:l:cmn' arg; do
- case "$arg" in
- h) usage ;;
- A) ABSROOT="$OPTARG" ;;
- l) LEVEL="$OPTARG" ;; # hidden option to know dep level.
- c) CLEANFIRST='true' ;;
- m) MAXLEVEL="$OPTARG" ;;
- n) UPDATEDB='false' ;;
- esac
+ case "$arg" in
+ h) usage; exit 0 ;;
+ A) ABSROOT="$OPTARG" ;;
+ l) LEVEL="$OPTARG" ;; # hidden option to know dep level.
+ c) CLEANFIRST='true' ;;
+ m) MAXLEVEL="$OPTARG" ;;
+ n) UPDATEDB='false' ;;
+ esac
done
-if [ ! -r PKGBUILD ]; then
- error "This directory doesnt contain a PKGBUILD"
- usage
+if [[ ! -r PKGBUILD ]]; then
+ error "This directory doesnt contain a PKGBUILD"
+ usage
+ exit 1
fi
shift $(( OPTIND - 1 ))
build_dir="${1}"
-if [ "$LEVEL" -eq 0 ]; then
+if [[ "$LEVEL" -eq 0 ]]; then
- build_dir="${1:-$(mktemp -d /tmp/fullpkg.XXXXXX)}"
+ build_dir="${1:-$(mktemp -d /tmp/fullpkg.XXXXXX)}"
- if [ ! -d "$build_dir" ]; then
- mkdir -p "$build_dir"
- elif "$CLEANFIRST"; then
- # Erase files already in dir
- msg "Cleaning up files in dir"
- find "$build_dir" -mindepth 1 -delete
- fi
+ if [[ ! -d "$build_dir" ]]; then
+ mkdir -p "$build_dir"
+ elif "$CLEANFIRST"; then
+ # Erase files already in dir
+ msg "Cleaning up files in dir"
+ find "$build_dir" -mindepth 1 -delete
+ fi
- if "$UPDATEDB"; then
- msg "Updating pacman db"
- sudo pacman -Sy --noconfirm || true
- fi
+ if "$UPDATEDB"; then
+ msg "Updating pacman db"
+ sudo pacman -Sy --noconfirm || true
+ fi
-# make files for log and buildorder
- touch "${build_dir}"/{log,BUILDORDER}
- buildorder="${build_dir}/BUILDORDER"
+ # make files for log and buildorder
+ touch "${build_dir}"/{log,BUILDORDER}
+ buildorder="${build_dir}/BUILDORDER"
- msg "Checking dependencies"
+ msg "Checking dependencies"
fi
find_deps
diff --git a/src/libregit/Makefile b/src/gitget/Makefile
index 2c76089..2c76089 100644
--- a/src/libregit/Makefile
+++ b/src/gitget/Makefile
diff --git a/src/gitget/gitget b/src/gitget/gitget
new file mode 100755
index 0000000..3e35cec
--- /dev/null
+++ b/src/gitget/gitget
@@ -0,0 +1,220 @@
+#!/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
+
+# from makepkg
+dir_is_empty() {
+ (
+ shopt -s dotglob nullglob
+ files=("$1"/*)
+ (( ${#files} == 0 ))
+ )
+}
+
+# from makepkg
+cd_safe() {
+ if ! cd "$1"; then
+ error "Failed to change to directory %s" "$1"
+ plain "Aborting..."
+ exit 1
+ fi
+}
+
+# from makepkg
+download_git_checkout() {
+ local url=$1
+ local ref=$2
+ local dir=$3
+ local name=$4
+ local push=${5:-}
+
+ if [[ ! -d "$dir/.git" ]] ; then
+ msg2 "Cloning %s %s repo..." "${name}" "git"
+ if ! git clone "$url" "$dir"; then
+ error "Failure while downloading %s %s repo" "${name}" "git"
+ plain "Aborting..."
+ exit 1
+ fi
+ cd_safe "$dir"
+ if [[ -n $push ]]; then
+ git config remote.origin.pushUrl "$push"
+ fi
+ git checkout "$ref"
+ else
+ cd_safe "$dir"
+ # Make sure we are fetching the right repo
+ if [[ "$url" != "$(git config --get remote.origin.url)" ]] ; then
+ if $FORCE; then
+ git config remote.origin.url "$url"
+ else
+ error "%s is not a clone of %s" "$dir" "$url"
+ plain "Aborting..."
+ exit 1
+ fi
+ fi
+ if [[ -n $push ]] ; then
+ if $FORCE; then
+ git config remote.origin.pushUrl "$push"
+ else
+ local curpush="$(git config --get remote.origin.pushUrl)"
+ if [[ $? != 0 ]] ; then
+ error "%s does not have a %s configured" pushUrl "$name"
+ plain "Aborting..."
+ exit 1
+ elif [[ $curpush != "$push" ]]; then
+ error "%s has %s configured, but it doesn't match %s" "$name" pushUrl "$push"
+ plain "Aborting..."
+ exit 1
+ fi
+ fi
+ fi
+ msg2 "Updating %s %s repo..." "${name}" "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
+}
+
+# from makepkg
+download_git_bare() {
+ local url=$1
+ local dir=$2
+ local name=$3
+ local push=${4:-}
+
+ if [[ ! -d "$dir" ]] || dir_is_empty "$dir" ; then
+ msg2 "Cloning %s %s repo..." "${name}" "git"
+ if ! git clone --mirror "$url" "$dir"; then
+ error "Failure while downloading %s %s repo" "${name}" "git"
+ plain "Aborting..."
+ exit 1
+ fi
+ if [[ -n $push ]]; then
+ cd_safe "$dir"
+ git config remote.origin.pushUrl "$push"
+ fi
+ else
+ cd_safe "$dir"
+ # Make sure we are fetching the right repo
+ if [[ "$url" != "$(git config --get remote.origin.url)" ]] ; then
+ error "%s is not a clone of %s" "$dir" "$url"
+ plain "Aborting..."
+ exit 1
+ fi
+ if [[ -n $push ]] ; then
+ if $FORCE; then
+ git config remote.origin.pushUrl "$push"
+ else
+ local curpush="$(git config --get remote.origin.pushUrl)"
+ if [[ $? != 0 ]] ; then
+ error "%s does not have a %s configured" pushUrl "$name"
+ plain "Aborting..."
+ exit 1
+ elif [[ $curpush != "$push" ]]; then
+ error "%s has %s configured, but it doesn't match %s" "$name" pushUrl "$push"
+ plain "Aborting..."
+ exit 1
+ fi
+ fi
+ fi
+ msg2 "Updating %s %s repo..." "${name}" "git"
+ if ! git fetch --all -p; then
+ # only warn on failure to allow offline builds
+ warning "Failure while updating %s %s repo" "${name}" "git"
+ fi
+ fi
+}
+
+usage() {
+ print 'Usage: %s [OPTIONS] bare URL DIRECTORY' "${0##*/}"
+ print 'Usage: %s [OPTIONS] checkout URL DIRECTORY' "${0##*/}"
+ print 'A URL-handler for git urls. Capable of updating or cloning.'
+ echo
+ prose "Clones or pulls from the git URL, to a local DIRECTORY. If
+ \`bare\` is specified, it will create a bare repository; if
+ \`checkout\` is specified, it will create or update a working tree."
+ echo
+ prose 'For a checkout, the tree to checkout is specified by appending
+ `#ANYTHING=TREE-ISH` to the URL. For example, `#branch=stable`,
+ or `#tag=v12.3`. Whatever is on the left side of the equal sign
+ is ignored, this is for compatability with `makepkg` source
+ URLs.'
+ echo
+ prose "The URL may be prefixed with \`git+\`. This is also for
+ compatability with \`makepkg\` source URLs."
+ echo
+ prose "It does safety checks, figures out whether to clone or pull, and
+ other helpful things. This exists because the same
+ \`download_git\` function from makepkg was being copied and
+ pasted again and again."
+ echo
+ print "Options:"
+ flag '-f' \
+ 'Instead of checking to make sure configured URLs match, force
+ the update, and set the URLs.'
+ flag "-p $(_ URL)" \
+ 'In addition to setting or checking `remotes.origin.url`, also
+ set or check `remotes.origin.pushUrl`'
+ flag "-n $(_ NAME)" \
+ 'In messages, instead of using the basename of DIRECTORY as the
+ repository name, use NAME'
+ flag '-h' 'Show this message'
+}
+
+FORCE=false
+main() {
+ local push=''
+ local name=''
+ while getopts 'fp:n:h' flag; do
+ case "${flag}" in
+ f) FORCE=true;;
+ p) push=$OPTARG;;
+ n) name=$OPTARG;;
+ h) usage; return 0;;
+ *) usage >&2; return 1;;
+ esac
+ done
+ shift $(($OPTIND - 1))
+ [[ $# == 3 ]] || { usage >&2; return 1; }
+ local mode=$1
+ local url=${2#git+}
+ local dir=$3
+
+ local urlmain=${url%%#*}
+ local urlfrag=${url#*#}
+ if [[ "$urlfrag" == "$urlmain" ]]; then
+ urlfrag=''
+ fi
+ local ref=${urlfrag#*=}
+
+ if [[ -z $ref ]]; then
+ ref=master
+ fi
+
+ name=${name:-${dir##*/}}
+
+ case "$mode" in
+ checkout) download_git_checkout "$urlmain" "$ref" "$dir" "$name" "$push";;
+ bare) download_git_bare "$urlmain" "$dir" "$name" "$push";;
+ *) usage >&2; return 1;;
+ esac
+}
+
+main "$@"
diff --git a/src/gitget/libregit b/src/gitget/libregit
new file mode 100755
index 0000000..95b59ff
--- /dev/null
+++ b/src/gitget/libregit
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+# 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
+
+usage() {
+ print 'Usage: %s repo ref dir' "${0##*/}"
+ print 'A compatability wrapper around `gitget checkout`'
+ echo
+ prose "This exists because gitget used to be called libregit, and took
+ the arguments in this format, and I'm sure there are a few
+ scripts floating around that use it."
+ echo
+ prose "Clones or pulls from the git URL 'repo', and checks out the git
+ ref 'ref' to the directory 'dir'."
+}
+
+
+main() {
+ [[ $# == 3 ]] || { usage >&2; return 1; }
+ repo=$1
+ ref=$2
+ dir=$3
+
+ gitget checkout "${repo}#ref=${ref}" "${dir}"
+}
diff --git a/src/is_built b/src/is_built
index 80d0719..ba5f061 100755
--- a/src/is_built
+++ b/src/is_built
@@ -1,18 +1,21 @@
#!/usr/bin/env bash
-cmd=${0##*/}
+. libremessages
+
usage() {
- echo "Usage: $cmd [-h] pkgname [pkgver]"
+ print "Usage: %s [-h] PKGNAME [PKGVER]" "${0##*/}" "${0##*/}"
+ print 'Detect iv a given package (version) is already in the repos'
echo
- echo "Detect if a given package version is already in repos"
- echo "Assuming you want greater or equal."
+ prose "If a version is specified, it assumedx that you want a greater or
+ equal version."
echo
- echo "Example usage: $cmd 'pcre' '20'"
+ prose "Example usage:"
+ print " $ %s 'pcre' '20'" "${0##*/}"
echo
- echo "Exit status:"
- echo " 0: The package is built"
- echo " 1: The package has not built"
- echo " >1: There was an error"
+ print "Exit status:"
+ print " 0: The package is built"
+ print " 1: The package has not built"
+ print " >1: There was an error"
}
while getopts 'h' arg; do
diff --git a/src/lib/Makefile b/src/lib/Makefile
index 45fd330..495abb1 100644
--- a/src/lib/Makefile
+++ b/src/lib/Makefile
@@ -1,8 +1,10 @@
copy_files = common.sh.in
-libexecs = $(filter-out librelib,$(wildcard libre*))
+libexecs = $(filter-out librelib,$(progs))
# include common.sh in libs explicitly, because it might not exist yet
# when the wildcard is performed
libs = $(sort $(wildcard *.sh) common.sh)
+
+pots = $(libs)
include ../../common.mk
# Build ##############################################################
@@ -12,19 +14,24 @@ common.sh: %: %.in %.top Makefile
@{ \
cat '$*.top' && \
echo && \
- sed -r -e '/encoding problem/d;/LANG=/d' -e 's/mesg=\$$(.)/mesg="$$(_ "$$\1")"/' '$*.in' && \
+ sed -r \
+ -e '/encoding problem/d;/LANG=/d' \
+ -e 's/mesg=\$$(.)/mesg="$$(_ "$$\1")"/' \
+ -e 's/gettext /_l _ /g' \
+ -e "s/^(\s+)(msg|error) '/\1_l \2 '/" \
+ -e 's|lock\(\)\s*\{|lock()\n{|' \
+ '$*.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 $@ $<
+ sed -n '/^# Usage:/,/()/{ /^#/ { =; p; } }' $< | \
+ sed -r -e 's/^# (.*)/msgid "\1"\nmsgstr ""\n/' \
+ -e 's/^[0-9]*$$/#. embedded usage text\n#: $<:&/'; \
+ $(xgettext-sh-prose); \
+ $(xgettext-sh-std); \
+ } | $(pofmt) > $@
diff --git a/src/lib/blacklist.sh.3.ronn b/src/lib/blacklist.sh.3.ronn
new file mode 120000
index 0000000..9001445
--- /dev/null
+++ b/src/lib/blacklist.sh.3.ronn
@@ -0,0 +1 @@
+libreblacklist.1.ronn \ No newline at end of file
diff --git a/src/lib/common.sh.3.ronn b/src/lib/common.sh.3.ronn
new file mode 100644
index 0000000..2ec113c
--- /dev/null
+++ b/src/lib/common.sh.3.ronn
@@ -0,0 +1,16 @@
+common.sh -- common Bash routines from devtools
+===============================================
+
+## SYNPOSIS
+
+`. $(librelib common)`
+
+## DESCRIPTION
+
+In short, don't use this. Use `libremessages`(1) instead.
+`libremessages` uses this internally.
+
+## SEE ALSO
+
+ * librelib(7)
+ * libremessages(1)/messages.sh(3)
diff --git a/src/lib/common.sh.top b/src/lib/common.sh.top
index 054301b..9c4ba2e 100644
--- a/src/lib/common.sh.top
+++ b/src/lib/common.sh.top
@@ -13,14 +13,20 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
+shopt -s extglob
+
if [[ -z ${_INCLUDE_COMMON_SH:-} ]]; then
_INCLUDE_COMMON_SH=true
-export TEXTDOMAIN='libretools'
-export TEXTDOMAINDIR='/usr/share/locale'
+[[ -n ${TEXTDOMAIN:-} ]] || export TEXTDOMAIN='libretools'
+[[ -n ${TEXTDOMAINDIR:-} ]] || export TEXTDOMAINDIR='/usr/share/locale'
if type gettext &>/dev/null; then
_() { gettext "$@"; }
else
_() { echo "$@"; }
fi
+
+_l() {
+ TEXTDOMAIN='librelib' TEXTDOMAINDIR='/usr/share/locale' "$@"
+}
diff --git a/src/lib/conf.sh b/src/lib/conf.sh
index f96af26..ee52f6f 100644
--- a/src/lib/conf.sh
+++ b/src/lib/conf.sh
@@ -1,7 +1,7 @@
#!/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>
+# Copyright (C) 2012-2014 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
@@ -29,7 +29,7 @@ if [[ -z ${XDG_CACHE_HOME:-} ]]; then
export XDG_CACHE_HOME="${LIBREHOME}/.cache"
fi
-# Generic functions ############################################################
+# Low-level generic functions ##################################################
# Usage: list_files $slug
# Lists the configuration files to be considered for $slug.
@@ -61,7 +61,7 @@ list_files() {
}
# Usage: list_envvars $slug
-# Lists the environmental variables that take precidence over the configuration
+# Lists the environmental variables that take precedence over the configuration
# files for $slug.
list_envvars() {
local slug=$1
@@ -73,10 +73,16 @@ list_envvars() {
PKGEXT SRCEXT \
GPGKEY PACKAGER
;;
+ libretools)
+ printf '%s\n' \
+ DIFFPROG
+ ;;
*) :;;
esac
}
+# High-level generic functions #################################################
+
# Usage: load_files $slug
# Loads the configuration files for $slug in the proper order.
load_files() {
@@ -106,7 +112,7 @@ load_files() {
# 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() {
+check_vars() (
local slug=$1; shift
local ret=0
@@ -116,10 +122,10 @@ check_vars() {
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"
+ _l print "Configure '%s' in one of:" "$VAR"
list_files $slug | sed 's/./ -> &/'
else
- print "Configure '%s' in '%s'" "$VAR" "$(list_files $slug)"
+ _l print "Configure '%s' in '%s'" "$VAR" "$(list_files $slug)"
fi
ret=1
fi
@@ -128,24 +134,27 @@ check_vars() {
if [[ $ret != 0 ]]; then
return 1
fi
-}
-
-# makepkg configuration ########################################################
+)
-# Usage: get_conf_makepkg <var_name> <default_value>
-get_conf_makepkg() (
+# Usage: get_var <slug> <var_name> <default_value>
+# Does not work with arrays
+get_var() (
set +euE
- local setting=$1
- local default=$2
- load_files makepkg
- printf '%s\n' "${!setting:-${default}}"
+ local slug=$1
+ local setting=$2
+ local default=$3
+ load_files "$slug"
+ printf '%s' "${!setting:-${default}}"
)
-set_conf_makepkg() {
- local key=$1
- local val=$2
+# Usage: set_var <slug> <var_name> <value>
+# Does not work with arrays
+set_var() {
+ local slug=$1
+ local key=$2
+ local val=$3
local file
- for file in $(list_files makepkg|tac); do
+ for file in $(list_files "$slug"|tac); do
if [[ -w $file ]]; then
sed -i "/^\s*$key=/d" "$file"
printf '%s=%q\n' "$key" "$val" >> "$file"
@@ -185,6 +194,6 @@ unset_PKGBUILD() {
load_PKGBUILD() {
local file=${1:-./PKGBUILD}
unset_PKGBUILD
- CARCH="$(get_conf_makepkg CARCH "`uname -m`")"
+ CARCH="$(get_var makepkg CARCH "`uname -m`")"
. "$file"
}
diff --git a/src/lib/conf.sh.3.ronn b/src/lib/conf.sh.3.ronn
new file mode 100644
index 0000000..4108f9a
--- /dev/null
+++ b/src/lib/conf.sh.3.ronn
@@ -0,0 +1,128 @@
+conf.sh(3) -- easy loading of configuration files
+==============================================
+
+## SYNOPSIS
+
+`. $(librelib conf)`
+
+## DESCRIPTION
+
+`conf.sh` is a Bash(1) library to easily load various configuration
+files related to Arch Linux/Parabola(7) and libretools(7).
+
+I recommend reading the source yourself--it is mostly
+self-explanatory, and is shorter than this document.
+
+### VARIABLES
+
+When loading configuration files in a program run with `sudo`(8), it
+is often desirable to load the configuration files from the home
+directory of the user who called `sudo`, instead of from /root.
+
+To accommodate this, instead of using the usual $<USER> and $<HOME>,
+`conf.sh` sets $<LIBREUSER> and $<LIBREHOME>, which it then uses.
+
+ * <LIBREUSER>:
+ If $<SUDO_USER> is set, then $<LIBREUSER> is set to
+ that. Otherwise, $<LIBREUSER> is set to the value of $<USER>.
+ * <LIBREHOME>:
+ If $<LIBREUSER> == $<USER>, then $<LIBREHOME> is set to the value
+ of $<HOME>. Otherwise, it is set to the default home directory
+ of the user $<LIBREUSER>.
+
+Further, `conf.sh` works with XDG; it sets and uses
+$<XDG_CONFIG_HOME> and $<XDG_CACHE_HOME> with the following values:
+
+ * <XDG_CONFIG_HOME>:
+ If it isn't already set, it is set to "$<LIBREHOME>/.config" and
+ exported.
+ * <XDG_CACHE_HOME>:
+ If it isn't already set, it is set to "$<LIBREHOME>/.cache" and
+ exported.
+
+Note that only the XDG_* variables are exported.
+
+### GENERIC ROUTINES
+
+The following routines take a "slug" to refer to a group of
+configuration files; that is the basename of the files. For example,
+<SLUG>='abs' will identify `/etc/abs.conf` and `$<LIBREHOME>/.abs.conf`.
+
+The routines you will likely actually use are:
+
+ * `load_files` <SLUG>:
+ Loads the configuration files for <SLUG>, loading the files in
+ the correct order, and checking the appropriate environmental
+ variables.
+ * `check_vars` <SLUG> <VARS>...:
+ Checks to see if all of <VARS> are defined. If any of them
+ aren't, it prints a message to configure them in the
+ configuration files for <SLUG>, and returns with a non-zero
+ status.
+ * `get_var` <SLUG> <VAR> <DEFAULT>:
+ If <VAR> is set in the configuration for <SLUG>, print it's
+ value, considering environmental variables. If it is not set,
+ return <DEFAULT>. This does NOT work for array variables.
+ * `set_var` <SLUG> <VAR> <VALUE>:
+ Set the variable <VAR> equal to <VALUE> in the configuration file
+ for <SLUG> of highest precedence that already exists, and is
+ writable. If no files fit this description, the routine does
+ nothing and returns a non-zero exit status. This does NOT work
+ for array variables.
+
+There are two more routines the above routines use internally that are
+used internally by . You are unlikely to use them directly, but they
+might be useful for debugging, or at least describing behavior.
+
+ * `list_files` <SLUG>:
+ Lists (newline-separated) the configuration files that must be
+ considered for <SLUG>. Files listed later take precedence over
+ files listed earlier.
+ * `list_envvars` <SLUG>:
+ Lists (newline-separated) the environmental variables that take
+ precedence over the settings in the configuration files for
+ <SLUG>. For example, in `makepkg.conf`(8) (<SLUG>=makepkg), if the
+ <PACKAGER> environmental variable is set, the value in the
+ configuration file is ignored.
+
+### PKGBUILD ROUTINES
+
+These two routines deal with loading `PKGBUILD`(5) files.
+
+ * `unset_PKGBUILD`:
+ Unsets all variables and functions that might be set in a
+ `PKGBUILD`(5) file, including those specific to `librefetch`(8).
+ * `load_PKGBUILD` [<FILE>]:
+ "Safely" loads a PKGBUILD. Everything that it would normally set
+ is unset first, $<CARCH> is set according to `makepkg.conf`(5),
+ then the file is loaded. The file to be loaded is <FILE>, or
+ "./PKGBUILD" by default. This isn't safe, security wise, in that
+ the PKGBUILD is free to execute code.
+
+### SLUGS
+
+The differences in behavior for anything that takes a slug comes down
+to the differences in the output for `list_files` and `list_envvars`.
+
+The "known" slugs are "abs", "makepkg", and "libretools". If anything
+else is given, then:
+
+ * `list_files` will give back "/etc/libretools.d/<SLUG>.conf" and
+ "$<XDG_CONFIG_HOME>/libretools/<SLUG>.conf"
+ * `list_envvars` will give back an empty list.
+
+The rules for <SLUG>=(abs|makepkg|libretools) are more easily
+expressed in code than prose, so it is recommended that you look at
+that.
+
+## BUGS
+
+`get_var` and `set_var` do not work with arrays.
+
+## SEE ALSO
+
+librelib(7)
+
+abs.conf(5), makepkg.conf(5), libretools.conf(5), PKGBUILD(5)
+
+chroot.conf(5), librefetch.conf(5)
diff --git a/src/lib/libreblacklist b/src/lib/libreblacklist
index 5db1a3f..5525098 100755
--- a/src/lib/libreblacklist
+++ b/src/lib/libreblacklist
@@ -2,7 +2,7 @@
# 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>
+# Copyright (C) 2013-2014 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
@@ -48,7 +48,7 @@ blacklist-update() (
local remote_blacklist="$BLACKLIST"
local local_blacklist="$XDG_CACHE_HOME/libretools/blacklist.txt"
- stat_busy "Downloading blacklist of proprietary software packages"
+ _l 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
@@ -58,9 +58,9 @@ blacklist-update() (
stat_done
rm "${local_blacklist}.part"
if [[ -e "$local_blacklist" ]]; then
- warning "Using local copy of blacklist"
+ _l warning "Using local copy of blacklist"
else
- error "Download failed, exiting"
+ _l error "Download failed, exiting"
return 1
fi
@@ -109,6 +109,8 @@ if [[ "${0##*/}" == libreblacklist ]]; then
sed 's/\r/\n/g'<<<"$1"|sed -e '/^$/d' -e 's/^# //'
}
usage() {
+ export TEXTDOMAIN='librelib'
+ export TEXTDOMAINDIR='/usr/share/locale'
. $(librelib messages)
if [[ $# -eq 0 ]]; then
print "Usage: %s [-h] COMMAND [ARGUMENTS]" "${0##*/}"
@@ -135,7 +137,7 @@ if [[ "${0##*/}" == libreblacklist ]]; then
}
if [[ $# -eq 0 ]]; then
- usage >/dev/stderr
+ usage >&2
exit 1
fi
_blacklist_cmd=$1
diff --git a/src/lib/libreblacklist.1.ronn b/src/lib/libreblacklist.1.ronn
new file mode 100644
index 0000000..e44aa8d
--- /dev/null
+++ b/src/lib/libreblacklist.1.ronn
@@ -0,0 +1,23 @@
+libreblacklist(1) -- Tools for working with the your-freedom blacklist
+======================================================================
+
+## SYNPOSIS
+
+`. $(librelib blacklist)`<br>
+`. libreblacklist`<br>
+`libremessages` [-h] <COMMAND> [<ARGS>...]
+
+## DESCRIPTION
+
+`libreblacklist` is a set of tools for working with the your-freedom
+blacklist.
+
+It may be included into a `Bash`(1) program as a library, which will
+expose it's routines as "blacklist-<COMMAND>", or it may be invoked on
+the command line as "libreblacklist <COMMAND>".
+
+See `libremessages -h` for more information.
+
+## SEE ALSO
+
+librelib(7)
diff --git a/src/lib/librelib b/src/lib/librelib
index 2dc9314..d0a06e5 100755
--- a/src/lib/librelib
+++ b/src/lib/librelib
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-# Copyright (c) 2013 by Luke Shumaker <lukeshu@sbcglobal.net>
+# Copyright (C) 2013-2014 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
@@ -16,25 +16,39 @@
default_libdir=/usr/lib/libretools
-if ! type gettext &>/dev/null; then
- gettext() { echo "$@"; }
+if type gettext &>/dev/null; then
+ _() { gettext "$@"; }
+else
+ _() { echo "$@"; }
fi
+_l() {
+ TEXTDOMAIN='librelib' TEXTDOMAINDIR='/usr/share/locale' "$@"
+}
+
print() {
- mesg=$1
+ local mesg="$(_ "$1")"
shift
- printf -- "$(gettext "$mesg")\n" "$@"
+ printf -- "$mesg\n" "$@"
+}
+
+_html_whitespace_collapse() {
+ [[ $# == 0 ]] || panic
+ tr '\n' ' ' | sed -r -e 's/\t/ /g' -e 's/ +/ /g'
}
prose() {
- print "$@" | fmt -su
+ [[ $# -ge 1 ]] || panic
+ local mesg="$(_ "$(_html_whitespace_collapse <<<"$1")")"; shift
+ printf -- "$mesg" "$@" | fmt -u
}
cmd=${0##*/}
usage() {
. libremessages
print 'Usage: . $(%s LIBRARY)' "$cmd"
- print "Finds a shell library file"
+ print 'Usage: %s -h' "$cmd"
+ print "Finds a Bash 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
@@ -45,16 +59,19 @@ usage() {
changed with the environmental variable LIBRETOOLS_LIBDIR.' "$default_libdir"
echo
print "Example usage:"
- printf ' . $(%s conf.sh)\n' "$cmd"
+ printf ' . $(%s conf)\n' "$cmd"
+ echo
+ print "Options:"
+ flag '-h' 'Show this message'
}
main() {
if [[ $# != 1 ]]; then
- usage >&2
+ _l usage >&2
return 2
fi
if [[ $1 == '-h' ]]; then
- usage
+ _l usage
return 0;
fi
@@ -72,7 +89,7 @@ main() {
return 0;
fi
done
- print '%s: could not find library: %s' "$cmd" "$lib" >> /dev/stderr
+ _l print '%s: could not find library: %s' "$cmd" "$lib" >&2
return 1
}
diff --git a/src/lib/librelib.1.ronn b/src/lib/librelib.1.ronn
new file mode 100644
index 0000000..42d8f15
--- /dev/null
+++ b/src/lib/librelib.1.ronn
@@ -0,0 +1,55 @@
+librelib(1) -- finds a Bash library file
+========================================
+
+## SYNOPSIS
+
+`. $(librelib LIBRARY)`<br>
+`librelib -h`
+
+## DESRIPTION
+
+`librelib` is a program to find a Bash(1) library file at run-time.
+This way, the path does not need to be hard-coded into the
+application; think of it as a sort of dynamic-linker for shell
+programs.
+
+There are several reasons for doing this, instead of hard-coding the
+path:
+
+ * The install path can change in the future without having to change
+ programs that use them.
+ * The install directory can be configured at runtime, by setting
+ `LIBRETOOLS_LIBDIR`, similar to `LD_PRELOAD` (this is used when
+ running the test suite).
+ * The naming scheme of a library can change (such as between
+ `libreNAME` and `NAME.sh` without changing programs that use it.
+
+By default, `librelib` looks in `/usr/lib/libretools`, but that can be
+changed by setting the `LIBRETOOLS_LIBDIR` environmental variable to
+the directory it should look in.
+
+When searching for a library, `librelib` first strips `libre` from the
+beginning of the name, and `.sh` from the end. This means that all of
+the following are equivalent:
+
+ . $(librelib messages)
+ . $(librelib messages.sh)
+ . $(librelib libremessages)
+ . $(librelib libremessages.sh)
+
+Once it has the 'base' name of the library it is looking for, it looks
+for a file with that 'base' name (allowing for, but not requiring
+`libre` to be prepended, or `.sh` to be appended) in whichever
+directory it is looking in.
+
+If it cannot find a suitable library file, it will print an error
+message to standard error, and exit with a code of 1.
+
+## Examples
+
+ . $(librelib messages)
+ . $(librelib conf)
+
+## SEE ALSO
+
+librelib(7)
diff --git a/src/lib/librelib.7.ronn b/src/lib/librelib.7.ronn
new file mode 100644
index 0000000..e030f6a
--- /dev/null
+++ b/src/lib/librelib.7.ronn
@@ -0,0 +1,50 @@
+librelib(7) -- Suite of Bash libraries
+======================================
+
+## SYNOPSIS
+
+Overview ot the librelib Bash library suite.
+
+## DESCRIPTION
+
+There are three parts to librelib:
+
+ 1. The `librelib`(1) executable.
+ 2. The non-executable libraries installed in `/usr/lib/libretools`
+ 3. The executable libraries installed in both `/usr/bin` and
+ `/usr/lib/libretools`.
+
+The `librelib` executable isn't very exciting, it just finds the
+libraries installed in `/usr/lib/libretools`. Think of it as a sort
+of dynamic-linker.
+
+The 'core' of librelib are the libraries installed in
+`/usr/lib/libretools`. These are `Bash`(1) libaries that may be sourced in
+Bash programs.
+
+Some of these libraries also make sense as stand-alone programs, where
+if they are invoked directly, the first argument is the library
+routine to be executed. For example, the `messages` library may be
+included, or executed:
+
+ . $(librelib messages)
+ msg2 "Foo was found: %s" "$foo"
+ # or
+ libremessages msg2 "Foo was found: %s" "$foo"
+
+The `blacklist` library is similar:
+
+ . $(librelib blacklist)
+ blacklist-update
+ # or
+ libreblacklist update
+
+
+
+## SEE ALSO
+
+ * librelib(1)
+ * libremessages(1)/messages.sh(3)
+ * libreblacklist(1)/blacklist.sh(3)
+ * conf.sh(3)
+ * common.sh(3)
diff --git a/src/lib/libremessages b/src/lib/libremessages
index c6d08e2..e5b7157 100755
--- a/src/lib/libremessages
+++ b/src/lib/libremessages
@@ -2,15 +2,15 @@
# 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>
+# 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-2014 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
@@ -36,7 +36,7 @@
################################################################################
panic() {
- echo "$(_ 'panic: malformed call to internal function')" >&2
+ echo "$(_l _ 'panic: malformed call to internal function')" >&2
exit 1
}
@@ -88,8 +88,6 @@ bullet() {
# bullet.
flag() {
[[ $# == 2 ]] || panic
- local n='
-'
local flag=$1
local desc="$(_ "$(_html_whitespace_collapse <<<"$2")")"
@@ -99,7 +97,7 @@ flag() {
done
local lines
- IFS=$n lines=($(fmt -u -w $((73-indent)) <<<"$desc"))
+ IFS=$'\n' lines=($(fmt -u -w $((73-indent)) <<<"$desc"))
local line
for line in "${lines[@]}"; do
printf " %-${indent}s %s\n" "$flag" "$line"
@@ -119,6 +117,25 @@ term_title() {
printf "$fmt" "$*"
}
+# Usage: setup_traps
+# Sets up traps on TERM, HUP, QUIT and INT signals, as well as the ERR event,
+# similar to makepkg
+setup_traps() {
+ _libremessages_trap_exit() {
+ local signal=$1; shift
+ echo
+ error "$@"
+ trap -- "$signal"
+ kill "-$signal" "$$"
+ }
+ set -E
+ for signal in TERM HUP QUIT; do
+ trap "_libremessages_trap_exit $signal '%s signal caught. Exiting...' $signal" $signal
+ done
+ trap '_libremessages_trap_exit INT "Aborted by user! Exiting..."' INT
+ trap '_libremessages_trap_exit USR1 "An unknown error has occurred. Exiting..."' ERR
+}
+
################################################################################
# Run one of the defined functions if invoked directly #
################################################################################
diff --git a/src/lib/libremessages.1.ronn b/src/lib/libremessages.1.ronn
new file mode 100644
index 0000000..d4c35fc
--- /dev/null
+++ b/src/lib/libremessages.1.ronn
@@ -0,0 +1,220 @@
+libremessages(1) -- common Bash routines
+========================================
+
+## SYNOPSIS
+
+`. $(librelib messages)`<br>
+`. libremessages`<br>
+`libremessages` <COMMAND>
+
+## DESCRIPTION
+
+`libremessages` is a shell library containing many common routines.
+The name is a bit of a misnomer, it mostly deals with printing
+messages, but also has other things.
+
+`libremessages` uses `common.sh`(3) internally for a large portion of
+it's functionality. The authors make no promises that functionality
+that is implemented in `libremessages` won't move into `common.sh` or
+vice-versa. So, it is recommended that you use `libremessages`, not
+`common.sh`.
+
+### STAND ALONE USAGE
+
+The "normal" way to use libremessages is to source it, then call the
+provided routines.
+
+However, if you call libremessages directly, the first argument is
+taken as a the function to call, and the remaining arguments are
+passed to it. The only cases where this doesn't work are the lockfile
+routines (`lock`, `slock`, and `lock_close`), because lockfiles are
+managed as file descriptors.
+
+### VARIABLES
+
+The following variables for printing terminal color codes are set:
+`ALL_OFF`, `BOLD`, `BLUE`, `GREEN`, `RED`, `YELLOW`. If standard
+error is not a terminal (see `isatty`(3)), they are set, but empty.
+They are marked as readonly, so it is an error to try to set them
+afterwords.
+
+### MESSAGE FORMAT
+
+All routines feed the message/format string through `gettext`(1), if
+it is available.
+
+The descriptions will frequently reference `printf`(1)--this isn't
+really that `printf`. The program described by the manual page
+`printf`(1) is probably the version from GNU coreutils, every time it
+is used here, it is `bash`(1)'s internal implementation; try running
+the command `help printf` from a Bash shell for more information.
+
+### GENERAL ROUTINES
+
+Unless otherwise noted, these do not implicitly call `gettext`.
+
+ * `_` <MESSAGE>:
+ If `gettext` is available, calls `gettext`, otherwise just prints
+ the arguments given.
+
+ * `in_array` <NEEDLE> <HAYSTACK>...:
+ Evaluates whether <HAYSTACK> includes <NEEDLE>; returns 0 if it
+ does, non-zero if it doesn't.
+
+ * `panic`:
+ For the times when you can't reasonably continue, similar to
+ "assert" in some programming languages.
+
+ * `term_title` <MESSAGE>...:
+ Joins all arguments with whitespace, and sets the terminal title
+ to that.
+
+ * `setup_traps`:
+ Sets traps on TERM, HUP, QUIT and INT signals, as sell as the ERR
+ event, similar to makepkg.
+
+### PROSE ROUTINES
+
+These routines print to standard output, ande are useful for printing
+word-wrapped prose.
+
+For each of these, <MESSAGE> is fed through `gettext` automatically.
+
+ * `print` <MESSAGE> [<ARGS>...]:
+ Like `printf`(1), but `gettext`-aware, and automatically prints a
+ trailing newline.
+
+ * `prose` <MESSAGE> [<ARGS>...]:
+ Takes a `printf`(1)-formatted string, collapses whitespace
+ (HTML-style), and then word-wraps it.
+
+ * `bullet` <MESSAGE> [<ARGS>...]:
+ Similar to `prose`, but prints a bullet point before the first
+ line, and indents the remaining lines.
+
+ * `flag` <FLAG> <DESCRIPTION>:
+ Print a flag and description formatted for `--help` text. For
+ example:<br>
+ `flag '-N' 'Disable networking in the chroot'`<br>
+ 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:<br>
+ `flag "-C <$(_ FILE)>" 'Use this file instead of pacman.conf'`<br>
+ Newlines in the description are ignored; it is
+ whitespace-collapsed (so newlines are stripped), then it is
+ re-word-wrapped, in the same way as `prose` and `bullet`.
+
+### NOTIFICATION ROUTINES
+
+These routines print to standard error, and all take arguments in the
+same format as `printf`(1), except for `stat_done`, which doesn't take
+any arguments. Each of these print to stderr, not stdout.
+
+For each of these, <MESSAGE> is fed through `gettext` automatically.
+
+ * `plain` <MESSAGE> [<ARGS>...]:
+ Prints "plain" message in bold, indented with 4 spaces.
+
+ * `msg` <MESSAGE> [<ARGS>...]:
+ Prints a top-level priority notification.
+
+ * `msg2` <MESSAGE> [<ARGS>...]:
+ Prints a secondary notification.
+
+ * `warning` <MESSAGE> [<ARGS>...]:
+ Prints a warning.
+
+ * `error` <MESSAGE> [<ARGS>...]:
+ Prints an error message.
+
+ * `stat_busy` <MESSAGE> [<ARGS>...]:
+ Prints a "working..." type message without a trailing newline.
+
+ * `stat_done`:
+ Prints a "done" type message to terminate `stat_busy`.
+
+### TEMPORARY DIRECTORY MANAGEMENT
+
+These are used by devtools, and not used within the rest of
+libretools.
+
+They work by creating and removing the directory referred to by the
+variable $<WORKDIR>; `libretools.conf`(5) uses the same variable to
+where the user saves all their work. If you aren't careful with
+these, you could end up deleting a lot of someone's work.
+
+ * `setup_workdir`:
+ Creates a temporary directory, and sets the environmental
+ variable $<WORKDIR> to it. Also sets traps for the signals INT,
+ QUIT, TERM and HUP to run `abort`; and EXIT to run `cleanup`
+ (see `signal`(7)).
+
+ * `cleanup` [<EXIT_STATUS>]:
+ *If* `setup_workdir` has been run, `rm -rf "$WORKDIR"`. If given
+ a numeric argument, it will then call `exit`(1) with that argument.
+
+ * `abort`:
+ Calls `msg` with the message "Aborting...", then calls
+ `cleanup 0`.
+
+ * `die` <MESSAGE> [<ARGS>...]:
+ Exactly like `error`, but calls `cleanup` and calls `exit`(1)
+ with a status of 1.
+
+### LOCKFILE ROUTINES
+
+ * `lock` <FD> <LOCKFILE> <MESSAGE> [<MSG_ARGS>...]:
+ Opens (creating if nescessary) the file <LOCKFILE> with file
+ descriptor <FD> in the current process, and gets an exclusive
+ lock on it. If another program already has a lock on the file,
+ and this program needs to wait for the lock to be release, then
+ it uses `stat_busy`/`stat_done` to print <MESSAGE>.
+
+ * `slock` <FD> <LOCKFILE> <MESSAGE> [<MSG_ARGS>...]:
+ Identical like `lock`, but opens a shared lock. This is also
+ known as a "read lock". Many programs can have a shared lock at
+ the same time, as long as no one has an exclusive lock on it.
+
+ * `lock_close` <FD>:
+ Closes file descriptor <FD>, releasing the lock opened on it.
+
+### MAKEPKG ROUTINES
+
+These routines relate to `makepkg`(8).
+
+ * `find_cached_package` <PKGNAME> <PKGVER>[-<PKGREL] <ARCH>:
+ Searches for a localy built copy of the specified package, in
+ <PKGDEST> and the current working directory. If <PKGREL> is not
+ specified, any value will match. If multiple matching files are
+ found (not counting duplicate links), then an error is printed to
+ stderr and nothing is prented to stdout.
+
+ * `get_full_version` [<PKGNAME>]:
+ Inspects variables that are set, and prints the full version
+ spec, including <epoch> if necessary, <pkgver>, and <pkgrel>. By
+ default, it will print the information for <pkgbase>, following
+ the normal rules for finding <pkgbase>. If <PKGNAME> is given,
+ it will print the information for that sub-package. The versions
+ for different parts of a split package don't have to be the same!
+
+## BUGS
+
+Generating `.pot` files for the prose functions is a pain. The
+libretools Makefiles have rules to do it, but it might make sense to
+pull it into a separate program.
+
+`term_title` currently only knows about the terminals screen, tmux,
+xterm and rxvt (and their various <TERM> values;
+"rxvt-unicode-256color" is still rxvt).
+
+Also, I think `abort` calling `cleanup 1` would make more sense than
+`cleanup 0`.
+
+## SEE ALSO
+
+librelib(7), gettext(1), common.sh(3)
+
+Things that were mentioned:
+
+bash(1), exit(1), isatty(3), libretools.conf(5), makepkg(8),
+printf(1), signal(7)
diff --git a/src/lib/messages.sh.3.ronn b/src/lib/messages.sh.3.ronn
new file mode 120000
index 0000000..391ecbd
--- /dev/null
+++ b/src/lib/messages.sh.3.ronn
@@ -0,0 +1 @@
+libremessages.1.ronn \ No newline at end of file
diff --git a/src/librefetch/librefetch b/src/librefetch/librefetch
index 086a5e9..82c8703 100755
--- a/src/librefetch/librefetch
+++ b/src/librefetch/librefetch
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# librefetch
-#
-# Copyright 2013 Luke Shumaker <lukeshu@sbcglobal.net>
+#
+# Copyright (C) 2013-2014 Luke Shumaker <lukeshu@sbcglobal.net>
#
# This file is part of Parabola.
#
@@ -18,60 +18,58 @@
# 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
+. $(librelib conf)
+. $(librelib messages)
+setup_traps
declare -r tempdir="$(mktemp -d --tmpdir ${0##*/}.XXXXXXXXXXX)"
-cleanup() { rm -rf -- "$tempdir"; }
-trap cleanup EXIT
+trap "rm -rf -- $(printf '%q' "$tempdir")" EXIT
cmd=${0##*/}
usage() {
- print "Usage: %s [options] <source-url> [<output-file>]" "$cmd"
- print "Usage: %s -[g|P|V|h]" "$cmd"
+ print "Usage: %s [OPTIONS] SOURCE_URL [OUTPUT_FILE]" "$cmd"
+ print "Usage: %s -[g|P|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."
+ prose "The default mode is to create OUTPUT_FILE, first by trying
+ download mode, then create mode."
+ echo
+ prose "If OUTPUT_FILE isn't specified, it defaults to the non-directory
+ part of SOURCE_URL, in the current directory."
echo
- print "If <output-file> isn't specified, it defaults to the non-directory"
- print "part of <source-url>, in the current directory."
+ prose "Unless '-C' is specified, if SOURCE_URL does not begin with a
+ configured mirror, create mode is inhibited."
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."
+ prose "In download mode, it simply tries to download SOURCE_URL. At the
+ beginning of a URL, 'libre://' expands to the first configured
+ mirror."
echo
- 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>."
+ prose "In create mode, it looks at a build script, and uses that to
+ create the source tarball. SOURCE_URL is ignored, except that it
+ is used to set the default value of OUTPUT_FILE."
echo
- print "The default build script is 'PKGBUILD', or 'SRCBUILD' if it exists."
+ prose "The default build script is 'PKGBUILD', or 'SRCBUILD' if it
+ exists."
echo
- print "Unrecognized options are passed straight to makepkg."
+ prose "Unrecognized options are passed straight to makepkg."
+ echo
+ prose "%s does NOT support getopt-style flag combining. You must use
+ '-a -b', not '-ab'." "$cmd"
echo
print "Example usage:"
- print ' $ %s libre://mypackage-1.0.tar.gz' "$cmd"
+ print ' $ %s https://repo.parabolagnulinux.org/other/mypackage/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"
+ flag "-C" "Force create mode (don't download)"
+ flag "-D" "Force download mode (don't create)"
+ flag "-p <$(_ FILE)>" "Use an alternate build script (instead of
+ 'PKGBUILD') If an SRCBUILD exists in the same
+ directory, it is used 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."
+ flag "-g, --geninteg" "Generage integrity checks for source files"
+ flag "-P, --print" "Print the effective build script (SRCBUILD)"
+ flag "-h, --help" "Show this message"
}
main() {
@@ -81,12 +79,8 @@ main() {
mode=download-create
parse_options "$@"
- # Mode: version, help ##################################################
+ # Mode: help ###########################################################
- if [[ $mode =~ version ]]; then
- version
- return 0
- fi
if [[ $mode =~ help ]]; then
usage
return 0
@@ -97,20 +91,20 @@ main() {
local BUILDFILEDIR="${BUILDFILE%/*}"
if [[ -f "${BUILDFILEDIR}/SRCBUILD" ]]; then
BUILDFILE="${BUILDFILEDIR}/SRCBUILD"
- srcbuild="$(modified_srcbuild "$BUILDFILE")"
- else
- srcbuild="$(modified_pkgbuild "$BUILDFILE")"
fi
+ if [[ ! -f "$BUILDFILE" ]]; then
+ error "%s does not exist." "$BUILDFILE"
+ exit 1
+ fi
+ case "$BUILDFILE" in
+ */SRCBUILD) srcbuild="$(modified_srcbuild "$BUILDFILE")";;
+ *) srcbuild="$(modified_pkgbuild "$BUILDFILE")";;
+ esac
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/ &/';;
@@ -122,45 +116,52 @@ main() {
# 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
+ local src="${extra_opts[0]}"
+ local dst="${extra_opts[1]:-${src##*/}}"
+
+ # Don't canonicalize $src unless mode =~ download, and we've validated
+ # that $MIRRORS is configured.
+
+ # Canonicalize $dst
+ dst="$(readlink -m -- "$dst")"
# Mode: download #######################################################
if [[ $mode =~ download ]]; then
load_files librefetch
- check_vars librefetch MIRROR DOWNLOADER || return 1
+ check_vars librefetch MIRRORS DOWNLOADER || return 1
+
+ # Canonicalize $src
+ if [[ "$src" == libre://* ]]; then
+ src="${MIRRORS[0]}/${src#libre://}"
+ fi
- local url="${MIRROR}/${src}"
+ # check to see if $src is a candidate for create mode
+ local inmirror=false;
+ local mirror
+ for mirror in "${MIRRORS[@]}"; do
+ if [[ "$src" == "$mirror"* ]]; then
+ inmirror=true
+ break
+ fi
+ done
+ if ! $inmirror; then
+ # inhibit create
+ mode=download
+ fi
local dlcmd="${DOWNLOADER}"
- dlcmd="${dlcmd//\%o/\"$dst\"}"
- dlcmd="${dlcmd//\%u/\"$url\"}"
- { eval "$dlcmd"; } >> /dev/stderr && return 0
+ [[ $dlcmd = *%u* ]] || dlcmd="$dlcmd %u"
+ dlcmd="${dlcmd//\%o/"\$dst"}"
+ dlcmd="${dlcmd//\%u/"\$src"}"
+
+ { eval "$dlcmd"; } >&2 && return 0
fi
# Mode: create #########################################################
@@ -172,16 +173,23 @@ main() {
export pkg_file=$dst
cd "$BUILDFILEDIR"
- "$makepkg" "${makepkg_opts[@]}" -p "$srcbuild" >> /dev/stderr || return $?
+ "$makepkg" "${makepkg_opts[@]}" -p "$srcbuild" >&2 || 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'))
+ # Detect makepkg options
+ local makepkg_orig="$(which makepkg)"
+ # --long flags that take a second argument
+ local makepkg_opt2long=( $(LC_ALL=C "${makepkg_orig}" -h | sed -rn 's/\s*(--\S*) <.*/\1/p'))
+ # -s hort flags that take a second argument
+ local makepkg_opt2short=($(LC_ALL=C "${makepkg_orig}" -h | sed -rn 's/\s*(-.) <.*/\1/p'))
+ # all flags
+ local makepkg_argall=( $(LC_ALL=C "${makepkg_orig}" -h | sed -rn \
+ -e 's/^ +(-.) .*/\1/p' \
+ -e 's/^ +(-.), (--\S*) .*/\1\n\2/p' \
+ -e 's/^ +(--\S*) .*/\1/p'))
local opt
local have_opt
@@ -204,18 +212,42 @@ parse_options() {
-g|--geninteg) mode=checksums;;
-P|--print) mode=print;;
-p) BUILDFILE="$(readlink -m -- "$opt")";;
- -V|--version) mode=version;;
-h|--help) mode=help;;
+ --) shift; break;;
-*)
- makepkg_opts+=("$arg")
- $have_opt && makepkg_opts+=("$opt")
+ if in_array "${arg}" "${makepkg_argall[@]}"; then
+ makepkg_opts+=("$arg")
+ $have_opt && makepkg_opts+=("$opt")
+ else
+ printf '%s: invalid flag: %s' "$cmd" "$arg"
+ return 1
+ fi
;;
- --) shift; break;;
*) extra_opts+=("$arg");;
esac
shift
done
extra_opts+=("$@")
+
+ # check the number of extra_opts
+ case "$mode" in
+ help) # don't worry about it
+ :;;
+ checksums|print) # don't take any extra arguments
+ if [[ ${#extra_opts[@]} != 0 ]]; then
+ print "%s: found extra non-flag arguments: %s" "$cmd" "${extra_opts[*]}" >&2
+ usage >&2
+ return 1
+ fi
+ ;;
+ *download*|*create*) # take 1 or 2 extra arguments
+ if [[ ${#extra_opts[@]} != 1 ]] && [[ ${#extra_opts[@]} != 2 ]]; then
+ print "%s: %d non-flag arguments found, expected 1 or 2: %s" "$cmd" ${#extra_opts[@]} >&2
+ usage >&2
+ return 1
+ fi
+ ;;
+ esac
}
# Modify makepkg ###############################################################
@@ -232,7 +264,11 @@ makepkg_modify='
/tidy_install\(\) \{/,/^\}$/ {
/for .*PURGE_TARGETS/itidy_install_purge
/for .*PURGE_TARGETS/,/done/d
- /^\}$/ifind . -exec touch --date="1990-01-01 0:0:0 +0" {} +
+ /^\}$/ifind . -exec touch --no-dereference --date="1990-01-01 0:0:0 +0" -- {} +
+}
+
+/download_sources\(\) \{/ {
+ arm -rf "$srcdir"\nmkdir "$srcdir"
}
s|srcdir=.*|&-libre|
@@ -298,8 +334,8 @@ checkdepends=()
makedepends=("${mkdepends[@]}")
####
-options+=(!strip docs libtool emptydirs !zipman purge !upx)
-PURGE_TARGETS+=(.bzr/ .cvs/ .git/ .hg/ .svn/ .makepkg/)
+options=(!strip docs libtool staticlibs emptydirs !zipman purge !upx)
+PURGE_TARGETS=(.bzr/ .cvs/ .git/ .hg/ .svn/ .makepkg/)
####
if ! declare -f mksource >/dev/null; then
diff --git a/src/librefetch/librefetch.8.ronn b/src/librefetch/librefetch.8.ronn
index 7fa15d4..7d2dfb3 100644
--- a/src/librefetch/librefetch.8.ronn
+++ b/src/librefetch/librefetch.8.ronn
@@ -3,32 +3,40 @@ librefetch(8) -- downloads or creates a liberated source tarball
## SYNOPSIS
-`librefetch` [options] <source-url> [<output-file>]<br>
-`librefetch` -[g|V|h]
+`librefetch` [<OPTIONS>] <SOURCE-URL> [<OUTPUT-FILE>]<br>
+`librefetch` `-`[`g`|`P`|`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.
+If a URL mentioned in the `source` array in a `PKGUILD` is in a
+location that Parabola uploads "custom" source tarballs (or configured
+locations), and no file is at that URL, librefetch will automatically
+create it for you.
-There are 7 modes:
+This works because a post-install script for the package configures
+`librefetch` as the download agent for `https://` URLs in
+`makepkg.conf`; allowing it to jump in and create a file if need be.
+Because of this, it is almost never necessary to call `librefetch`
+manually.
+
+The post-install script also configures `librefetch` as the download
+agent for `libre://` URLs, for compatability with PKGBUILDs that used
+a previous version of librefetch.
+
+There are 5 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.
+The normal mode of operation is `download` mode. If `download` mode
+fails, it may choose to try `create` mode.
+
## OPTIONS
* `-C`: Force `create` mode (don't download)
@@ -39,9 +47,26 @@ There are 7 modes:
* `-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.
+## DOWNLOAD MODE
+
+If <SOURCE-URL> begins with the string `libre://`, it is replaced with
+the first value in `MIRRORS`, as configured in `librefetch.conf(5)`;
+this is for compatability with PKGBUILDs that used a previous version
+of librefetch.
+
+It uses `DOWNLOADER`, as configured in `librefetch.conf` to attempt to
+download the source tarball from that URL. If that fails, and
+following conditions are met, it proceeds to `create` mode:
+
+ * The `-D` flag has not been specified to inhibit `create` mode.
+ * The `<source-url>` begins with one of the values in `MIRRORS`.
+
+The latter requirement allows librefetch to be used as a generic
+HTTP(S) download agent, that can automatically create files from
+whitelisted locations.
+
## CREATE MODE
The principle of `create` mode is that a special `PKGBUILD(5)`, called
@@ -128,11 +153,11 @@ Other changes:
* `options=()` is set have `makepkg` avoid making changes to
`$pkgdir`. The exact change is:
- options+=(!strip docs libtool emptydirs !zipman purge !upx)
+ options=(!strip docs libtool staticlibs emptydirs !zipman purge !upx)
* `PURGE_TARGETS=()` has vcs directories added to it:
- PURGE_TARGETS+=(.bzr/ .cvs/ .git/ .hg/ .svn/ .makepkg/)
+ PURGE_TARGETS=(.bzr/ .cvs/ .git/ .hg/ .svn/ .makepkg/)
### MAKEPKG MODIFICATIONS
diff --git a/src/librefetch/librefetch.conf b/src/librefetch/librefetch.conf
index 40d2078..6948e8d 100644
--- a/src/librefetch/librefetch.conf
+++ b/src/librefetch/librefetch.conf
@@ -1,2 +1,5 @@
-MIRROR='https://repo.parabolagnulinux.org/sources/'
+MIRRORS=(
+ 'https://repo.parabolagnulinux.org/sources/'
+ 'https://repo.parabolagnulinux.org/other/'
+)
DOWNLOADER='/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'
diff --git a/src/librefetch/librefetch.conf.5.ronn b/src/librefetch/librefetch.conf.5.ronn
index 3d80ab5..6158104 100644
--- a/src/librefetch/librefetch.conf.5.ronn
+++ b/src/librefetch/librefetch.conf.5.ronn
@@ -24,13 +24,19 @@ If `$XDG_CONFIG_HOME` is not set, a default value is set:
## OPTIONS
- * `MIRROR='https://repo.parabolagnulinux.org/sources/'`:
- The location to download pre-built source tarball in download
- mode.
+ * `MIRRORS=( ... )`:
+ A list of locations that generated source tarballs may be located
+ at. If a URL begins with `libre://`, then `libre://` is replaced
+ with the first location listed here.
* `DOWNLOADER='/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'`:
The HTTP client to use when downloading pre-built source tarballs
- in download mode.
+ in download mode. The format and semantics are similar to
+ `DLAGENTS` in `makepkg.conf`(5). If present, `%u` will be replaced
+ with the download URL (correctly quoted), otherwise the download
+ URL will be appended to the end of the command. If present, `%o`
+ will be replaced with the local filename that it should be
+ downloaded to.
## SEE ALSO
-librefetch(8)
+librefetch(8), makepkg.conf(5)
diff --git a/src/libregit/libregit b/src/libregit/libregit
deleted file mode 100755
index 8687d2f..0000000
--- a/src/libregit/libregit
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/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
index 593aed6..4b1973a 100644
--- a/src/libretools.conf
+++ b/src/libretools.conf
@@ -5,14 +5,14 @@
################################################################################
# The dir where you work on
-WORKDIR=/home/$LIBREUSER/packages
+WORKDIR="$LIBREHOME/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'`
+DIFFPROG=`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`
@@ -27,17 +27,17 @@ REPOS=('core' 'libre' 'extra' 'community' 'libre-testing' 'social' 'sugar' 'pcr'
ARCHES=('x86_64' 'i686' 'mips64el')
## ABSLibre
-#ABSLIBREGIT=http://projects.parabolagnulinux.org/abslibre.git
-ABSLIBREGIT=ssh://git@projects.parabolagnulinux.org:1863/srv/git/abslibre.git
+## Used by `createworkdir`
+ABSLIBRERECV=git://projects.parabolagnulinux.org/abslibre.git
+ABSLIBRESEND=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
+# '/staging/' is appended; this is for compatability with previous versions.
+REPODEST=repo@repo:/srv/http/repo/staging/$LIBREUSER
## Assumes something similar in your .ssh/config:
# Host repo
# Port 1863
diff --git a/src/mips64el-tools/mipsrelease b/src/mips64el-tools/mipsrelease
index de17651..ea15f85 100755
--- a/src/mips64el-tools/mipsrelease
+++ b/src/mips64el-tools/mipsrelease
@@ -5,7 +5,7 @@
# Called by HOOKLOCALRELEASE
# $1 repo
-# $2+ packages
+# $2+ packages
. libremessages
. $(librelib conf.sh)
diff --git a/src/pkgbuild-check-licenses b/src/pkgbuild-check-licenses
deleted file mode 100755
index 85ca2c3..0000000
--- a/src/pkgbuild-check-licenses
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/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
index 1cc0d9b..7b73745 100755
--- a/src/pkgbuild-check-nonfree
+++ b/src/pkgbuild-check-nonfree
@@ -1,10 +1,12 @@
#!/usr/bin/env bash
+# -*- tab-width: 4 ; sh-basic-offset: 4 -*-
# pkgbuild-check-nonfree
-# Copyright 2010 Haase Hernández
-# Copyright 2010 Joseph Graham
-# Copyright 2010 Joshua Ismael
-# Copyright 2012-2013 Luke Shumaker
+# Copyright (C) 2010 Haase Hernández
+# Copyright (C) 2010 Joseph Graham
+# Copyright (C) 2010 Joshua Ismael
+# Copyright (C) 2010 Nicolás Reynolds
+# Copyright (C) 2012-2013 Luke Shumaker
#
# This file is part of Parabola.
#
@@ -21,80 +23,61 @@
# 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
+# I appologize that this program got *huge*.
+# It's not complicated, just long.
- 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
-)
+. $(librelib messages)
+. $(librelib conf)
+. $(librelib blacklist)
usage() {
print "Usage: %s [OPTIONS] [PKGBUILD1 PKGBUILD2 ...]" "${0##*/}"
+ print "Analyzes a PKGBUILD for freedom issues"
echo
prose 'If no PKGBUILD is specified, `./PKGBUILD` is implied.'
echo
- print "Exit status:"
+ print "Exit status (add them for combinations):"
print " 0: Everything OK, no freedom issues"
print " 1: Ran with error"
- print " 15: Depends on non-free packages"
+ print "Warning-level freedom issues:"
+ print " 2: Uses unrecognized licenses, check them"
+ print " 4: Uses GPL-incompatible licenses"
+ print "Error-level freedom issues:"
+ print " 8: Uses known unacceptable licenses"
+ print " 16: Has nonfree dependencies"
+ print " 32: Is a known nonfree package"
echo
print "Options:"
- flag '-c' 'Use the cached blacklist, do not try downloading.'
+ flag '-c' 'Use the cached blacklist, do not try downloading'
flag '-f' 'Allow running as root user'
+ echo
+ flag '-q' 'Be quiet'
+ flag '-v' 'Be verbose'
+ echo
flag '-h' 'Show this message'
}
+# Make sure these match pkgbuild-summarize-nonfree
+declare -ri _E_OK=0
+declare -ri _E_ERROR=1
+declare -ri _E_LIC_UNKNOWN=2
+declare -ri _E_LIC_NOGPL=4
+declare -ri _E_LIC_NONFREE=8
+declare -ri _E_DEP_NONFREE=16
+declare -ri _E_PKG_NONFREE=32
main() {
- local asroot=false
+ # Parse flags
local cache=false
- while getopts 'cfh' arg; do
+ local asroot=false
+ local v=1
+ while getopts 'cfqvh' arg; do
case "$arg" in
c) cache=true;;
f) asroot=true;;
- h) usage; return 0;;
- *) usage; return 1;;
+ q) v=0;;
+ v) v=2;;
+ h) usage; return $_E_OK;;
+ *) usage >&2; return $_E_ERROR;;
esac
done
shift $(($OPTIND - 1))
@@ -104,18 +87,222 @@ main() {
pkgbuilds=("$@")
fi
+ # Do a check to see if we are running as root
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
+ # Adjust the verbosity
+ if [[ $v == 0 ]]; then
+ error() { :; }
+ warning() { :; }
+ plain() { :; }
+ info() { :; }
+ elif [[ $v == 1 ]]; then
+ info() { :; }
+ elif [[ $v == 2 ]]; then
+ info() { plain "$@"; }
+ fi
+
+ # Update the blacklist
+ $cache || blacklist-update || return $_E_ERROR
- local ret=0
+ # Do the work
+ declare -i ret=0
+ local pkgbuild
for pkgbuild in "${pkgbuilds[@]}"; do
- check_deps "$pkgbuild" || ret=15
+ pkgbuild_check "$pkgbuild" || ret=$(($ret|$?))
done
return $ret
}
+# Helper functions #############################################################
+# These should maybe be moved into lib/conf.sh
+
+# Usage: var="$(pkgbuild_get_pkg_str ${pkgname} ${varname})"
+# Gets a package-level string for a split-package
+pkgbuild_get_pkg_str() {
+ [[ $# == 2 ]] || panic 'malformed call to pkgbuild_get_pkg_str'
+ local pkg=$1
+ local var=$2
+
+ local indirect=${!var}
+ eval $(declare -f package_$pkg | sed -rn "s/^\s*${var}(\+?=)/indirect\1/p")
+ printf '%s' "${indirect}"
+}
+# Usage: eval $(pkgbuild_get_pkg_ary ${pkgname} ${varname} [$variable_name_to_set])
+# Gets a package-level array for a split-package
+pkgbuild_get_pkg_ary() {
+ [[ $# == 2 ]] || [[ $# == 3 ]] || panic 'malformed call to pkgbuild_get_pkg_ary'
+ local pkg=$1
+ local var=$2
+ local out="${3:-$var}"
+
+ local ary="${var}[@]"
+ local indirect=("${!ary}")
+ eval $(declare -f package_$pkg | sed -rn "s/^\s*${var}(\+?=)/indirect\1/p")
+ declare -p indirect|sed "s/ indirect=/ ${out}=/"
+}
+
+# Checker functions ############################################################
+
+# Usage: check_lic "${licence}"
+# Check a license name to see if it is OK
+check_lic() {
+ [[ $# == 1 ]] || panic 'malformed call to check_license'
+ local license=$1
+
+ info 'Checking license: %s' "$license"
+
+ if [[ -e "/usr/share/licenses/common/$license" ]]; then
+ return $_E_OK
+ else
+ case "${license#custom:}" in
+ WTFPL)
+ # accept as common, I think it should be in the licenses package
+ return $_E_OK;;
+ BSD1|BSD2|BSD3|MIT|X11)
+ # accept these as common; they can't be included in the
+ # 'licenses' package because some text must be customized
+ return $_E_OK;;
+ BSD4)
+ warning "The 4-clause BSD license is free but has practical problems."
+ return $_E_LIC_NOGPL;;
+ BSD)
+ warning "License 'BSD' is ambiguous, use 'BSD{1..4}' to specify the number of clauses."
+ return $_E_LIC_UNKNOWN;;
+ JSON)
+ error "License '%s' is a known non-free license." "$license"
+ return $_E_LIC_NONFREE;;
+ *)
+ warning "License '%s' is not a common (recognized) license." "$license"
+ return $_E_LIC_UNKNOWN;;
+ esac
+ fi
+ panic 'code should never be reached'
+}
+
+# Usage: check_dep "${dependency}"
+# Checks for ${dependency} in the blacklist
+check_dep() {
+ [[ $# == 1 ]] || panic 'malformed call to check_dep'
+ local pkg=$1
+
+ local line="$(blacklist-cat|blacklist-lookup "$pkg")"
+ local rep="$(blacklist-get-rep <<<"$line")"
+ if [[ -z $line ]]; then
+ # not mentioned in blacklist; free
+ info '%s: not blacklisted' "$pkg"
+ return $_E_OK
+ elif [[ -z $rep ]]; then
+ # non-free with no replacement
+ plain '%s: blacklisted' "$pkg"
+ return $_E_DEP_NONFREE
+ else
+ # non-free with free replacement
+ if [[ "$rep" == "$pkg" ]]; then
+ info '%s: repackaged with the same name' "$pkg"
+ else
+ info '%s: replaced by %s' "$pkg" "$rep"
+ fi
+ return $_E_OK
+ fi
+ panic 'code should never be reached'
+}
+
+# Usage: check_pkg "${pkgname}"
+# Checks for ${pkgname} in the blacklist
+check_pkg() {
+ [[ $# == 1 ]] || panic 'malformed call to check_pkg'
+ check_dep "$@"
+ case $? in
+ $_E_OK)
+ return $_E_OK;;
+ $_E_DEP_NONFREE)
+ return $_E_PKG_NONFREE;;
+ *)
+ panic 'unexpected return code from check_dep';;
+ esac
+ panic 'code should never be reached'
+}
+
+# Usage: pkgbuild_ckec $pkgbuild
+# Check whether a PKGBUILD has any issues (using the above)
+pkgbuild_check() (
+ [[ $# == 1 ]] || panic 'malformed call to pkgbuild_check'
+ local pkgbuild=$1
+
+ load_PKGBUILD "$pkgbuild"
+ if [[ -z $pkgname ]]; then
+ return $_E_ERROR # not a PKGBUILD
+ fi
+
+ declare -i ret=0 # the return status
+ local dep lic # iterators for us in `for` loops
+ local ck_deps ck_lics # lists of deps and licenses that have been checked
+
+ if [[ ${#pkgname[@]} == 1 ]]; then
+ msg2 'Inspecting package pkgname=%q (%s)' "$pkgname" "$(get_full_version)"
+ else
+ msg2 'Inspecting split package pkgbase=%q (%s)' "${pkgbase:-${pkgname[0]}}" "$(get_full_version)"
+ fi
+
+ # Check if this is blacklisted
+ check_pkg "${pkgbase:-${pkgname[0]}}" || ret=$(($ret|$?))
+ # Check if dependencies are blacklisted
+ for dep in "${depends[@]}" "${makedepends[@]}" "${checkdepends[@]}" \
+ "${optdepends[@]%%:*}" "${mkdepends[@]}"
+ do
+ check_dep "$dep" || ret=$(($ret|$?))
+ ck_deps+=("$dep")
+ done
+ # Check the licenses
+ for lic in "${license[@]}"; do
+ check_lic "$lic" || ret=$(($ret|$?))
+ ck_lics+=("$lic")
+ done
+
+ if [[ ${#pkgname[@]} == 1 ]]; then
+ # Non-split package
+ # Make sure a license is set
+ if [[ ${#ck_lics[@]} == 0 ]]; then
+ error "The license array is empty"
+ ret=$(($ret|$_E_ERROR))
+ fi
+ else
+ # Split package
+ # Check the individual split packages
+ local _pkgname _license _depends _optdepends
+ for _pkgname in "${pkgname[@]}"; do
+ msg2 'Inspecting split package pkgname=%q (%s)' "$_pkgname" "$(get_full_version "$_pkgname")"
+ eval $(pkgbuild_get_pkg_ary "$_pkgname" license _license)
+ eval $(pkgbuild_get_pkg_ary "$_pkgname" depends _depends)
+ eval $(pkgbuild_get_pkg_ary "$_pkgname" optdepends _optdepends)
+
+ # Check if this is blacklisted
+ check_pkg "$_pkgname" || ret=$(($ret|$?))
+ # Check if dependencies are blacklisted
+ for dep in "${_depends[@]}" "${_optdepends[@]%%:*}"; do
+ if ! in_array "$dep" "${ck_deps[@]}"; then
+ check_dep "$dep" || ret=$(($ret|$?))
+ fi
+ done
+ # Check the licenses
+ for lic in "${_license[@]}"; do
+ if ! in_array "$lic" "${ck_lics[@]}"; then
+ check_lic "$lic" || ret=$(($ret|$?))
+ fi
+ done
+
+ if [[ ${#_license[@]} == 0 ]]; then
+ error "The license array is empty"
+ ret=$(($ret|$_E_ERROR))
+ fi
+ done
+ fi
+
+ return $ret
+)
+
main "$@"
diff --git a/src/pkgbuild-summarize-nonfree b/src/pkgbuild-summarize-nonfree
new file mode 100755
index 0000000..7b005d5
--- /dev/null
+++ b/src/pkgbuild-summarize-nonfree
@@ -0,0 +1,88 @@
+#!/bin/bash
+
+. $(librelib messages)
+
+# Make sure these match pkgbuild-check-nonfree
+declare -ri _E_OK=0
+declare -ri _E_ERROR=1
+declare -ri _E_LIC_UNKNOWN=2
+declare -ri _E_LIC_NOGPL=4
+declare -ri _E_LIC_NONFREE=8
+declare -ri _E_DEP_NONFREE=16
+declare -ri _E_PKG_NONFREE=32
+
+usage() {
+ print "Usage: %s [OPTIONS] STATUS" "${0##*/}"
+ print "Summarizes a status code from pkgbuild-check-nonfree"
+ echo
+ prose 'It thresholds the issues it finds, only failing for error-level
+ issues, and ignoring warnings. Unless `-q` is specified, it also
+ prints a summary of the issues it found.'
+ echo
+ print 'Options:'
+ flag '-q' 'Be quiet'
+ flag '-h' 'Show this message'
+}
+
+main() {
+ local quiet=false
+ while getopts 'qh' arg; do
+ case "$arg" in
+ q) quiet=true;;
+ h) usage; return 0;;
+ *) usage >&2; return 1;;
+ esac
+ done
+ shift $(($OPTIND - 1))
+ if [[ $# -ne 1 ]]; then
+ usage >&2
+ return 1
+ fi
+ if ! [[ $1 =~ ^[0-9]+$ ]]; then
+ error 'STATUS must be an integer'
+ usage >&2
+ return 1
+ fi
+
+ if $quiet; then
+ error() { :; }
+ warning() { :; }
+ fi
+
+ parse $1;
+ return $?
+}
+
+parse() {
+ [[ $# == 1 ]] || panic 'malformed call to parse'
+ declare -i s=$1;
+
+ declare -i ret=0
+ declare -i i
+ for i in 1 2 4 8 16 32; do
+ if [[ $(($s & $i)) -gt 0 ]]; then
+ case $i in
+ $_E_ERROR)
+ # could be anything, assume the worst
+ error "There was an error processing the PKGBUILD"
+ ret=1;;
+ $_E_LIC_UNKNOWN)
+ warning "This PKGBUILD has an unknown license";;
+ $_E_LIC_NOGPL)
+ warning "This PKGBUILD has a GPL-incompatible license";;
+ $_E_LIC_NONFREE)
+ error "This PKGBUILD has a known nonfree license"
+ ret=1;;
+ $_E_DEP_NONFREE)
+ error "This PKGBUILD depends on known nonfree packages"
+ ret=1;;
+ $_E_PKG_NONFREE)
+ error "This PKGBUILD is for a known nonfree package"
+ ret=1;;
+ esac
+ fi
+ done
+ return $ret
+}
+
+main "$@"
diff --git a/src/treepkg b/src/treepkg
index a1b4e38..73ef93b 100755
--- a/src/treepkg
+++ b/src/treepkg
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
#set -x
-# (c) 2012 Nicolás Reynolds <fauno@parabola.nu>
+# Copyright (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
@@ -19,15 +19,15 @@ source libremessages
source $(librelib conf.sh)
load_files libretools
-check_vars libretools HOOKPREBUILD FULLBUILDCMD HOOKLOCALRELEASE
+check_vars libretools HOOKPREBUILD FULLBUILDCMD HOOKLOCALRELEASE || exit 1
load_files makepkg
-term_title "$(basename $0)"
+term_title "${0##*/}"
# End inmediately but print an useful message
trap_exit() {
- term_title "error!"
- error "($(basename $0)) $@ (leftovers on ${BUILDDIR})"
+ term_title "${0##*/}: $(_ 'Error!')"
+ error "%s: %s (leftovers on %s" "${0##*/}" "$*" "${BUILDDIR}"
exit 1
}
@@ -59,10 +59,10 @@ bury() {
# 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
+ 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}"
@@ -78,8 +78,8 @@ guess_repo() {
basename "$(dirname "${1}")"
}
-if [ ! -f PKGBUILD ]; then
- error "Missing PKGBUILD ($PWD)"
+if [[ ! -f PKGBUILD ]]; then
+ error "Missing PKGBUILD (%s)" "$PWD"
exit 1
fi
@@ -97,13 +97,13 @@ 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)}"
+BUILDDIR="${1:-$(mktemp --tmpdir -d ${pkgbase}-treepkg.XXXXXXXXXX)}"
BUILDORDER="${BUILDDIR}/BUILDORDER"
DEPTH=${2:-0}
NEXTDEPTH=$((${DEPTH} + 1))
@@ -182,21 +182,21 @@ if ! ${BUILDNOW}; then
fi
# Only build at the end
-if [ ${DEPTH} -eq 0 ]; then
+if [[ ${DEPTH} -eq 0 ]]; then
${VERBOSE} && msg "Starting build" || true
if ${BUILD}; then
- ${VERBOSE} && msg "Build tree stored in ${BUILDORDER}" || true
+ ${VERBOSE} && msg "Build tree stored in %s" "${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
+ 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
+ if [[ -f "${BUILDDIR}/${_pkg}/built_ok" ]]; then continue; fi
- ${VERBOSE} && msg "Building ${_pkg/_/ }" || true
+ ${VERBOSE} && msg "Building %s" "${_pkg/_/ }" || true
# Remove leading zeros and space if any
term_title "$(echo ${_pkg/_/ } | sed "s/^0\+ \?//")"
@@ -221,11 +221,11 @@ if [ ${DEPTH} -eq 0 ]; then
fi
if (( CLEANUP )) ; then
- msg2 "Removing ${BUILDDIR}"
+ msg2 "Removing %s" "${BUILDDIR}"
rm -rf "${BUILDDIR}"
fi
fi
-term_title "done"
+term_title "$(_ Done)"
exit $?
diff --git a/test/aur-test.sh b/test/aur-test.sh
index 1fbe659..5de590b 100644
--- a/test/aur-test.sh
+++ b/test/aur-test.sh
@@ -13,18 +13,18 @@ after() {
}
it_displays_help() {
- LANG=C aur -h >$tmpdir/stdout 2>$tmpdir/stderr
+ LC_ALL=C aur -h >$tmpdir/stdout 2>$tmpdir/stderr
[[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]]
- [[ -z "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stderr
}
it_fails_with_0_args() {
aur >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
[[ $stat != 0 ]]
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
# TODO: Actually test
diff --git a/test/is_built-test.sh b/test/is_built-test.sh
index 62847e5..f7f6c65 100644
--- a/test/is_built-test.sh
+++ b/test/is_built-test.sh
@@ -13,48 +13,48 @@ after() {
}
it_displays_help() {
- LANG=C is_built -h >$tmpdir/stdout 2>$tmpdir/stderr
+ LC_ALL=C is_built -h >$tmpdir/stdout 2>$tmpdir/stderr
[[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]]
- [[ -z "$(cat $tmpdir/stderr)" ]]
+ empty $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)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
it_succeeds_with_1_arg() {
is_built sh >$tmpdir/stdout 2>$tmpdir/stderr
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -z "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ empty $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)" ]]
+ [[ $stat == 1 ]]
+ empty $tmpdir/stdout
+ empty $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)" ]]
+ [[ $stat == 1 ]]
+ empty $tmpdir/stdout
+ empty $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)" ]]
+ empty $tmpdir/stdout
+ empty $tmpdir/stderr
}
diff --git a/test/lib-blacklist-test.sh b/test/lib-blacklist-test.sh
index c496167..9dfd5da 100644
--- a/test/lib-blacklist-test.sh
+++ b/test/lib-blacklist-test.sh
@@ -45,26 +45,26 @@ it_works_with_colons_in_reason() {
v="$(libreblacklist get-reason <<<"$line")"; [[ $v == 'my:reason' ]]
}
-it_fails_update_when_there_is_no_blacklist_or_network() {
+it_fails_update_with_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)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
-it_fails_cat_when_there_is_no_blacklist_or_network() {
+it_fails_cat_with_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)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
it_fails_update_when_BLACKLIST_is_unset() {
@@ -74,8 +74,8 @@ it_fails_update_when_BLACKLIST_is_unset() {
libreblacklist update >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
[[ $stat != 0 ]]
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
it_fails_cat_when_syntax_error_in_conf() {
@@ -86,8 +86,8 @@ it_fails_cat_when_syntax_error_in_conf() {
libreblacklist cat >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
[[ $stat != 0 ]]
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
it_downloads_the_blacklist_as_needed() {
@@ -97,7 +97,7 @@ it_downloads_the_blacklist_as_needed() {
libreblacklist cat >$tmpdir/stdout 2>$tmpdir/stderr
- [[ -n "$(cat $tmpdir/stdout)" ]]
+ not empty $tmpdir/stdout
}
it_downloads_the_blacklist_repeatedly() {
@@ -110,23 +110,23 @@ it_downloads_the_blacklist_repeatedly() {
}
it_displays_help_and_fails_with_no_args() {
- LANG=C libreblacklist >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
+ LC_ALL=C libreblacklist >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
[[ $stat != 0 ]]
- [[ -z "$(cat $tmpdir/stdout)" ]]
+ empty $tmpdir/stdout
[[ "$(sed 1q $tmpdir/stderr)" =~ 'Usage: libreblacklist ' ]]
}
it_displays_help_when_given_h() {
- LANG=C libreblacklist -h >$tmpdir/stdout 2>$tmpdir/stderr
+ LC_ALL=C libreblacklist -h >$tmpdir/stdout 2>$tmpdir/stderr
[[ "$(sed 1q $tmpdir/stdout)" =~ 'Usage: libreblacklist ' ]]
- [[ -z "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stderr
}
it_displays_help_when_given_h_cat() {
- LANG=C libreblacklist -h cat >$tmpdir/stdout 2>$tmpdir/stderr
+ LC_ALL=C libreblacklist -h cat >$tmpdir/stdout 2>$tmpdir/stderr
[[ "$(sed 1q $tmpdir/stdout)" == 'Usage: libreblacklist cat' ]]
- [[ -z "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stderr
}
diff --git a/test/lib-conf-test.sh b/test/lib-conf-test.sh
index 0d028b8..efad907 100644
--- a/test/lib-conf-test.sh
+++ b/test/lib-conf-test.sh
@@ -16,7 +16,7 @@ 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
+ MAKEPKG_CONF="$tmpdir/makepkg.conf" set_var makepkg PKGDEST /pkgdest
. "$tmpdir/makepkg.conf"
[[ $PKGDEST == /pkgdest ]]
}
diff --git a/test/lib-messages-test.sh b/test/lib-messages-test.sh
index 826556b..3fcac63 100644
--- a/test/lib-messages-test.sh
+++ b/test/lib-messages-test.sh
@@ -30,15 +30,15 @@ it_works_with_no_color_and_set_euE() (
msg Foo
) >$tmpdir/stdout 2>$tmpdir/stderr
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
)
it_can_be_called_without_including() {
libremessages msg Foo >$tmpdir/stdout 2>$tmpdir/stderr
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
it_fails_with_msg_and_no_args() {
diff --git a/test/librechroot-test.sh b/test/librechroot-test.sh
index 76afb56..c22ac58 100644
--- a/test/librechroot-test.sh
+++ b/test/librechroot-test.sh
@@ -4,55 +4,96 @@ describe librechroot
. ./test-common.sh
+_setup_chrootdir
+
before() {
_before librechroot
+
mkdir -p "$XDG_CONFIG_HOME"/libretools
- echo "CHROOTDIR='$tmpdir/chrootdir'" > "$XDG_CONFIG_HOME"/libretools/chroot.conf
+
+ echo "CHROOTDIR='${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() (
_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
+ testsudo librechroot -l "$roundup_test_name" 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
+ testsudo librechroot -l "$roundup_test_name" make
+ testsudo librechroot -l "$roundup_test_name" clean-repo
+ testsudo librechroot -l "$roundup_test_name" run test -r /repo/repo.db
# TODO: inspect /repo/* more
}
+it_respects_exit_status_if_out_isnt_a_tty() (
+ require network sudo || return 0
+ set -o pipefail
+ libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty
+ r=0
+ { testsudo librechroot -l "$roundup_test_name" run exit 3 | cat; } || r=$?
+ [[ $r == 3 ]]
+)
+
+it_creates_ca_certificates() {
+ require network sudo || return 0
+ libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty
+ testsudo librechroot -l "$roundup_test_name" run test -r /etc/ssl/certs/ca-certificates.crt
+}
+
+it_disables_networking_when_requested() {
+ require network sudo || return 0
+ libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty
+
+ testsudo librechroot -l "$roundup_test_name" run curl https://repo.parabolagnulinux.org/ >/dev/null
+ not testsudo librechroot -l "$roundup_test_name" -N run curl https://repo.parabolagnulinux.org/ >/dev/null
+}
+
+it_handles_CHROOTEXTRAPKG_correctly() {
+ requuire network sudo || return 0
+ libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty
+
+ not testsudo librechroot -l "$roundup_test_name" run lsof
+ echo "CHROOTEXTRAPKG=(lsof)" >> "$XDG_CONFIG_HOME"/libretools/chroot.conf
+ testsudo librechroot -l "$roundup_test_name" install-name lsof
+ testsudo librechroot -l "$roundup_test_name" clean-pkgs
+ testsudo librechroot -l "$roundup_test_name" run lsof
+ echo "CHROOTEXTRAPKG=()" >> "$XDG_CONFIG_HOME"/libretools/chroot.conf
+ testsudo librechroot -l "$roundup_test_name" clean-pkgs
+ not testsudo librechroot -l "$roundup_test_name" run lsof
+}
+
it_displays_help_as_normal_user() {
rm -rf "$XDG_CONFIG_HOME"
- LANG=C librechroot help >$tmpdir/stdout 2>$tmpdir/stderr
+ LC_ALL=C librechroot help >$tmpdir/stdout 2>$tmpdir/stderr
[[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]]
- [[ -z "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stderr
}
it_otherwise_fails_as_normal_user() {
- librechroot run true >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
+ librechroot -l "$roundup_test_name" run true >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
[[ $stat != 0 ]]
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
it_displays_help_and_fails_with_0_args() {
- LANG=C librechroot >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
+ LC_ALL=C librechroot -l "$roundup_test_name" >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
[[ $stat != 0 ]]
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ "$(sed 1q $tmpdir/stderr)" =~ Usage:.* ]]
+ empty $tmpdir/stdout
+ [[ "$(sed -n 2p $tmpdir/stderr)" =~ Usage:.* ]]
}
# requires sudo so we know it's not failing because it needs root
@@ -61,8 +102,8 @@ it_fails_for_unknown_commands() {
testsudo librechroot phony >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
[[ $stat != 0 ]]
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
# requires sudo so we know it's not failing because it needs root
@@ -71,6 +112,6 @@ it_fails_for_unknown_flags() {
testsudo librechroot -q >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
[[ $stat != 0 ]]
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
diff --git a/test/librefetch-test.sh b/test/librefetch-test.sh
new file mode 100644
index 0000000..92f67a1
--- /dev/null
+++ b/test/librefetch-test.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env roundup
+
+describe librefetch
+
+. ./test-common.sh
+
+before() {
+ _before
+
+ mkdir -p "$HOME"
+ printf '%s\n' \
+ 'DLAGENTS+=({https,libre}'\''::/usr/bin/librefetch -p "$BUILDFILE" -- %u %o'\'')' \
+ 'BUILDDIR=""' \
+ > "$HOME/.makepkg.conf"
+
+ mkdir -p "$XDG_CONFIG_HOME/libretools"
+ printf '%s\n' \
+ 'MIRROR="phony://example.com/dir/"' \
+ 'DOWNLOADER=/usr/bin/false' \
+ > "$XDG_CONFIG_HOME/libretools/librefetch.conf"
+}
+
+after() {
+ _after
+}
+
+it_displays_help() {
+ LC_ALL=C librefetch -h >$tmpdir/stdout 2>$tmpdir/stderr
+
+ [[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]]
+ empty $tmpdir/stderr
+}
+
+it_cleans_src_libre_first() {
+ cp librefetch.d/* "$tmpdir/"
+ cd "$tmpdir"
+
+ # create garbage
+ mkdir -p src-libre/foo
+ touch src-libre/foo/file
+
+ # run librefetch
+ makepkg -g
+
+ srcball=src/testpkg-1.0.tar.gz
+ bsdtar tf "$srcball" > list-pkg.txt
+ diff -u list.txt list-pkg.txt
+}
diff --git a/test/librefetch.d/PKGBUILD b/test/librefetch.d/PKGBUILD
new file mode 100644
index 0000000..723d82e
--- /dev/null
+++ b/test/librefetch.d/PKGBUILD
@@ -0,0 +1,15 @@
+pkgname=testpkg
+pkgver=1.0
+pkgrel=1
+pkgdesc=foo
+arch=(any)
+source=("libre://$pkgname-$pkgver.tar.gz")
+
+mksource() {
+ mkdir "$srcdir/bar"
+ touch "$srcdir/bar/file"
+}
+
+package() {
+ :;
+}
diff --git a/test/librefetch.d/list.txt b/test/librefetch.d/list.txt
new file mode 100644
index 0000000..b04d5d1
--- /dev/null
+++ b/test/librefetch.d/list.txt
@@ -0,0 +1,2 @@
+bar/
+bar/file
diff --git a/test/librelib-test.sh b/test/librelib-test.sh
index e86dffe..a74ce0a 100644
--- a/test/librelib-test.sh
+++ b/test/librelib-test.sh
@@ -16,7 +16,7 @@ it_displays_help_and_fails_with_0_args() {
ret=0
librelib >$tmpdir/stdout 2>$tmpdir/stderr || ret=$?
- [[ -z "$(cat $tmpdir/stdout)" ]]
+ empty $tmpdir/stdout
[[ "$(sed 1q $tmpdir/stderr)" =~ Usage:.* ]]
[[ $ret != 0 ]]
}
@@ -25,8 +25,8 @@ it_fails_with_2_args() {
ret=0
librelib a b >$tmpdir/stdout 2>$tmpdir/stderr || ret=$?
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
[[ $ret != 0 ]]
}
@@ -34,7 +34,7 @@ it_displays_usage_text() {
librelib -h >$tmpdir/stdout 2>$tmpdir/stderr
[[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]]
- [[ -z "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stderr
}
# libremessages is executable
@@ -67,7 +67,7 @@ it_fails_to_find_phony() {
ret=0
librelib phony >$tmpdir/stdout 2>$tmpdir/stderr || ret=$?
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
[[ $ret != 0 ]]
}
diff --git a/test/libremakepkg-test.sh b/test/libremakepkg-test.sh
index be19e17..4d8a7c5 100644
--- a/test/libremakepkg-test.sh
+++ b/test/libremakepkg-test.sh
@@ -4,6 +4,8 @@ describe libremakepkg
. ./test-common.sh
+_setup_chrootdir
+
before() {
_before libremakepkg
@@ -11,7 +13,7 @@ before() {
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 "CHROOTDIR='${chrootdir}'" > "$XDG_CONFIG_HOME"/libretools/chroot.conf
echo "CHROOT='default'" >> "$XDG_CONFIG_HOME"/libretools/chroot.conf
echo "CHROOTEXTRAPKG=()" >> "$XDG_CONFIG_HOME"/libretools/chroot.conf
}
@@ -26,28 +28,90 @@ it_builds_a_trivial_package() {
cd "$tmpdir"
libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty
- testsudo libremakepkg
+ testsudo libremakepkg -l "$roundup_test_name"
[[ -f $(echo libretools-hello-1.0-1-any.pkg.tar.?z) ]]
}
+it_enables_networking_during_prepare() {
+ require network sudo || return 0
+ cp libremakepkg.d/PKGBUILD-netprepare "$tmpdir/PKGBUILD"
+ cd "$tmpdir"
+
+ libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty
+ testsudo libremakepkg -l "$roundup_test_name"
+ [[ -f $(echo libretools-netprepare-1.0-1-any.pkg.tar.?z) ]]
+}
+
+it_disables_networking_during_build() {
+ require network sudo || return 0
+ cp libremakepkg.d/PKGBUILD-netbuild "$tmpdir/PKGBUILD"
+ cd "$tmpdir"
+
+ libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty
+ not testsudo libremakepkg -l "$roundup_test_name"
+ not [[ -f $(echo libretools-netbuild-1.0-1-any.pkg.tar.?z) ]]
+ testsudo libremakepkg -l "$roundup_test_name" -N
+ [[ -f $(echo libretools-netbuild-1.0-1-any.pkg.tar.?z) ]]
+}
+
+it_disables_networking_during_package() {
+ require network sudo || return 0
+ cp libremakepkg.d/PKGBUILD-netpackage "$tmpdir/PKGBUILD"
+ cd "$tmpdir"
+
+ libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty
+ not testsudo libremakepkg -l "$roundup_test_name"
+ not [[ -f $(echo libretools-netpackage-1.0-1-any.pkg.tar.?z) ]]
+ testsudo libremakepkg -l "$roundup_test_name" -N
+ [[ -f $(echo libretools-netpackage-1.0-1-any.pkg.tar.?z) ]]
+}
+
+it_cleans_the_chroot_before_building() {
+ require network sudo || return 0
+ # 1. First, we build testpkg1
+ # 2. Then, we build testpkg2, which depends on testpkg1
+ # Therefore, testpkg1 will be installed after testpkg2 is built, we
+ # check for that.
+ # 3. Then, we build hello, which depends on neither, so testpkg1 should
+ # be removed.
+
+ # Also, do funny things with the output of libremakepkg to get a helpful
+ # fail case.
+
+ mkdir -p "$tmpdir"/{1,2,3}
+ cp libremakepkg.d/PKGBUILD-testpkg1 "$tmpdir/1/PKGBUILD"
+ cp libremakepkg.d/PKGBUILD-testpkg2 "$tmpdir/2/PKGBUILD"
+ cp libremakepkg.d/PKGBUILD-hello "$tmpdir/3/PKGBUILD"
+
+ libremessages msg 'Creating a chroot, may take a few minutes' &>/dev/tty
+ cd "$tmpdir/1"
+ testsudo libremakepkg -l "$roundup_test_name" &> "$tmpdir/out" || { r=$?; tail "$tmpdir/out"|cat -v; return $r; }
+ cd "$tmpdir/2"
+ testsudo libremakepkg -l "$roundup_test_name" &> "$tmpdir/out" || { r=$?; tail "$tmpdir/out"|cat -v; return $r; }
+ testsudo librechroot -l "$roundup_test_name" run libretools-testpkg1 'first time, pass'
+ cd "$tmpdir/3"
+ testsudo libremakepkg -l "$roundup_test_name" &> "$tmpdir/out" || { r=$?; tail "$tmpdir/out"|cat -v; return $r; }
+ not testsudo librechroot -l "$roundup_test_name" run libretools-testpkg1 'second time, fail'
+}
+
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
+ testsudo env PKGDEST="$tmpdir/dest/pkgdest" libremakepkg -l "$roundup_test_name"
[[ -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
+ LC_ALL=C libremakepkg -h >$tmpdir/stdout 2>$tmpdir/stderr
[[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]]
- [[ -z "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stderr
}
it_otherwise_fails_as_normal_user() {
@@ -58,6 +122,6 @@ it_otherwise_fails_as_normal_user() {
libremakepkg >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
[[ $stat != 0 ]]
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
diff --git a/test/libremakepkg.d/PKGBUILD-netbuild b/test/libremakepkg.d/PKGBUILD-netbuild
new file mode 100644
index 0000000..7be896b
--- /dev/null
+++ b/test/libremakepkg.d/PKGBUILD-netbuild
@@ -0,0 +1,17 @@
+pkgname='libretools-netbuild'
+pkgver=1.0
+license=('GPL')
+url='https://parabolagnulinux.org'
+
+pkgrel=1
+arch=(any)
+
+build() {
+ cd "$srcdir"
+ curl https://repo.parabolagnulinux.org/ > index.html
+}
+
+package() {
+ cd "$srcdir"
+ install -Dm644 index.html "$pkgdir"/usr/share/$pkgname/index.html
+}
diff --git a/test/libremakepkg.d/PKGBUILD-netpackage b/test/libremakepkg.d/PKGBUILD-netpackage
new file mode 100644
index 0000000..cbefe8f
--- /dev/null
+++ b/test/libremakepkg.d/PKGBUILD-netpackage
@@ -0,0 +1,12 @@
+pkgname='libretools-netpackage'
+pkgver=1.0
+license=('GPL')
+url='https://parabolagnulinux.org'
+
+pkgrel=1
+arch=(any)
+
+package() {
+ install -d "$pkgdir"/usr/share/$pkgname
+ curl https://repo.parabolagnulinux.org/ > "$pkgdir"/usr/share/$pkgname/index.html
+}
diff --git a/test/libremakepkg.d/PKGBUILD-netprepare b/test/libremakepkg.d/PKGBUILD-netprepare
new file mode 100644
index 0000000..90f3e82
--- /dev/null
+++ b/test/libremakepkg.d/PKGBUILD-netprepare
@@ -0,0 +1,17 @@
+pkgname='libretools-netprepare'
+pkgver=1.0
+license=('GPL')
+url='https://parabolagnulinux.org'
+
+pkgrel=1
+arch=(any)
+
+prepare() {
+ cd "$srcdir"
+ curl https://repo.parabolagnulinux.org/ > index.html
+}
+
+package() {
+ cd "$srcdir"
+ install -Dm644 index.html "$pkgdir"/usr/share/$pkgname/index.html
+}
diff --git a/test/libremakepkg.d/PKGBUILD-testpkg1 b/test/libremakepkg.d/PKGBUILD-testpkg1
new file mode 100644
index 0000000..b7961bb
--- /dev/null
+++ b/test/libremakepkg.d/PKGBUILD-testpkg1
@@ -0,0 +1,19 @@
+pkgname='libretools-testpkg1'
+pkgver=1.0
+license=('GPL')
+url='https://parabolagnulinux.org'
+
+pkgrel=1
+arch=(any)
+depends=(sh)
+
+build() {
+ cd "$srcdir"
+ echo '#!/bin/sh' > testpkg1.sh
+ echo 'echo testpkg1' >> testpkg1.sh
+}
+
+package() {
+ cd "$srcdir"
+ install -Dm755 testpkg1.sh "$pkgdir"/usr/bin/libretools-testpkg1
+}
diff --git a/test/libremakepkg.d/PKGBUILD-testpkg2 b/test/libremakepkg.d/PKGBUILD-testpkg2
new file mode 100644
index 0000000..11f7fe8
--- /dev/null
+++ b/test/libremakepkg.d/PKGBUILD-testpkg2
@@ -0,0 +1,19 @@
+pkgname='libretools-testpkg2'
+pkgver=1.0
+license=('GPL')
+url='https://parabolagnulinux.org'
+
+pkgrel=1
+arch=(any)
+depends=(sh libretools-testpkg1)
+
+build() {
+ cd "$srcdir"
+ echo '#!/bin/sh' > testpkg2.sh
+ echo 'libretools-testpkg1' >> testpkg2.sh
+}
+
+package() {
+ cd "$srcdir"
+ install -Dm755 testpkg2.sh "$pkgdir"/usr/bin/libretools-testpkg2
+}
diff --git a/test/librerelease-test.sh b/test/librerelease-test.sh
new file mode 100644
index 0000000..a44b150
--- /dev/null
+++ b/test/librerelease-test.sh
@@ -0,0 +1,56 @@
+#!/usr/bin/env roundup
+
+describe librestage
+
+. ./test-common.sh
+
+before() {
+ _before
+
+ mkdir -p $XDG_CONFIG_HOME/libretools
+ {
+ echo "WORKDIR='$tmpdir/workdir'"
+ echo 'REPODEST=repo@repo:/srv/http/repo/staging-$LIBREUSER'
+ } >$XDG_CONFIG_HOME/libretools/libretools.conf
+ {
+ echo 'PKGEXT=.pkg.tar.gz'
+ echo "PKGDEST='$tmpdir/workdir/pkgdest'"
+ echo "GPGKEY=YOURKEY"
+ } > $HOME/.makepkg.conf
+ mkdir -p "$tmpdir/workdir/pkgdest"
+}
+
+after() {
+ _after
+}
+
+it_displays_usage_text() {
+ rm -rf "$XDG_CONFIG_HOME"
+ LC_ALL=C librerelease -h >"$tmpdir/stdout" 2>"$tmpdir/stderr"
+
+ [[ "$(sed 1q "$tmpdir/stdout")" =~ Usage:.* ]]
+ empty "$tmpdir/stderr"
+}
+
+it_lists_all_files() {
+ WORKDIR="$tmpdir/workdir"
+ mkdir -p "$WORKDIR/staging/repo1" "$WORKDIR/staging/repo2/sub"
+ touch \
+ "$WORKDIR/staging/repo1/file1" \
+ "$WORKDIR/staging/repo1/file2" \
+ "$WORKDIR/staging/repo2/file with spaces" \
+ "$WORKDIR/staging/repo2/sub/subfolder"
+ unset WORKDIR
+ LC_ALL=C librerelease -l &>"$tmpdir/list"
+
+ cat > "$tmpdir/list-correct" <<EOF
+ -> repo1
+ file1
+ file2
+ -> repo2
+ file with spaces
+ sub/subfolder
+EOF
+
+ diff "$tmpdir/list-correct" "$tmpdir/list"
+}
diff --git a/test/librestage-test.sh b/test/librestage-test.sh
index 849a68c..460eb58 100644
--- a/test/librestage-test.sh
+++ b/test/librestage-test.sh
@@ -23,26 +23,26 @@ after() {
it_displays_usage_text() {
rm -rf "$XDG_CONFIG_HOME"
- LANG=C librestage -h >$tmpdir/stdout 2>$tmpdir/stderr
+ LC_ALL=C librestage -h >$tmpdir/stdout 2>$tmpdir/stderr
[[ "$(sed 1q "$tmpdir/stdout")" =~ Usage:.* ]]
- [[ -z "$(cat "$tmpdir/stderr")" ]]
+ empty "$tmpdir/stderr"
}
it_fails_with_0_args() {
librestage >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
[[ $stat != 0 ]]
- [[ -z "$(cat "$tmpdir/stdout")" ]]
- [[ -n "$(cat "$tmpdir/stderr")" ]]
+ empty "$tmpdir/stdout"
+ not empty "$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")" ]]
+ empty "$tmpdir/stdout"
+ not empty "$tmpdir/stderr"
}
# This was an actual bug I hit with md/emacs-mdmua a long time ago; solution was
diff --git a/test/pkgbuild-check-licenses-test.sh b/test/pkgbuild-check-licenses-test.sh
deleted file mode 100644
index 220ef6b..0000000
--- a/test/pkgbuild-check-licenses-test.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/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
index d547e24..2af2669 100644
--- a/test/pkgbuild-check-nonfree-test.sh
+++ b/test/pkgbuild-check-nonfree-test.sh
@@ -2,6 +2,7 @@
# avoid carpel tunnel
pcn=pkgbuild-check-nonfree
+psn=pkgbuild-summarize-nonfree
describe $pcn
@@ -26,36 +27,42 @@ 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
+ LC_ALL=C $pcn -h >$tmpdir/stdout 2>$tmpdir/stderr
stat=$?
[[ "$(sed 1q $tmpdir/stdout)" =~ Usage:.* ]]
- [[ -z "$(cat $tmpdir/stderr)" ]]
+ empty $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)" ]]
+ empty $tmpdir/stdout
+ not empty $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)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
[[ $stat == 0 ]]
}
-it_fails_with_15_for_nonfree_depend() {
+it_fails_for_nonfree_depend() {
$pcn $pcn.d/PKGBUILD.nonfree >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
+ [[ $stat != 0 ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
- [[ $stat == 15 ]]
+ local pcn_stat=$stat
+
+ $psn $pcn_stat >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
+ [[ $stat != 0 ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
}
it_fails_when_there_is_no_blacklist() {
@@ -65,7 +72,7 @@ it_fails_when_there_is_no_blacklist() {
$pcn $pcn.d/PKGBUILD.free >$tmpdir/stdout 2>$tmpdir/stderr || stat=$?
- [[ -z "$(cat $tmpdir/stdout)" ]]
- [[ -n "$(cat $tmpdir/stderr)" ]]
+ empty $tmpdir/stdout
+ not empty $tmpdir/stderr
[[ $stat != 0 ]] && [[ $stat != 15 ]]
}
diff --git a/test/test-common.sh b/test/test-common.sh
index 01b1b35..c525dd8 100644
--- a/test/test-common.sh
+++ b/test/test-common.sh
@@ -6,7 +6,12 @@ if [[ $HOME == "$(eval echo ~$USER)" ]]; then
fi
_before() {
+ unset PKGDEST SRCDEST SRCPKGDEST LOGDEST
+ unset BUILDDIR
+ unset PKGEXT SRCEXT
+ unset GPGKEY PACKAGER
tmpdir="$(mktemp -d --tmpdir "test-${roundup_desc//\//-}.XXXXXXXXXXXX")"
+ chmod 755 "$tmpdir"
stat=0
}
@@ -22,7 +27,31 @@ _after_sudo() {
fi
}
-require() {
+_setup_chrootdir() {
+ if [[ -z "$chrootdir" ]]; then
+ export chrootdir="$(mktemp -d --tmpdir "test-chrootdir.XXXXXXXXXXXX")"
+ trap "$(printf '_cleanup_chrootdir %q' "$chrootdir")" EXIT
+ fi
+}
+
+_cleanup_chrootdir() (
+ chrootdir=$1
+ shopt -s nullglob
+ if [[ $SUDO ]]; then
+ for copydir in "$chrootdir"/*/*/; do
+ local chroottype=$(stat -f -c %T "$copydir")
+ if [[ "$chroottype" == btrfs ]] && ! mountpoint -q "$copydir"; then
+ sudo btrfs subvolume delete "$copydir" >/dev/null
+ fi
+ done
+ sudo rm -rf -- "$chrootdir"
+ else
+ rm -rf -- "$chrootdir"
+ fi
+)
+
+require() (
+ set +x
local missing=()
if libremessages in_array "network" "$@" && ! [[ $NETWORK ]]; then
missing+=('networking')
@@ -35,4 +64,15 @@ require() {
return 1
fi
return 0;
-}
+)
+
+empty() (
+ set +x
+ [[ $(stat -c %s "$1") -eq 0 ]]
+)
+
+# Just using '!' doesn't trip `set -e`
+not() (
+ set +x
+ ! eval "$@"
+)
diff --git a/test/testenv b/test/testenv
index e6c882f..847a948 100755
--- a/test/testenv
+++ b/test/testenv
@@ -15,6 +15,11 @@ while [[ $# -gt 0 ]]; do
done
export NETWORK SUDO
+if [[ $# == 0 ]]; then
+ echo 'You need to run testenv with arguments!' >&2
+ exit 1
+fi
+
# 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