279 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			279 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| basedir=$(cd $(dirname $0); pwd)
 | |
| chroot=$basedir/chroot
 | |
| 
 | |
| if [ `whoami` == 'root' ]; then
 | |
|    echo "Must not be run as root."
 | |
|    exit 1;
 | |
| fi
 | |
| 
 | |
| exe() { echo "\$ $@" ; "$@" ; }
 | |
| 
 | |
| create_chroot() {
 | |
|     (
 | |
| 	set -e
 | |
| 	if [ ! -d $chroot ]; then
 | |
| 	    echo "## Creating arch chroot ..."
 | |
| 	    exe mkdir $chroot
 | |
| 	    exe mkarchroot $chroot/root base-devel
 | |
| 	    # install cower:
 | |
| 	    gpg --recv-keys --keyserver hkp://pgp.mit.edu 1EB2638FF56C0C53
 | |
|     	    TMP_BUILD=`mktemp -d`
 | |
|     	    exe cd $TMP_BUILD
 | |
| 	    curl https://aur.archlinux.org/cgit/aur.git/snapshot/cower.tar.gz | tar xz
 | |
| 	    exe cd cower
 | |
| 	    exe makechrootpkg -r $chroot -l root -- -i
 | |
| 	    exe rm -rf $TMP_BUILD
 | |
| 	    echo "## Root chroot build complete."
 | |
| 	fi
 | |
|     )
 | |
| }
 | |
| 
 | |
| install_system_deps() {
 | |
|     (
 | |
| 	set -e
 | |
| 	pkg_dep() {
 | |
| 	    if !(pacman -Q $1 > /dev/null 2>&1); then
 | |
| 		echo "Installing $1..."
 | |
| 		exe sudo pacman -S --noconfirm $1
 | |
| 	    fi
 | |
| 	}
 | |
| 	pkg_dep devtools
 | |
| 	pkg_dep git
 | |
| 	pkg_dep findutils
 | |
|     )
 | |
| }
 | |
| 
 | |
| package_build() {
 | |
|     # Build a package in a container. $1=container $2=package
 | |
|     # PKGBUILD must already exist in src/
 | |
|     # If package has dependencies we also maintain in src/, recursively build those first.
 | |
|     (
 | |
| 	set -e
 | |
| 	if [ "$#" -ne 2 ]; then
 | |
| 	    echo "package_build takes two args: repo_name and package_name"
 | |
| 	    return 1
 | |
| 	fi
 | |
| 	repo_name=$1
 | |
| 	package_name=$2
 | |
| 	setup
 | |
| 	pkgdir=$basedir/src/$package_name
 | |
| 	if [ ! -d $pkgdir ]; then
 | |
| 	    echo "Package $package_name not found in $pkgdir"
 | |
| 	    echo "Try running: package_add $package_name"
 | |
| 	    return 1
 | |
| 	fi
 | |
| 	if [ ! -f $pkgdir/PKGBUILD ]; then
 | |
| 	    echo "Cannot find PKGBUILD in $pkgdir"
 | |
| 	    return 1
 | |
| 	fi
 | |
| 	if (arch-nspawn $chroot/$repo_name pacman -Q $package_name > /dev/null 2>&1); then
 | |
| 	    echo "Package $package_name already built"
 | |
| 	    return
 | |
| 	fi
 | |
| 	# Find and build dependencies:
 | |
| 	find_deps $package_name | while read dep; do
 | |
| 	    # Build the dep if we haven't already yet:
 | |
| 	    if !(arch-nspawn $chroot/$repo_name pacman -Q $dep > /dev/null 2>&1); then
 | |
| 		package_build $repo_name $dep
 | |
| 	    fi
 | |
| 	done
 | |
| 	# Build package:
 | |
| 	cd $pkgdir
 | |
| 	rm -f *.pkg.tar.xz
 | |
| 	mkdir -p $basedir/$repo_name
 | |
| 	exe makechrootpkg -r $chroot -l $repo_name -- -i
 | |
| 	exe mv *.pkg.tar.xz $basedir/$repo_name
 | |
|     )
 | |
| }
 | |
| 
 | |
| sign_packages() {
 | |
|     if [ "$#" -lt 1 ]; then
 | |
| 	echo "sign_packages requires specifying the list of packages to sign"
 | |
| 	return 1
 | |
|     fi
 | |
|     (
 | |
| 	set -e
 | |
| 	cd $(dirname $1)
 | |
| 	for pkg in "$@"; do
 | |
| 		gpg -v "${pkg}.sig" 2>/dev/null || (rm -f "${pkg}.sig"; gpg -u 'ECB9B8CBAAC68C03!' --detach-sign --use-agent "$pkg")
 | |
| 	done
 | |
|     )
 | |
| }
 | |
| 
 | |
| find_deps() {
 | |
|     # Inspect package srcinfo and pull out the dependencies that we maintain in src
 | |
|     (
 | |
| 	set -e
 | |
| 	setup
 | |
| 	cat $basedir/src/$1/.SRCINFO | sed -nr 's/^\W*depends = ([-a-zA-Z0-9]+).*$/\1/p' | while read dep; do
 | |
| 	    if [ -d $basedir/src/$dep ]; then
 | |
| 		echo $dep
 | |
| 	    fi
 | |
| 	done
 | |
|     )
 | |
| }
 | |
| 
 | |
| add() {
 | |
|     # Add packages and their AUR dependencies to src
 | |
|     (
 | |
| 	set -e
 | |
| 	if [ "$#" -lt 1 ]; then
 | |
| 	    echo "Must specify package(s) to add"
 | |
| 	    return 1
 | |
| 	fi
 | |
| 	setup
 | |
| 	if [ ! -d $basedir/src ]; then
 | |
| 	    mkdir $basedir/src
 | |
| 	fi
 | |
| 	for pkg in "$@"; do
 | |
| 	    arch-nspawn $chroot/root --bind=$basedir/src:/src cower -q -t /src -f -d -d $pkg
 | |
| 	done
 | |
| 	sudo chown $USER -R $basedir/src
 | |
| 	echo "## All requested packages added"
 | |
|    )
 | |
| }
 | |
| 
 | |
| update() {
 | |
|     # Update a package and it's dependencies from the AUR
 | |
|     (
 | |
| 	#set -e # breaks updating all if one fails, ignore errors
 | |
| 	if [ "$#" -eq 0 ]; then
 | |
| 	    cd $basedir/src
 | |
| 	    update *
 | |
| 	    return
 | |
| 	fi
 | |
| 	for pkg in "$@"; do
 | |
| 	    if [ ! -d $basedir/src/$pkg ]; then
 | |
| 		echo "No package called $pkg found in src"
 | |
| 		return 1
 | |
| 	    fi
 | |
| 	done
 | |
| 	for pkg in "$@"; do
 | |
| 	    check_in_git() {
 | |
| 		(
 | |
| 		    cd $basedir
 | |
| 		    if (! git ls-files $1 --error-unmatch >/dev/null 2>&1); then
 | |
| 			echo "$1 is not under git control yet. Add and commit it before updating."
 | |
| 			return 1
 | |
| 		    fi
 | |
| 		)
 | |
| 	    }
 | |
| 	    check_in_git $basedir/src
 | |
| 	    check_in_git $basedir/src/$pkg
 | |
| 	    find_deps $pkg | while read dep; do
 | |
| 		check_in_git $basedir/src/$dep
 | |
| 	    done
 | |
| 	    # Check if package has uncommited changes
 | |
| 	    if [ $(git -C $basedir diff HEAD $basedir/src/$pkg | wc -l) -gt 0 ]; then
 | |
| 		echo "warning: Package $pkg has uncommited changes. Commit or discard those changes first."
 | |
| 		#return 1
 | |
| 	    fi
 | |
| 	    # Use a temporary dir to download all PKGBUILDS atomically
 | |
|             [ -z "$tmp_dl" ] && tmp_dl=`mktemp -d`
 | |
|             cd $tmp_dl
 | |
|             arch-nspawn $chroot/root --bind=$tmp_dl:/src cower -q -t /src -d -d $pkg >/dev/null 2>&1
 | |
| 	    cp -a * $basedir/src
 | |
| 	done
 | |
| 	git -C $basedir diff --name-status $basedir/src/
 | |
|     )
 | |
| }
 | |
| 
 | |
| 
 | |
| list() {
 | |
|     if [ "$#" -ne 1 ]; then
 | |
| 	echo "Must specify repository name to list"
 | |
| 	return 1
 | |
|     fi
 | |
|     setup
 | |
|     arch-nspawn $chroot/$1 pacman -Qm
 | |
| }
 | |
| 
 | |
| setup() {
 | |
|     mkdir -p $basedir/src
 | |
|     install_system_deps
 | |
|     create_chroot
 | |
| }
 | |
| 
 | |
| clean() {
 | |
|     (
 | |
|         set -e
 | |
|         if [ "$#" -lt 1 ]; then
 | |
|             echo "Must specify repository names to clean"
 | |
|             return 1
 | |
|         fi
 | |
|         for repo in "$@"; do
 | |
|             # Clean repository and chroot
 | |
|             if [ -d $basedir/chroot/$repo ]; then
 | |
|             # Test if chroot uses BTRFS and remove using btrfs subvolume delete
 | |
|                 if [ `stat --format=%i $basedir/chroot/$repo` -eq 256 ] && [ `stat -f --format=%T $basedir/chroot/$repo` ] ; then
 | |
|                     exe sudo btrfs subvolume delete $basedir/chroot/$repo
 | |
|                     exe sudo rm $basedir/chroot/$repo.lock
 | |
|             # Otherwise delete using rm
 | |
|                 else
 | |
|                     exe sudo rm -rf $basedir/chroot/$repo $basedir/chroot/$repo.lock
 | |
|                 fi
 | |
|             fi
 | |
|             if [ -d $basedir/$repo ]; then
 | |
|                 exe rm -rf $basedir/$repo
 | |
|             fi
 | |
|         done
 | |
|     )
 | |
| }
 | |
| 
 | |
| build() {
 | |
|     (
 | |
| 	set -e
 | |
| 	if [ "$#" -lt 1 ]; then
 | |
| 	    echo "Must specify repository name to build (and optional package list to include)"
 | |
| 	    return 1
 | |
| 	fi
 | |
| 	setup
 | |
| 	repo_name=$1
 | |
| 	mkdir -p $basedir/$repo_name
 | |
| 	shift
 | |
| 	if [ "$#" -gt 0 ]; then
 | |
| 	    # Build only requested packages
 | |
| 	    for pkg in "$@"; do
 | |
| 		package_build $repo_name $pkg
 | |
| 	    done
 | |
| 	    echo "## All requested packages built"
 | |
| 	else
 | |
| 	    # Build all packages:
 | |
| 	    cd $basedir/src
 | |
| 	    find -type d | sed 's/\.\///' | tail -n +2 | while read pkg; do
 | |
| 		package_build $repo_name $pkg
 | |
| 	    done
 | |
| 	    echo "## All packages built"
 | |
| 	fi
 | |
| 	echo "## Updating repository database"
 | |
| 	cd $basedir/$repo_name
 | |
| 	if [ `ls *.pkg.tar.xz 2> /dev/null | wc -l` -lt 1 ]; then
 | |
| 	    echo "No packages found in $basedir/$repo_name"
 | |
| 	    return 1;
 | |
| 	fi
 | |
| 	sign_packages *.pkg.tar.xz
 | |
| 	repose -f -z $repo_name
 | |
| 	sign_packages $repo_name.db $repo_name.files
 | |
|     )
 | |
| }
 | |
| 
 | |
| rebuild() {
 | |
| 		(
 | |
| 		set -e
 | |
| 		setup
 | |
| 		repo_name=$1
 | |
| 		mkdir -p $basedir/$repo_name
 | |
| 		shift
 | |
| 		arch-nspawn $chroot/$repo_name pacman -Rscn --noconfirm "$@"
 | |
| 		build "$repo_name" "$@"
 | |
| 		)
 | |
| }
 | |
| 
 | |
| if [ "$#" -gt 0 ]; then
 | |
|     $*
 | |
| else
 | |
|     echo "Must specify a command, eg: add, build, list, clean"
 | |
|     exit 1
 | |
| fi
 | 
