mirror of
https://github.com/endeavouros-team/eos-pkgbuild-setup.git
synced 2026-06-13 01:54:36 +00:00
2293 lines
71 KiB
Makefile
Executable File
2293 lines
71 KiB
Makefile
Executable File
#!/bin/bash
|
|
|
|
# TODO:
|
|
# - 2.12.2021: update of multi-package PKGBUILD? Install should work, but deletion of old packages (thus updating) doesn't!
|
|
# - better epoch handling?
|
|
|
|
source /etc/eos-color.conf
|
|
|
|
Color2() { eos-color "$1" 2; } # Color to stderr
|
|
Color1() { eos-color "$1"; } # Color to stdout
|
|
# echo2info() { Color2 info; echo2 "==>" "$@"; Color2 reset; }
|
|
|
|
echoreturn() { echo "$@" ; } # for "return" values!
|
|
|
|
echo2() { echo "$@" >&2 ; } # output to stderr
|
|
printf2() { printf "$@" >&2 ; } # output to stderr
|
|
|
|
DIE() {
|
|
Color2 error
|
|
echo2 "Error: $@"
|
|
echo2 "Call stack lines: ${BASH_LINENO[*]}"
|
|
if [ "${FUNCNAME[1]}" = "Main" ] ; then
|
|
Color2 tip
|
|
Usage
|
|
fi
|
|
Color2
|
|
Destructor
|
|
exit 1
|
|
}
|
|
WARN() { Color2 warning; echo2 -n "Warning: " ; echo2 "$@" ; Color2; }
|
|
|
|
FileSizePrint() {
|
|
# Print size of file in bytes, numbers are is groups of three.
|
|
# Examples:
|
|
# 43854 ==> 43 854
|
|
# 52341928 ==> 52 341 928
|
|
# Note: user must align right if needed.
|
|
|
|
local file="$1"
|
|
local nr nr2="" nrtail
|
|
local left remove=3
|
|
|
|
nr=$(stat -c %s "$file")
|
|
left=${#nr}
|
|
while [ $left -gt 0 ] ; do
|
|
if [ $remove -gt $left ] ; then
|
|
remove=$left
|
|
fi
|
|
((left -= remove))
|
|
nrtail="${nr: -remove}"
|
|
nr="${nr:: -remove}"
|
|
nr2="$nrtail $nr2"
|
|
done
|
|
[ "${nr2::1}" = " " ] && nr2="${nr2:1}" # skip leading space
|
|
[ "${nr2: -1}" = " " ] && nr2="${nr2:: -1}" # skip trailing space
|
|
|
|
echo "$nr2"
|
|
}
|
|
|
|
read2() {
|
|
# Special handling for option -t (and -p).
|
|
# The read value goes to the REPLY variable only.
|
|
|
|
local name=""
|
|
local prompt=""
|
|
local count=0
|
|
local cr=$'\r'
|
|
local args=()
|
|
local arg
|
|
local has_t_opt="no"
|
|
local prev=""
|
|
local retval=0
|
|
|
|
OPTIND=1 # for some reason this is required!
|
|
|
|
# get the prompt and timeout (=count) values, if they exist
|
|
while getopts ersa:d:i:n:N:p:t:u: name ; do
|
|
case $name in
|
|
t) count="$OPTARG" ; has_t_opt="yes" ;;
|
|
p) prompt="$OPTARG" ;;
|
|
esac
|
|
done
|
|
|
|
# add parameters from "$@" to the "args" array, except -t and -p and their values
|
|
for arg in "$@" ; do
|
|
case "$arg" in
|
|
-t) prev=t ;;
|
|
-t*) ;;
|
|
-p) prev=p ;;
|
|
-p*) ;;
|
|
*)
|
|
case "$prev" in
|
|
t|p) prev="" ;;
|
|
*) args+=("$arg") ;;
|
|
esac
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# read value
|
|
if [ "$has_t_opt" = "yes" ] ; then
|
|
# while reading, show a seconds counter
|
|
while [ $count -gt 0 ] ; do
|
|
printf2 "%s[%s] " "$cr" "$count"
|
|
read -t 1 -p "$prompt" "${args[@]}" >&2
|
|
retval=$?
|
|
test $retval -eq 0 && break
|
|
test -n "$REPLY" && break
|
|
((count--))
|
|
done
|
|
else
|
|
# just read the value, no special handling
|
|
read -p "$prompt" "${args[@]}" >&2
|
|
retval=$?
|
|
fi
|
|
test -z "$REPLY" && echo2 ""
|
|
return $retval
|
|
}
|
|
|
|
Pushd() { pushd "$@" >/dev/null || DIE "${FUNCNAME[1]}: pushd $* failed" ; }
|
|
|
|
Popd() {
|
|
local count=1 xx
|
|
case "$1" in
|
|
-c=*) count=${1:3} ; shift ;;
|
|
-c*) count=${1:2} ; shift ;;
|
|
esac
|
|
for ((xx=0;xx<count;xx++)) ; do
|
|
popd "$@" >/dev/null || DIE "${FUNCNAME[1]}: popd $* failed"
|
|
done
|
|
}
|
|
|
|
GetPkgbuildValue() { # this is used in assets.conf too!
|
|
#
|
|
# Extract one or more values from variables of file PKGBUILD into respective user variables.
|
|
#
|
|
# Usage: GetPkgbuildValue PKGBUILD toVariable pkgbuildVariable [torVariable pkgbuildVariable [toVariable pkgbuildVariable] ...]
|
|
#
|
|
# Example:
|
|
# local Pkgver Pkgrel # user variables
|
|
# GetPkgbuildValue $mydir/PKGBUILD Pkgver "pkgver" Pkgrel "pkgrel"
|
|
# will return values of 'pkgver' and 'pkgrel' from $mydir/PKGBUILD into Pkgver and Pkgrel, respectively
|
|
#
|
|
|
|
local PKGBUILD="$1"
|
|
shift
|
|
|
|
while declare -F pkgver &> /dev/null ; do
|
|
unset -f pkgver # remove possible function from another PKGBUILD
|
|
done
|
|
|
|
source "$PKGBUILD" || return 1 # reading PKGBUILD may fail
|
|
|
|
while [ "$1" ] ; do
|
|
[ "$2" ] || DIE "$FUNCNAME: internal error: number of call parameters is not even!"
|
|
local -n retvar_for_all="$1"
|
|
GetPkgbuildValue1 "$2" retvar_for_all
|
|
unset -n retvar_for_all
|
|
shift 2
|
|
done
|
|
}
|
|
|
|
CursorLeft() { local num="$1"; echo2 -en "\033[${num}D"; } # move cursor left $num chars
|
|
|
|
GetPkgbuildValue1() {
|
|
local varname="$1"
|
|
local -n retvar="$2"
|
|
local retval2=""
|
|
|
|
case "$varname" in
|
|
arch) retvar=("${arch[@]}") ;;
|
|
backup) retvar=("${backup[@]}") ;;
|
|
conflicts) retvar=("${conflicts[@]}") ;;
|
|
depends) retvar=("${depends[@]}") ;;
|
|
makedepends) retvar=("${makedepends[@]}") ;;
|
|
optdepends) retvar=("${optdepends[@]}") ;;
|
|
pkgname) retvar=("${pkgname[@]}") ;;
|
|
provides) retvar=("${provides[@]}") ;;
|
|
replaces) retvar=("${replaces[@]}") ;;
|
|
source) retvar=("${source[@]}") ;;
|
|
validpgpkeys) retvar=("${validpgpkeys[@]}") ;;
|
|
|
|
epoch) retvar="$epoch" ;;
|
|
install) retvar="$install" ;;
|
|
pkgdesc) retvar="$pkgdesc" ;;
|
|
pkgrel) retvar="$pkgrel" ;;
|
|
url) retvar="$url" ;;
|
|
|
|
_ver) retvar="$_ver" ;;
|
|
|
|
pkgver)
|
|
if declare -F pkgver &> /dev/null ; then
|
|
# printf2 " running function pkgver() ... "
|
|
if [ $listing_updates = yes ] ; then
|
|
CursorLeft 2
|
|
HookIndicator "$hook_pkgver_func" yes
|
|
# echo2 -n "p "
|
|
fi
|
|
|
|
# We want to run pkgver() to get the correct pkgver.
|
|
# But first we must run makepkg because the needed git stuff hasn't been fetched yet...
|
|
|
|
Pushd ${PKGBUILD%/*}
|
|
|
|
makepkg --skipinteg -od &> /dev/null || DIE "$FUNCNAME: cannot determine 'pkgver' from $PKGBUILD."
|
|
|
|
# sed -E -i "$PKGBUILD" -e "s|^pkgrel=[0-9\.]+|pkgrel=$pkgrel|" # Prevents makepkg from changing pkgrel to 1.
|
|
|
|
if false ; then
|
|
unset -f pkgver
|
|
source "$PKGBUILD"
|
|
retvar="$(pkgver)"
|
|
else
|
|
retvar=$(grep ^pkgver= "$PKGBUILD") # pkgver=something
|
|
retvar=${retvar#*=} # remove pkgver=
|
|
retvar=${retvar%% *} # remove all after space
|
|
retvar=${retvar//[\'\"]/} # remove all quote marks
|
|
fi
|
|
unset -f pkgver
|
|
|
|
Popd
|
|
retval2="$(echo "$retvar" | tail -n1)" # $retvar may have 2 items in 2 lines !?
|
|
[ -n "$retval2" ] && retvar="$retval2"
|
|
else
|
|
retvar="$pkgver"
|
|
fi
|
|
;;
|
|
*)
|
|
WARN "$FUNCNAME: unsupported variable name '$varname'"
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
IsListedPackage() {
|
|
# Is a package one of the listed packages in PKGNAMES?
|
|
local Pkgname="$1"
|
|
printf "%s\n" "${PKGNAMES[@]}" | grep -P "^$Pkgname/aur$|^$Pkgname$" >/dev/null
|
|
}
|
|
|
|
IsAurPackage() {
|
|
# Determine AUR from PKGNAMES array directly since we don't have PKGBUILD yet.
|
|
local Pkgname="$1"
|
|
printf "%s\n" "${PKGNAMES[@]}" | grep "^$Pkgname/aur$" >/dev/null
|
|
}
|
|
|
|
HandlePossibleEpoch() {
|
|
# Github release assets cannot have colon (:) in the file name.
|
|
# So if a package has an epoch value in PKGBUILD, return a new fixed name for a package
|
|
# fetched from github release assets.
|
|
|
|
local Pkgname="$1" # e.g. welcome
|
|
local pkg="$2" # e.g. welcome-2.3.9.6-1-any.pkg.tar.zst # assumes: epoch=2
|
|
local -n Newname="$3"
|
|
local cwd=""
|
|
local Epoch=""
|
|
|
|
if [ ! -r PKGBUILD ] ; then
|
|
cwd="$PWD"
|
|
|
|
if [ ! -r "$PKGBUILD_ROOTDIR/$Pkgname/PKGBUILD" ] ; then
|
|
if IsAurPackage "$Pkgname" ; then
|
|
cd "$PKGBUILD_ROOTDIR"
|
|
$helper -Ga "$Pkgname" >/dev/null || DIE "fetching PKGBUILD of '$Pkgname' failed."
|
|
else
|
|
DIE "sorry, getting PKGBUILD of '$Pkgname' not supported yet."
|
|
fi
|
|
fi
|
|
cd "$PKGBUILD_ROOTDIR/$Pkgname"
|
|
fi
|
|
|
|
GetPkgbuildValue "PKGBUILD" Epoch "epoch"
|
|
|
|
if [ -z "$Epoch" ] ; then
|
|
Newname="$pkg"
|
|
else
|
|
Newname=$(echo "$pkg" | sed "s|\(${Pkgname}-[0-9][0-9]*\)\.\(.*\)|\1:\2|")
|
|
fi
|
|
|
|
if [ -n "$cwd" ] ; then
|
|
cd "$cwd"
|
|
[ -n "$tmpdir" ] && rm -rf $tmpdir
|
|
fi
|
|
}
|
|
|
|
IncludesOption() {
|
|
local where="$1" # list of options, e.g. "-r --rmdeps"
|
|
local opt="$2" # e.g. "-r"
|
|
|
|
printf "%s\n" $where | grep -w "\\$opt" >/dev/null
|
|
}
|
|
|
|
Build()
|
|
{
|
|
local pkgdirname="$1"
|
|
local assetsdir="$2"
|
|
local pkgbuilddir="$3"
|
|
local Pkgname
|
|
local pkg pkgs
|
|
local workdir=$(mktemp -d)
|
|
local log=$workdir/buildlog-"$pkgdirname".log
|
|
local missdeps="Missing dependencies"
|
|
local opts=""
|
|
local msg=""
|
|
|
|
if [ "${#PKG_MAKEPKG_OPTIONS[@]}" -gt 0 ] ; then
|
|
if [ -n "${PKG_MAKEPKG_OPTIONS[$pkgdirname]}" ] ; then # from assets.conf
|
|
opts="${PKG_MAKEPKG_OPTIONS[$pkgdirname]}"
|
|
fi
|
|
fi
|
|
|
|
Pushd "$workdir"
|
|
cp -r "$pkgbuilddir" .
|
|
Pkgname="$(PkgBuildName "$pkgdirname")"
|
|
Pushd "$workdir/$pkgdirname"
|
|
|
|
# now build, assume we have PKGBUILD
|
|
# special handling for missing dependencies
|
|
local exitcode=0
|
|
LANG=C makepkg --clean $opts &> "$log" || {
|
|
exitcode=$?
|
|
if [ -z "$(grep "$missdeps:" "$log")" ] ; then
|
|
Popd -c2
|
|
DIE "makepkg for '$Pkgname' failed (makepkg: see $log and files at $workdir/$pkgdirname)"
|
|
fi
|
|
msg="Installing $(echo "$missdeps" | tr [:upper:] [:lower:])"
|
|
if IncludesOption "$opts" "--rmdeps" || IncludesOption "$opts" "-r" ; then
|
|
msg+=" and removing them right after build"
|
|
fi
|
|
echo2 "$msg:"
|
|
# grep -A100 "$missdeps:" "$log" | grep "^ -> " >&2
|
|
|
|
# use special pacman wrapper in the makepkg call below
|
|
local wrapper=/usr/bin/pacman-for-assets.make
|
|
[ -x "$wrapper" ] || DIE "sorry, $wrapper does not exist!"
|
|
|
|
PACMAN=$wrapper makepkg --syncdeps --clean $opts >"$log" || { Popd -c2 ; DIE "makepkg for '$Pkgname' failed (see $log)" ; }
|
|
}
|
|
pkgs=(*.pkg.tar.$_COMPRESSOR)
|
|
case "$pkgs" in
|
|
"" | "*.pkg.tar.$_COMPRESSOR") DIE "$pkgdirname: build failed" ;;
|
|
esac
|
|
for pkg in "${pkgs[@]}" ; do
|
|
# HandlePossibleEpoch "$Pkgname" "$pkg" pkg # not needed here since makepkg should handle epoch OK (?)
|
|
mv $pkg "$assetsdir"
|
|
built+=("$assetsdir/$pkg")
|
|
built_under_this_pkgname+=("$pkg")
|
|
done
|
|
Popd
|
|
Popd
|
|
rm -rf "$workdir"
|
|
}
|
|
|
|
PkgBuildName()
|
|
{
|
|
local pkgdirname="$1"
|
|
source "$PKGBUILD_ROOTDIR"/"$(JustPkgname "$pkgdirname")"/PKGBUILD
|
|
echoreturn "$pkgname"
|
|
}
|
|
|
|
PkgBuildVersion()
|
|
{
|
|
local _pkgdirname="$1"
|
|
local _srcfile="$PKGBUILD_ROOTDIR"/"$(JustPkgname "$_pkgdirname")"/PKGBUILD
|
|
|
|
if [ ! -r "$_srcfile" ] ; then
|
|
DIE "'$_srcfile' does not exist."
|
|
fi
|
|
|
|
local Epoch="" Pkgver="" Pkgrel=""
|
|
|
|
# GetPkgbuildValue "$_srcfile" Epoch "epoch" Pkgver "pkgver" Pkgrel "pkgrel"
|
|
GetPkgbuildValue "$_srcfile" Epoch "epoch"
|
|
GetPkgbuildValue "$_srcfile" Pkgver "pkgver"
|
|
GetPkgbuildValue "$_srcfile" Pkgrel "pkgrel"
|
|
|
|
if [ -n "$Epoch" ] ; then
|
|
echoreturn "$Epoch:${Pkgver}-$Pkgrel"
|
|
else
|
|
echoreturn "${Pkgver}-$Pkgrel"
|
|
fi
|
|
}
|
|
|
|
LocalVersion()
|
|
{
|
|
local Pkgname="$1"
|
|
local pkgs
|
|
local xx
|
|
|
|
Pkgname="$(JustPkgname "$Pkgname")"
|
|
|
|
for xx in zst xz ; do # order is important because of change to zstd!
|
|
pkgs=$(ListPkgsWithName "$ASSETSDIR/$Pkgname" "$xx")
|
|
test -n "$pkgs" && break
|
|
done
|
|
|
|
[ "$pkgs" ] || { echoreturn "0"; return; }
|
|
case "$(echo "$pkgs" | wc -l)" in
|
|
0) echoreturn "0" ; return ;;
|
|
1) ;;
|
|
*) echo2 -n "$hook_multiversion "
|
|
# WARN -n "$Pkgname: many local versions, using the latest. "
|
|
pkgs="$(echo "$pkgs" | tail -n 1)"
|
|
;;
|
|
esac
|
|
|
|
pkg-name-components --real EVR "$pkgs"
|
|
}
|
|
|
|
AurMarkingFail() {
|
|
local fakepath="$1" # no more: "aur/pkgname"
|
|
DIE "marking AUR packages as $fakepath is no more supported!"
|
|
}
|
|
|
|
JustPkgname()
|
|
{
|
|
local fakepath="$1"
|
|
case "$fakepath" in
|
|
./*) fakepath="${fakepath:2}" ;;
|
|
*/aur) fakepath="${fakepath:: -4}" ;;
|
|
aur/*) AurMarkingFail "$fakepath" ;;
|
|
# *) fakepath="${fakepath}" ;;
|
|
esac
|
|
echoreturn ${fakepath##*/}
|
|
}
|
|
|
|
HookIndicator() {
|
|
local mark="$1"
|
|
local force="$2"
|
|
if [ "$fetch" = "yes" ] || [ "$force" = "yes" ] ; then
|
|
echo2 -n "$mark "
|
|
fi
|
|
}
|
|
|
|
ExplainHookMarks() {
|
|
Color2 tip
|
|
printf2 "\nPossible markings above mean indications from %s:\n" "$ASSETS_CONF"
|
|
printf2 " %s = a package hook changed pkgver in PKGBUILD.\n" "$hook_pkgver"
|
|
printf2 " %s = execute pkgver() from PKGBUILD.\n" "$hook_pkgver_func" # not a hook!
|
|
printf2 " %s = a package hook found many local versions, used latest.\n" "$hook_multiversion"
|
|
printf2 " %s = a package hook was executed.\n" "$hook_yes"
|
|
printf2 " %s = compare new and existing PKGBUILD files from AUR.\n" "$hook_compare"
|
|
printf2 "\n"
|
|
Color2
|
|
}
|
|
|
|
ShowPkgListWithTitle() { # Show lines like: $title name [name...]
|
|
local title="$1"
|
|
shift
|
|
local name
|
|
local line=""
|
|
local columns="$COLUMNS"
|
|
[ "$columns" ] || columns=80
|
|
|
|
for name in "$@" ; do
|
|
[ "$line" ] || line="$title"
|
|
line+=" $name"
|
|
if [ ${#line} -gt $((columns-10)) ] ; then
|
|
printf2 "%s\n" "$line"
|
|
line=""
|
|
fi
|
|
done
|
|
[ "$line" ] && printf2 "%s\n" "$line"
|
|
}
|
|
|
|
AurSource() {
|
|
# Use AUR if possible, otherwise use the backup repo at github.
|
|
local -n _refvar="$1"
|
|
[ "$_refvar" != aur ] && return
|
|
local url=https://aur.archlinux.org/packages
|
|
|
|
/bin/curl --fail -Lsm 5 $url >/dev/null && _refvar=aur || _refvar=repo
|
|
}
|
|
FetchAurPkgs() {
|
|
DebugBreak
|
|
local pkgs
|
|
readarray -t pkgs < <(printf "%s\n" "${PKGNAMES[@]}" | /bin/grep /aur | /bin/sed 's|/aur||')
|
|
if [ "${pkgs[0]}" ] ; then
|
|
rm -rf "${pkgs[@]}"
|
|
AurSource aur_src
|
|
case "$aur_src" in
|
|
aur)
|
|
Color2 info; echo2 " -> $helper -Ga ${pkgs[*]}"; Color2
|
|
$helper -Ga "${pkgs[@]}" &>/dev/null && return
|
|
;;
|
|
repo)
|
|
Color2 info; echo2 " -> aur-pkgs-fetch ${pkgs[*]}"; Color2
|
|
Color2 warning; echo2 " -> please wait..."; Color2
|
|
aur-pkgs-fetch "${pkgs[@]}" && return
|
|
;;
|
|
local)
|
|
Color2 info; echo2 " -> copy from '${AURSRCDIR/$HOME/\~}/$REPONAME'"; Color2
|
|
for pkg in "${pkgs[@]}" ; do
|
|
if [ -d "$AURSRCDIR/$REPONAME/$pkg" ] ; then
|
|
cp -r "$AURSRCDIR/$REPONAME/$pkg" ./
|
|
else
|
|
WARN "folder '$AURSRCDIR/$REPONAME/$pkg' is not found!"
|
|
fi
|
|
done
|
|
return
|
|
;;
|
|
esac
|
|
DIE "fetching ${pkgs[*]} failed."
|
|
fi
|
|
}
|
|
|
|
ListNameToPkgName()
|
|
{
|
|
# "returns" pkgdirname and hookout
|
|
#
|
|
# PKGNAMES array (from $ASSETS_CONF) uses certain syntax for package names
|
|
# to mark where they come from, either local or AUR packages.
|
|
# AUR packages are fetched from AUR, local packages
|
|
# are simply used from a local folder.
|
|
#
|
|
# Supported syntax:
|
|
# pkgname local package
|
|
# ./pkgname local package (emphasis)
|
|
# aur/pkgname AUR package "aur/pkgname" NO MORE SUPPORTED!
|
|
# pkgname/aur AUR package (another way)
|
|
|
|
local xx="$1"
|
|
local run_hook="$2"
|
|
local Pkgname
|
|
local hook
|
|
local hookretval=0
|
|
|
|
hookout=""
|
|
|
|
Pkgname=$(JustPkgname "$xx")
|
|
|
|
[ "${xx::4}" = "aur/" ] && AurMarkingFail "$xx"
|
|
|
|
# if [ "${xx: -4}" = "/aur" ] ; then
|
|
# case "$run_hook" in
|
|
# yes)
|
|
# rm -rf "$Pkgname"
|
|
# $helper -Ga "$Pkgname" >/dev/null || DIE "'$helper -Ga $Pkgname' failed."
|
|
# # Compare "$Pkgname" "$Pkgname/PKGBUILD" || return 1
|
|
# ;;
|
|
# esac
|
|
# fi
|
|
|
|
# A pkg may need some changes:
|
|
hook="${ASSET_PACKAGE_HOOKS[$Pkgname]}"
|
|
if [ -n "$hook" ] ; then
|
|
if [ "$run_hook" = "yes" ] ; then
|
|
hookout=$($hook) || hookretval=$?
|
|
case $hookretval in
|
|
0) HookIndicator "$hook_yes" ;; # OK
|
|
11) HookIndicator "$hook_pkgver" ;; # pkgver was updated by hook
|
|
1) HookIndicator "?" ;; # failed
|
|
*) HookIndicator "??" ;; # unknown error
|
|
esac
|
|
fi
|
|
else
|
|
HookIndicator "$hook_no"
|
|
fi
|
|
|
|
pkgdirname="$Pkgname"
|
|
return $hookretval
|
|
}
|
|
|
|
Compare() {
|
|
# Compare new PKGBUILD from AUR to the saved PKGBUILD.
|
|
|
|
local PKGNAME="$1"
|
|
local pkgbuild_new="$2"
|
|
local pkgbuild_old="$HOME/.aur-pkgbuilds/$PKGNAME/PKGBUILD"
|
|
|
|
mkdir -p "${pkgbuild_old%/*}"
|
|
|
|
if [ -e "$pkgbuild_old" ] ; then
|
|
diff "$pkgbuild_old" "$pkgbuild_new" >/dev/null && return # return if identical
|
|
fi
|
|
|
|
HookIndicator "$hook_compare"
|
|
/bin/meld "$pkgbuild_old" "$pkgbuild_new"
|
|
|
|
if [ -e "$pkgbuild_old" ] ; then
|
|
# Skip copying if package is marked as unacceptable, or user wants to skip.
|
|
|
|
if [ "${SKIP_UNACCEPTABLE_PKGBUILD[$PKGNAME]}" ] ; then
|
|
Color2 warning; echo2 "SKIP (unacceptable PKGBUILD)"; Color2
|
|
return 1
|
|
else
|
|
Color2 info; read -p "Continue $PROGNAME (Y/n): " >&2; Color2
|
|
case "$REPLY" in
|
|
[Nn]*) DIE "stopped due to the unacceptable PKGBUILD of $PKGNAME" ;;
|
|
esac
|
|
fi
|
|
fi
|
|
|
|
/bin/cp "$pkgbuild_new" "$pkgbuild_old"
|
|
}
|
|
|
|
LogStuff() {
|
|
case "$mode" in
|
|
dryrun-local) return ;; # avoid unnecessary pw asking
|
|
# dryrun) return ;; # avoid unnecessary pw asking
|
|
esac
|
|
if which logstuff >& /dev/null ; then
|
|
if ! logstuff state ; then
|
|
Color2 info; echo2 "==> logstuff on"; Color2
|
|
logstuff on
|
|
fi
|
|
fi
|
|
}
|
|
|
|
HubRelease() {
|
|
hub release "$@"
|
|
}
|
|
|
|
HubReleaseShow() {
|
|
# also convert characters:
|
|
# %2B ==> +
|
|
# %3A ==> :
|
|
HubRelease show "$@" | sed -e 's|%2B|+|g' # -e 's|%3A|:|g'
|
|
}
|
|
|
|
GetRemoteAssetNames() {
|
|
GetFromGit() {
|
|
local dir="$1"
|
|
|
|
if [ -r "$dir/$REPONAME.db" ] && [ -d "$GITDIR/.git" ] ; then
|
|
Pushd "$dir"
|
|
git pull >& /dev/null
|
|
remote_files=$(ls -1 | sort)
|
|
Popd
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
if [ "$PREFER_GIT_OVER_RELEASE" = "yes" ] ; then
|
|
names_from_git=yes
|
|
case "$REPONAME" in
|
|
endeavouros) GetFromGit "$GITDIR/$REPONAME/$ARCH" && return ;;
|
|
endeavouros-testing-dev) GetFromGit "$GITDIR/$REPONAME" && return ;;
|
|
*) GetFromGit "$GITDIR/repo" && return ;;
|
|
esac
|
|
fi
|
|
|
|
# fallback to release assets
|
|
remote_files=$(release-asset-names ${RELEASE_TAGS[0]} | sort)
|
|
names_from_git=no
|
|
}
|
|
|
|
AskFetchingFromGithub() {
|
|
local -r msg="Fetch assets from github (Y=only if different, n=no, f=yes)? "
|
|
if [ "$fetch_timeout" ] ; then
|
|
read2 -p "$msg" -t "$fetch_timeout"
|
|
else
|
|
printf2 "\n%s " "$msg"
|
|
read2
|
|
fi
|
|
case "$REPLY" in
|
|
[yY]*|"")
|
|
echo2 "==> Using remote assets if there are differences, otherwise local."
|
|
;;
|
|
[fF]*|"")
|
|
echo2 "==> Using remote assets."
|
|
return 0
|
|
;;
|
|
*)
|
|
echo2 "==> Using local assets."
|
|
echo2 ""
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
# Selected using remote assets with checks.
|
|
# Check if there differences between local and remote file names.
|
|
# If not, use local assets.
|
|
|
|
DebugBreak "remote assets with checking"
|
|
|
|
local local_files=""
|
|
local remote_files=""
|
|
local diffs=none # what kind of diffs, if any?
|
|
|
|
if [ "$use_release_assets" = "yes" ] ; then
|
|
local_files=$(ls -1 *.{db,files,zst,xz,sig} 2> /dev/null | sort) # $asset_file_endings
|
|
GetRemoteAssetNames
|
|
fi
|
|
|
|
if [ "$local_files" != "$remote_files" ] ; then
|
|
# There are differences in file names.
|
|
# Could be the epoch related file name change, they will be fixed later.
|
|
|
|
if [ "$names_from_git" = "yes" ] ; then
|
|
diffs=real
|
|
elif OnlyEpochDiffs ; then
|
|
diffs=epoch # because of github
|
|
else
|
|
diffs=real
|
|
fi
|
|
|
|
if [ $diffs = real ] ; then
|
|
local tmpdir_local=$(mktemp -d /tmp/local.XXX)
|
|
local tmpdir_remote=$(mktemp -d /tmp/remote.XXX)
|
|
|
|
touch $(echo "$local_files" | sed "s|^|$tmpdir_local/|")
|
|
touch $(echo "$remote_files" | sed "s|^|$tmpdir_remote/|")
|
|
|
|
LANG=C diff $tmpdir_local $tmpdir_remote | sed -E \
|
|
-e "s|^Only in /tmp/remote[^:]+: |Only in REMOTE: |" \
|
|
-e "s|^Only in /tmp/local[^:]+: |Only in LOCAL: |"
|
|
rm -rf $tmpdir_local $tmpdir_remote
|
|
fi
|
|
fi
|
|
|
|
case "$diffs" in
|
|
none) return 1 ;; # no diffs ==> local
|
|
epoch) return 1 ;; # only epoch no diffs ==> local
|
|
real) return 0 ;; # real diffs ==> remote
|
|
esac
|
|
}
|
|
|
|
OnlyEpochDiffs() {
|
|
# input: $local_files and $remote_files
|
|
local count_ll=$(echo "$local_files" | wc -l)
|
|
local count_rr=$(echo "$remote_files" | wc -l)
|
|
local loc rem
|
|
local ll rr ix
|
|
local epoch_diff_count=0
|
|
|
|
[ "$count_ll" != "$count_rr" ] && return 1
|
|
|
|
readarray -t loc < <(echo "$local_files")
|
|
readarray -t rem < <(echo "$remote_files")
|
|
|
|
# epoch test: change first colon in local to dot and compare to remote
|
|
|
|
for ((ix=0; ix < count_ll; ix++)) ; do
|
|
ll="${loc[$ix]}"
|
|
rr="${rem[$ix]}"
|
|
[ "${ll}" = "$rr" ] && continue # local = remote
|
|
[ "${ll/:/.}" = "$rr" ] && {
|
|
((epoch_diff_count++))
|
|
continue # only epoch diff, will be fixed later
|
|
}
|
|
return 1 # real diff found
|
|
done
|
|
if [ $epoch_diff_count -gt 0 ] ; then
|
|
echo2 "Local and remote file names have only epoch diffs (because of github limitations) and they will be fixed automatically."
|
|
echo2 ""
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
Assets_clone()
|
|
{
|
|
local names_from_git=no
|
|
|
|
if [ "$mode" = "dryrun-local" ] && [ "$REPONAME" != "endeavouros_calamares" ] ; then
|
|
return
|
|
fi
|
|
if [ "$use_release_assets" = "no" ] ; then
|
|
if [ -n "$GITREPOURL" ] && [ -n "$GITREPODIR" ] ; then
|
|
AskFetchingFromGithub || return 0
|
|
echo2 "==> Copying files from the git repo to local dir."
|
|
local tmpdir=$(mktemp -d)
|
|
Pushd $tmpdir
|
|
git clone "$GITREPOURL" >& /dev/null || DIE "cloning '$GITREPOURL' failed"
|
|
rm -f "$ASSETSDIR"/*.{db,files,zst,xz,sig,txt,old} # $asset_file_endings
|
|
if true ; then
|
|
local srcfiles=()
|
|
readarray -t srcfiles < <(/bin/ls "$GITREPODIR"/*.{db,files,zst,xz,sig} 2>/dev/null)
|
|
if [ "$srcfiles" ] ; then
|
|
cp "${srcfiles[@]}" "$ASSETSDIR"
|
|
else
|
|
DIE "$FUNCNAME: no files in $GITREPODIR to copy to $ASSETSDIR!"
|
|
fi
|
|
else
|
|
cp "$GITREPODIR"/*.{db,files,zst,xz,sig} "$ASSETSDIR" # $asset_file_endings
|
|
fi
|
|
sync
|
|
Popd
|
|
rm -rf $tmpdir
|
|
else
|
|
DIE "GITREPOURL and/or GITREPODIR missing for $REPONAME while USE_RELEASE_ASSETS = '$use_release_assets'"
|
|
fi
|
|
return
|
|
fi
|
|
|
|
local xx yy hook
|
|
|
|
# It is possible that your local release assets in folder $ASSETSDIR
|
|
# are not in sync with github.
|
|
# If so, you can delete your local assets and fetch assets from github now.
|
|
|
|
case "$REPONAME" in
|
|
endeavouros_calamares) ;; # many maintainers, so make sure we have the same assets!
|
|
*)
|
|
if [ "$repoup" = "1" ] ; then
|
|
echo2 "==> Using local assets."
|
|
return
|
|
fi
|
|
AskFetchingFromGithub || return 0
|
|
;;
|
|
esac
|
|
|
|
Pushd "$ASSETSDIR"
|
|
|
|
local tag
|
|
local remotes remote
|
|
local waittime=30
|
|
|
|
for tag in "${RELEASE_TAGS[@]}" ; do
|
|
remotes="$(HubReleaseShow -f %as%n $tag | sed 's|^.*/||')"
|
|
for remote in $remotes ; do
|
|
[ -r $remote ] || break
|
|
done
|
|
break
|
|
done
|
|
|
|
DebugBreak "remote asset checking"
|
|
|
|
if [ -r $remote ] ; then
|
|
read2 -p "Asset names at github are the same as here, fetch anyway (y/N)? " -t $waittime
|
|
case "$REPLY" in
|
|
[yY]*) ;;
|
|
*) Popd ; return ;;
|
|
esac
|
|
fi
|
|
|
|
save_folder=$(mktemp -d "$PWD"/SAVED.XXX)
|
|
echo2 "==> Saving current local assets to '$save_folder' ..."
|
|
|
|
# $pkgname in PKGBUILD may not be the same as values in $PKGNAMES,
|
|
# so delete all packages and databases.
|
|
|
|
# rm -f *.{db,files,zst,xz,sig,txt,old} # $asset_file_endings
|
|
mv *.{db,files,zst,xz,sig,txt,old} "$save_folder"/ 2>/dev/null # $asset_file_endings
|
|
local leftovers="$(command ls *.{db,files,zst,xz,sig,old} 2>/dev/null)" # $asset_file_endings
|
|
test -z "$leftovers" || DIE "removing local assets failed!"
|
|
|
|
echo2 "==> Fetching all github assets..."
|
|
|
|
hook="${ASSET_PACKAGE_HOOKS[assets_mirrors]}"
|
|
for xx in "${RELEASE_TAGS[@]}" ; do
|
|
if [ "$names_from_git" = "yes" ] ; then
|
|
local cpdir=""
|
|
case "$REPONAME" in
|
|
endeavouros) cpdir="$GITDIR/$REPONAME/$ARCH" ;;
|
|
endeavouros-testing-dev) cpdir="$GITDIR/$REPONAME" ;;
|
|
*) cpdir="$GITDIR/repo" ;;
|
|
esac
|
|
[ -n "$cpdir" ] || DIE "git dir is empty, cannot copy files"
|
|
echo2 "==> Copying files from '$cpdir' ..."
|
|
cp "$cpdir"/* .
|
|
else
|
|
HubRelease download $xx
|
|
sleep 1
|
|
|
|
# Unfortunately github release assets cannot contain a colon (epoch mark) in file name, so rename those packages locally
|
|
# after fetching them above.
|
|
|
|
local oldname newname Pkgname
|
|
|
|
for oldname in *.pkg.tar.{zst,xz} ; do
|
|
case "$oldname" in
|
|
"*.pkg."*) continue ;;
|
|
esac
|
|
Pkgname=$(pkg-name-components N "$oldname")
|
|
IsListedPackage "$Pkgname" || continue
|
|
HandlePossibleEpoch "$Pkgname" "$oldname" newname
|
|
if [ "$newname" != "$oldname" ] ; then
|
|
echo2 "==> Fix: $oldname --> $newname"
|
|
echo2 "==> Fix: $oldname.sig --> $newname.sig"
|
|
mv $oldname $newname
|
|
mv $oldname.sig $newname.sig
|
|
fi
|
|
done
|
|
fi
|
|
test -n "$hook" && { $hook && break ; } # we need assets from only one tag since assets in other tags are the same
|
|
done
|
|
|
|
Popd
|
|
}
|
|
|
|
PkgbuildExists() {
|
|
local Pkgname="$1" # a name from "${PKGNAMES[@]}"
|
|
local special="$2"
|
|
local yy=$(JustPkgname "$Pkgname")
|
|
|
|
if [ -r "$PKGBUILD_ROOTDIR/$yy/PKGBUILD" ] ; then
|
|
return 0
|
|
else
|
|
((no_pkgbuild_count++))
|
|
if [ "$special" != "" ] ; then
|
|
local files=$(ls -l "$PKGBUILD_ROOTDIR/$yy" 2>/dev/null)
|
|
printf2 "$WARNING (${PROGNAME}, $special): no PKGBUILD!\n"
|
|
if [ -n "$files" ] ; then
|
|
printf2 "File listing:\n"
|
|
echo2 "$files" | sed 's|^| ==> |'
|
|
fi
|
|
fi
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
IsEmptyString() {
|
|
local name="$1"
|
|
local value="${!name}"
|
|
test -n "$value" || DIE "value of variable '$name' is empty"
|
|
}
|
|
DirExists() {
|
|
local name="$1"
|
|
local docreate="$2"
|
|
local value="${!name}"
|
|
|
|
case "$docreate" in
|
|
yes) mkdir -p "$value" ;;
|
|
*) test -d "$value" || {
|
|
DIE "variable '$name' has folder name value '$value' - the folder does not exist"
|
|
} ;;
|
|
esac
|
|
}
|
|
|
|
ShowIndented() {
|
|
# shows the "head" of a listed value, possibly indented
|
|
|
|
local txt="$1"
|
|
local indent_level="$2" # optional number >= 0
|
|
local xx
|
|
local ind=""
|
|
|
|
case "$indent_level" in
|
|
"") ;;
|
|
*)
|
|
for ((xx=0; xx < indent_level; xx++)) ; do
|
|
ind+=" "
|
|
done
|
|
;;
|
|
esac
|
|
printf2 "%s%-35s : " "$ind" "$1"
|
|
}
|
|
|
|
RationalityTests()
|
|
{
|
|
ShowIndented "Checking values in $ASSETS_CONF"
|
|
|
|
IsEmptyString ASSETSDIR
|
|
IsEmptyString PKGBUILD_ROOTDIR
|
|
IsEmptyString GITDIR
|
|
IsEmptyString PKGNAMES
|
|
IsEmptyString REPONAME
|
|
IsEmptyString RELEASE_TAGS
|
|
IsEmptyString SIGNER
|
|
DirExists ASSETSDIR
|
|
DirExists PKGBUILD_ROOTDIR yes # silently create the dir
|
|
DirExists GITDIR
|
|
|
|
if [ -z "$REPO_COMPRESSOR" ] ; then
|
|
REPO_COMPRESSOR=xz
|
|
fi
|
|
|
|
echo2 "done."
|
|
}
|
|
|
|
Constructor()
|
|
{
|
|
# make sure proper .git symlink exists; create new or change existing if necessary
|
|
|
|
if [ ! "$GITDIR"/.git -ef "$ASSETSDIR"/.git ] ; then
|
|
echo2 "Warning: '$ASSETSDIR/.git' ($(ls -l $ASSETSDIR/.git)) does not refer to proper place, fixing..."
|
|
rm -f "$ASSETSDIR"/.git || DIE "failed to remove: '$ASSETSDIR/.git'"
|
|
ln -s "$GITDIR"/.git "$ASSETSDIR"/.git || DIE "failed to symlink: '$ASSETSDIR/.git' -> '$GITDIR/.git'"
|
|
fi
|
|
}
|
|
|
|
Destructor()
|
|
{
|
|
[ -n "$save_folder" ] && rm -rf "$save_folder"
|
|
test -n "$buildsavedir" && rm -rf "$buildsavedir"
|
|
}
|
|
|
|
ShowOldCompressedPackages() {
|
|
# If we have *both* .zst and .xz package, show the .xz package.
|
|
|
|
local pkg pkgdir Pkgname
|
|
local pkg2 pkg22
|
|
|
|
for pkg in $(ls "$ASSETSDIR"/*.pkg.tar.zst 2>/dev/null) ; do
|
|
Pkgname=${pkg##*/}
|
|
pkgdir=${pkg%/*}
|
|
pkg2="$pkgdir/$(echo "$Pkgname" | sed 's|\-[0-9].*$||')"
|
|
pkg22="$(ls "$pkg2"-*.pkg.tar.xz 2>/dev/null)"
|
|
if [ -n "$pkg22" ] ; then
|
|
for pkg2 in $pkg22 ; do
|
|
printf2 "Remove old packages:\n %s\n %s\n" "$pkg2" "$pkg2.sig"
|
|
rm -i "$pkg2" "$pkg2.sig"
|
|
done
|
|
fi
|
|
done
|
|
}
|
|
|
|
_ASSERT_() {
|
|
local ret=0
|
|
"$@" &> /dev/null || ret=$?
|
|
if [ $ret -ne 0 ] ; then
|
|
echo2 "'$*' failed"
|
|
exit $ret
|
|
fi
|
|
}
|
|
|
|
_pkgbuilds_alt_hook() {
|
|
if [ -d "$ASSETSDIR/.$REPONAME/.git" ] ; then
|
|
_ASSERT_ pushd "$ASSETSDIR/.$REPONAME"
|
|
printf2 "git pull... "
|
|
_ASSERT_ git pull
|
|
else
|
|
_ASSERT_ pushd "$ASSETSDIR"
|
|
_ASSERT_ rmdir "$PKGBUILD_ROOTDIR"
|
|
_ASSERT_ rm -f "${PKGBUILD_ROOTDIR##*/}"
|
|
printf2 "git clone... "
|
|
_ASSERT_ git clone "$GITREPOURL" ".$REPONAME"
|
|
_ASSERT_ ln -s ".$REPONAME/${PKGBUILD_ROOTDIR##*/}"
|
|
fi
|
|
_ASSERT_ popd
|
|
echo2 "done."
|
|
}
|
|
|
|
PkgAdjusted() { printf2 "$pkg: planned adjustment. "; }
|
|
|
|
Fix_PKGBUILD_if_changed() {
|
|
local out=$(/bin/git diff) # used for detecting local changes in PKGBUILD files
|
|
local pkg
|
|
local changed_pkgs # list of package names that have a changed PKGBUILD
|
|
local left # number of changed packages that have no "fix" yet
|
|
|
|
changed_pkgs="$(echo "$out" | grep -E "^... b/.*/PKGBUILD$" | sed -E 's|^... b/(.*)/PKGBUILD$|\1|')" # which PKGBUILDs have changed
|
|
if [ "$changed_pkgs" ] ; then
|
|
left=$(echo "$changed_pkgs" | wc -l)
|
|
else
|
|
left=0
|
|
fi
|
|
|
|
case "$REPONAME" in
|
|
endeavouros-testing-dev)
|
|
for pkg in $changed_pkgs ; do
|
|
case "$pkg" in
|
|
calamares-git)
|
|
# Special handling for calamares-git in repo endavouros-testing-dev because its PKGBUILD has line:
|
|
# pkgver=.
|
|
((left--)) # this is a known thing, we fix it here
|
|
if [ "$(echo "$out" | grep "^-pkgver=\.$")" ] ; then # line 'pkgver=.' replaced?
|
|
sed -i calamares-git/PKGBUILD -e "s|^pkgver=.*$|pkgver=.|" # set it back to 'pkgver=.' before 'git pull'
|
|
PkgAdjusted
|
|
fi
|
|
;;
|
|
# add possible other 'endeavouros-testing-dev' package PKGBUILD management here
|
|
esac
|
|
done
|
|
;;
|
|
endeavouros)
|
|
for pkg in $changed_pkgs ; do
|
|
case "$pkg" in
|
|
eos-lightdm-gtk-theme) # the package was copied from ARM, just accept it here
|
|
((left--))
|
|
PkgAdjusted
|
|
;;
|
|
# add possible other 'endeavouros' package PKGBUILD management here
|
|
esac
|
|
done
|
|
;;
|
|
esac
|
|
|
|
if [ $left -gt 0 ] ; then
|
|
# show unknown changes and let user fix them
|
|
echo2 "local $REPONAME/$PKGBUILDS has differences with the repository, please fix it if possible"
|
|
/bin/meld .
|
|
WantToContinue
|
|
fi
|
|
}
|
|
|
|
WantToContinue() {
|
|
while true ; do
|
|
read -p "==> Want to continue (Y/n)? " >&2
|
|
case "$REPLY" in
|
|
"" | [Yy]*) break ;;
|
|
[Nn]*) DIE "user wanted to stop now" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
_pkgbuilds_eos_hook()
|
|
{
|
|
# A hook function to make sure local EndeavourOS PKGBUILDS are up to date.
|
|
|
|
local PKGBUILDS=PKGBUILDS
|
|
|
|
if [ -d "$ASSETSDIR/.$REPONAME/$PKGBUILDS/.git" ] ; then
|
|
_ASSERT_ pushd "$ASSETSDIR/.$REPONAME/$PKGBUILDS"
|
|
Fix_PKGBUILD_if_changed
|
|
printf2 "git pull... "
|
|
_ASSERT_ git pull
|
|
else
|
|
local GITPKGBUILDSURL=https://github.com/endeavouros-team/$PKGBUILDS.git
|
|
_ASSERT_ pushd "$ASSETSDIR"
|
|
if [ -d $PKGBUILDS ] && [ ! -L $PKGBUILDS ] ; then
|
|
rmdir $PKGBUILDS
|
|
fi
|
|
printf2 "git clone... "
|
|
_ASSERT_ git clone "$GITPKGBUILDSURL" ".$REPONAME/$PKGBUILDS"
|
|
_ASSERT_ ln -s ".$REPONAME/$PKGBUILDS"
|
|
fi
|
|
echo2 "done"
|
|
_ASSERT_ popd
|
|
}
|
|
|
|
RunPreHooks()
|
|
{
|
|
if [ "$repoup" = "1" ] ; then
|
|
return
|
|
fi
|
|
|
|
ShowIndented "Running asset hooks..."
|
|
|
|
case "$REPONAME" in
|
|
endeavouros | endeavouros-testing-dev)
|
|
_pkgbuilds_eos_hook ;;
|
|
*)
|
|
_pkgbuilds_alt_hook ;;
|
|
esac
|
|
}
|
|
|
|
GitUpdate_repo() {
|
|
[ "$PREFER_GIT_OVER_RELEASE" = "yes" ] || return
|
|
|
|
local -r app=/usr/bin/EosGitUpdate
|
|
local newrepodir="$GITDIR"
|
|
|
|
if [ -n "$built" ] || [ "$repoup" = "1" ] ; then
|
|
# if [ -e "$newrepodir/.GitUpdate" ] ; then
|
|
FinalStopBeforeSyncing "$REPONAME repo"
|
|
Pushd "$newrepodir"
|
|
$app "$ARCH: $*" "$ASSETSDIR" || DIE "$app failed!"
|
|
Popd
|
|
ManualCheckOfAssets addition repo
|
|
# fi
|
|
fi
|
|
}
|
|
|
|
RunPostHooks()
|
|
{
|
|
if [ "$repoup" = "1" ] ; then
|
|
return
|
|
fi
|
|
if [ -n "$ASSET_POST_HOOKS" ] ; then
|
|
ShowIndented "Running asset post hooks"
|
|
local xx
|
|
for xx in "${ASSET_POST_HOOKS[@]}" ; do
|
|
$xx
|
|
done
|
|
echo2 "done."
|
|
fi
|
|
}
|
|
|
|
Browser() {
|
|
local browser
|
|
for browser in firefox firefox-developer-edition exo-open kde-open xdg-open ; do
|
|
if [ -x /usr/bin/$browser ] ; then
|
|
/usr/bin/$browser "$@" &> /dev/null
|
|
return
|
|
fi
|
|
done
|
|
}
|
|
|
|
AskYesNo() {
|
|
local -n _answer="$1" # return the result with this variable
|
|
local prompt="$2" # the question without any tail like "(Y/n)? "
|
|
local -r default="$3" # "yes" or "no"
|
|
local ask_timeout="$4" # seconds; optional; default=30
|
|
|
|
case "$default" in
|
|
yes) prompt+=" (Y/n)? " ;;
|
|
no) prompt+=" (y/N)? " ;;
|
|
*) _answer=no; return ;; # usage error?
|
|
esac
|
|
[ "$ask_timeout" ] || ask_timeout=30
|
|
|
|
while true ; do
|
|
eos-color warning 2 # TODO: better "note" than "warning"
|
|
read2 -sn1 -p "$prompt" -t $ask_timeout
|
|
eos-color reset 2
|
|
if [ $? -eq 0 ] ; then
|
|
case "$REPLY" in
|
|
[yY]) _answer=yes; return ;;
|
|
[nN]|"") _answer=no; return ;;
|
|
*) ;; # wrong answer ==> ask again
|
|
esac
|
|
else
|
|
_answer=$default # timeout ==> return the default
|
|
return
|
|
fi
|
|
done
|
|
}
|
|
|
|
WantPkgDiffs() {
|
|
local xx="$1"
|
|
local pkgdirname="$2"
|
|
local changelog_for_pkg="" # "${PKG_CHANGELOGS[$pkgdirname]}"
|
|
|
|
Pushd "$ASSETSDIR"
|
|
changelog_for_pkg="$(eos-pkg-changelog --github --quiet -du "$pkgdirname")" || { Popd; return; }
|
|
Popd
|
|
|
|
if [ "$changelog_for_pkg" ] ; then
|
|
if [ "$pkgdiff" = "unknown" ] ; then
|
|
local -r ask_timeout=20
|
|
AskYesNo pkgdiff "Want to see changelog(s)" no $ask_timeout
|
|
echo2 "$pkgdiff"
|
|
fi
|
|
if [ "$pkgdiff" = "yes" ] ; then
|
|
local urls=()
|
|
readarray -t urls < <(echo "${changelog_for_pkg//|/$'\n'}")
|
|
PKG_DIFFS+=("${urls[@]}")
|
|
fi
|
|
fi
|
|
}
|
|
|
|
ShowPkgDiffs() {
|
|
if [ "$pkgdiff" = "yes" ] ; then
|
|
if [ ${#PKG_DIFFS[@]} -gt 0 ] ; then
|
|
Browser "${PKG_DIFFS[@]}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
Exit()
|
|
{
|
|
local code="$1"
|
|
Destructor
|
|
exit "$code"
|
|
}
|
|
|
|
_SleepSeconds() {
|
|
local sec="$1"
|
|
local xx
|
|
for ((xx=sec; xx>0; xx--)) ; do
|
|
printf2 "\r%s " "$xx"
|
|
sleep 1
|
|
done
|
|
printf2 "\r%s\n" "$xx"
|
|
}
|
|
|
|
MirrorCheck() {
|
|
if [ ! -r endeavouros.db ] ; then
|
|
return
|
|
fi
|
|
local checker="/usr/share/endeavouros/scripts/mirrorcheck"
|
|
local mirror_check="Alpix mirror check"
|
|
local timeout
|
|
local opt="--no-filelist"
|
|
|
|
test "$use_filelist" = "yes" && opt=""
|
|
|
|
if [ -n "$built" ] ; then
|
|
timeout="$mirror_check_wait"
|
|
else
|
|
timeout=3
|
|
fi
|
|
if [ -x "$checker" ] ; then
|
|
if [ $timeout -eq 180 ] ; then
|
|
read2 -p "Do $mirror_check (Y/n)?"
|
|
fi
|
|
case "$REPLY" in
|
|
""|[yY]*)
|
|
echo2 "Starting $mirror_check after countdown, please wait..."
|
|
_SleepSeconds $timeout
|
|
$checker $opt .
|
|
;;
|
|
esac
|
|
else
|
|
echo2 "Sorry, checker $checker not found."
|
|
echo2 "Cannot do $mirror_check."
|
|
fi
|
|
}
|
|
|
|
TimeStamp() {
|
|
local start_sec="$1"
|
|
|
|
case "$start_sec" in
|
|
"")
|
|
# return starting time
|
|
/usr/bin/date +%s
|
|
;;
|
|
[0-9]*)
|
|
# return elapsed time
|
|
/usr/bin/date -u --date=@$(($(TimeStamp) - start_sec)) '+%Hh %Mm %Ss'
|
|
;;
|
|
esac
|
|
}
|
|
|
|
Vercmp() {
|
|
# like vercmp, but "$notexist" is always older
|
|
|
|
if [ "$1" = "$notexist" ]; then
|
|
echo '-1'
|
|
elif [ "$2" = "$notexist" ]; then
|
|
echo '1'
|
|
else
|
|
vercmp "$1" "$2"
|
|
fi
|
|
}
|
|
|
|
PkgnameFilter() {
|
|
# remove trailing parts after the 'pkgname'
|
|
# sed 's|-[^-]*-[^-]*-[^-]*$||'
|
|
sed -E 's|-[^-]+-[^-]+-[^\.]+\.pkg\.tar\..*$||'
|
|
}
|
|
|
|
PkgnameFromPkg() {
|
|
local pkg="$1"
|
|
pkg=${pkg##*/}
|
|
# echo "$pkg" | PkgnameFilter
|
|
echo "$pkg" | pkg-name-components N
|
|
}
|
|
|
|
ListPkgsWithName() {
|
|
local Pkgname="$1"
|
|
local compr="$2"
|
|
local name
|
|
local tmp=""
|
|
local dir=${Pkgname%/*}
|
|
|
|
if [ "$Pkgname" = "$dir" ] ; then
|
|
dir="."
|
|
else
|
|
Pkgname=${Pkgname##*/}
|
|
fi
|
|
|
|
Pushd "$dir"
|
|
tmp=$(/bin/ls -1v "$Pkgname"-*.pkg.tar.$compr 2> /dev/null | grep -E "${Pkgname}-[^-]+-[^-]+-[^\.]+\.pkg\.tar\.$compr$")
|
|
Popd
|
|
[ "$tmp" ] || return
|
|
|
|
for name in $tmp ; do
|
|
if [ "$(echo "$name" | pkg-name-components N)" = "$Pkgname" ] ; then
|
|
echo "$dir/$name"
|
|
fi
|
|
done
|
|
}
|
|
|
|
Usage() {
|
|
cat <<EOF >&2
|
|
$PROGNAME: Build packages and transfer them to github.
|
|
|
|
$PROGNAME [ options ]
|
|
Options:
|
|
--allow-downgrade, -ad New package may have smaller version number.
|
|
--dryrun-local, -n Show what would be done, but do nothing. Use local assets.
|
|
--dryrun, -nn Show what would be done, but do nothing.
|
|
--explain-hook-marks, -e Explain markings on hooks.
|
|
--fetch-timeout=X | -T=X Timeout (in seconds) when asking to fetch remote assets (default: no timeout).
|
|
--pkgnames="X" X is a comma separated list of packages to use instead of PKGNAMES array in assets.conf.
|
|
--pkgdiff Show changelog for modified packages.
|
|
--repoup (Advanced) Force update of repository database files.
|
|
--no-aur Dont't try to use packages from the AUR (sometimes it is unavailable).
|
|
--aursrc=X From where we fetch AUR packages, one of: aur (default), repo, local.
|
|
EOF
|
|
# --versuffix=X Append given suffix (X) to pkgver of PKGBUILD.
|
|
# --mirrorcheck=X X is the time (in seconds) to wait before starting the mirrorcheck.
|
|
|
|
test -n "$1" && exit "$1"
|
|
}
|
|
|
|
IsInWaitList() {
|
|
local pkg="$1"
|
|
local newver="$2" # optional!
|
|
local xx
|
|
|
|
if [ -n "$PKGNAMES_WAIT" ] ; then
|
|
for xx in "${PKGNAMES_WAIT[@]}" ; do
|
|
case "$xx" in
|
|
"$pkg")
|
|
# old syntax - pkgname - still supported currently, may be deprecated later
|
|
return 0
|
|
;;
|
|
"$pkg|"*)
|
|
# New syntax: pkgname|version-to-skip[*]
|
|
# Note: skip_version may end with a '*' to match any tail, then e.g.
|
|
# skip_version: v14.1.r*
|
|
# newver: v14.1.r13.gc504674-1
|
|
# match.
|
|
[ -n "$newver" ] || newver="$(PkgBuildVersion "$PKGBUILD_ROOTDIR/$pkgdirname")"
|
|
local skip_version="${xx#*|}"
|
|
if [ "${skip_version: -1}" = "*" ] ; then
|
|
# skip_version ends with a '*'
|
|
case "$newver" in
|
|
"${skip_version:: -1}"*) return 0 ;;
|
|
esac
|
|
else
|
|
[ "$skip_version" = "$newver" ] && return 0
|
|
fi
|
|
return 1 # $pkg handled, no match
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
DowngradeProbibited() {
|
|
local cmpresult="$1"
|
|
local allow_downgrade="$2"
|
|
|
|
[ $cmpresult -lt 0 ] && [ "$allow_downgrade" = "no" ] && [ "${HAS_GIT_PKGVER[$pkgdirname]}" != "yes" ]
|
|
}
|
|
|
|
ShowResult() {
|
|
local -r verdict="$1"
|
|
local -r hookout="$2"
|
|
local -r fastfunc="$3"
|
|
|
|
if [ -n "$hookout" ] ; then
|
|
if [ "$fastfunc" ] ; then
|
|
echo2 "$verdict [$fastfunc: $hookout]"
|
|
else
|
|
echo2 "$verdict [hook: $hookout]"
|
|
fi
|
|
else
|
|
echo2 "$verdict"
|
|
fi
|
|
}
|
|
|
|
MovePackageAsLastToBuild() {
|
|
local -r pkgname="$1"
|
|
if [ "$(printf "%s\n" "${PKGNAMES[@]}" | grep "^$pkgname$")" ] ; then
|
|
local tmp=()
|
|
readarray -t tmp < <(printf "%s\n" "${PKGNAMES[@]}" | grep -v "^$pkgname$")
|
|
tmp+=("$pkgname")
|
|
PKGNAMES=("${tmp[@]}")
|
|
fi
|
|
}
|
|
|
|
assert_is_number_ge_0() {
|
|
[ "${1//[0-9]/}" ] && DIE "'$1' is not a non-negative number"
|
|
}
|
|
|
|
SetAurDelay() {
|
|
local val="$1"
|
|
case "$val" in
|
|
*h) aur_delay=${val:: -1} ; assert_is_number_ge_0 "$aur_delay" ; ((aur_delay*=3600)) ;;
|
|
*m) aur_delay=${val:: -1} ; assert_is_number_ge_0 "$aur_delay" ; ((aur_delay*=60)) ;;
|
|
*s) aur_delay=${val:: -1} ; assert_is_number_ge_0 "$aur_delay" ;;
|
|
*) aur_delay=${val} ; assert_is_number_ge_0 "$aur_delay" ;;
|
|
esac
|
|
}
|
|
|
|
Main2() {
|
|
test -n "$PKGEXT" && unset PKGEXT # don't use env vars!
|
|
|
|
local buildStartTime
|
|
local listing_updates=""
|
|
|
|
local mode=""
|
|
local xx yy zz
|
|
local repoup=0
|
|
local explain_hooks=no
|
|
local pkgver_suffix=""
|
|
local pkgdiff=unknown # yes=show AUR diff, no=don't show, unknown=need to ask for yes or no
|
|
local filelist_txt
|
|
local use_filelist # yes or no
|
|
local allow_downgrade=no
|
|
local PKG_DIFFS=()
|
|
local mirror_check_wait=180
|
|
local use_release_assets # currently only for [endeavouros] repo
|
|
local save_folder=""
|
|
local PKGNAMES_PARAMETER=""
|
|
local AUR_IS_AVAILABLE=yes # to be used also in assets.conf files
|
|
local aur_src=aur
|
|
local aur_delay=0
|
|
local fetch_timeout=""
|
|
local helper=""
|
|
local -r config_file="/etc/eos-script-lib-yad.conf"
|
|
|
|
source "$config_file"
|
|
|
|
while true ; do
|
|
if [ -z "$EOS_AUR_HELPER" ] ; then
|
|
WARN "EOS_AUR_HELPER is empty in $config_file"
|
|
else
|
|
helper="$EOS_AUR_HELPER"
|
|
[ -x "/bin/$helper" ] && break
|
|
fi
|
|
if [ -z "$EOS_AUR_HELPER_OTHER" ] ; then
|
|
WARN "EOS_AUR_HELPER_OTHER is empty in $config_file"
|
|
else
|
|
helper="$EOS_AUR_HELPER_OTHER"
|
|
[ -x "/bin/$helper" ] && break
|
|
fi
|
|
break
|
|
done
|
|
if [ "$helper" ] && [ ! -x "/bin/$helper" ] ; then
|
|
WARN "AUR helper not installed? Check EOS_AUR_HELPER and EOS_AUR_HELPER_OTHER in $config_file"
|
|
helper="yay"
|
|
fi
|
|
|
|
local -r hook_pkgver="#"
|
|
local -r hook_pkgver_func="p"
|
|
local -r hook_multiversion="+"
|
|
local -r hook_yes="*"
|
|
local -r hook_compare="c"
|
|
local hook_no="" # will contain strlen(hook_yes) spaces
|
|
for xx in $(seq 1 ${#hook_yes}) ; do
|
|
hook_no+=" "
|
|
done
|
|
|
|
DebugBreak
|
|
|
|
# Check given parameters:
|
|
if [ -n "$1" ] ; then
|
|
for xx in "$@" ; do
|
|
case "$xx" in
|
|
--no-aur) AUR_IS_AVAILABLE=no ;;
|
|
--aursrc=*) aur_src="${xx#*=}" ;; # * = aur (default), repo, local.
|
|
--aur-delay=*) SetAurDelay "${xx#*=}" ;; # * = <number>{s|m|h}
|
|
--dryrun-local | -nl | -n) mode=dryrun-local ;;
|
|
--dryrun | -nr | -nn) mode=dryrun ;;
|
|
--repoup) repoup=1 ;; # sync repo even when no packages are built
|
|
--pkgdiff) pkgdiff=yes ;;
|
|
-e | --explain-hook-marks) explain_hooks=yes ;;
|
|
--allow-downgrade | -ad) allow_downgrade=yes ;;
|
|
|
|
--pkgnames=*) PKGNAMES_PARAMETER="$xx" ;;
|
|
--fetch-timeout=* | -T=*) fetch_timeout="${xx#*=}" ;;
|
|
|
|
--dump-options) ;;
|
|
|
|
# currently not used!
|
|
--mirrorcheck=*) mirror_check_wait="${xx#*=}";;
|
|
--versuffix=*) pkgver_suffix="${xx#*=}" ;;
|
|
|
|
-h | --help | *) Usage 0 ;;
|
|
esac
|
|
done
|
|
fi
|
|
eos-connection-checker || DIE "internet connection is not available."
|
|
|
|
test -r $ASSETS_CONF || DIE "cannot find local file $ASSETS_CONF"
|
|
|
|
local PKGNAMES=()
|
|
local PKGNAMES_WAIT=()
|
|
local EOS_ROOT="" # configures the base folder for all EOS stuff
|
|
local _PACKAGER=""
|
|
local REPOSIG=0 # 1 = sign repo too, 0 = don't sign repo
|
|
local SKIP_UNACCEPTABLE_PKGBUILD=()
|
|
|
|
source /etc/$PROGNAME.conf # sets the base folder of everything
|
|
[ -n "$EOS_ROOT" ] || DIE "EOS_ROOT is not set in /etc/$PROGNAME.conf!"
|
|
[ -n "$_PACKAGER" ] || DIE "_PACKAGER is not set in /etc/$PROGNAME.conf!"
|
|
|
|
declare -A ASSET_FAST_UPDATE_CHECKS=()
|
|
|
|
if false && [ $AUR_IS_AVAILABLE = yes ] && grep -E "^[ ]+[^ ]+/aur$" $ASSETS_CONF >/dev/null ; then
|
|
echo2 -n "==> Checking AUR availability: "
|
|
if is-aur-available --seconds=$aur_delay ; then
|
|
echo2 success
|
|
else
|
|
AUR_IS_AVAILABLE=no
|
|
echo2 failure
|
|
fi
|
|
fi
|
|
source $ASSETS_CONF # local variables (with CAPITAL letters)
|
|
|
|
export PACKAGER="$_PACKAGER"
|
|
echo2 "PACKAGER: $PACKAGER"
|
|
|
|
# [ "$PKGNAMES_PARAMETER" ] && PKGNAMES=(${PKGNAMES_PARAMETER#*=})
|
|
if [ "$PKGNAMES_PARAMETER" ] ; then
|
|
PKGNAMES_PARAMETER="${PKGNAMES_PARAMETER#*=}" # remove leading --pkgnames=
|
|
PKGNAMES_PARAMETER="${PKGNAMES_PARAMETER//,/ }" # convert commas to spaces
|
|
PKGNAMES=($PKGNAMES_PARAMETER)
|
|
fi
|
|
|
|
filelist_txt="$ASSETSDIR/repofiles.txt"
|
|
use_filelist="$USE_GENERATED_FILELIST"
|
|
test -n "$use_filelist" || use_filelist="no"
|
|
use_release_assets="$USE_RELEASE_ASSETS"
|
|
test -n "$use_release_assets" || use_release_assets=yes
|
|
|
|
LogStuff
|
|
|
|
DebugBreak "before RationalityTests"
|
|
|
|
RationalityTests # check validity of values in $ASSETS_CONF
|
|
|
|
Constructor
|
|
|
|
# aur-fetch-pkg-info --fetch # get metainfo of AUR packages
|
|
|
|
RunPreHooks # may/should update local PKGBUILDs
|
|
Assets_clone # offer getting assets from github instead of using local ones
|
|
unset -f pkgver # remove possible leftover pkgver() from any PKGBUILD
|
|
|
|
# Check if we need to build new versions of packages.
|
|
# To do that, we compare local asset versions to PKGBUILD versions.
|
|
# Note that
|
|
# - Assets_clone above may have downloaded local assets from github (if user decides it is necessary)
|
|
# - RunPreHooks above may/should have updated local PKGBUILDs
|
|
|
|
local removable=() # collected
|
|
local removableassets=() # collected
|
|
local built=() # collected
|
|
local signed=() # collected
|
|
local repo_removes=()
|
|
declare -A newv oldv
|
|
local tmp tmpcurr
|
|
local pkg
|
|
local pkgdirname # dir name for a package
|
|
local Pkgname
|
|
local buildsavedir # tmp storage for built packages
|
|
local notexist='<non-existing>'
|
|
local cmpresult
|
|
local total_items_to_build=0
|
|
local items_waiting=0
|
|
local no_pkgbuild_count=0
|
|
local hookout=""
|
|
local -r WARNING="$(Color1 warning)WARNING$(Color1)"
|
|
local -r OK="$(Color1 ok)OK$(Color1)"
|
|
local -r WAITING="$(Color1 info)UPDATE WAIT$(Color1)"
|
|
local -r IN_WAIT_LIST="$(Color1 info)also in wait list$(Color1)"
|
|
local -r CHANGED="$(Color1 warning)CHANGED$(Color1)"
|
|
local ret=""
|
|
local fastmsg=""
|
|
local fastfunc=""
|
|
|
|
listing_updates=yes
|
|
|
|
DebugBreak "before check loop"
|
|
|
|
if [ "$repoup" = "0" ] ; then
|
|
|
|
echo2 "Finding package info ..."
|
|
|
|
Pushd "$PKGBUILD_ROOTDIR"
|
|
|
|
FetchAurPkgs
|
|
|
|
for xx in "${PKGNAMES[@]}" ; do
|
|
ShowIndented "$xx" 1 # show also the "/aur" suffix if available
|
|
hookout=""
|
|
ListNameToPkgName "$xx" yes || continue # sets pkgdirname and hookout
|
|
[ -n "$pkgdirname" ] || DIE "converting or fetching '$xx' failed"
|
|
PkgbuildExists "$pkgdirname" "line $LINENO" || continue
|
|
|
|
# get current versions from local asset files
|
|
Pkgname="$(PkgBuildName "$pkgdirname")"
|
|
tmpcurr="$(LocalVersion "$ASSETSDIR/$Pkgname")"
|
|
case "$tmpcurr" in
|
|
"") DIE "LocalVersion for '$xx' failed" ;;
|
|
"-" | 0)
|
|
# package (and version) not found
|
|
tmpcurr="$notexist"
|
|
;;
|
|
esac
|
|
|
|
fastfunc="${ASSET_FAST_UPDATE_CHECKS[$pkgdirname]}"
|
|
if [ "$fastfunc" ] ; then
|
|
fastmsg="$($fastfunc)"
|
|
ret=$?
|
|
case "$ret" in
|
|
0) ;; # there are changes, so carry on!
|
|
1) ShowResult "$OK ($tmpcurr)" "$fastmsg" "$fastfunc" ; continue ;;
|
|
2|3) ;;
|
|
*) echo2 "error: fast check hook returned $ret"; continue ;;
|
|
esac
|
|
fi
|
|
|
|
# get versions from latest PKGBUILDs
|
|
tmp="$(PkgBuildVersion "$PKGBUILD_ROOTDIR/$pkgdirname")"
|
|
test -n "$tmp" || DIE "PkgBuildVersion for '$xx' failed"
|
|
|
|
newv[$pkgdirname]="$tmp"
|
|
oldv[$pkgdirname]="$tmpcurr"
|
|
|
|
cmpresult=$(Vercmp "$tmp" "$tmpcurr")
|
|
|
|
if IsInWaitList "$xx" "$tmp" ; then
|
|
((items_waiting++))
|
|
if [ "$tmpcurr" = "$tmp" ] ; then
|
|
ShowResult "$OK ($tmpcurr) [$IN_WAIT_LIST]" "$hookout"
|
|
else
|
|
ShowResult "$WAITING ($tmpcurr ==> $tmp)" "$hookout"
|
|
fi
|
|
continue
|
|
fi
|
|
if [ $cmpresult -eq 0 ] ; then
|
|
ShowResult "$OK ($tmpcurr)" "$hookout"
|
|
continue
|
|
fi
|
|
if DowngradeProbibited "$cmpresult" "$allow_downgrade" ; then
|
|
ShowResult "$OK ($tmpcurr)" "$hookout"
|
|
continue
|
|
fi
|
|
|
|
DebugBreak "decided to build"
|
|
|
|
((total_items_to_build++))
|
|
ShowResult "$CHANGED ($tmpcurr ==> $tmp)" "$hookout"
|
|
|
|
[ $cmpresult -gt 0 ] && WantPkgDiffs "$xx" "$pkgdirname"
|
|
done
|
|
|
|
DebugBreak "before building"
|
|
|
|
[ "${#PKG_DIFFS[@]}" -gt 0 ] && ShowPkgDiffs
|
|
|
|
Popd
|
|
|
|
local exit_code=$total_items_to_build
|
|
local color
|
|
if [ $total_items_to_build -eq 0 ] ; then
|
|
total_items_to_build=NONE
|
|
color="${GREEN}"
|
|
else
|
|
color="${RED}"
|
|
fi
|
|
|
|
printf2 "\nItems to build for %s: %s%s/%s%s\n" "$(Color1 warning)$REPONAME$(Color1)" "$color" "$total_items_to_build" "${#PKGNAMES[@]}" "$(Color1)"
|
|
|
|
if [ "$items_waiting" != "0" ] ; then
|
|
printf2 "Items waiting: %s\n" "$items_waiting"
|
|
fi
|
|
if [ "$no_pkgbuild_count" != "0" ] ; then
|
|
printf2 "No PKGBUILD: %s\n" "$no_pkgbuild_count"
|
|
fi
|
|
|
|
if [ "$explain_hooks" = "yes" ] ; then
|
|
ExplainHookMarks
|
|
else
|
|
printf2 "\n"
|
|
fi
|
|
fi
|
|
|
|
case "$mode" in
|
|
dryrun | dryrun-local)
|
|
Exit $((exit_code + 100)) # return 100 + number of items that need building
|
|
;;
|
|
esac
|
|
|
|
listing_updates=no
|
|
|
|
if [ "$repoup" = "0" ] ; then
|
|
# build if newer versions exist. When building, collect removables and builds.
|
|
|
|
buildsavedir="$(mktemp -d "$HOME/.tmpdir.XXXXX")"
|
|
|
|
MovePackageAsLastToBuild calamares # if calamares will be built, make it the last to build
|
|
|
|
local built_under_this_pkgname
|
|
# local remove_under_this_pkgname
|
|
echo2 "Check if building is needed..."
|
|
for xx in "${PKGNAMES[@]}" ; do
|
|
ListNameToPkgName "$xx" no
|
|
PkgbuildExists "$xx" "line $LINENO ($xx)" || continue
|
|
|
|
cmpresult=$(Vercmp "${newv[$pkgdirname]}" "${oldv[$pkgdirname]}")
|
|
|
|
# See if we have to build.
|
|
[ "$cmpresult" -eq 0 ] && continue
|
|
|
|
if DowngradeProbibited "$cmpresult" "$allow_downgrade" ; then
|
|
continue
|
|
fi
|
|
if IsInWaitList "$xx" "${newv[$pkgdirname]}" ; then
|
|
echo2 "==> skipped: $xx"
|
|
continue
|
|
fi
|
|
|
|
# Build the package (or possibly many packages!)
|
|
built_under_this_pkgname=()
|
|
# remove_under_this_pkgname=() # we don't know only from pkgname!
|
|
|
|
echo2 "==> $pkgdirname:"
|
|
buildStartTime="$(TimeStamp)"
|
|
|
|
Build "$pkgdirname" "$buildsavedir" "$PKGBUILD_ROOTDIR/$pkgdirname"
|
|
|
|
echo2 " ==> Build time: $(TimeStamp $buildStartTime)"
|
|
for yy in "${built_under_this_pkgname[@]}" ; do
|
|
printf2 " ==> %15s %s\n" "$(FileSizePrint "$buildsavedir/$yy")" "$yy"
|
|
#echo2 " ==> $yy"
|
|
done
|
|
|
|
# determine old pkgs, may be many
|
|
for zz in zst xz ; do
|
|
for yy in "${built_under_this_pkgname[@]}" ; do
|
|
Pkgname="$(PkgnameFromPkg "$yy")"
|
|
# pkg="$(ls -1 "$ASSETSDIR/$Pkgname"-[0-9]*.pkg.tar.$zz 2> /dev/null)"
|
|
pkg=$(ListPkgsWithName "$Pkgname" "$zz")
|
|
if [ -n "$pkg" ] ; then
|
|
local xyz
|
|
for xyz in $pkg ; do
|
|
removable+=("$xyz")
|
|
removable+=("$xyz".sig)
|
|
|
|
yy=${xyz##*/}
|
|
removableassets+=("$yy")
|
|
#removableassets+=("$yy".sig)
|
|
done
|
|
fi
|
|
done
|
|
done
|
|
done
|
|
fi
|
|
|
|
if [ -n "$built" ] || [ "$repoup" = "1" ] ; then
|
|
|
|
# We have something built to be sent to github, or we want to update repo to github.
|
|
|
|
# now we have: removable (and removableassets), built and signed
|
|
|
|
if [ ! "$PWD" -ef "$ASSETSDIR" ] ; then
|
|
DIE "wrong directory: $PWD != $ASSETSDIR"
|
|
fi
|
|
|
|
# Move built and signed to assets dir...
|
|
if [ -n "$built" ] && [ "$repoup" = "0" ] ; then
|
|
echo2 "Signing and putting it all together..."
|
|
|
|
if [ -n "$built" ] ; then
|
|
# sign built packages
|
|
for pkg in "${built[@]}" ; do
|
|
gpg --local-user "$SIGNER" \
|
|
--output "$pkg.sig" \
|
|
--detach-sign "$pkg" || DIE "signing '$pkg' failed"
|
|
signed+=("$pkg.sig")
|
|
done
|
|
|
|
mv -i "${built[@]}" "${signed[@]}" "$ASSETSDIR"
|
|
|
|
rm -rf $buildsavedir
|
|
|
|
# ...and fix the variables 'built' and 'signed' accordingly.
|
|
tmp=("${built[@]}")
|
|
built=()
|
|
for xx in "${tmp[@]}" ; do
|
|
built+=("${xx##*/}")
|
|
done
|
|
tmp=("${signed[@]}")
|
|
signed=()
|
|
for xx in "${tmp[@]}" ; do
|
|
signed+=("${xx##*/}")
|
|
done
|
|
|
|
for xx in "${built[@]}" ; do
|
|
case "$xx" in
|
|
*.pkg.tar.$_COMPRESSOR)
|
|
#pkgname="$(basename "$xx" | sed 's|\-[0-9].*$||')"
|
|
Pkgname="$(PkgnameFromPkg "$xx")"
|
|
repo_removes+=("$Pkgname")
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ -n "$removable" ] ; then
|
|
# Here we have some old packages after upgrading them.
|
|
# Save them automatically into an archive at github.
|
|
# Then downgrading of EOS packages can be supported with app 'eos-downgrade'.
|
|
|
|
if [ -n "$ARCHIVE_TAG" ] ; then
|
|
local archiving=success
|
|
local pkg_archive="$ASSETSDIR/PKG_ARCHIVE"
|
|
|
|
# local archiving
|
|
|
|
mkdir -p "$pkg_archive" || archiving=fail1
|
|
if [ "$archiving" = "success" ] ; then
|
|
chmod -R u+w "$pkg_archive" || archiving=fail2
|
|
fi
|
|
if [ "$archiving" = "success" ] ; then
|
|
mv -f "${removable[@]}" "$pkg_archive" || archiving=fail3
|
|
fi
|
|
|
|
if [ "$archiving" = "success" ] ; then
|
|
|
|
# remove archiving
|
|
|
|
Pushd "$pkg_archive"
|
|
|
|
# (re)create proper symlink
|
|
if [ ! -e .git ] || [ -L .git ] ; then
|
|
if [ -d "$ARCHIVE_GIT" ] ; then
|
|
rm -f .git
|
|
ln -s "$ARCHIVE_GIT"
|
|
fi
|
|
fi
|
|
if [ -d .git ] ; then
|
|
case "$REPONAME" in
|
|
endeavouros | endeavouros-testing-dev) archive-sync-to-remote "$ARCHIVE_TAG" ;;
|
|
*) add-release-assets "$ARCHIVE_TAG" "${removable[@]##*/}" ;;
|
|
esac
|
|
else
|
|
WARN "the .git folder of the pkg archive was not found"
|
|
fi
|
|
|
|
Popd
|
|
else
|
|
WARN "($archiving) problem moving old packages to $pkg_archive"
|
|
fi
|
|
chmod -R -w "$pkg_archive" # do not (accidentally) delete archived packages...
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$repo_removes" ] ; then
|
|
# check if repo db contains any of the packages to be removed
|
|
# yy="$(tar --list --exclude */desc -f "$ASSETSDIR/$REPONAME".db.tar.$REPO_COMPRESSOR | sed 's|-[0-9].*$||')"
|
|
yy="$(tar --list -f "$ASSETSDIR/$REPONAME".db.tar.$REPO_COMPRESSOR | grep "/desc$" | sed 's|-[^-]*-[^-]*$||')"
|
|
zz=()
|
|
for xx in "${repo_removes[@]}" ; do
|
|
if [ -n "$(echo "$yy" | grep "^$xx$")" ] ; then
|
|
zz+=("$xx")
|
|
fi
|
|
done
|
|
if [ -n "$zz" ] ; then
|
|
# packages found in the repo db, so remove them
|
|
repo-remove "$ASSETSDIR/$REPONAME".db.tar.$REPO_COMPRESSOR "${zz[@]}"
|
|
sleep 1
|
|
fi
|
|
fi
|
|
|
|
# Put changed assets (built) to db.
|
|
repo-add --include-sigs "$ASSETSDIR/$REPONAME".db.tar.$REPO_COMPRESSOR "${built[@]}"
|
|
fi
|
|
fi
|
|
|
|
if [ $REPOSIG -eq 1 ] ; then
|
|
echo2 "Signing repo $REPONAME ..."
|
|
repo-add --sign --key "$SIGNER" "$ASSETSDIR/$REPONAME".db.tar.$REPO_COMPRESSOR >/dev/null
|
|
fi
|
|
for xx in db files ; do
|
|
rm -f "$ASSETSDIR/$REPONAME".$xx.tar.$REPO_COMPRESSOR.old{,.sig}
|
|
rm -f "$ASSETSDIR/$REPONAME".$xx
|
|
cp -a "$ASSETSDIR/$REPONAME".$xx.tar.$REPO_COMPRESSOR "$ASSETSDIR/$REPONAME".$xx
|
|
if [ $REPOSIG -eq 1 ] ; then
|
|
rm -f "$ASSETSDIR/$REPONAME".$xx.sig
|
|
cp -a "$ASSETSDIR/$REPONAME".$xx.tar.$REPO_COMPRESSOR.sig "$ASSETSDIR/$REPONAME".$xx.sig
|
|
fi
|
|
done
|
|
|
|
# Now all is ready for syncing with github.
|
|
|
|
GitUpdate_repo "${built[@]}"
|
|
|
|
sleep 3
|
|
|
|
if false ; then
|
|
case "$REPONAME" in
|
|
endeavouros)
|
|
case "$use_release_assets" in
|
|
yes) ManageGithubReleaseAssets ;;
|
|
*) ;; # ManageGithubNormalFiles ;;
|
|
esac
|
|
;;
|
|
*)
|
|
ManageGithubReleaseAssets
|
|
;;
|
|
esac
|
|
else
|
|
ManageGithubReleaseAssets
|
|
fi
|
|
else
|
|
echo2 "Nothing to do."
|
|
fi
|
|
|
|
Destructor
|
|
|
|
ShowOldCompressedPackages # should show nothing
|
|
|
|
#MirrorCheck
|
|
|
|
RunPostHooks
|
|
}
|
|
|
|
SettleDown() {
|
|
local arg
|
|
local ask=yes
|
|
local msg
|
|
|
|
for arg in "$@" ; do
|
|
case "$arg" in
|
|
--no-ask) ask=no ;;
|
|
-*) WARN "$FUNCNAME: unsupported parameter '$arg'." ;;
|
|
*) msg="$arg" ;;
|
|
esac
|
|
done
|
|
test -n "$msg" && echo2 "Info: $msg"
|
|
if [ "$ask" = "yes" ] ; then
|
|
read2 -p "Wait, let things settle down, then press ENTER to continue: " -t 10
|
|
fi
|
|
echo2 ""
|
|
}
|
|
|
|
AssetCmdShow() {
|
|
local xx
|
|
local line="$1" # cmd
|
|
shift
|
|
|
|
case "$1" in
|
|
-*) shift ;; # option --quietly for delete-release-assets
|
|
esac
|
|
|
|
line+=" for $1:" # tag
|
|
shift
|
|
|
|
echo2 "$line"
|
|
for xx in "$@" ; do
|
|
echo2 " $xx"
|
|
done
|
|
}
|
|
|
|
AssetCmd() {
|
|
local arg=""
|
|
case "$1" in
|
|
--no-ask) arg="$1" ; shift ;;
|
|
esac
|
|
|
|
# AssetCmdShow "$@"
|
|
"$@"
|
|
if [ $? -ne 0 ] ; then
|
|
DIE "command '$*' failed!"
|
|
fi
|
|
|
|
SettleDown $arg
|
|
}
|
|
AssetCmdLast() {
|
|
local arg=""
|
|
if [ "$tag" = "${RELEASE_TAGS[$last_tag]}" ] ; then
|
|
arg="--no-ask"
|
|
else
|
|
arg="--no-ask" # arg=""
|
|
fi
|
|
AssetCmd $arg "$@"
|
|
}
|
|
|
|
ManualCheckOfAssets() {
|
|
local op="$1"
|
|
local what="$2"
|
|
local timeout="$EOS_PKGBUILD_GITHUB_TIMEOUT"
|
|
|
|
[ -n "$timeout" ] || timeout=5 # was 10
|
|
|
|
case "$what" in
|
|
repo) [ "$use_release_assets" = "yes" ] || return ;;
|
|
esac
|
|
|
|
sleep 1
|
|
while true ; do
|
|
case "$what" in
|
|
assets) what="assets in $tag" ;;
|
|
esac
|
|
echo2 ""
|
|
read2 -t $timeout -p "$what: Is $op OK (Y/n)? "
|
|
case "$REPLY" in
|
|
[yY]* | "") break ;;
|
|
*) ;;
|
|
esac
|
|
done
|
|
#echo2 ""
|
|
}
|
|
|
|
FinalStopBeforeSyncing() {
|
|
local what="$1"
|
|
printf2 "\n%s\n" "Final stop before syncing '$what' with github!"
|
|
read2 -p "Continue (Y/n)? "
|
|
case "$REPLY" in
|
|
[yY]*|"") ;;
|
|
*) Exit 0 ;;
|
|
esac
|
|
}
|
|
|
|
ManageGithubReleaseAssets() {
|
|
case "$use_release_assets" in
|
|
no) return ;;
|
|
esac
|
|
|
|
echo2 "Syncing $REPONAME release assets with github:"
|
|
|
|
local last_tag=$((${#RELEASE_TAGS[@]} - 1))
|
|
local assets
|
|
|
|
# Github seems to have issues with some files:
|
|
# - too long paths when adding release assets to github ??
|
|
# - file orders --> cache issues ??
|
|
|
|
# Remove old assets (removable) from github and local folder.
|
|
|
|
for tag in "${RELEASE_TAGS[@]}" ; do
|
|
assets=()
|
|
|
|
# delete-release-assets does not need the whole file name, only unique start!
|
|
assets+=("$REPONAME".{db,files})
|
|
|
|
if [ -n "$removableassets" ] ; then
|
|
#AssetCmd delete-release-assets --quietly "$tag" "${removableassets[@]}"
|
|
assets+=("${removableassets[@]}")
|
|
|
|
if [ -r "$filelist_txt" ] ; then
|
|
#AssetCmd delete-release-assets --quietly "$tag" "$(basename "$filelist_txt")"
|
|
assets+=("${filelist_txt##*/}")
|
|
fi
|
|
fi
|
|
|
|
AssetCmd --no-ask delete-release-assets --quietly "$tag" "${assets[@]}"
|
|
|
|
if [ -r "$filelist_txt" ] ; then
|
|
echo2 "deleting file $filelist_txt ..."
|
|
rm -f "$filelist_txt"
|
|
fi
|
|
|
|
ManualCheckOfAssets deletion assets
|
|
|
|
# Now manage new assets.
|
|
|
|
assets=()
|
|
|
|
if [ "$use_filelist" = "yes" ] ; then
|
|
# create a list of package and db files that should be also on the mirror
|
|
Pushd "$ASSETSDIR"
|
|
pkg="$(ls -1 *.pkg.tar.* "$REPONAME".{db,files}{,.tar.$REPO_COMPRESSOR}{,.sig} 2>/dev/null)"
|
|
if [ -n "$filelist_txt" ] ; then
|
|
[ "$RELEASE_ASSETS_REMOTE_BASE" ] || DIE "RELEASE_ASSETS_REMOTE_BASE is not set in ${ASSETS_CONF}!"
|
|
echo "$pkg" | sed "s|^|$RELEASE_ASSETS_REMOTE_BASE/|" > "$filelist_txt"
|
|
fi
|
|
popd >/dev/null
|
|
fi
|
|
|
|
# transfer assets (built, signed and db) to github
|
|
if [ -n "$built" ] ; then
|
|
#AssetCmd add-release-assets "$tag" "${signed[@]}" "${built[@]}"
|
|
assets+=("${built[@]}")
|
|
if [ -r "$filelist_txt" ] ; then
|
|
#AssetCmd add-release-assets "$tag" "$filelist_txt"
|
|
assets+=("${filelist_txt##*/}")
|
|
fi
|
|
fi
|
|
|
|
assets+=(
|
|
"$REPONAME".{db,files}
|
|
"$REPONAME".{db,files}.tar.$REPO_COMPRESSOR
|
|
)
|
|
if [ $REPOSIG -eq 1 ] ; then
|
|
assets+=("$REPONAME".{db,files}.tar.$REPO_COMPRESSOR.sig)
|
|
assets+=("$REPONAME".{db,files}.sig)
|
|
fi
|
|
if [ -n "$built" ] ; then
|
|
assets+=("${signed[@]}")
|
|
fi
|
|
|
|
AssetCmdLast add-release-assets "$tag" "${assets[@]}"
|
|
|
|
if [ "$tag" = "${RELEASE_TAGS[$last_tag]}" ] ; then
|
|
sleep 1
|
|
break
|
|
fi
|
|
|
|
ManualCheckOfAssets addition assets
|
|
done
|
|
}
|
|
|
|
ManageGithubNormalFiles() {
|
|
return # no more needed !!?
|
|
|
|
case "$REPONAME" in
|
|
endeavouros) ;;
|
|
endeavouros-testing-dev) return ;; # TODO: remove 'return' when the repo exists!
|
|
*) return ;;
|
|
esac
|
|
|
|
local workdir="$HOME/EOS/repo"
|
|
local targetdir="$workdir/$REPONAME"
|
|
local cp_output
|
|
|
|
test -d "$workdir" || DIE "work folder $workdir does not exist."
|
|
test -d "$targetdir" || DIE "target folder $targetdir does not exist."
|
|
|
|
Pushd "$workdir"
|
|
cp_output="$(cp -uv "$ASSETSDIR"/*.{db,files,zst,xz,sig} "$targetdir")" # $asset_file_endings
|
|
Popd
|
|
|
|
if [ -n "$cp_output" ] ; then
|
|
echo2 "$cp_output"
|
|
printf2 "\nFiles were updated. Goto $workdir and transfer changes to github (with git commands).\n"
|
|
else
|
|
echo2 "Nothing more to do."
|
|
fi
|
|
}
|
|
|
|
AssetsConfLocalVal() {
|
|
# Search file assets.conf for values like:
|
|
# local REPONAME="repo-name"
|
|
|
|
local searchval="$1"
|
|
grep "^local ${searchval}=" $ASSETS_CONF | cut -d '=' -f 2 | tr -d '"' | tr -d "'"
|
|
}
|
|
|
|
Main() {
|
|
local PROGNAME="${0##*/}"
|
|
[ "$PROGNAME" ] || PROGNAME="${BASH_ARGV0##*/}"
|
|
[ "$PROGNAME" ] || PROGNAME="assets.make"
|
|
|
|
[[ "$*" =~ "--help" ]] && Usage 0
|
|
|
|
local -r ASSETS_CONF=assets.conf # This file must exist in the current folder when building packages.
|
|
local -r ARCH=x86_64
|
|
local -r _first_arg="$1"
|
|
local fail=0
|
|
|
|
if [[ "$*" =~ "--dump-options" ]] ; then
|
|
local all_options=(
|
|
--allow-downgrade
|
|
--dryrun-local
|
|
--dryrun
|
|
--explain-hook-marks
|
|
--fetch-timeout=
|
|
--pkgnames=
|
|
--pkgdiff
|
|
--repoup
|
|
--no-aur
|
|
--aursrc=
|
|
--aur-delay=
|
|
)
|
|
echo "${all_options[*]}"
|
|
exit 0
|
|
fi
|
|
|
|
case "$_first_arg" in
|
|
--dir=*) # user wants to change to the given folder
|
|
cd "${_first_arg#*=}" || DIE "'cd ${_first_arg#*=}' failed."
|
|
shift
|
|
;;
|
|
esac
|
|
|
|
[ -r $ASSETS_CONF ] || DIE "file '$PWD/$ASSETS_CONF' does not exist."
|
|
[ -L .git ] || DIE "$PWD/.git must be a symlink to the real .git!"
|
|
|
|
local _COMPRESSOR="$(grep "^PKGEXT=" /etc/makepkg.conf | tr -d "'" | sed 's|.*\.pkg\.tar\.||')"
|
|
local REPO_COMPRESSOR="$(AssetsConfLocalVal REPO_COMPRESSOR)"
|
|
|
|
test -n "$REPO_COMPRESSOR" || REPO_COMPRESSOR=xz
|
|
|
|
if [ -z "$(grep ^PKGEXT /etc/makepkg.conf | grep zst)" ] ; then
|
|
echo2 "/etc/makepkg.conf: please use 'zst' in variable PKGEXT"
|
|
fail=1
|
|
fi
|
|
if [ -z "$(grep ^COMPRESSZST /etc/makepkg.conf | grep T0)" ] ; then
|
|
echo2 "/etc/makepkg.conf: add -T0 -19 into variable COMPRESSZST"
|
|
fail=1
|
|
fi
|
|
test $fail -eq 1 && return
|
|
|
|
if false ; then
|
|
local _packager="$(AssetsConfLocalVal _PACKAGER)"
|
|
if [ -n "$_packager" ] ; then
|
|
export PACKAGER="$_packager"
|
|
else
|
|
export PACKAGER="EndeavourOS <info@endeavouros.com>"
|
|
fi
|
|
_packager=""
|
|
echo2 "PACKAGER: $PACKAGER"
|
|
fi
|
|
|
|
local -r PACKAGE_NAME=eos-pkgbuild-setup
|
|
[ -x /bin/expac ] && echo2 "VERSION: $(expac %v $PACKAGE_NAME)"
|
|
|
|
DebugBreak "before Main2"
|
|
|
|
Main2 "$@"
|
|
}
|
|
|
|
DebugBreak_not_used() {
|
|
local from_function="${FUNCNAME[1]}"
|
|
|
|
case "$from_function" in
|
|
source) from_function="[PROGRAM]" ;;
|
|
esac
|
|
|
|
case "$DEBUG_BREAK" in
|
|
5) echo "Function '$FUNCNAME' <--- line ${BASH_LINENO[0]} function $from_function" ;;
|
|
esac
|
|
: # this is the break line
|
|
}
|
|
|
|
DebugBreak() { : ; }
|
|
|
|
Main "$@"
|