diff --git a/.gitignore b/.gitignore index d1aa7b0..214166a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,10 @@ *.orig.tar.gz *.tar.gz *~ +.idea/ etc/freight.conf var +test/tmp +!test/fixtures/* +debian/freight* +debian/files diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e34a0c2 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +sudo: required +env: + - SH=dash + - SH=bash +script: + - find bin lib -type f | xargs shellcheck -s sh + - shfmt -i 4 -ci -p -l -s -w lib/ bin/ + - git diff --exit-code + - make check +notifications: + irc: "chat.freenode.net#freight" +dist: xenial diff --git a/Makefile b/Makefile index a3cb9b9..d956d43 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ -VERSION=0.3.5 +VERSION=0.3.12 BUILD=1 +SH=dash + prefix=/usr/local bindir=${prefix}/bin libdir=${prefix}/lib @@ -10,7 +12,7 @@ mandir=${prefix}/share/man all: clean: - rm -rf *.deb debian man/man*/*.html + rm -rf *.deb deb man/man*/*.html test/tmp find . -name '*~' -delete install: install-bin install-lib install-man install-sysconf @@ -23,7 +25,7 @@ install-lib: install-man: find man -type f -name \*.[12345678] -printf %P\\0 | xargs -0r -I__ install -m644 -D man/__ $(DESTDIR)$(mandir)/__ - find man -type f -name \*.[12345678] -printf %P\\0 | xargs -0r -I__ gzip $(DESTDIR)$(mandir)/__ + find man -type f -name \*.[12345678] -printf %P\\0 | xargs -0r -I__ gzip -f $(DESTDIR)$(mandir)/__ install-sysconf: find etc -type f -not -name freight.conf -printf %P\\0 | xargs -0r -I__ install -m644 -D etc/__ $(DESTDIR)$(sysconfdir)/__ @@ -50,19 +52,15 @@ uninstall-sysconf: rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(sysconfdir) || true build: - make install prefix=/usr sysconfdir=/etc DESTDIR=debian + make install prefix=/usr sysconfdir=/etc DESTDIR=deb fpm -s dir -t deb \ -n freight -v $(VERSION) --iteration $(BUILD) -a all \ -d coreutils -d dash -d dpkg -d gnupg -d grep \ -m "Richard Crowley " \ - --url "https://github.com/rcrowley/freight" \ + --url "https://github.com/freight-team/freight" \ --description "A modern take on the Debian archive." \ - -C debian . - make uninstall prefix=/usr sysconfdir=/etc DESTDIR=debian - -deploy: - scp freight_$(VERSION)-$(BUILD)_all.deb root@rcrowley.org: - ssh -t root@rcrowley.org "freight add freight_$(VERSION)-$(BUILD)_all.deb apt/squeeze apt/wheezy apt/sid apt/lucid apt/precise apt/quantal apt/raring apt/saucy apt/trusty && rm freight_$(VERSION)-$(BUILD)_all.deb && freight cache apt/squeeze apt/wheezy apt/sid apt/lucid apt/precise apt/quantal apt/raring apt/saucy apt/trusty" + -C deb . + make uninstall prefix=/usr sysconfdir=/etc DESTDIR=deb man: find man -name \*.ronn | xargs -n1 ronn --manual=Freight --style=toc @@ -83,4 +81,19 @@ gh-pages: man git push origin gh-pages git checkout -q master -.PHONY: all install uninstall deb deploy man gh-pages +test/tmp/bats: + git clone --depth 1 https://github.com/sstephenson/bats.git test/tmp/bats + +test/tmp/bats-assert: + git clone --depth 1 https://github.com/jasonkarns/bats-assert.git test/tmp/bats-assert + +test/tmp/bin: + mkdir -p test/tmp/bin + +test/tmp/bin/sh: test/tmp/bin + ln -sf $$(which $(SH)) test/tmp/bin/sh + +check: test/tmp/bats test/tmp/bats-assert test/tmp/bin/sh + PATH=test/tmp/bin/:$$PATH test/tmp/bats/bin/bats test/ + +.PHONY: all clean install uninstall build man docs gh-pages check diff --git a/README.md b/README.md index 92f7032..83c30ae 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,18 @@ # Freight +[![IRC channel](https://kiwiirc.com/buttons/irc.freenode.net/freight.png)](https://kiwiirc.com/client/irc.freenode.net/?#freight) +[![Build Status](https://travis-ci.org/freight-team/freight.svg?branch=master)](https://travis-ci.org/freight-team/freight) + A modern take on the Debian archive. +This repository has been forked (in the traditional sense of the word) from +Richard Crowley's [freight](https://github.com/rcrowley/freight) repository. A +fork had become necessary because the main project was not actively maintained +and serious issues had started to crop up. While fixes and improvements were +available in various freight GitHub forks, they were not merged to the main +project. This fork and the associated GitHub organization, +[freight-team](https://github.com/freight-team), attempts to fix these issues. + ## Usage Install Freight and create a minimal configuration in `/usr/local/etc/freight.conf` or `/etc/freight.conf` as appropriate containing the name of your GPG key: @@ -16,6 +27,13 @@ Build the cache of all the files needed to be accepted as a Debian archive: freight cache +If your system has GnuPG 2.x make sure that a gpg-agent is running and that you +have installed a pinentry package (e.g. pinentry-curses) that suits your needs. +On freight 0.3.11 and older you may also need to set the GPG_TTY environment +variable like this: + + export GPG_TTY=$(tty) + Serve `/var/cache/freight` via your favorite web server and install it as an APT source: echo "deb http://example.com $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/example.list @@ -23,20 +41,30 @@ Serve `/var/cache/freight` via your favorite web server and install it as an APT sudo apt-get update sudo apt-get -y install foobar +Make sure your webserver is configured to follow symlinks inside of the hosted directory. + ## Installation ### From source - git clone git://github.com/rcrowley/freight.git + git clone git://github.com/freight-team/freight.git cd freight && make && sudo make install ### From a Debian archive - echo "deb http://packages.rcrowley.org $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/rcrowley.list - sudo wget -O /etc/apt/trusted.gpg.d/rcrowley.gpg http://packages.rcrowley.org/keyring.gpg + wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg|sudo apt-key add - + echo "deb http://build.openvpn.net/debian/freight_team $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/freight.list sudo apt-get update sudo apt-get -y install freight +### From a custom-made Debian package + +You need `build-essential` package installed. Clone the freight repository, build a package and install it: + + git clone git://github.com/freight-team/freight.git + cd freight && dpkg-buildpackage -uc -us -b + sudo dpkg -i ../freight_-_all.deb + ### From Fedora/EPEL repositories EL users must first [configure EPEL](http://fedoraproject.org/wiki/EPEL/FAQ#How_can_I_install_the_packages_from_the_EPEL_software_repository.3F). @@ -51,15 +79,27 @@ There's also [French documentation](http://blog.valouille.fr/2014/03/creer-un-de ## Manuals -* [`freight`(1)](http://rcrowley.github.com/freight/freight.1.html) -* [`freight-add`(1)](http://rcrowley.github.com/freight/freight-add.1.html) -* [`freight-cache`(1)](http://rcrowley.github.com/freight/freight-cache.1.html) -* [`freight`(5)](http://rcrowley.github.com/freight/freight.5.html) +* [`freight`(1)](http://freight-team.github.io/freight/freight.1.html) +* [`freight-add`(1)](http://freight-team.github.io/freight/freight-add.1.html) +* [`freight-cache`(1)](http://freight-team.github.io/freight/freight-cache.1.html) +* [`freight-clear-cache`(1)](http://freight-team.github.io/freight/freight-clear-cache.1.html) +* [`freight-init`(1)](http://freight-team.github.io/freight/freight-init.1.html) +* [`freight`(5)](http://freight-team.github.io/freight/freight.5.html) ## Contribute -Freight is [BSD-licensed](https://github.com/rcrowley/freight/blob/master/LICENSE) +Freight is [BSD-licensed](https://github.com/freight-team/freight/blob/master/LICENSE) + +* Source code: +* Issue tracker: +* Wiki: + +### Static analysis and code style + +[Shellcheck](https://www.shellcheck.net/) and [shfmt](https://github.com/mvdan/sh) are used to ensure consistency, please see the Travis configuration for the actual tests. + +### Test suite + +The Freight test suite can be executed by running `make check` from any git checkout of this repository. git and GnuPG are required for most tests, and extended tests require apt. -* Source code: -* Issue tracker: -* Wiki: +Contributions should include a new test case where possible by extending one or more of the `test/*.bats` files. diff --git a/bin/freight b/bin/freight index 1208b19..1343662 100755 --- a/bin/freight +++ b/bin/freight @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env sh # `freight` dispatches to `freight-*` commands. @@ -7,13 +7,15 @@ set -e # Just like the DevStructure tools, which try to be just like Git, accept # a subcommand that really just completes the name of a real command. COMMAND=$0-$1 -[ -x $COMMAND ] && { - shift - exec $COMMAND "$@" +[ -x "$COMMAND" ] && { + shift + exec "$COMMAND" "$@" } # Be helpful in this case since no subcommand was found. -echo "Usage: $(basename $0) [...]" >&2 +echo "Usage: $(basename "$0") [...]" >&2 echo "Common commands: add cache init" >&2 -echo "See all available commands by typing \"$(basename $0)-\"" >&2 +echo "See all available commands by typing \"$(basename "$0")-\"" >&2 exit 1 + +# vim: et:ts=4:sw=4 diff --git a/bin/freight-add b/bin/freight-add index 603b8d9..e59b8c9 100755 --- a/bin/freight-add +++ b/bin/freight-add @@ -1,10 +1,12 @@ -#!/bin/sh +#!/usr/bin/env sh +# shellcheck disable=SC1090 # Add a package to the Freight library. #/ Usage: freight add [-c ] [-v] [-h] /... #/ -c , --conf= config file to parse #/ -v, --verbose verbose mode +#/ -e, --add-error exit with error if package already added #/ -h, --help show this help message set -e @@ -13,33 +15,37 @@ usage() { grep "^#/" "$0" | cut -c"4-" >&2 exit "$1" } -while [ "$#" -gt 0 ] -do - case "$1" in - -c|--conf) CONF="$2" shift 2;; - -c*) CONF="$(echo "$1" | cut -c"3-")" shift;; - --conf=*) CONF="$(echo "$1" | cut -c"8-")" shift;; - -v|--verbose) VERBOSE=1 shift;; - -h|--help) usage 0;; - -*) echo "# [freight] unknown switch: $1" >&2;; - *) break;; - esac +while [ "$#" -gt 0 ]; do + case "$1" in + -c | --conf) CONF="$2" shift 2 ;; + -c*) CONF="$(echo "$1" | cut -c"3-")" shift ;; + --conf=*) CONF="$(echo "$1" | cut -c"8-")" shift ;; + -v | --verbose) VERBOSE=1 shift ;; + -e | --add-error) FREIGHT_ADD_ERROR="YES" shift ;; + -h | --help) usage 0 ;; + -*) + echo "# [freight] unknown switch: $1" >&2 + usage 1 + ;; + *) break ;; + esac done -. "$(dirname $(dirname $0))/lib/freight/conf.sh" +. "$(dirname "$(dirname "$0")")/lib/freight/conf.sh" # The non-option argument(s) following the last option are package files. # Binary packages have only one but source packages require two or three. # When the last of these is found, the remaining arguments are each assumed # to be `/` pairs for this (source) package. -while [ "$#" -gt 0 ] -do - case "$1" in - *.deb|*.dsc|*.orig.tar.gz|*.diff.gz|*.debian.tar.gz|*.tar.gz) - PATHNAMES="$PATHNAMES $1" shift;; - *.build|*.changes) shift;; - *) break;; - esac +while [ "$#" -gt 0 ]; do + case "$1" in + *.deb | *.ddeb | *.dsc | *.orig.tar.gz | *.orig.tar.bz2 | *.orig.tar.xz | *.orig.tar.lzma | *.diff.gz | *.debian.tar.gz | *.debian.tar.bz2 | *.debian.tar.xz | *.debian.tar.lzma | *.tar.gz | *.tar.bz2 | *.tar.xz | *.tar.lzma) + # shellcheck disable=SC2153 + PATHNAMES="$PATHNAMES $1" shift + ;; + *.build | *.changes) shift ;; + *) break ;; + esac done [ -z "$PATHNAMES" ] && usage 1 [ -z "$*" ] && usage 1 @@ -49,10 +55,10 @@ done # later Freight commands will rely on the link count being reduced to one. mkdir -p "$VARLIB" TMP="$(mktemp -d "$VARLIB/freight.$$.XXXXXXXXXX")" +# shellcheck disable=SC2064 trap "rm -rf \"$TMP\"" EXIT INT TERM -for PATHNAME in $PATHNAMES -do - cp "$PATHNAME" "$TMP/" +for PATHNAME in $PATHNAMES; do + cp "$PATHNAME" "$TMP/" done # Enter the Freight library directory so that items in `$@` may be given as @@ -64,12 +70,16 @@ cd "$VARLIB" # PATHNAME. The first two are given fairly directly to ln(1); the final one # is used to create appropriate success or failure messages. add() { - if ln "$TMP/$1" "$2/$1" 2>"$TMP/ln" - then echo "# [freight] added $3 to $2${4+" as "}$4" >&2 + if ln "$TMP/$1" "$2/$1" 2>"$TMP/ln"; then + echo "# [freight] added $3 to $2${4+" as "}$4" >&2 else - if grep -q "File exists" "$TMP/ln" - then echo "# [freight] $2 already has $3${4+" as "}$4" >&2 - else cat "$TMP/ln" >&2 + if grep -q "File exists" "$TMP/ln"; then + echo "# [freight] $2 already has $3${4+" as "}$4" >&2 + else + cat "$TMP/ln" >&2 + fi + if [ -n "$FREIGHT_ADD_ERROR" ]; then + exit 2 fi fi } @@ -77,15 +87,13 @@ add() { # Hard link this package into every `/` given in `$@`. # These links will later be used to compile the `Release` and `Packages` # files in the Freight cache. -for PATHNAME in $PATHNAMES -do - FILENAME="$(basename "$PATHNAME")" - for DIRNAME in "$@" - do - mkdir -p "$DIRNAME" +for PATHNAME in $PATHNAMES; do + FILENAME="$(basename "$PATHNAME")" + for DIRNAME in "$@"; do + mkdir -p "$DIRNAME" case "$FILENAME" in - *_*_*.deb) add "$FILENAME" "$DIRNAME" "$PATHNAME";; - *.deb) + *_*_*.deb | *_*_*.ddeb) add "$FILENAME" "$DIRNAME" "$PATHNAME" ;; + *.deb | *.ddeb) . "$(dirname "$(dirname "$0")")/lib/freight/apt.sh" dpkg-deb -I "$TMP/$FILENAME" "control" >"$TMP/$FILENAME-control" DEBNAME="$( @@ -94,9 +102,12 @@ do apt_binary_version "$TMP/$FILENAME-control" )_$( apt_binary_arch "$TMP/$FILENAME-control" - ).deb" - add "$FILENAME" "$DIRNAME" "$PATHNAME" "$DEBNAME";; - *) add "$FILENAME" "$DIRNAME" "$PATHNAME";; + ).${FILENAME##*.}" + add "$FILENAME" "$DIRNAME" "$PATHNAME" "$DEBNAME" + ;; + *) add "$FILENAME" "$DIRNAME" "$PATHNAME" ;; esac - done + done done + +# vim: et:ts=4:sw=4 diff --git a/bin/freight-cache b/bin/freight-cache index c6e8fcc..f1d78a6 100755 --- a/bin/freight-cache +++ b/bin/freight-cache @@ -1,14 +1,17 @@ -#!/bin/sh +#!/usr/bin/env sh +# shellcheck disable=SC1090 # Rebuild the Freight cache from the Freight library. The cache contains # actual repositories that are suitable targets for `apt-get` (and maybe # more in the future). -#/ Usage: freight cache [-k] [-g ] [-p ] [-c ] [-v] [-h] [/][...] +#/ Usage: freight cache [-k] [-g ] [-p ] [-a ] [-c ] [-v] [-h] [/][...] #/ -k, --keep keep unreferenced versions of packages -#/ -g , --gpg= GPG key to use -#/ -p , +#/ -g , --gpg= GPG key to use, may be given multiple times +#/ -p , #/ --passphrase-file= path to file containing the passphrase of the GPG key +#/ -a , +#/ --digest-algo= digest algorithm that GPG should use, e.g SHA512 #/ -c , --conf= config file to parse #/ -v, --verbose verbose mode #/ -h, --help show this help message @@ -16,27 +19,53 @@ set -e usage() { - grep "^#/" "$0" | cut -c"4-" >&2 - exit "$1" + grep "^#/" "$0" | cut -c"4-" >&2 + exit "$1" } -while [ "$#" -gt 0 ] -do - case "$1" in - -k|--keep) KEEP=1 shift;; - -g|--gpg) GPG="$2" shift 2;; - -g*) GPG="$(echo "$1" | cut -c"3-")" shift;; - --gpg=*) GPG="$(echo "$1" | cut -c"7-")" shift;; - -p|--passphrase-file) GPG_PASSPHRASE_FILE="$2" shift 2;; - -p*) GPG_PASSPHRASE_FILE="$(echo "$1" | cut -c"3-")" shift;; - --passphrase-file=*) GPG_PASSPHRASE_FILE="$(echo "$1" | cut -c"19-")" shift;; - -c|--conf) CONF="$2" shift 2;; - -c*) CONF="$(echo "$1" | cut -c"3-")" shift;; - --conf=*) CONF="$(echo "$1" | cut -c"8-")" shift;; - -v|--verbose) VERBOSE=1 shift;; - -h|--help) usage 0;; - -*) echo "# [freight] unknown switch: $1" >&2;; - *) break;; - esac +while [ "$#" -gt 0 ]; do + case "$1" in + -k | --keep) KEEP=1 shift ;; + -g | --gpg) + if [ -z "$GPG" ]; then + GPG=$2 + else + GPG="$GPG $2" + fi + shift 2 + ;; + -g*) + if [ -z "$GPG" ]; then + GPG=$(echo "$1" | cut -c"3-") + else + GPG="$GPG $(echo "$1" | cut -c"3-")" + fi + shift + ;; + --gpg=*) + if [ -z "$GPG" ]; then + GPG=$(echo "$1" | cut -c"7-") + else + GPG="$GPG $(echo "$1" | cut -c"7-")" + fi + shift + ;; + -p | --passphrase-file) GPG_PASSPHRASE_FILE="$2" shift 2 ;; + -p*) GPG_PASSPHRASE_FILE="$(echo "$1" | cut -c"3-")" shift ;; + --passphrase-file=*) GPG_PASSPHRASE_FILE="$(echo "$1" | cut -c"19-")" shift ;; + -a | --digest-algo) GPG_DIGEST_ALGO="$2" shift 2 ;; + -a*) GPG_DIGEST_ALGO="$(echo "$1" | cut -c"3-")" shift ;; + --digest-algo=*) GPG_DIGEST_ALGO="$(echo "$1" | cut -c"15-")" shift ;; + -c | --conf) CONF="$2" shift 2 ;; + -c*) CONF="$(echo "$1" | cut -c"3-")" shift ;; + --conf=*) CONF="$(echo "$1" | cut -c"8-")" shift ;; + -v | --verbose) VERBOSE=1 shift ;; + -h | --help) usage 0 ;; + -*) + echo "# [freight] unknown switch: $1" >&2 + usage 1 + ;; + *) break ;; + esac done LIB="$(cd "$(dirname "$(dirname "$0")")/lib/freight" && pwd)" @@ -44,11 +73,15 @@ LIB="$(cd "$(dirname "$(dirname "$0")")/lib/freight" && pwd)" # If `GPG_PASSPHRASE_FILE` is set the specified file should exist and be # readable by the user running Freight. -[ -z "$GPG_PASSPHRASE_FILE" -o -r "$GPG_PASSPHRASE_FILE" ] || echo "# [freight] could not read passphrase file: $GPG_PASSPHRASE_FILE." >&2 +[ -z "$GPG_PASSPHRASE_FILE" ] || [ -r "$GPG_PASSPHRASE_FILE" ] || echo "# [freight] could not read passphrase file: $GPG_PASSPHRASE_FILE." >&2 + +# If `GPG_DIGEST_ALGO` is unset, force it to the freight default of SHA512 +[ -z "$GPG_DIGEST_ALGO" ] && GPG_DIGEST_ALGO="SHA512" # Create a working directory on the same device as the Freight cache. mkdir -p "$VARCACHE" TMP="$(mktemp -d "$VARCACHE/work.$$.XXXXXXXXXX")" +# shellcheck disable=SC2064 trap "rm -rf \"$TMP\"" EXIT INT TERM # Enter the Freight library directory so that items in `$@` may be given as @@ -58,39 +91,41 @@ mkdir -p "$VARLIB" cd "$VARLIB" # Rebuild each distro serially. -if [ -z "$*" ] -then - DIRS="$( - find "$VARLIB" -mindepth 2 -maxdepth 2 -type d -printf "%P\n" | - grep -v "^\\." | - tr "\n" " " - )" +if [ -z "$*" ]; then + DIRS="$( + find "$VARLIB"/ -mindepth 2 -maxdepth 2 -type d -printf "%P\n" | + grep -v '^\.' | + tr "\n" " " + )" else - DIRS="$@" + DIRS=$* fi -for DIR in $DIRS -do - - # Parse the manager and distro out of the Freight library path. - DIR="$(readlink -f "$DIR")" - DIR="${DIR##"$VARLIB/"}" - MANAGER="$(dirname "$DIR")" - DIST="$(basename "$DIR")" - - # Should we follow symbolic links when finding components to cache? - [ "$SYMLINKS" = "on" ] && FIND_L="-L" || FIND_L="" - - # From here the process is customized on a per-manager basis. The - # sorted list of package filenames comes on `stdin` and the name of - # the distro is the only argument. From there, each manager can do - # whatever it wants. - . "$LIB/$MANAGER.sh" - SORT="$(sort -V <"/dev/null" 2>"/dev/null" && echo "sort -V" || echo "sort")" - find $FIND_L "$DIR" -type "f" -printf "%P\n" 2>"/dev/null" | - eval "$SORT" | - eval "${MANAGER}_cache" "$DIST" - - # Clean up old packages as dictated by the manager. - [ -z "$KEEP" ] && eval "${MANAGER}_clean" +for DIR in $DIRS; do + + # Parse the manager and distro out of the Freight library path. + DIR="$(readlink -f "$DIR")" + DIR="${DIR##"$(readlink -f "$VARLIB")/"}" + MANAGER="$(dirname "$DIR")" + DIST="$(basename "$DIR")" + + # Should we follow symbolic links when finding components to cache? + [ "$SYMLINKS" = "on" ] && FIND_L="-L" || FIND_L="" + + # From here the process is customized on a per-manager basis. The + # sorted list of package filenames comes on `stdin` and the name of + # the distro is the only argument. From there, each manager can do + # whatever it wants. + . "$LIB/$MANAGER.sh" + SORT="$(sort -V <"/dev/null" 2>"/dev/null" && echo "sort -V" || echo "sort")" + find $FIND_L "$DIR" -type "f" -printf "%P\n" 2>"/dev/null" | + eval "$SORT" | + eval "${MANAGER}_cache" "$DIST" + + # Clean up old packages as dictated by the manager. + if [ -z "$KEEP" ]; then + eval "${MANAGER}_clean" + fi done + +# vim: et:ts=4:sw=4 diff --git a/bin/freight-clear-cache b/bin/freight-clear-cache index d120859..96a9190 100755 --- a/bin/freight-clear-cache +++ b/bin/freight-clear-cache @@ -1,4 +1,5 @@ -#!/bin/sh +#!/usr/bin/env sh +# shellcheck disable=SC1090 # Clear the cache that is built up during freight-cache runs # so that it can be regenerated on the next freight-cache invocation. @@ -11,20 +12,22 @@ set -e usage() { - grep "^#/" "$0" | cut -c"4-" >&2 - exit "$1" + grep "^#/" "$0" | cut -c"4-" >&2 + exit "$1" } -while [ "$#" -gt 0 ] -do - case "$1" in - -c|--conf) CONF="$2" shift 2;; - -c*) CONF="$(echo "$1" | cut -c"3-")" shift;; - --conf=*) CONF="$(echo "$1" | cut -c"8-")" shift;; - -v|--verbose) VERBOSE=1 shift;; - -h|--help) usage 0;; - -*) echo "# [freight] unknown switch: $1" >&2;; - *) break;; - esac +while [ "$#" -gt 0 ]; do + case "$1" in + -c | --conf) CONF="$2" shift 2 ;; + -c*) CONF="$(echo "$1" | cut -c"3-")" shift ;; + --conf=*) CONF="$(echo "$1" | cut -c"8-")" shift ;; + -v | --verbose) VERBOSE=1 shift ;; + -h | --help) usage 0 ;; + -*) + echo "# [freight] unknown switch: $1" >&2 + usage 1 + ;; + *) break ;; + esac done . "$(dirname "$(dirname "$0")")/lib/freight/conf.sh" @@ -32,6 +35,7 @@ done # Create a working directory on the same device as the Freight cache. mkdir -p "$VARCACHE" TMP="$(mktemp -d "$VARCACHE/work.$$.XXXXXXXXXX")" +# shellcheck disable=SC2064 trap "rm -rf \"$TMP\"" EXIT INT TERM # Enter the Freight library directory so that items in `$@` may be given as @@ -41,27 +45,27 @@ mkdir -p "$VARLIB" cd "$VARLIB" # Rebuild each distro serially. -if [ -z "$*" ] -then - DIRS="$( - find "$VARLIB" -mindepth 2 -maxdepth 2 -type d -printf "%P\n" | - grep -v "^\\." | - tr "\n" " " - )" +if [ -z "$*" ]; then + DIRS="$( + find "$VARLIB" -mindepth 2 -maxdepth 2 -type d -printf "%P\n" | + grep -v '^\.' | + tr "\n" " " + )" else - DIRS="$@" + DIRS=$* fi -for DIR in $DIRS -do +for DIR in $DIRS; do - # Parse the manager and distro out of the Freight library path. - DIR="$(readlink -f "$DIR")" - DIR="${DIR##"$VARLIB/"}" - MANAGER="$(dirname "$DIR")" - DIST="$(basename "$DIR")" + # Parse the manager and distro out of the Freight library path. + DIR="$(readlink -f "$DIR")" + DIR="${DIR##"$VARLIB/"}" + MANAGER="$(dirname "$DIR")" + DIST="$(basename "$DIR")" - # From here the process is customized on a per-manager basis. - . "$(dirname "$(dirname "$0")")/lib/freight/$MANAGER.sh" - eval "${MANAGER}_clear_cache" "$DIST" + # From here the process is customized on a per-manager basis. + . "$(dirname "$(dirname "$0")")/lib/freight/$MANAGER.sh" + eval "${MANAGER}_clear_cache" "$DIST" done + +# vim: et:ts=4:sw=4 diff --git a/bin/freight-init b/bin/freight-init index a8671c5..867d74e 100755 --- a/bin/freight-init +++ b/bin/freight-init @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env sh # Initialize a Freight directory (similar to git init). @@ -17,40 +17,64 @@ set -e CONF="etc/freight.conf" +GPG="" usage() { grep "^#/" "$0" | cut -c"4-" >&2 exit "$1" } -while [ "$#" -gt 0 ] -do - case "$1" in - -g|--gpg) GPG="$2" shift 2;; - -g*) GPG="$(echo "$1" | cut -c"3-")" shift;; - --gpg=*) GPG="$(echo "$1" | cut -c"7-")" shift;; - -c|--conf) CONF="$2" shift 2;; - -c*) CONF="$(echo "$1" | cut -c"3-")" shift;; - --conf=*) CONF="$(echo "$1" | cut -c"8-")" shift;; - --libdir) VARLIB="$2" shift 2;; - --libdir=*) VARLIB="$(echo "$1" | cut -c"10-")" shift;; - --cachedir) VARCACHE="$2" shift 2;; - --cachedir=*) VARCACHE="$(echo "$1" | cut -c"12-")" shift;; - --archs) ARCHS="$2" shift 2;; - --archs=*) ARCHS="$(echo "$1" | cut -c"9-")" shift;; - --origin) ORIGIN="$2" shift 2;; - --origin=*) ORIGIN="$(echo "$1" | cut -c"10-")" shift;; - --label) LABEL="$2" shift 2;; - --label=*) LABEL="$(echo "$1" | cut -c"9-")" shift;; - --suite) SUITE="$2" shift 2;; - --suite=*) SUITE="$(echo "$1" | cut -c"9-")" shift;; - -v|--verbose) VERBOSE=1 shift;; - -h|--help) usage 0;; - -*) echo "# [freight] unknown switch: $1" >&2;; - *) break;; - esac +while [ "$#" -gt 0 ]; do + case "$1" in + -g | --gpg) + if [ -z "$GPG" ]; then + GPG=$2 + else + GPG="$GPG $2" + fi + shift 2 + ;; + -g*) + if [ -z "$GPG" ]; then + GPG=$(echo "$1" | cut -c"3-") + else + GPG="$GPG $(echo "$1" | cut -c"3-")" + fi + shift + ;; + --gpg=*) + if [ -z "$GPG" ]; then + GPG=$(echo "$1" | cut -c"7-") + else + GPG="$GPG $(echo "$1" | cut -c"7-")" + fi + shift + ;; + -c | --conf) CONF="$2" shift 2 ;; + -c*) CONF="$(echo "$1" | cut -c"3-")" shift ;; + --conf=*) CONF="$(echo "$1" | cut -c"8-")" shift ;; + --libdir) VARLIB="$2" shift 2 ;; + --libdir=*) VARLIB="$(echo "$1" | cut -c"10-")" shift ;; + --cachedir) VARCACHE="$2" shift 2 ;; + --cachedir=*) VARCACHE="$(echo "$1" | cut -c"12-")" shift ;; + --archs) ARCHS="$2" shift 2 ;; + --archs=*) ARCHS="$(echo "$1" | cut -c"9-")" shift ;; + --origin) ORIGIN="$2" shift 2 ;; + --origin=*) ORIGIN="$(echo "$1" | cut -c"10-")" shift ;; + --label) LABEL="$2" shift 2 ;; + --label=*) LABEL="$(echo "$1" | cut -c"9-")" shift ;; + --suite) SUITE="$2" shift 2 ;; + --suite=*) SUITE="$(echo "$1" | cut -c"9-")" shift ;; + -v | --verbose) VERBOSE=1 shift ;; + -h | --help) usage 0 ;; + -*) + echo "# [freight] unknown switch: $1" >&2 + usage 1 + ;; + *) break ;; + esac done DIRNAME="$(cd "${1:-"."}" && pwd)" -[ -z "$GPG" -o -z "$DIRNAME" ] && usage 1 +[ -z "$GPG" ] || [ -z "$DIRNAME" ] && usage 1 # The default value for VARLIB and VARCACHE lies within DIRNAME but otherwise # follows the FHS style. @@ -76,3 +100,5 @@ EOF # return 0 when we come here exit 0 + +# vim: et:ts=4:sw=4 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..756c1a4 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,44 @@ +freight (0.3.13) stable; urgency=low + + * Merge pull request #90 from stuwil/ddeb_support (Samuli Seppänen, 6baefb5) + * Added missing symlink requirement (Ben Tyger, df4f2d9) + * use xenial for travis tests (Michael Moll, d110d7d) + * Reformat with newer shfmt version (Michael Moll, bc1d80c) + * Support 'ddeb' file extension (Stuart Williams, dab1dbe) + + -- Samuli Seppänen Wed, 4 Nov 2020 13:05:00 +0000 + +freight (0.3.12) stable; urgency=low + + * bump version to 0.3.12 (Michael Moll, 6f31de8) + * Support gpg2 in freight cache passphrase file option (Hiroaki Nakamura, 60b5263) + * use shfmt and add it to travis (Michael Moll, 92dc0e2) + * Unrecognized switches caused infinite loop in all the commands. (Stanislaw Klekot, 105c1dc) + * create InRelease file (Michael Moll, 0a8c99a) + * refactor signing of the Release file (Michael Moll, 12060a3) + * refactor multikey signing test (Michael Moll, de3c875) + * Document caveats when using GnuPG 2.x (Samuli Seppänen, 2d967bc) + * Travis does provide haveged now (Michael Moll, a1af28b) + * adjust .travis.yml after Travis updates (Michael Moll, 32ce114) + * Suppress link error messages. (Dancho Penev, 78949f8) + * calculate size correctly (Michael Moll, ba9f37e) + * fix new shellcheck warnings (Michael Moll, 42d0067) + + -- Samuli Seppänen Mon, 4 Jun 2018 06:00:00 +0000 + +freight (0.3.11) stable; urgency=low + + * bump version to 0.3.11 (Michael Moll, de67c6e) + * Add the ability to build deb package the Debian way (Vasily, e935511) + * Include NotAutomatic and ButAutomaticUpgrades in Release files (David R. Bild, fb4b600) + * Add NotAutomatic and ButAutomaticUpgrades to conf (David R. Bild, 6968e48) + * Prevent GPG >= 2.1 from using .kbx pubring format (Jeremy Teale, fb02979) + * Let install-man task work on second and subsequent attempts (Stephen Ryan, 4f412fa) + + -- Samuli Seppänen Thu, 18 May 2017 15:00:00 +0000 + +freight (0.3.10) UNRELEASED; urgency=low + + * Initial release. + + -- Vasily Laur Tue, 11 Apr 2017 14:46:08 +0000 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..0b2f590 --- /dev/null +++ b/debian/control @@ -0,0 +1,11 @@ +Source: freight +Section: utils +Priority: extra +Maintainer: Freight team +Build-Depends: debhelper (>=9) +Homepage: https://github.com/freight-team/freight + +Package: freight +Architecture: all +Depends: gnupg +Description: A modern take on the Debian archive diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..6bec60f --- /dev/null +++ b/debian/rules @@ -0,0 +1,10 @@ +#!/usr/bin/make -f + +%: + dh $@ + +# hide next line to enable tests +override_dh_auto_test: ; + +override_dh_auto_install: + dh_auto_install -- prefix=/usr sysconfdir=/etc diff --git a/etc/freight.conf.example b/etc/freight.conf.example index 8e8fa7c..d1b78d0 100644 --- a/etc/freight.conf.example +++ b/etc/freight.conf.example @@ -5,18 +5,31 @@ VARLIB="/var/lib/freight" VARCACHE="/var/cache/freight" -# Default `Origin` and `Label` fields for `Release` files. +# Default `Origin`, `Label`, `NotAutomatic`, and +# `ButAutomaticUpgrades` fields for `Release` files. ORIGIN="Freight" LABEL="Freight" +NOT_AUTOMATIC="no" +BUT_AUTOMATIC_UPGRADES="no" # Cache the control files after each run (on), or regenerate them every # time (off). CACHE="off" -# GPG key to use to sign repositories. This is required by the `apt` +# GPG key(s) to use to sign repositories. This is required by the `apt` # repository provider. Use `gpg --gen-key` (see `gpg`(1) for more # details) to generate a key and put its email address here. +# +# Multiple addresses can be given sign the repository with them all. GPG="example@example.com" +# GPG="example@example.com another@example.com" + +# Message digest algorithm that GPG should use to sign the repository. +# It is not recommended to use SHA1 as new versions of `apt` will report +# that the repository is half-broken due to weak digest. +# +# SHA512 is the default +GPG_DIGEST_ALGO="SHA512" # Whether to follow symbolic links in `$VARLIB` to produce extra components # in the cache directory (on) or not (off). diff --git a/lib/freight/apt.sh b/lib/freight/apt.sh index ad6040c..cb7880d 100644 --- a/lib/freight/apt.sh +++ b/lib/freight/apt.sh @@ -1,323 +1,369 @@ -TTY="$(tty -s && echo "1" || :)" +if tty -s; then + TTY="1" +fi # Fetch the given field from the package's control file. apt_info() { - egrep -i "^$2:" "$1" | cut -d: -f2- | awk '{print $1}' + grep -E -i "^$2:" "$1" | cut -d: -f2- | awk '{print $1}' } # Print the package name from the given control file. apt_binary_name() { - apt_info "$1" Package + apt_info "$1" Package } # Print the version from the given control file. apt_binary_version() { - apt_info "$1" Version + apt_info "$1" Version } # Print the architecture from the given control file. apt_binary_arch() { - apt_info "$1" Architecture + apt_info "$1" Architecture } apt_binary_filesize() { - apt_info "$1" Size + apt_info "$1" Size } # Print the source name from the given control file. apt_binary_sourcename() { - SOURCE="$(apt_info "$1" Source)" - [ -z "$SOURCE" ] && SOURCE="$(apt_binary_name "$1")" - echo "$SOURCE" + SOURCE="$(apt_info "$1" Source)" + [ -z "$SOURCE" ] && SOURCE="$(apt_binary_name "$1")" + echo "$SOURCE" } # Print the prefix the given control file should use in the pool. apt_binary_prefix() { - apt_prefix "$(apt_binary_sourcename "$1")" + apt_prefix "$(apt_binary_sourcename "$1")" } # Print the name portion of a source package's pathname. apt_source_name() { - basename "$1" ".dsc" | cut -d_ -f1 + basename "$1" ".dsc" | cut -d_ -f1 } # Print the version portion of a source package's pathname. apt_source_version() { - basename "$1" ".dsc" | cut -d_ -f2 + basename "$1" ".dsc" | cut -d_ -f2 } # Print the original version portion of a source package's pathname. apt_source_origversion() { - apt_source_version "$1" | cut -d- -f1 + apt_source_version "$1" | cut -d- -f1 } # Print the prefix for a package name. apt_prefix() { - [ "$(echo "$1" | cut -c1-3)" = "lib" ] && C=4 || C=1 - echo "$1" | cut -c-$C + [ "$(echo "$1" | cut -c1-3)" = "lib" ] && C=4 || C=1 + echo "$1" | cut -c-$C } # Print the checksum portion of the normal checksumming programs' output. apt_md5() { - md5sum "$1" | cut -d" " -f1 + md5sum "$1" | cut -d" " -f1 } apt_sha1() { - sha1sum "$1" | cut -d" " -f1 + sha1sum "$1" | cut -d" " -f1 } apt_sha256() { - sha256sum "$1" | cut -d" " -f1 + sha256sum "$1" | cut -d" " -f1 +} +apt_sha512() { + sha512sum "$1" | cut -d" " -f1 } # Print the size of the given file. apt_filesize() { - stat -c%s "$1" + stat -c%s "$(readlink -f "$1")" } # Setup the repository for the distro named in the first argument, # including all packages read from `stdin`. apt_cache() { - DIST="$1" - SUITE="${SUITE:-$DIST}" - - # Generate a timestamp to use in this build's directory name. - DATE="$(date +%Y%m%d%H%M%S%N)" - DISTCACHE="$VARCACHE/dists/$DIST-$DATE" - - # For a Debian archive, each distribution needs at least this directory - # structure in place. The directory for this build must not exist, - # otherwise this build would clobber a previous one. The `.refs` - # directory contains links to all the packages currently included in - # this distribution to enable cleaning by link count later. - mkdir -p "$DISTCACHE/.refs" - mkdir -p "$VARCACHE/pool/$DIST" - - # Work through every package that should be part of this distro. - while read PATHNAME - do - - # Extract the component, if present, from the package's pathname. - case "$PATHNAME" in - */*) COMP="${PATHNAME%%/*}" PACKAGE="${PATHNAME##*/}";; - *) COMP="main" PACKAGE="$PATHNAME";; - esac - - case "$PATHNAME" in - - # Binary packages. - *.deb) apt_cache_binary "$DIST" "$DISTCACHE" "$PATHNAME" "$COMP" "$PACKAGE";; - - # Source packages. The *.dsc file is considered the "entrypoint" - # and will find the associated *.orig.tar.gz, *.diff.gz, and/or + REL_DATE="$(LC_ALL=en_US date -u '+%a, %d %b %Y %H:%M:%S %Z')" + VALID_DATE="Tue, 30 Nov 2038 00:00:00 UTC" + DIST="$1" + SUITE="${SUITE:-$DIST}" + + # Generate a timestamp to use in this build's directory name. + DATE="$(date +%Y%m%d%H%M%S%N)" + DISTCACHE="$VARCACHE/dists/$DIST-$DATE" + + # For a Debian archive, each distribution needs at least this directory + # structure in place. The directory for this build must not exist, + # otherwise this build would clobber a previous one. The `.refs` + # directory contains links to all the packages currently included in + # this distribution to enable cleaning by link count later. + mkdir -p "$DISTCACHE/.refs" + mkdir -p "$VARCACHE/pool/$DIST" + + # Work through every package that should be part of this distro. + while read -r PATHNAME; do + + # Extract the component, if present, from the package's pathname. + case "$PATHNAME" in + */*) COMP="${PATHNAME%%/*}" PACKAGE="${PATHNAME##*/}" ;; + *) COMP="main" PACKAGE="$PATHNAME" ;; + esac + + case "$PATHNAME" in + + # Binary packages. + *.deb | *.ddeb) apt_cache_binary "$DIST" "$DISTCACHE" "$PATHNAME" "$COMP" "$PACKAGE" ;; + + # Source packages. The *.dsc file is considered the "entrypoint" + # and will find the associated *.orig.tar.gz, *.diff.gz, and/or # *.tar.gz as they are needed. - *.dsc) apt_cache_source "$DIST" "$DISTCACHE" "$PATHNAME" "$COMP" "$PACKAGE";; - *.debian.tar.gz|*.diff.gz|*.orig.tar.gz|*.tar.gz|*.deb-control|*.dsc-cached) ;; - - *) echo "# [freight] skipping extraneous file $PATHNAME" >&2;; - esac - done - COMPS="$(ls "$DISTCACHE")" - - # Build a `Release` file for each component and architecture. `gzip` - # the `Packages` file, too. - for COMP in $COMPS - do - for ARCH in $ARCHS - do - cat >"$DISTCACHE/$COMP/binary-$ARCH/Release" <&2 ;; + esac + done + COMPS="$(ls "$DISTCACHE")" + + # Build a `Release` file for each component and architecture. `gzip` + # the `Packages` file, too. + for COMP in $COMPS; do + # shellcheck disable=SC2153 + for ARCH in $ARCHS; do + if [ -d "$DISTCACHE/$COMP/binary-$ARCH" ]; then + cat >"$DISTCACHE/$COMP/binary-$ARCH/Release" <"$DISTCACHE/$COMP/binary-$ARCH/Packages.gz" - done - if [ -d "$DISTCACHE/$COMP/source" ] - then - cat >"$DISTCACHE/$COMP/source/Release" <"$DISTCACHE/$COMP/binary-$ARCH/Packages.gz" + fi + done + if [ -d "$DISTCACHE/$COMP/source" ]; then + cat >"$DISTCACHE/$COMP/source/Release" <"$DISTCACHE/$COMP/source/Sources.gz" - fi - done - - # Begin the top-level `Release` file with the lists of components - # and architectures present in this repository and the checksums - # of all the `Release` and `Packages.gz` files within. - { - cat <"$DISTCACHE/$COMP/source/Sources.gz" + fi + done + + # Begin the top-level `Release` file with the lists of components + # and architectures present in this repository and the checksums + # of all the `Release` and `Packages.gz` files within. + { + cat <&3 - echo " $(apt_sha1 "$DISTCACHE/$FILE" ) $SIZE $FILE" >&4 - echo " $(apt_sha256 "$DISTCACHE/$FILE" ) $SIZE $FILE" >&5 - done 3>"$TMP/md5sums" 4>"$TMP/sha1sums" 5>"$TMP/sha256sums" - echo "MD5Sum:" - cat "$TMP/md5sums" - echo "SHA1:" - cat "$TMP/sha1sums" - echo "SHA256:" - cat "$TMP/sha256sums" - - } >"$DISTCACHE/Release" - - # Sign the top-level `Release` file with `gpg`. - gpg -abs$([ "$TTY" ] || echo " --no-tty") --use-agent -u"$GPG" \ - $([ "$GPG_PASSPHRASE_FILE" ] && echo " --batch --passphrase-fd 1 --passphrase-file $GPG_PASSPHRASE_FILE") \ - -o"$DISTCACHE/Release.gpg" "$DISTCACHE/Release" || { - cat <&3 + echo " $(apt_sha1 "$DISTCACHE/$FILE") $SIZE $FILE" >&4 + echo " $(apt_sha256 "$DISTCACHE/$FILE") $SIZE $FILE" >&5 + echo " $(apt_sha512 "$DISTCACHE/$FILE") $SIZE $FILE" >&6 + done 3>"$TMP/md5sums" 4>"$TMP/sha1sums" 5>"$TMP/sha256sums" 6>"$TMP/sha512sums" + echo "MD5Sum:" + cat "$TMP/md5sums" + echo "SHA1:" + cat "$TMP/sha1sums" + echo "SHA256:" + cat "$TMP/sha256sums" + echo "SHA512:" + cat "$TMP/sha512sums" + + } >"$DISTCACHE/Release" + + # compose one gpg parameter string with all GPG keys + USERKEYS="" + for GPGKEY in $GPG; do + USERKEYS="$USERKEYS$(printf %s "-u$GPGKEY") " + done + + # Check if gpg supports --pinentry loopback option + # See https://wiki.archlinux.org/index.php/GnuPG#Unattended_passphrase + PINENTRY_LOOPBACK="" + [ "$GPG_PASSPHRASE_FILE" ] && + gpg --no-tty --pinentry-mode loopback --list-keys >/dev/null 2>&1 && + PINENTRY_LOOPBACK=" --pinentry-mode loopback" + + # Sign the top-level `Release` file with `gpg` + # shellcheck disable=SC2046 disable=SC2086 disable=SC2015 + gpg -abs$([ "$TTY" ] || echo " --no-tty") --use-agent ${USERKEYS} \ + $([ "$GPG_PASSPHRASE_FILE" ] && echo " --batch$PINENTRY_LOOPBACK --passphrase-fd 1 --passphrase-file $GPG_PASSPHRASE_FILE") \ + $([ "$GPG_DIGEST_ALGO" ] && echo " --personal-digest-preferences $GPG_DIGEST_ALGO") \ + -o"$DISTCACHE/Release.gpg" "$DISTCACHE/Release" && + # Create/Sign the top-level `InRelease` file with `gpg` + gpg --clearsign$([ "$TTY" ] || echo " --no-tty") --use-agent ${USERKEYS} \ + $([ "$GPG_PASSPHRASE_FILE" ] && echo " --batch$PINENTRY_LOOPBACK --passphrase-fd 1 --passphrase-file $GPG_PASSPHRASE_FILE") \ + $([ "$GPG_DIGEST_ALGO" ] && echo " --personal-digest-preferences $GPG_DIGEST_ALGO") \ + -o"$DISTCACHE/InRelease" "$DISTCACHE/Release" || { + cat <= 2.1 from using the + # new `pubring.kbx` format during an initial `gpg --import`. + : >"$TMP/gpg/pubring.gpg" && chmod 644 "$TMP/gpg/pubring.gpg" + # shellcheck disable=SC2086 + gpg -q --export -a $GPG | + tee "$VARCACHE/pubkey.gpg" | + gpg -q --homedir "$TMP/gpg" --import + mv "$TMP/gpg/pubring.gpg" "$VARCACHE/keyring.gpg" + + # Move the symbolic link for this distro to this build. + ln -s "$DIST-$DATE" "$DISTCACHE-" + OLD="$(readlink "$VARCACHE/dists/$DIST" || true)" + mv -T "$DISTCACHE-" "$VARCACHE/dists/$DIST" + [ -z "$OLD" ] || rm -rf "$VARCACHE/dists/$OLD" } # Clear the cached control files from the dist apt_clear_cache() { - # First remove the binary control cache - find "$VARLIB/apt/$DIST" -name *-control | xargs --no-run-if-empty rm - # Next remove the source control cache - find "$VARLIB/apt/$DIST" -name *-cached | xargs --no-run-if-empty rm + # First remove the binary control cache + find "$VARLIB/apt/$DIST" -name '*-control' -print0 | xargs -0 --no-run-if-empty rm + # Next remove the source control cache + find "$VARLIB/apt/$DIST" -name '*-cached' -print0 | xargs -0 --no-run-if-empty rm } # Add a binary package to the given dist and to the pool. apt_cache_binary() { - DIST="$1" - DISTCACHE="$2" - PATHNAME="$3" - COMP="$4" - PACKAGE="$5" - - # Verify this package by way of extracting its control information - # to be used throughout this iteration of the loop. - # Don't extract the deb archive each time. Stick the control file - # in the $VARLIB alongside the other package artifacts for easy - # use later. - if [ "$CACHE" = "on" ]; then - CONTROL="$VARLIB/apt/$DIST/$PATHNAME-control" - else - CONTROL="$TMP/DEBIAN/binary-control" - fi - # If caching is off or if the binary has changed size, this will generate the - # binary control file - if ! ( [ -e "$CONTROL" ] && \ - [ "$(apt_binary_filesize "$CONTROL")" -eq "$(apt_filesize "$VARLIB/apt/$DIST/$PATHNAME")" ] ); then - dpkg-deb -e "$VARLIB/apt/$DIST/$PATHNAME" "$TMP/DEBIAN" || { - echo "# [freight] skipping invalid Debian package $PATHNAME" >&2 - return - } - { - # Grab and augment the control file from this package. Remove - # `Size`, `MD5Sum`, etc. lines and replace them with newly - # generated values. Update it once when generating the - # cached control file. Add a Filename line that can be updated - # easily later with the real path. Strip out empty control fields - # as these might cause problems. - grep . "$TMP/DEBIAN/control" | - grep -E -v "^[A-Za-z-]+:\s+$" | - grep -v "^(Essential|Filename|MD5Sum|SHA1|SHA256|Size)" - cat <&2 + return + } + { + # Grab and augment the control file from this package. Remove + # `Size`, `MD5Sum`, etc. lines and replace them with newly + # generated values. Update it once when generating the + # cached control file. Add a Filename line that can be updated + # easily later with the real path. Strip out empty control fields + # as these might cause problems. + grep . "$TMP/DEBIAN/control" | + grep -E -v "^[A-Za-z-]+:\s+$" | + grep -v "^(Essential|Filename|MD5Sum|SHA1|SHA256|SHA512|Size)" + cat < "$CONTROL" - fi - - # Create all architecture-specific directories. This will allow - # packages marked `all` to actually be placed in all architectures. - for ARCH in $ARCHS - do - mkdir -p "$DISTCACHE/$COMP/binary-$ARCH" - touch "$DISTCACHE/$COMP/binary-$ARCH/Packages" - done - - # Link or copy this package into this distro's `.refs` directory. - mkdir -p "$DISTCACHE/.refs/$COMP" - ln "$VARLIB/apt/$DIST/$PATHNAME" "$DISTCACHE/.refs/$COMP" || - cp "$VARLIB/apt/$DIST/$PATHNAME" "$DISTCACHE/.refs/$COMP" - - # Package properties. Remove the epoch from the version number - # in the package filename, as is customary. - ARCH="$(apt_binary_arch "$CONTROL")" - NAME="$(apt_binary_name "$CONTROL")" - VERSION="$(apt_binary_version "$CONTROL")" - PREFIX="$(apt_binary_prefix "$CONTROL")" - SOURCE="$(apt_binary_sourcename "$CONTROL")" - FILENAME="${NAME}_${VERSION##*:}_${ARCH}.deb" - - # Link this package into the pool. - POOL="pool/$DIST/$COMP/$PREFIX/$SOURCE" - mkdir -p "$VARCACHE/$POOL" - if [ ! -f "$VARCACHE/$POOL/$FILENAME" ] - then - if [ "$PACKAGE" != "$FILENAME" ] - then echo "# [freight] adding $PACKAGE to pool (as $FILENAME)" >&2 - else echo "# [freight] adding $PACKAGE to pool" >&2 - fi - ln "$DISTCACHE/.refs/$COMP/$PACKAGE" "$VARCACHE/$POOL/$FILENAME" - fi - - # Build a list of the one-or-more `Packages` files to append with - # this package's info. - if [ "$ARCH" = "all" ] - then FILES="$(find "$DISTCACHE/$COMP" -type f -name "Packages")" - else FILES="$DISTCACHE/$COMP/binary-$ARCH/Packages" - fi - - # Add the `Filename` field containing the path to the - # package, starting with `pool/`. - sed "s,^Filename: FILENAME$,Filename: $POOL/$FILENAME,g" "$CONTROL" | - tee -a $FILES >/dev/null - - # Cleanup the extracted package - if [ -d "$TMP/DEBIAN" ]; then - rm -rf "$TMP/DEBIAN" - fi + echo + } >"$CONTROL" + fi + + # Create all architecture-specific directories. This will allow + # packages marked `all` to actually be placed in all architectures. + for ARCH in $ARCHS; do + mkdir -p "$DISTCACHE/$COMP/binary-$ARCH" + touch "$DISTCACHE/$COMP/binary-$ARCH/Packages" + done + + # Link or copy this package into this distro's `.refs` directory. + mkdir -p "$DISTCACHE/.refs/$COMP" + ln "$VARLIB/apt/$DIST/$PATHNAME" "$DISTCACHE/.refs/$COMP" >/dev/null 2>&1 || + cp "$VARLIB/apt/$DIST/$PATHNAME" "$DISTCACHE/.refs/$COMP" + + # Package properties. Remove the epoch from the version number + # in the package filename, as is customary. + ARCH="$(apt_binary_arch "$CONTROL")" + NAME="$(apt_binary_name "$CONTROL")" + VERSION="$(apt_binary_version "$CONTROL")" + PREFIX="$(apt_binary_prefix "$CONTROL")" + SOURCE="$(apt_binary_sourcename "$CONTROL")" + FILENAME="${NAME}_${VERSION##*:}_${ARCH}.${PATHNAME##*.}" + + # Link this package into the pool. + POOL="pool/$DIST/$COMP/$PREFIX/$SOURCE" + mkdir -p "$VARCACHE/$POOL" + if [ ! -f "$VARCACHE/$POOL/$FILENAME" ]; then + if [ "$PACKAGE" != "$FILENAME" ]; then + echo "# [freight] adding $PACKAGE to pool (as $FILENAME)" >&2 + else + echo "# [freight] adding $PACKAGE to pool" >&2 + fi + ln "$DISTCACHE/.refs/$COMP/$PACKAGE" "$VARCACHE/$POOL/$FILENAME" + fi + + # Build a list of the one-or-more `Packages` files to append with + # this package's info. + if [ "$ARCH" = "all" ]; then + FILES="$(find "$DISTCACHE/$COMP" -type f -name "Packages")" + else + FILES="$DISTCACHE/$COMP/binary-$ARCH/Packages" + fi + + # Add the `Filename` field containing the path to the + # package, starting with `pool/`. + # shellcheck disable=SC2086 + sed "s,^Filename: FILENAME$,Filename: $POOL/$FILENAME,g" "$CONTROL" | + tee -a $FILES >/dev/null + + # Cleanup the extracted package + if [ -d "$TMP/DEBIAN" ]; then + rm -rf "$TMP/DEBIAN" + fi } @@ -325,118 +371,132 @@ EOF # *.diff.gz, and/or *.tar.gz will be found based on PATHNAME and associated # with the correct source package. apt_cache_source() { - DIST="$1" - DISTCACHE="$2" - PATHNAME="$3" - COMP="$4" - PACKAGE="$5" - - NAME="$(apt_source_name "$PATHNAME")" - VERSION="$(apt_source_version "$PATHNAME")" - ORIG_VERSION="$(apt_source_origversion "$PATHNAME")" - DIRNAME="$(dirname "$PATHNAME")" - DSC_FILENAME="${NAME}_${VERSION%*:}.dsc" - DEBTAR_FILENAME="${NAME}_${VERSION%*:}.debian.tar.gz" - DIFFGZ_FILENAME="${NAME}_${VERSION%*:}.diff.gz" - ORIG_FILENAME="${NAME}_${ORIG_VERSION}.orig.tar.gz" - TAR_FILENAME="${NAME}_${VERSION%*:}.tar.gz" + DIST="$1" + DISTCACHE="$2" + PATHNAME="$3" + COMP="$4" + PACKAGE="$5" + + NAME="$(apt_source_name "$PATHNAME")" + VERSION="$(apt_source_version "$PATHNAME")" + ORIG_VERSION="$(apt_source_origversion "$PATHNAME")" + DIRNAME="$(dirname "$PATHNAME")" + DSC_FILENAME="${NAME}_${VERSION%*:}.dsc" + DEBTAR_GZ_FILENAME="${NAME}_${VERSION%*:}.debian.tar.gz" + DEBTAR_BZ2_FILENAME="${NAME}_${VERSION%*:}.debian.tar.bz2" + DEBTAR_XZ_FILENAME="${NAME}_${VERSION%*:}.debian.tar.xz" + DEBTAR_LZMA_FILENAME="${NAME}_${VERSION%*:}.debian.tar.lzma" + DIFFGZ_FILENAME="${NAME}_${VERSION%*:}.diff.gz" + ORIG_FILENAME="${NAME}_${ORIG_VERSION}.orig.tar.gz" + TAR_FILENAME="${NAME}_${VERSION%*:}.tar.gz" # Find which style of diff they're using. - if [ -f "$VARLIB/apt/$DIST/$DIRNAME/$DEBTAR_FILENAME" ] - then DIFF_FILENAME=${DEBTAR_FILENAME} - else DIFF_FILENAME=${DIFFGZ_FILENAME} - fi - - # Verify this package by ensuring the other necessary files are present. - [ -f "$VARLIB/apt/$DIST/$DIRNAME/$ORIG_FILENAME" -a -f "$VARLIB/apt/$DIST/$DIRNAME/$DIFF_FILENAME" -o -f "$VARLIB/apt/$DIST/$DIRNAME/$TAR_FILENAME" ] || { - echo "# [freight] skipping invalid Debian source package $PATHNAME" >&2 - return - } - - # Create the architecture-parallel source directory and manifest. - mkdir -p "$DISTCACHE/$COMP/source" - touch "$DISTCACHE/$COMP/source/Sources" - - # Link or copy this source package into this distro's `.refs` directory - # if it isn't already there (which can happen when two packages derive - # from the same original tarball). - mkdir -p "$DISTCACHE/.refs/$COMP" - for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME" - do + if [ -f "$VARLIB/apt/$DIST/$DIRNAME/$DEBTAR_GZ_FILENAME" ]; then + DIFF_FILENAME=${DEBTAR_GZ_FILENAME} + elif [ -f "$VARLIB/apt/$DIST/$DIRNAME/$DEBTAR_BZ2_FILENAME" ]; then + DIFF_FILENAME=${DEBTAR_BZ2_FILENAME} + elif [ -f "$VARLIB/apt/$DIST/$DIRNAME/$DEBTAR_XZ_FILENAME" ]; then + DIFF_FILENAME=${DEBTAR_XZ_FILENAME} + elif [ -f "$VARLIB/apt/$DIST/$DIRNAME/$DEBTAR_LZMA_FILENAME" ]; then + DIFF_FILENAME=${DEBTAR_LZMA_FILENAME} + else + DIFF_FILENAME=${DIFFGZ_FILENAME} + fi + + # Verify this package by ensuring the other necessary files are present. + [ -f "$VARLIB/apt/$DIST/$DIRNAME/$ORIG_FILENAME" ] && [ -f "$VARLIB/apt/$DIST/$DIRNAME/$DIFF_FILENAME" ] || [ -f "$VARLIB/apt/$DIST/$DIRNAME/$TAR_FILENAME" ] || { + echo "# [freight] skipping invalid Debian source package $PATHNAME" >&2 + return + } + + # Create the architecture-parallel source directory and manifest. + mkdir -p "$DISTCACHE/$COMP/source" + touch "$DISTCACHE/$COMP/source/Sources" + + # Link or copy this source package into this distro's `.refs` directory + # if it isn't already there (which can happen when two packages derive + # from the same original tarball). + mkdir -p "$DISTCACHE/.refs/$COMP" + for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME"; do [ -f "$VARLIB/apt/$DIST/$DIRNAME/$FILENAME" ] || continue [ -f "$DISTCACHE/.refs/$COMP/$FILENAME" ] || - ln "$VARLIB/apt/$DIST/$DIRNAME/$FILENAME" "$DISTCACHE/.refs/$COMP" || - cp "$VARLIB/apt/$DIST/$DIRNAME/$FILENAME" "$DISTCACHE/.refs/$COMP" - done - - # Package properties. Remove the epoch from the version number - # in the package filename, as is customary. - - # Link this source package into the pool. - POOL="pool/$DIST/$COMP/$(apt_prefix "$NAME")/$NAME" - mkdir -p "$VARCACHE/$POOL" - for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME" - do - if [ -f "$DISTCACHE/.refs/$COMP/$FILENAME" -a ! -f "$VARCACHE/$POOL/$FILENAME" ] - then - echo "# [freight] adding $FILENAME to pool" >&2 - ln "$DISTCACHE/.refs/$COMP/$FILENAME" "$VARCACHE/$POOL" - fi - done - - # Grab and augment the control fields from this source package. Remove - # and recalculate file checksums. Change the `Source` field to `Package`. - # Add the `Directory` field. Only do this if a cached copy does not exist. - if [ "$CACHE" = "on" ]; then - CONTROL="$VARLIB/apt/$DIST/$PATHNAME-cached" - else - CONTROL="$TMP/source-control" - fi - if ! [ -e "$CONTROL" ]; then - { - egrep "^[A-Z][^:]+: ." "$VARLIB/apt/$DIST/$PATHNAME" | - egrep -v "^(Version: GnuPG|Hash: )" | - sed "s/^Source:/Package:/" - echo "Directory: DIRECTORY" - echo "Files:" - for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME" - do + ln "$VARLIB/apt/$DIST/$DIRNAME/$FILENAME" "$DISTCACHE/.refs/$COMP" >/dev/null 2>&1 || + cp "$VARLIB/apt/$DIST/$DIRNAME/$FILENAME" "$DISTCACHE/.refs/$COMP" + done + + # Package properties. Remove the epoch from the version number + # in the package filename, as is customary. + + # Link this source package into the pool. + POOL="pool/$DIST/$COMP/$(apt_prefix "$NAME")/$NAME" + mkdir -p "$VARCACHE/$POOL" + for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME"; do + if [ -f "$DISTCACHE/.refs/$COMP/$FILENAME" ] && ! [ -f "$VARCACHE/$POOL/$FILENAME" ]; then + echo "# [freight] adding $FILENAME to pool" >&2 + ln "$DISTCACHE/.refs/$COMP/$FILENAME" "$VARCACHE/$POOL" + fi + done + + # Grab and augment the control fields from this source package. Remove + # and recalculate file checksums. Change the `Source` field to `Package`. + # Add the `Directory` field. Only do this if a cached copy does not exist. + if [ "$CACHE" = "on" ]; then + CONTROL="$VARLIB/apt/$DIST/$PATHNAME-cached" + else + CONTROL="$TMP/source-control" + fi + if ! [ -e "$CONTROL" ]; then + { + grep -E "^[A-Z][^:]+: ." "$VARLIB/apt/$DIST/$PATHNAME" | + grep -E -v "^(Version: GnuPG|Hash: )" | + sed "s/^Source:/Package:/" + echo "Directory: DIRECTORY" + echo "Files:" + for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME"; do + [ -f "$VARCACHE/$POOL/$FILENAME" ] || continue + SIZE="$(apt_filesize "$VARCACHE/$POOL/$FILENAME")" + MD5="$(apt_md5 "$VARCACHE/$POOL/$FILENAME")" + echo " $MD5 $SIZE $FILENAME" + done + echo "Checksums-Sha1:" + for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME"; do [ -f "$VARCACHE/$POOL/$FILENAME" ] || continue - SIZE="$(apt_filesize "$VARCACHE/$POOL/$FILENAME")" - MD5="$(apt_md5 "$VARCACHE/$POOL/$FILENAME")" - echo " $MD5 $SIZE $FILENAME" - done - echo "Checksums-Sha1:" - for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME" - do + SIZE="$(apt_filesize "$VARCACHE/$POOL/$FILENAME")" + SHA1="$(apt_sha1 "$VARCACHE/$POOL/$FILENAME")" + echo " $SHA1 $SIZE $FILENAME" + done + echo "Checksums-Sha256:" + for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME"; do [ -f "$VARCACHE/$POOL/$FILENAME" ] || continue - SIZE="$(apt_filesize "$VARCACHE/$POOL/$FILENAME")" - SHA1="$(apt_sha1 "$VARCACHE/$POOL/$FILENAME")" - echo " $SHA1 $SIZE $FILENAME" - done - echo "Checksums-Sha256:" - for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME" - do + SIZE="$(apt_filesize "$VARCACHE/$POOL/$FILENAME")" + SHA256="$(apt_sha256 "$VARCACHE/$POOL/$FILENAME")" + echo " $SHA256 $SIZE $FILENAME" + done + echo "Checksums-Sha512:" + for FILENAME in "$DSC_FILENAME" "$ORIG_FILENAME" "$DIFF_FILENAME" "$TAR_FILENAME"; do [ -f "$VARCACHE/$POOL/$FILENAME" ] || continue - SIZE="$(apt_filesize "$VARCACHE/$POOL/$FILENAME")" - SHA256="$(apt_sha256 "$VARCACHE/$POOL/$FILENAME")" - echo " $SHA256 $SIZE $FILENAME" - done - echo - } > "$CONTROL" - fi - - sed "s,^Directory: DIRECTORY$,Directory: $POOL,g" "$CONTROL" | - tee -a "$DISTCACHE/$COMP/source/Sources" >/dev/null - -# Clean up the tmp space - if [ -f "$TMP/source-control" ]; then - rm "$TMP/source-control" - fi + SIZE="$(apt_filesize "$VARCACHE/$POOL/$FILENAME")" + SHA512="$(apt_sha512 "$VARCACHE/$POOL/$FILENAME")" + echo " $SHA512 $SIZE $FILENAME" + done + echo + } >"$CONTROL" + fi + + sed "s,^Directory: DIRECTORY$,Directory: $POOL,g" "$CONTROL" | + tee -a "$DISTCACHE/$COMP/source/Sources" >/dev/null + + # Clean up the tmp space + if [ -f "$TMP/source-control" ]; then + rm "$TMP/source-control" + fi } # Clean up old packages in the pool. apt_clean() { - find "$VARCACHE/pool" -links 1 -delete || true + find "$VARCACHE/pool" -links 1 -type f -delete + find "$VARCACHE/pool" -type d -empty -delete } + +# vim: et:ts=4:sw=4 diff --git a/lib/freight/conf.sh b/lib/freight/conf.sh index 139da65..8630b03 100644 --- a/lib/freight/conf.sh +++ b/lib/freight/conf.sh @@ -1,3 +1,4 @@ +# shellcheck disable=SC1090,SC1091 # Freight configuration. # Default directories for the Freight library and Freight cache. Your @@ -6,36 +7,45 @@ VARLIB="/var/lib/freight" VARCACHE="/var/cache/freight" # Default architectures. +# shellcheck disable=SC2034 ARCHS="i386 amd64" -# Default `Origin` and `Label` fields for `Release` files. +# Default `Origin`, `Label`, 'NotAutomatic`, and +# `ButAutomaticUpgrades` fields for `Release` files. +# shellcheck disable=SC2034 ORIGIN="Freight" +# shellcheck disable=SC2034 LABEL="Freight" +# shellcheck disable=SC2034 +NOT_AUTOMATIC="no" +# shellcheck disable=SC2034 +BUT_AUTOMATIC_UPGRADES="no" +# shellcheck disable=SC2034 CACHE="off" +# shellcheck disable=SC2034 SYMLINKS="off" # Source all existing configuration files from lowest- to highest-priority. -PREFIX="$(dirname $(dirname $0))" -if [ "$PREFIX" = "/usr" ] -then [ -f "/etc/freight.conf" ] && . "/etc/freight.conf" -else [ -f "$PREFIX/etc/freight.conf" ] && . "$PREFIX/etc/freight.conf" +PREFIX="$(dirname "$(dirname "$0")")" +if [ "$PREFIX" = "/usr" ]; then + [ -f "/etc/freight.conf" ] && . "/etc/freight.conf" +else + [ -f "$PREFIX/etc/freight.conf" ] && . "$PREFIX/etc/freight.conf" fi [ -f "$HOME/.freight.conf" ] && . "$HOME/.freight.conf" DIRNAME="$PWD" -while true -do - [ -f "$DIRNAME/etc/freight.conf" ] && . "$DIRNAME/etc/freight.conf" && break - [ -f "$DIRNAME/.freight.conf" ] && . "$DIRNAME/.freight.conf" && break - [ "$DIRNAME" = "/" ] && break - DIRNAME="$(dirname "$DIRNAME")" +while true; do + [ -f "$DIRNAME/etc/freight.conf" ] && . "$DIRNAME/etc/freight.conf" && break + [ -f "$DIRNAME/.freight.conf" ] && . "$DIRNAME/.freight.conf" && break + [ "$DIRNAME" = "/" ] && break + DIRNAME="$(dirname "$DIRNAME")" done -[ "$FREIGHT_CONF" -a -f "$FREIGHT_CONF" ] && . "$FREIGHT_CONF" -if [ "$CONF" ] -then - if [ -f "$CONF" ] - then . "$CONF" +[ "$FREIGHT_CONF" ] && [ -f "$FREIGHT_CONF" ] && . "$FREIGHT_CONF" +if [ "$CONF" ]; then + if [ -f "$CONF" ]; then + . "$CONF" else echo "# [freight] $CONF does not exist" >&2 exit 1 @@ -45,3 +55,5 @@ fi # Normalize directory names. VARLIB=${VARLIB%%/} VARCACHE=${VARCACHE%%/} + +# vim: et:ts=4:sw=4 diff --git a/man/man1/freight-add.1 b/man/man1/freight-add.1 index e8344bb..ef569d2 100644 --- a/man/man1/freight-add.1 +++ b/man/man1/freight-add.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "FREIGHT\-ADD" "1" "January 2014" "" "Freight" +.TH "FREIGHT\-ADD" "1" "September 2016" "" "Freight" . .SH "NAME" \fBfreight\-add\fR \- add a package to Freight @@ -10,7 +10,7 @@ \fBfreight add\fR [\fB\-c\fR \fIconf\fR] [\fB\-v\fR] [\fB\-h\fR] \fIpackage\fR \fImanager\fR/\fIdistro\fR[/\fIcomponent\fR][\.\.\.] . .SH "DESCRIPTION" -\fBfreight\-add\fR registers \fIpackage\fR with one or more \fImanager\fR/\fIdistro\fR[/\fIcomponent\fR] pairs (or triples)\. Currently, \fBapt\fR is the only supported \fImanager\fR and \fIpackage\fR must be one of \fI*\.deb\fR, \fI*\.dsc *\.debian\.tar\.gz *\.orig\.tar\.gz\fR, \fI*\.dsc *\.diff\.gz *\.orig\.tar\.gz\fR, or \fI*\.dsc *\.tar\.gz\fR\. \fIdistro\fR may be any arbitrary value but is best suited to naming a particular version of the target operating system (for example, "wheezy" or "precise")\. \fIcomponent\fR is optional and for \fBapt\fR defaults to \fBmain\fR\. +\fBfreight\-add\fR registers \fIpackage\fR with one or more \fImanager\fR/\fIdistro\fR[/\fIcomponent\fR] pairs (or triples)\. Currently, \fBapt\fR is the only supported \fImanager\fR and \fIpackage\fR must be one of \fI*\.deb\fR, \fI*\.ddeb\fR, \fI*\.dsc *\.debian\.tar\.gz *\.orig\.tar\.gz\fR, \fI*\.dsc *\.diff\.gz *\.orig\.tar\.gz\fR, or \fI*\.dsc *\.tar\.gz\fR\. \fIdistro\fR may be any arbitrary value but is best suited to naming a particular version of the target operating system (for example, "wheezy" or "precise")\. \fIcomponent\fR is optional and for \fBapt\fR defaults to \fBmain\fR\. . .P The package files are organized in the Freight library so \fBfreight\-cache\fR(1) has an easy time of creating package repositories for each \fImanager\fR/\fIdistro\fR[/\fIcomponent\fR] later\. @@ -26,6 +26,10 @@ Use an alternate configuration file\. Verbose mode\. . .TP +\fB\-e\fR, \fB\-\-add\-error\fR +Raises an error if the package to add is already registered\. +. +.TP \fB\-h\fR, \fB\-\-help\fR Show a help message\. . @@ -41,6 +45,10 @@ The default configuration files\. See \fBfreight\fR(5)\. \fBFREIGHT_CONF\fR The pathname of an alternate configuration file\. See \fBfreight\fR(5)\. . +.TP +\fBFREIGHT_ADD_ERROR\fR +If not empty acts as \-\-add\-error option\. +. .SH "THEME SONG" The New Pornographers \- "All the Old Showstoppers" . diff --git a/man/man1/freight-add.1.ronn b/man/man1/freight-add.1.ronn index 207285f..6ca4ecf 100644 --- a/man/man1/freight-add.1.ronn +++ b/man/man1/freight-add.1.ronn @@ -7,7 +7,7 @@ freight-add(1) -- add a package to Freight ## DESCRIPTION -`freight-add` registers _package_ with one or more _manager_/_distro_[/_component_] pairs (or triples). Currently, `apt` is the only supported _manager_ and _package_ must be one of _\*.deb_, _\*.dsc \*.debian.tar.gz \*.orig.tar.gz_, _\*.dsc \*.diff.gz \*.orig.tar.gz_, or _\*.dsc \*.tar.gz_. _distro_ may be any arbitrary value but is best suited to naming a particular version of the target operating system (for example, "wheezy" or "precise"). _component_ is optional and for `apt` defaults to `main`. +`freight-add` registers _package_ with one or more _manager_/_distro_[/_component_] pairs (or triples). Currently, `apt` is the only supported _manager_ and _package_ must be one of _\*.deb_, _\*.ddeb_, _\*.dsc \*.debian.tar.gz \*.orig.tar.gz_, _\*.dsc \*.diff.gz \*.orig.tar.gz_, or _\*.dsc \*.tar.gz_. _distro_ may be any arbitrary value but is best suited to naming a particular version of the target operating system (for example, "wheezy" or "precise"). _component_ is optional and for `apt` defaults to `main`. The package files are organized in the Freight library so `freight-cache`(1) has an easy time of creating package repositories for each _manager_/_distro_[/_component_] later. @@ -17,6 +17,8 @@ The package files are organized in the Freight library so `freight-cache`(1) has Use an alternate configuration file. * `-v`, `--verbose`: Verbose mode. +* `-e`, `--add-error`: + Raises an error if the package to add is already registered. * `-h`, `--help`: Show a help message. @@ -29,6 +31,8 @@ The package files are organized in the Freight library so `freight-cache`(1) has * `FREIGHT_CONF`: The pathname of an alternate configuration file. See `freight`(5). +* `FREIGHT_ADD_ERROR`: + If not empty acts as --add-error option. ## THEME SONG diff --git a/man/man1/freight-cache.1 b/man/man1/freight-cache.1 index 51c4713..2dca184 100644 --- a/man/man1/freight-cache.1 +++ b/man/man1/freight-cache.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "FREIGHT\-CACHE" "1" "January 2014" "" "Freight" +.TH "FREIGHT\-CACHE" "1" "March 2016" "" "Freight" . .SH "NAME" \fBfreight\-cache\fR \- (re)builds package repositories @@ -29,13 +29,17 @@ Keep unreferenced versions of packages\. This is different than keeping multiple . .TP \fB\-g\fR \fIemail\fR, \fB\-\-gpg=\fR\fIemail\fR -Use an alternate GPG key\. +Use an alternate GPG key\. May be given multiple times\. . .TP \fB\-p\fR \fIpassphrase file\fR, \fB\-\-passphrase\-file=\fR\fIpassphrase file\fR Use an alternate file containing the GPG key passphrase\. This file should obviously be protected and only readable by the user running Freight\. . .TP +\fB\-a\fR \fIdigest algorithm\fR, \fB\-\-digest\-algo=\fR\fIdigest algorithm\fR +Message digest algorithm that GPG should use to sign the repository, e\.g SHA512 +. +.TP \fB\-c\fR \fIconf\fR, \fB\-\-conf=\fR\fIconf\fR Use an alternate configuration file\. . diff --git a/man/man1/freight-cache.1.ronn b/man/man1/freight-cache.1.ronn index 99d3f8c..26e4afe 100644 --- a/man/man1/freight-cache.1.ronn +++ b/man/man1/freight-cache.1.ronn @@ -20,9 +20,11 @@ From version 0.0.8 onwards, distros in an APT repository no longer share the con * `-k`, `--keep`: Keep unreferenced versions of packages. This is different than keeping multiple versions of a package in the repository, which is supported without any special options. * `-g` _email_, `--gpg=`_email_: - Use an alternate GPG key. + Use an alternate GPG key. May be given multiple times. * `-p` _passphrase file_, `--passphrase-file=`_passphrase file_: Use an alternate file containing the GPG key passphrase. This file should obviously be protected and only readable by the user running Freight. +* `-a` _digest algorithm_, `--digest-algo=`_digest algorithm_: + Message digest algorithm that GPG should use to sign the repository, e.g SHA512 * `-c` _conf_, `--conf=`_conf_: Use an alternate configuration file. * `-v`, `--verbose`: diff --git a/man/man1/freight-clear-cache.1 b/man/man1/freight-clear-cache.1 index 04af341..55fdef2 100644 --- a/man/man1/freight-clear-cache.1 +++ b/man/man1/freight-clear-cache.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "FREIGHT\-CLEAR\-CACHE" "1" "July 2014" "" "Freight" +.TH "FREIGHT\-CLEAR\-CACHE" "1" "March 2016" "" "Freight" . .SH "NAME" \fBfreight\-clear\-cache\fR \- clears existing package repositories diff --git a/man/man1/freight-init.1 b/man/man1/freight-init.1 index 6a36afd..c3b69b5 100644 --- a/man/man1/freight-init.1 +++ b/man/man1/freight-init.1 @@ -1,36 +1,52 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "FREIGHT\-INIT" "1" "January 2014" "" "Freight" +.TH "FREIGHT\-INIT" "1" "March 2016" "" "Freight" . .SH "NAME" \fBfreight\-init\fR \- initialize a Freight directory . .SH "SYNOPSIS" -\fBfreight init\fR [\fB\-l\fR \fIvarlib\fR] [\fB\-\-cache\fR \fIvarcache\fR] \fB\-g\fR \fIgpg\fR \fIdirname\fR +\fBfreight init\fR [\fB\-\-libdir\fR \fIvarlib\fR] [\fB\-\-cachedir\fR \fIvarcache\fR] [\fB\-\-archs\fR \fIarchs\fR] [\fB\-\-origin\fR \fIorigin\fR] [\fB\-\-label\fR \fIlabel\fR] [\fB\-v\fR] [\fB\-h\fR] \fB\-g\fR \fIgpg\fR \fIdirname\fR . .SH "DESCRIPTION" -\fBfreight\-init\fR will setup a directory to be used by Freight\. It will generate small wrappers around the original Freight commands\. Use \fB\./freight\-add\fR and \fB\./freight\-cache\fR to work against the \fBVARLIB\fR and \fBVARCACHE\fR given to \fBfreight init\fR\. +\fBfreight\-init\fR will setup a directory to be used by Freight\. It will generate small wrappers around the original Freight commands\. Use \fBfreight\-add\fR(1) and \fBfreight\-cache\fR(1) to work against the \fBVARLIB\fR and \fBVARCACHE\fR given to \fBfreight init\fR\. . .P -The benefit of using \fBfreight\-init\fR is, that all data is stored in one place and dont have to pass \fB\-c _conf_\fR option all the time\. +The benefit of using \fBfreight\-init\fR is to automate the setup of Freight and to configure all data to be stored in one directory\. . .P -Configuration is stored in \fB_dirname_/\.freight\.conf\fR\. +Configuration is stored in \fIdirname\fR\fB/etc/freight\.conf\fR\. . .SH "OPTIONS" . .TP -\fB\-g\fR \fIgpg\fR, \fB\-\-gpg=\fR\fIgpg\fR` -GPG key\. +\fB\-g\fR \fIgpg\fR, \fB\-\-gpg=\fR\fIgpg\fR +GPG key\. May be given multiple times\. . .TP -\fB\-l\fR \fIvarlib\fR, \fB\-\-varlib=\fR\fIvarlib\fB_\fR\fR -VARLIB directory to use\. Defaults todirname_/lib` +\fB\-\-libdir=\fR\fIvarlib\fR +VARLIB directory to use\. Defaults to \fIdirname\fR\fB/var/lib\fR . .TP -\fB\-\-varcache=\fR\fIvarcache\fB_\fR\fR -VARCACHE directory to use\. Defaults todirname_/cache` +\fB\-\-cachedir=\fR\fIvarcache\fR +VARCACHE directory to use\. Defaults to \fIdirname\fR\fB/var/cache\fR +. +.TP +\fB\-\-archs=\fR\fIarchs\fR +Architectures to generate archives for\. Defaults to \fBi386 amd64\fR +. +.TP +\fB\-\-origin=\fR\fIorigin\fR +Debian archive Origin field value\. Defaults to \fBFreight\fR +. +.TP +\fB\-\-label=\fR\fIlabel\fR +Debian archive Label field value\. Defaults to \fBFreight\fR +. +.TP +\fB\-\-suite=\fR\fIsuite\fR +Debian archive Suite field value\. . .TP \fB\-v\fR, \fB\-\-verbose\fR diff --git a/man/man1/freight-init.1.ronn b/man/man1/freight-init.1.ronn index c010f2a..09f5ce0 100644 --- a/man/man1/freight-init.1.ronn +++ b/man/man1/freight-init.1.ronn @@ -3,24 +3,32 @@ freight-init(1) -- initialize a Freight directory ## SYNOPSIS -`freight init` [`-l` _varlib_] [`--cache` _varcache_] `-g` _gpg_ _dirname_ +`freight init` [`--libdir` _varlib_] [`--cachedir` _varcache_] [`--archs` _archs_] [`--origin` _origin_] [`--label` _label_] [`-v`] [`-h`] `-g` _gpg_ _dirname_ ## DESCRIPTION -`freight-init` will setup a directory to be used by Freight. It will generate small wrappers around the original Freight commands. Use `./freight-add` and `./freight-cache` to work against the `VARLIB` and `VARCACHE` given to `freight init`. +`freight-init` will setup a directory to be used by Freight. It will generate small wrappers around the original Freight commands. Use `freight-add`(1) and `freight-cache`(1) to work against the `VARLIB` and `VARCACHE` given to `freight init`. -The benefit of using `freight-init` is, that all data is stored in one place and dont have to pass `-c _conf_` option all the time. +The benefit of using `freight-init` is to automate the setup of Freight and to configure all data to be stored in one directory. -Configuration is stored in `_dirname_/.freight.conf`. +Configuration is stored in _dirname_`/etc/freight.conf`. ## OPTIONS -* `-g` _gpg_, `--gpg=`_gpg_`: - GPG key. -* `-l` _varlib_, `--varlib=`_varlib`_: - VARLIB directory to use. Defaults to `_dirname_/lib` -* `--varcache=`_varcache`_: - VARCACHE directory to use. Defaults to `_dirname_/cache` +* `-g` _gpg_, `--gpg=`_gpg_: + GPG key. May be given multiple times. +* `--libdir=`_varlib_: + VARLIB directory to use. Defaults to _dirname_`/var/lib` +* `--cachedir=`_varcache_: + VARCACHE directory to use. Defaults to _dirname_`/var/cache` +* `--archs=`_archs_: + Architectures to generate archives for. Defaults to `i386 amd64` +* `--origin=`_origin_: + Debian archive Origin field value. Defaults to `Freight` +* `--label=`_label_: + Debian archive Label field value. Defaults to `Freight` +* `--suite=`_suite_: + Debian archive Suite field value. * `-v`, `--verbose`: Verbose mode. * `-h`, `--help`: diff --git a/man/man1/freight.1 b/man/man1/freight.1 index 3f17ae5..71e9345 100644 --- a/man/man1/freight.1 +++ b/man/man1/freight.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "FREIGHT" "1" "January 2014" "" "Freight" +.TH "FREIGHT" "1" "March 2016" "" "Freight" . .SH "NAME" \fBfreight\fR \- a modern take on the Debian archive diff --git a/man/man5/freight.5 b/man/man5/freight.5 index 874db71..9158226 100644 --- a/man/man5/freight.5 +++ b/man/man5/freight.5 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "FREIGHT" "5" "January 2014" "" "Freight" +.TH "FREIGHT" "5" "March 2016" "" "Freight" . .SH "NAME" \fBfreight\fR \- Freight configuration @@ -32,18 +32,30 @@ The \fBOrigin\fR field in the Debian archive\. The \fBLabel\fR field in the Debian archive\. . .TP +\fBNOT_AUTOMATIC\fR +The \fBNotAutomatic\fR field in the Debian archive\. +. +.TP +\fBBUT_AUTOMATIC_UGPRADES\fR +The \fBButAutomaticUpgrades\fR field in the Debian archive\. +. +.TP \fBCACHE\fR \fIon\fR to cache package control files or \fIoff\fR to read them from the packages on each \fBfreight\-cache\fR(1) run\. . .TP \fBGPG\fR -The GPG key to use\. This value must be set either in a configuration file or by using the \fB\-g\fR option to \fBfreight\-cache\fR(1)\. +The GPG key(s) to use\. This value must be set either in a configuration file or by using the \fB\-g\fR option to \fBfreight\-cache\fR(1)\. Multiple keys can be given to sign the repository with more signatures\. . .TP \fBGPG_PASSPHRASE_FILE\fR Pathname of a file containing the GPGP private key\'s passphrase\. This sets the \fB\-\-passphrase\-fd\fR and \fB\-\-passphrase\-file\fR options to \fBgpg\fR(1)\. The passphrase file can be set either in a configuration file or by using the \fB\-p\fR option to \fBfreight\-cache\fR(1)\. . .TP +\fBGPG_DIGEST_ALGO\fR +Message digest algorithm that GPG should use to sign the repository\. Apt is phasing out SHA1 so it is recommended to use SHA512 for most use\-cases\. This sets the \fB\-\-personal\-digest\-preferences\fR option to \fBgpg\fR(1)\. The digest algorithm can be set either in a configuration file or by using the \fB\-a\fR option to \fBfreight\-cache\fR(1)\. +. +.TP \fBSYMLINKS\fR \fIon\fR to follow symbolic links in \fBVARLIB\fR to produce extra components in the cache directory or \fIoff\fR to offer no special treatment\. . diff --git a/man/man5/freight.5.ronn b/man/man5/freight.5.ronn index de75aa1..d46cdd5 100644 --- a/man/man5/freight.5.ronn +++ b/man/man5/freight.5.ronn @@ -20,9 +20,11 @@ The Freight configuration is a `source`d shell script that defines a few importa * `CACHE`: _on_ to cache package control files or _off_ to read them from the packages on each `freight-cache`(1) run. * `GPG`: - The GPG key to use. This value must be set either in a configuration file or by using the `-g` option to `freight-cache`(1). + The GPG key(s) to use. This value must be set either in a configuration file or by using the `-g` option to `freight-cache`(1). Multiple keys can be given to sign the repository with more signatures. * `GPG_PASSPHRASE_FILE`: Pathname of a file containing the GPGP private key's passphrase. This sets the `--passphrase-fd` and `--passphrase-file` options to `gpg`(1). The passphrase file can be set either in a configuration file or by using the `-p` option to `freight-cache`(1). +* `GPG_DIGEST_ALGO`: + Message digest algorithm that GPG should use to sign the repository. Apt is phasing out SHA1 so it is recommended to use SHA512 for most use-cases. This sets the `--personal-digest-preferences` option to `gpg`(1). The digest algorithm can be set either in a configuration file or by using the `-a` option to `freight-cache`(1). * `SYMLINKS`: _on_ to follow symbolic links in `VARLIB` to produce extra components in the cache directory or _off_ to offer no special treatment. diff --git a/test/apt_add.bats b/test/apt_add.bats new file mode 100644 index 0000000..b3fc7b1 --- /dev/null +++ b/test/apt_add.bats @@ -0,0 +1,61 @@ +# vim: et:ts=4:sw=4:ft=sh + +load freight_helpers + +setup() { + freight_init +} + +@test "freight-add adds package to distro main component" { + run freight_add ${FIXTURES}/test_1.0_all.deb apt/example + assert_success + assert_output "# [freight] added ${FIXTURES}/test_1.0_all.deb to apt/example" + test -e ${FREIGHT_LIB}/apt/example/test_1.0_all.deb +} + +@test "freight-add adds package to a component" { + freight_add ${FIXTURES}/test_1.0_all.deb apt/example/comp + test -e ${FREIGHT_LIB}/apt/example/comp/test_1.0_all.deb +} + +@test "freight-add adds package and hard link to multiple components" { + freight_add ${FIXTURES}/test_1.0_all.deb apt/example/comp apt/example/another + test -e ${FREIGHT_LIB}/apt/example/comp/test_1.0_all.deb + test -e ${FREIGHT_LIB}/apt/example/another/test_1.0_all.deb + test $(stat -c '%i' ${FREIGHT_LIB}/apt/example/comp/*.deb) -eq $(stat -c '%i' ${FREIGHT_LIB}/apt/example/another/*.deb) +} + +@test "freight-add detects duplicate package" { + freight_add ${FIXTURES}/test_1.0_all.deb apt/example + run freight_add ${FIXTURES}/test_1.0_all.deb apt/example + assert_success + assert_output "# [freight] apt/example already has ${FIXTURES}/test_1.0_all.deb" +} + +@test "freight-add adds source .dsc files" { + run freight_add ${FIXTURES}/source_1.0-1.dsc apt/example + assert_success + assert_output "# [freight] added ${FIXTURES}/source_1.0-1.dsc to apt/example" + test -e ${FREIGHT_LIB}/apt/example/source_1.0-1.dsc +} + +@test "freight-add adds source .tar.gz files" { + run freight_add ${FIXTURES}/source_1.0-1.tar.gz apt/example + assert_success + assert_output "# [freight] added ${FIXTURES}/source_1.0-1.tar.gz to apt/example" + test -e ${FREIGHT_LIB}/apt/example/source_1.0-1.tar.gz +} + +@test "freight-add adds source .orig.tar.gz files" { + run freight_add ${FIXTURES}/source_1.0.orig.tar.gz apt/example + assert_success + assert_output "# [freight] added ${FIXTURES}/source_1.0.orig.tar.gz to apt/example" + test -e ${FREIGHT_LIB}/apt/example/source_1.0.orig.tar.gz +} + +@test "freight-add handles VARLIB being a symlink" { + mv $FREIGHT_LIB ${FREIGHT_LIB}_real + ln -s ${FREIGHT_LIB}_real $FREIGHT_LIB + freight_add ${FIXTURES}/test_1.0_all.deb apt/example/comp + test -e ${FREIGHT_LIB}_real/apt/example/comp/test_1.0_all.deb +} diff --git a/test/apt_cache.bats b/test/apt_cache.bats new file mode 100644 index 0000000..def96a9 --- /dev/null +++ b/test/apt_cache.bats @@ -0,0 +1,93 @@ +# vim: et:ts=4:sw=4:ft=sh + +load freight_helpers +load apt_helpers + +setup() { + freight_init + freight_add ${FIXTURES}/test_1.0_all.deb apt/example + freight_add ${FIXTURES}/test_1.0_all.deb apt/example/comp + configure_local_apt +} + +@test "freight-cache builds distro Release/InRelease file" { + freight_cache -v + test -e ${FREIGHT_CACHE}/dists/example/Release + egrep "^Components: comp main" ${FREIGHT_CACHE}/dists/example/Release + test -e ${FREIGHT_CACHE}/dists/example/InRelease + egrep "^Components: comp main" ${FREIGHT_CACHE}/dists/example/InRelease +} + +@test "freight-cache builds per-component Release file" { + freight_cache -v + test -e ${FREIGHT_CACHE}/dists/example/comp/binary-amd64/Release + test -e ${FREIGHT_CACHE}/dists/example/main/binary-amd64/Release +} + +@test "freight-cache builds pool" { + freight_cache -v + test -e ${FREIGHT_CACHE}/pool/example/comp/t/test/test_1.0_all.deb + test -e ${FREIGHT_CACHE}/pool/example/main/t/test/test_1.0_all.deb +} + +@test "freight-cache generates valid Release/InRelease signatures" { + freight_cache -v + gpg --verify ${FREIGHT_CACHE}/dists/example/Release.gpg ${FREIGHT_CACHE}/dists/example/Release + gpg --verify ${FREIGHT_CACHE}/dists/example/InRelease +} + +@test "freight-cache signs Release/InRelease with two keys" { + sed -i 's/^GPG=.*/GPG="freight@example.com freight2@example.com"/' $FREIGHT_CONFIG + freight_cache -v + + gpg --status-fd 1 --verify ${FREIGHT_CACHE}/dists/example/Release.gpg ${FREIGHT_CACHE}/dists/example/Release >/tmp/verify.out + run grep -c GOODSIG /tmp/verify.out + assert_output "2" + + gpg --status-fd 1 --verify ${FREIGHT_CACHE}/dists/example/InRelease >/tmp/verify.out + run grep -c GOODSIG /tmp/verify.out + assert_output "2" +} + +@test "freight-cache works without tty" { + run freight_cache_nohup -v + assert_success +} + +@test "apt-get fetches package list" { + check_apt_support + freight_cache -v + echo "deb file://${FREIGHT_CACHE} example main" > ${TMPDIR}/apt/etc/apt/sources.list + apt-get -c ${FIXTURES}/apt.conf update + apt-cache -c ${FIXTURES}/apt.conf show test +} + +@test "freight-cache removes deleted packages from pool" { + freight_cache -v + test -e ${FREIGHT_CACHE}/pool/example/main/t/test/test_1.0_all.deb + rm -f ${FREIGHT_LIB}/apt/example/test_1.0_all.deb + + run freight_cache -v + assert_success + assert_output "" + test ! -e ${FREIGHT_CACHE}/pool/example/main/t/test/test_1.0_all.deb +} + +@test "freight-cache --keep retains deleted packages in pool" { + freight_cache -v + test -e ${FREIGHT_CACHE}/pool/example/main/t/test/test_1.0_all.deb + rm -f ${FREIGHT_LIB}/apt/example/test_1.0_all.deb + + run freight_cache -v --keep + assert_success + assert_output "" + test -e ${FREIGHT_CACHE}/pool/example/main/t/test/test_1.0_all.deb +} + +@test "freight-cache handles VARLIB being a symlink" { + mv $FREIGHT_LIB ${FREIGHT_LIB}_real + ln -s ${FREIGHT_LIB}_real $FREIGHT_LIB + freight_cache + test -e ${FREIGHT_CACHE}/pool/example/comp/t/test/test_1.0_all.deb + test -e ${FREIGHT_CACHE}/pool/example/main/t/test/test_1.0_all.deb +} diff --git a/test/apt_cache_source.bats b/test/apt_cache_source.bats new file mode 100644 index 0000000..34fca4e --- /dev/null +++ b/test/apt_cache_source.bats @@ -0,0 +1,40 @@ +# vim: et:ts=4:sw=4:ft=sh + +load freight_helpers +load apt_helpers + +setup() { + freight_init + configure_local_apt +} + +@test "freight-cache skips partial source packages" { + freight_add ${FIXTURES}/source_1.0-1.dsc apt/example + run freight_cache + assert_success + assert_output "# [freight] skipping invalid Debian source package source_1.0-1.dsc" +} + +@test "freight-cache builds source-only archive" { + freight_add ${FIXTURES}/source_1.0-1.dsc apt/example + freight_add ${FIXTURES}/source_1.0-1.tar.gz apt/example + freight_add ${FIXTURES}/source_1.0.orig.tar.gz apt/example + run freight_cache + assert_success + echo -e "# [freight] adding source_1.0-1.dsc to pool\n# [freight] adding source_1.0.orig.tar.gz to pool\n# [freight] adding source_1.0-1.tar.gz to pool" | assert_output + test -e ${FREIGHT_CACHE}/pool/example/main/s/source/source_1.0-1.dsc + test -e ${FREIGHT_CACHE}/pool/example/main/s/source/source_1.0-1.tar.gz + test -e ${FREIGHT_CACHE}/pool/example/main/s/source/source_1.0.orig.tar.gz +} + +@test "apt-get fetches source package list" { + check_apt_support + freight_add ${FIXTURES}/source_1.0-1.dsc apt/example + freight_add ${FIXTURES}/source_1.0-1.tar.gz apt/example + freight_add ${FIXTURES}/source_1.0.orig.tar.gz apt/example + freight_cache + + echo "deb-src file://${FREIGHT_CACHE} example main" > ${TMPDIR}/apt/etc/apt/sources.list + apt-get -c ${FIXTURES}/apt.conf update + apt-cache -c ${FIXTURES}/apt.conf showsrc source | grep "Package: source" +} diff --git a/test/apt_helpers.bash b/test/apt_helpers.bash new file mode 100644 index 0000000..dc007a7 --- /dev/null +++ b/test/apt_helpers.bash @@ -0,0 +1,12 @@ +# vim: et:ts=4:sw=4:ft=sh + +configure_local_apt() { + mkdir -p ${TMPDIR}/apt/etc/apt + mkdir -p ${TMPDIR}/apt/var/lib/apt + mkdir -p ${TMPDIR}/apt/var/cache/apt +} + +check_apt_support() { + type apt-get || skip "missing apt-get" + apt-get --version | grep Ver:.*deb || skip "missing apt-get deb support" +} diff --git a/test/fixtures/apt.conf b/test/fixtures/apt.conf new file mode 100644 index 0000000..fe68786 --- /dev/null +++ b/test/fixtures/apt.conf @@ -0,0 +1,2 @@ +Dir "./test/tmp/apt"; +Debug::NoLocking true; diff --git a/test/fixtures/gpg.conf b/test/fixtures/gpg.conf new file mode 100644 index 0000000..0c54e4b --- /dev/null +++ b/test/fixtures/gpg.conf @@ -0,0 +1,8 @@ +Key-Type: 1 +Key-Length: 1024 +Subkey-Type: 1 +Subkey-Length: 1024 +Name-Real: Freight Test Key +Name-Email: freight@example.com +Name-Comment: TEST USE ONLY +Expire-Date: 0 diff --git a/test/fixtures/gpg2.conf b/test/fixtures/gpg2.conf new file mode 100644 index 0000000..3d3971c --- /dev/null +++ b/test/fixtures/gpg2.conf @@ -0,0 +1,8 @@ +Key-Type: 1 +Key-Length: 1024 +Subkey-Type: 1 +Subkey-Length: 1024 +Name-Real: Freight Test Second Key +Name-Email: freight2@example.com +Name-Comment: TEST USE ONLY +Expire-Date: 0 diff --git a/test/fixtures/source_1.0-1.dsc b/test/fixtures/source_1.0-1.dsc new file mode 100644 index 0000000..3ca6bb9 --- /dev/null +++ b/test/fixtures/source_1.0-1.dsc @@ -0,0 +1,17 @@ +Format: 1.0 +Source: source +Binary: source +Architecture: any +Version: 1.0-1 +Maintainer: Freight +Homepage: +Standards-Version: 3.9.5 +Build-Depends: debhelper (>= 9) +Package-List: + source deb unknown optional arch=any +Checksums-Sha1: + 4459fbd51b13076ef5f21df77a4a68a48322adeb 9977 source_1.0-1.tar.gz +Checksums-Sha256: + dbb1d5069e4bb814493eb0ed3bb6a9b8a15b45a2bf7d1e04f95622007bef8d98 9977 source_1.0-1.tar.gz +Files: + 5af1440b5a785910a9a1a841139c6745 9977 source_1.0-1.tar.gz diff --git a/test/fixtures/source_1.0-1.tar.gz b/test/fixtures/source_1.0-1.tar.gz new file mode 100644 index 0000000..6e8b16a Binary files /dev/null and b/test/fixtures/source_1.0-1.tar.gz differ diff --git a/test/fixtures/source_1.0.orig.tar.gz b/test/fixtures/source_1.0.orig.tar.gz new file mode 100644 index 0000000..74d49cf Binary files /dev/null and b/test/fixtures/source_1.0.orig.tar.gz differ diff --git a/test/fixtures/test_1.0_all.deb b/test/fixtures/test_1.0_all.deb new file mode 100644 index 0000000..455b2b1 Binary files /dev/null and b/test/fixtures/test_1.0_all.deb differ diff --git a/test/freight_helpers.bash b/test/freight_helpers.bash new file mode 100644 index 0000000..b911ab8 --- /dev/null +++ b/test/freight_helpers.bash @@ -0,0 +1,48 @@ +# vim: et:ts=4:sw=4:ft=sh + +TOPDIR=$PWD +FIXTURES=${TOPDIR}/test/fixtures +TMPDIR=${TOPDIR}/test/tmp + +load ${TMPDIR}/bats-assert/all.bash + +FREIGHT_HOME=${TMPDIR}/freight +FREIGHT_CONFIG=${FREIGHT_HOME}/etc/freight.conf +FREIGHT_CACHE=${FREIGHT_HOME}/var/cache +FREIGHT_LIB=${FREIGHT_HOME}/var/lib + +export GNUPGHOME=${TMPDIR}/gpg + +freight_init() { + gpg_init + rm -rf $FREIGHT_HOME + mkdir -p $FREIGHT_CACHE $FREIGHT_LIB + bin/freight init \ + -g freight@example.com \ + -c $FREIGHT_CONFIG \ + --libdir $FREIGHT_LIB \ + --cachedir $FREIGHT_CACHE \ + "$@" +} + +freight_add() { + bin/freight add -c $FREIGHT_CONFIG "$@" +} + +freight_cache() { + bin/freight cache -c $FREIGHT_CONFIG "$@" +} + +freight_cache_nohup() { + nohup bin/freight cache -c $FREIGHT_CONFIG "$@" +} + +# Generates a GPG key for all tests, once only due to entropy required +gpg_init() { + if [ ! -e $GNUPGHOME ]; then + mkdir -p $GNUPGHOME + chmod 0700 $GNUPGHOME + gpg --batch --gen-key test/fixtures/gpg.conf + gpg --batch --gen-key test/fixtures/gpg2.conf + fi +}