#!/usr/bin/env bash # The purpose of this script is to automate the maintenance of a custom pacman (Arch Linux) repository, whose goal is to # provide package-ready AUR softs. # This script should NOT be run as root. # Dependencies # Make sure that AWK rules file is present, readable and correctly set in this script's parameters # Make sure the following packages are installed before running this script: # package-query aurutils git # Functions ################################################################## ascii_frag() { expr match "$1" "\([^[:digit:]]*\)" } ascii_remainder() { expr match "$1" "[^[:digit:]]*\(.*\)" } numeric_frag() { expr match "$1" "\([[:digit:]]*\)" } numeric_remainder() { expr match "$1" "[[:digit:]]*\(.*\)" } # return 1 for $1 > $2 # return 2 for $1 < $2 # return 0 for equal vercomp() { local WORK1="$1" local WORK2="$2" local NUM1="", NUM2="", ASCII1="", ASCII2="" while true; do ASCII1=`ascii_frag "${WORK1}"` ASCII2=`ascii_frag "${WORK2}"` WORK1=`ascii_remainder "${WORK1}"` WORK2=`ascii_remainder "${WORK2}"` if [ "${ASCII1}" \> "${ASCII2}" ]; then return 1 elif [ "${ASCII1}" \< "${ASCII2}" ]; then return 2 fi NUM1=`numeric_frag "${WORK1}"` NUM2=`numeric_frag "${WORK2}"` WORK1=`numeric_remainder "${WORK1}"` WORK2=`numeric_remainder "${WORK2}"` if [ -z "${NUM1}" -a -z "${NUM2}" ]; then return 0 elif [ -z "${NUM1}" -a -n "${NUM2}" ]; then return 2 elif [ -n "${NUM1}" -a -z "${NUM2}" ]; then return 1 fi if [ "${NUM1}" -gt "${NUM2}" ]; then return 1 elif [ "${NUM1}" -lt "${NUM2}" ]; then return 2 fi done } ################################################################## init() { # Only run if the user is not root if [[ $USER = 'root' ]] ; then echo "You cannot run this script as root!" exit 1 fi if [ -n "$(ls $run_directory_path)" ] ; then echo "The running directory is not empty!" exit 1 fi source ../variables.conf repo_db_file=$repo_name.db.tar repo_db_filesfile=$repo_name.files.tar awk_rules_file='../parser.awk' eval "$(ssh-agent)" ssh-add $ssh_key # TODO Check if required packages are installed echo "ArchRepo update script" } checkUpdates() { echo "Checking for updates:" upgraded_packages="" scp $ssh_options $remote_repository/$repo_db_file $remote_repository/$repo_db_filesfile $run_directory_path/ stream=$(tar xOf $run_directory_path/$repo_db_file --wildcards */desc | awk -f $awk_rules_file) OIFS=$IFS IFS='|' stream="${stream:1}" for package in $stream do IFS=' ' count=0 for line in $package; do if [ $count -eq 0 ]; then filename=$line elif [ $count -eq 1 ]; then name=$line elif [ $count -eq 2 ]; then version=$line fi ((count++)) done reg="(linux-lts).+-((docs)|(headers))" if [[ $name =~ $reg ]]; then echo -e "\nSkipping $name ($version, default exception)." continue 1 fi reg="(kodi-addon-game).+-((debug))" if [[ $name =~ $reg ]]; then echo -e "\nSkipping $name ($version, default exception)." continue 1 fi if echo $exlist | grep -w $name > /dev/null; then echo -e "\nSkipping $name ($version, temporary exception)." continue 1 fi reg="(package-query-debug)" if [[ $name =~ $reg ]]; then echo -e "\nSkipping $name ($version, default exception)." continue 1 fi echo -e "\nChecking $name ($version)..." aur_version=$(package-query -A -f %v $name) vercomp $aur_version $version result=$? if [[ $result -eq 1 ]]; then echo "New version for $name: $version -> $aur_version" IFS=$OIFS createPackage $name addPackageToRepo $name $aur_version upgraded_packages="$upgraded_packages $name" fi IFS='|' done IFS=$OIFS echo "All packages processed." if [[ $upgraded_packages != "" ]]; then echo "The following packages were upgraded:" echo $upgraded_packages fi } addPackage() { createPackage $1 addPackageToRepo $1 } createPackage() { # Create package $1 echo "Fetching $1 from AUR..." aur fetch $1 # TODO This could be replaced by a git clone or even a wget+tar thanks to package-query echo "Making $1 package..." cd $1 makepkg -s --noconfirm --noprogressbar cd $run_directory_path } # TODO: try manually: can we update db file before sending to remote repo? addPackageToRepo() { # Add package $1 echo "Adding $1 to repository..." scp $ssh_options $run_directory_path/$1/$1-$2*.pkg.tar.* $remote_repository/ repo-add $repo_db_file $run_directory_path/$1/$1-$2*.pkg.tar.* reg="(linux-lts).+" if [[ $name =~ $reg ]]; then echo "Adding $1-headers and $1-docs to repository..." repo-add $repo_db_file $run_directory_path/$1/$1-headers-$2*.pkg.tar.* $run_directory_path/$1/$1-docs-$2*.pkg.tar.* scp $ssh_options $run_directory_path/$1/$1-headers-$2*.pkg.tar.* $run_directory_path/$1/$1-docs-$2*.pkg.tar.* $remote_repository/ fi scp $ssh_options $run_directory_path/$repo_db_file $run_directory_path/$repo_db_file.old $run_directory_path/$repo_db_filesfile $run_directory_path/$repo_db_filesfile.old $remote_repository/ } clean() { echo "Cleaning directory..." rm -rf $run_directory_path/* echo "Done." } run_directory_path=$(pwd) # Main process if [ "$1" = "" ]; then init checkUpdates elif [ "$1" = "add" ]; then init scp $ssh_options $remote_repository/$repo_db_file $remote_repository/$repo_db_filesfile $run_directory_path/ for arg in "$@"; do if [[ $arg = "add" ]]; then continue fi addPackage $arg done elif [ "$1" = "clean" ]; then clean else exit 1 fi exit 0