arch-pkgbuilder/bin/pkgbuilder
2024-03-06 23:24:23 +01:00

458 lines
13 KiB
Bash
Executable File

#!/bin/bash
showHelp() {
echo "arch-pkg-builder"
echo "----------------"
echo "arch-pkg-builder [args] command [args]"
echo ""
echo "command :"
echo " list List packages infos"
echo " infos pkgname Display package infos"
echo " build pkgname Build and publish package"
echo " bump pkgname Bump release and publish package"
echo " checkupdate pkgname Check package update"
echo " checkupdateall Check all packages update"
echo " update pkgname Update package"
echo " updateall Update all packages"
echo " pushtoaur pkgname Push package to AUR"
echo ""
echo "args :"
echo " --cnf configfile"
echo " --notify"
echo " --nopush"
echo " --dry-run"
echo " --dbg"
}
readSetting() { # $1=filename $2=name $3=defaultvalue
local -r LINE=$(grep "^${2}=" "${1}")
local -r VALUE=${LINE/${2}=/}
if [ "${VALUE}" != "" ]; then
echo "${VALUE}"
else
echo "${3}"
fi
}
writeSetting() { #$1=filename $2=valuename $3=value
local -r LINE=$(grep "^${2}=" "${1}")
if [ "${LINE}" != "" ]; then
sed -i "s/^${2}=.*/${2}=${3}/" "${1}"
else
echo "${2}=${3}" >> "${1}"
fi
}
tblCell() { #$1=Text $2=Size
local CELL=""
CELL=$(printf "%-${2}s")
CELL="${1}${CELL}"
CELL=${CELL:0:${2}}
echo "${CELL}"
}
getPluginFile() { # $1=PKGDIR $2=PKGNAME $3=PLUGINDIR
local -r PKGDIR=${1}
local -r PKGNAME=${2}
local -r PLUGINDIR=${3}
local -r PLUGIN=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "plugin" "manual")
if [ "${PLUGIN}" == "custom" ]; then
if [ ! -f "${PKGDIR}"/"${PKGNAME}"/plugin ]; then
return 1
fi
echo "${PKGDIR}"/"${PKGNAME}"/plugin
else
if [ ! -f "${PLUGINDIR}"/"${PLUGIN}" ]; then
return 1
fi
echo "${PLUGINDIR}"/"${PLUGIN}"
fi
}
updatePkgSums() { # $1=FILES
local -r FILES=${1}
local TMPDIR=""
TMPDIR=$(mktemp -d)
cp -r "${FILES}"/* "${TMPDIR}"
chown -R pkgbuilder "${TMPDIR}"
sudo -u pkgbuilder updpkgsums "${TMPDIR}"/PKGBUILD
cp -r "${TMPDIR}"/PKGBUILD "${FILES}/"
rm -rf "${TMPDIR}"
}
notify() {
if [ ${NOTIFY} == 0 ]; then
return 0
fi
if [ "${NOTIFYMSG}" == "" ]; then
return 0
fi
if [ ! -f /usr/bin/sendmail ]; then
return 0
fi
local EMAIL=""
EMAIL=$(readSetting "${CNFFILE}" "EMAIL" "")
if [ "${EMAIL}" == "" ]; then
return 0
fi
echo -e "subject:PKGBuilder - Notifications\n${NOTIFYMSG}" | sendmail "${EMAIL}"
}
pkgList() {
if [ ! -d "${PKGDIR}" ]; then
return 1
fi
for PKGDIRNAME in "${PKGDIR}"/*; do
[[ -e "${PKGDIRNAME}" ]] || break
local PKGNAME=""
PKGNAME=$(basename "${PKGDIRNAME}")
local VALUES=()
VALUES+=("$(tblCell "${PKGNAME}" 30)")
VALUE=$(tblCell "$(readSetting "${PKGDIRNAME}"/settings version)" 24)
VALUES+=("${VALUE}")
if [ "$(readSetting "${PKGDIRNAME}"/settings aursshkey '')" == "" ]; then
VALUES+=(" ")
else
VALUES+=(" *")
fi
VALUES+=("$(tblCell "$(readSetting "${PKGDIRNAME}"/settings plugin)" 20)")
VALUES+=("$(tblCell "$(readSetting "${PKGDIRNAME}"/settings target)" 20)")
VALUE=$(tblCell "$(readSetting "${PKGDIRNAME}"/settings lastbuilddate)" 20)
VALUES+=("${VALUE}")
VALUES+=("$(readSetting "${PKGDIRNAME}"/settings lastbuildstatus)")
echo "${VALUES[@]}"
done
}
pkgInfos() { # $1=PKGNAME
local -r PKGNAME=${1}
if [ ! -f "${PKGDIR}"/"${PKGNAME}"/settings ]; then
return 1
fi
cat "${PKGDIR}"/"${PKGNAME}"/settings
}
pkgCreate() { # $1=PKGNAME $2=MODELNAME
local -r PKGNAME=${1}
local -r MODELNAME=${2}
if [ ! -d "${MODELDIR}"/"${MODELNAME}" ]; then
return 1
fi
cp -r "${MODELDIR}"/"${MODELNAME}" "${PKGDIR}"/"${PKGNAME}"
}
pkgBuild() { # $1=PKGNAME
local -r PKGNAME=${1}
local -r BUILDDATE=$(date "+%Y.%m.%d %H:%M:%S")
if [[ "${DRYRUN}" == "0" ]]; then
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "lastbuilddate" "${BUILDDATE}"
fi
local PLUGINFILE=""
if ! PLUGINFILE=$(getPluginFile "${PKGDIR}" "${PKGNAME}" "${PLUGINDIR}"); then
return 1
fi
# shellcheck disable=SC2034 # Variable for plugin
local -r PKGSETTINGS=${PKGDIR}/${PKGNAME}/settings
# shellcheck disable=SC2034 # Variable for plugin
local -r PKGBUILD="${PKGDIR}/${PKGNAME}/files/PKGBUILD"
. "${PLUGINFILE}"
local PKGFILES="${PKGDIR}/${PKGNAME}/files"
if ! PKGFILES=$(plugin_getpkgfiles "${PKGDIR}" "${PKGNAME}"); then
if [[ "${DRYRUN}" == "0" ]]; then
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "lastbuildstatus" "Error - No PKG files provided"
fi
return 1
fi
if [ ! -d "${PKGFILES}" ]; then
if [[ "${DRYRUN}" == "0" ]]; then
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "lastbuildstatus" "Error - PKG files not found"
fi
return 1
fi
mkdir "${WORKDIR}"/.output
local BUILDARGS=()
BUILDARGS+=(-w "${WORKDIR}")
BUILDARGS+=(-d /var/lib/pkgbuilder)
BUILDARGS+=(-o "${WORKDIR}"/.output)
local -r PKGMIRROR=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "mirror" "")
if [[ "${PKGMIRROR}" != "" ]]; then
BUILDARGS+=(-m "${PKGMIRROR}")
fi
# shellcheck disable=SC2207
local -r PKGPKGS=($(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "pkgs" ""))
if [[ "${PKGPKGS[*]}" != "" ]]; then
for PKGPKG in "${PKGPKGS[@]}"; do
BUILDARGS+=(-p "${PKGPKG}")
done
fi
local -r PKGNODEPS=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "nodeps" "")
if [[ "${PKGNODEPS}" == "1" ]]; then
BUILDARGS+=(-n)
fi
# shellcheck disable=SC2207
local -r PKGREPOS=($(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "repos" ""))
if [[ "${PKGREPOS[*]}" != "" ]]; then
for PKGREPO in "${PKGREPOS[@]}"; do
BUILDARGS+=(-r "${PKGREPO}")
done
fi
if [[ "${DBGMODE}" == "1" ]]; then
BUILDARGS+=(--dbg)
fi
BUILDARGS+=("${PKGFILES}")
# shellcheck disable=SC2068
if ! buildpkg ${BUILDARGS[@]}; then
if [[ "${DRYRUN}" == "0" ]]; then
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "lastbuildstatus" "Error - Build"
fi
return 1
fi
local PKGFILENAME=""
# shellcheck disable=SC2012
PKGFILENAME=$(ls "${WORKDIR}"/.output/"${PKGNAME}"*.pkg.tar.zst | head -n 1)
local VERSION=""
VERSION=$(pacman -Qp "${PKGFILENAME}" | awk -F ' ' '{print $2}')
if [[ "${DRYRUN}" == "0" ]]; then
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "version" "${VERSION}"
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "builddate" "${BUILDDATE}"
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "lastbuildstatus" "Ok"
fi
local -r PKGTARGET=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "target" "")
pkgPush "${PKGNAME}" "${PKGFILENAME}"
rm "${WORKDIR}"/.output/"${PKGNAME}"*.pkg.tar.zst
}
pkgPush() { # $1=PKGNAME $2=PKGFILE
local -r PKGNAME=${1}
local -r PKGFILE=${2}
if [[ ${NOPUSH} == 0 ]]; then
local -r PKGTARGET=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "target" "")
if [ -f "${TRGDIR}"/"${PKGTARGET}" ]; then
local -r PKGTARGETTYPE=$(readSetting "${TRGDIR}"/"${PKGTARGET}" "type" "")
local -r TARGETDEST=$(readSetting "${TRGDIR}"/"${PKGTARGET}" "dest" "")
if [[ "${DRYRUN}" == "0" ]]; then
case ${PKGTARGETTYPE} in
dir)
if [ -d "${TARGETDEST}" ]; then
local -r TARGETFILENAME=${TARGETDEST}/$(basename "${PKGFILE}")
cp "${PKGFILE}" "${TARGETFILENAME}"
repo-add -n -R "${TARGETDEST}/${PKGTARGET}.db.tar.zst" "${TARGETFILENAME}"
fi
;;
ssh)
local -r TARGETPUBKEY=$(readSetting "${TRGDIR}"/"${PKGTARGET}" "pubkey" "")
local -r TARGETSRV=$(awk -F':/' '{print $1}' <<< "${TARGETDEST}")
local -r TARGETDIR=/$(awk -F':/' '{print $2}' <<< "${TARGETDEST}")
local -r TARGETFILENAME=${TARGETDEST}/$(basename "${PKGFILE}")
if [ "${TARGETPUBKEY}" == "" ]; then
scp "${PKGFILE}" "${TARGETDEST}"
ssh "${TARGETSRV}" repo-add -n -R "${TARGETDIR}"/"${PKGTARGET}".db.tar.zst "${TARGETDIR}"/"$(basename "${TARGETFILENAME}")"
else
scp -i "${TARGETPUBKEY}" "${PKGFILE}" "${TARGETDEST}"
ssh -i "${TARGETPUBKEY}" "${TARGETSRV}" repo-add -n -R "${TARGETDIR}"/"${PKGTARGET}".db.tar.zst "${TARGETDIR}"/"$(basename "${TARGETFILENAME}")"
fi
;;
esac
fi
fi
fi
}
pkgBump() { # $1=PKGNAME
local -r PKGNAME=${1}
local PLUGINFILE=""
if ! PLUGINFILE=$(getPluginFile "${PKGDIR}" "${PKGNAME}" "${PLUGINDIR}"); then
return 1
fi
# shellcheck disable=SC2034 # Variable for plugin
local -r PKGSETTINGS=${PKGDIR}/${PKGNAME}/settings
# shellcheck disable=SC2034 # Variable for plugin
local -r PKGBUILD="${PKGDIR}/${PKGNAME}/files/PKGBUILD"
. "${PLUGINFILE}"
if ! plugin_isbumpable; then
return 1
fi
if [[ "${DRYRUN}" == "0" ]]; then
if ! plugin_bump "${PKGDIR}" "${PKGNAME}"; then
return 1
fi
pkgBuild "${PKGNAME}"
fi
}
pkgCheckUpdate() { # $1=PKGNAME
local -r PKGNAME=${1}
local PLUGINFILE=""
if ! PLUGINFILE=$(getPluginFile "${PKGDIR}" "${PKGNAME}" "${PLUGINDIR}"); then
return 1
fi
# shellcheck disable=SC2034 # Variable for plugin
local -r PKGSETTINGS=${PKGDIR}/${PKGNAME}/settings
# shellcheck disable=SC2034 # Variable for plugin
local -r PKGBUILD="${PKGDIR}/${PKGNAME}/files/PKGBUILD"
. "${PLUGINFILE}"
local -r PKGVERSION=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "version" "0")
local -r PKGPLUGIN=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "plugin" "")
local VALUES=()
VALUES+=("$(tblCell "${PKGNAME}" 30)")
VALUE=$(tblCell "$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings version)" 24)
VALUES+=("${VALUE}")
if ! plugin_isupdatable; then
VALUES+=(" ")
VALUES+=("$(tblCell 'Skipping' 25)")
VALUES+=("$(tblCell "${PKGPLUGIN}" 25)")
echo "${VALUES[@]}"
return 0
fi
local -r ONLINEVERSION=$(plugin_getlatestversion)
if [ "${ONLINEVERSION}" == "" ]; then
return 1
fi
if [[ "${ONLINEVERSION}" != "${PKGVERSION}" ]]; then
VALUES+=(" -> ")
VALUES+=("$(tblCell "${ONLINEVERSION}" 25)")
NOTIFYMSG+="${PKGNAME} ${PKGVERSION} -> ${ONLINEVERSION}\n"
else
VALUES+=(" ")
VALUES+=("$(tblCell 'Up to date' 25)")
fi
VALUES+=("$(tblCell "${PKGPLUGIN}" 25)")
echo "${VALUES[@]}"
}
pkgCheckUpdateAll() {
if [ ! -d "${PKGDIR}" ]; then
return 1
fi
for PKGDIRNAME in "${PKGDIR}"/*; do
[[ -e "${PKGDIRNAME}" ]] || break
local PKGNAME=""
PKGNAME=$(basename "${PKGDIRNAME}")
pkgCheckUpdate "${PKGNAME}"
done
notify
}
pkgUpdate() { # $1=PKGNAME
local -r PKGNAME=${1}
local PLUGINFILE=""
if ! PLUGINFILE=$(getPluginFile "${PKGDIR}" "${PKGNAME}" "${PLUGINDIR}"); then
return 1
fi
# shellcheck disable=SC2034 # Variable for plugin
local -r PKGSETTINGS=${PKGDIR}/${PKGNAME}/settings
# shellcheck disable=SC2034 # Variable for plugin
local -r PKGBUILD="${PKGDIR}/${PKGNAME}/files/PKGBUILD"
. "${PLUGINFILE}"
if ! plugin_isupdatable; then
return 1
fi
local -r ONLINEVERSION=$(plugin_getlatestversion)
if [ "${ONLINEVERSION}" == "" ]; then
return 1
fi
local -r PKGVERSION=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "version" "0")
if [[ "${ONLINEVERSION}" == "${PKGVERSION}" ]]; then
return 0
fi
if ! plugin_update; then
return 1
fi
pkgBuild "${PKGNAME}"
}
pkgUpdateAll() {
if [ ! -d "${PKGDIR}" ]; then
return 1
fi
for PKGDIRNAME in "${PKGDIR}"/*; do
[[ -e "${PKGDIRNAME}" ]] || break
local PKGNAME=""
PKGNAME=$(basename "${PKGDIRNAME}")
pkgUpdate "${PKGNAME}"
done
}
pkgPushToAUR() { # $1=PKGNAME
local -r PKGNAME=${1}
local PLUGINFILE=""
if ! PLUGINFILE=$(getPluginFile "${PKGDIR}" "${PKGNAME}" "${PLUGINDIR}"); then
return 1
fi
. "${PLUGINFILE}"
if ! plugin_ispushabletoaur; then
return 1
fi
local -r AURSSHKEY=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "aursshkey" "")
if [ "${AURSSHKEY}" == "" ]; then
return 1
fi
local -r PKGVERSION=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "version" "0")
local -r PKGFILES="${PKGDIR}/${PKGNAME}/files"
local TMPDIR=""
TMPDIR=$(mktemp -d)
cd "${TMPDIR}" || return 1
if ! git clone ssh://aur@aur.archlinux.org/"${PKGNAME}".git --config core.sshCommand="ssh -i ${AURSSHKEY}"; then
return 1
fi
cd "${PKGNAME}" || return 1
git rm -rf ".*"
git rm -rf "*"
cp -r "${PKGFILES}"/* .
chown -R pkgbuilder "${TMPDIR}"
# shellcheck disable=SC2024
sudo -u pkgbuilder makepkg --printsrcinfo > .SRCINFO
chown -R root "${TMPDIR}"
git add -A
git commit -a -m "Version ${PKGVERSION}"
if ! git push; then
rm -rf "${TMPDIR}"
return 1
fi
rm -rf "${TMPDIR}"
}
CNFFILE="/etc/pkgbuilder/config"
ARGCMD=""
ARGPKG=""
ARGMDL=""
NOTIFYMSG=""
NOTIFY=0
NOPUSH=0
DRYRUN=0
DBGMODE=0
while [[ ${#} -gt 0 ]]; do
case ${1} in
--help) showHelp; exit 0;;
list | checkupdateall | updateall) ARGCMD="${1}"; shift;;
infos | build | bump | checkupdate | update | pushtoaur) ARGCMD="${1}"; ARGPKG="${2}"; shift; shift;;
create) ARGCMD="${1}"; ARGMDL="${2}"; ARGPKG="${3}"; shift; shift;;
--cnf) CNFFILE="${2}"; shift; shift;;
--notify) NOTIFY=1; shift;;
--nopush) NOPUSH=1; shift;;
--dry-run) DRYRUN=1; shift;;
--dbg) DBGMODE=1; shift;;
*) shift;;
esac
done
PKGDIR=$(readSetting "${CNFFILE}" "PKGDIR" "/etc/pkgbuilder/packages")
TRGDIR=$(readSetting "${CNFFILE}" "TRGDIR" "/etc/pkgbuilder/targets")
PLUGINDIR=$(readSetting "${CNFFILE}" "PLUGINDIR" "/usr/share/pkgbuilder/plugins")
MODELDIR=$(readSetting "${CNFFILE}" "MODELDIR" "/usr/share/pkgbuilder/models")
WORKDIR=$(readSetting "${CNFFILE}" "WORKDIR" "/var/cache/pkgbuilder")
# VARDIR=$(readSetting "${CNFFILE}" "VARDIR" "/var/lib/pkgbuilder")
case ${ARGCMD} in
list) pkgList;;
infos) pkgInfos "${ARGPKG}";;
create) pkgCreate "${ARGPKG}" "${ARGMDL}";;
build) pkgBuild "${ARGPKG}";;
bump) pkgBump "${ARGPKG}";;
checkupdate) pkgCheckUpdate "${ARGPKG}";;
checkupdateall) pkgCheckUpdateAll;;
update) pkgUpdate "${ARGPKG}";;
updateall) pkgUpdateall;;
pushtoaur) pkgPushToAUR "${ARGPKG}";;
*) showHelp; exit 1;;
esac