archrepo/update-repo.sh

265 lines
6.4 KiB
Bash
Executable File

#!/bin/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
# TODO Check if required packages are installed
echo "ArchRepo update script"
}
checkUpdates() {
echo "Checking for updates:"
upgraded_packages=""
stream=$(tar xOf $repo_directory/$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
if echo $exlist | grep -w $name > /dev/null; then
echo -e "\nSkipping $name ($version, temporary 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"
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
# if linux-lts{414,49} then download kernel source from local repo (saves ~100MB each time)
# WARNING this onlys works because we already have said sources AND because PKBUILD follow this particular line
# (not the same in 419 nor 54)
reg="(linux-lts).+"
if [[ $1 =~ $reg ]]; then
sed -i -e "s/\"https:\/\/www.kernel.org\/pub\/linux\/kernel\/v4.x\/\${_srcname}.tar.xz\"/\"https:\/\/archlinux.kto.black\/resources\/\${_srcname}.tar.xz\"/g" ./PKGBUILD
fi
makepkg -s --noconfirm --noprogressbar
cd $run_directory_path
}
addPackageToRepo() { # Add package $1
echo "Adding $1 to repository..."
cp $run_directory_path/$1/$1-$2*.pkg.tar.xz $repo_directory
repo-add $repo_directory/$repo_db_file $repo_directory/$1-$2*.pkg.tar.xz
reg="(linux-lts).+"
if [[ $name =~ $reg ]]; then
echo "Adding $1-headers and $1-docs to repository..."
cp $run_directory_path/$1/$1-headers-$2*.pkg.tar.xz $run_directory_path/$1/$1-docs-$2*.pkg.tar.xz $repo_directory
repo-add $repo_directory/$repo_db_file $repo_directory/$1-headers-$2*.pkg.tar.xz $repo_directory/$1-docs-$2*.pkg.tar.xz
fi
}
clean() {
echo "Cleaning directory..."
rm -rf $run_directory_path/*
echo "Done."
}
clearRepo() {
stream=$(tar xOf $repo_directory/$repo_db_file --wildcards */desc | awk -f $awk_rules_file)
OIFS=$IFS
IFS='|'
stream="${stream:1}"
current=""
for package in $stream
do
IFS='
'
count=0
for line in $package; do
if [ $count -eq 0 ]; then
current="$current $line"
else
continue
fi
((count++))
done
IFS='|'
done
IFS=$OIFS
cd $repo_directory
reg="^($repo_name.).+"
for filename in *; do
if [[ $filename =~ $reg || $filename = 'sync' || $filename = 'local' || $filename = 'resources' ]]; then
continue
fi
for package in $current; do
if [ $filename = $package ]; then
continue 2
fi
done
echo "Removing $filename..."
rm $filename
done
}
run_directory_path=$(pwd)
# Set parameters
repo_directory='/mnt/archrepo'
repo_name='kto'
repo_db_file=$repo_name.db.tar
awk_rules_file='../parser.awk'
#repo_db_file='kto.db.tar' # You can set db name manually here if different
# Main process
if [ "$1" = "" ]; then
init
checkUpdates
elif [ "$1" = "add" ]; then
init
addPackage $2
elif [ "$1" = "clean" ]; then
clean
elif [ "$1" = "clear" ]; then
read -r -p "Are you sure? [y/N] " response
response=${response,,} # tolower
if [[ "$response" =~ ^(yes|y)$ ]]; then
clearRepo
else
echo "Cancelling... Perhaps did you mean 'clean', which empties the local build directory?"
exit 1
fi
else
exit 1
fi
exit 0