* updated maddy (0.7.1 -> 0.8.1), untested
[t2sde.git] / scripts / Emerge-Pkg
blobf573b07c4075f9e30b5561fcd2a3a86708dc7ad0
1 #!/usr/bin/env bash
3 # --- T2-COPYRIGHT-BEGIN ---
4 # t2/scripts/Emerge-Pkg
5 # Copyright (C) 2004 - 2025 The T2 SDE Project
6 # Copyright (C) 2004 - 2006 Rene Rebe <rene@exactcode.de>
7 # SPDX-License-Identifier: GPL-2.0
8 # --- T2-COPYRIGHT-END ---
10 exec 2>&1
12 options=
13 dloptions=
14 config='default'
15 deps='indirect2'
16 debug=0
17 downloadonly=0
18 verbose=1
19 ignore_chksum=1
20 backup=1
21 dryrun=0
22 force=0
23 rebuild=1
24 repositories=
25 system=
26 depth=0
27 missing='only'
28 optional='ask'
30 deptree=
31 esttime=0
34 # ---- Functions
37 . scripts/functions.in
39 help_msg() {
40 local spacer=" "
41 echo
42 echo "Usage: Emerge-Pkg [ -cfg <config> ] [ -dry-run ] [ -force ] [ -nobackup ]"
43 echo "$spacer [ -consider-chksum ] [ -norebuild ] [ -deps=none|fast|indirect ]"
44 echo "$spacer [ -missing=yes|no|only ] [ -optional-deps=yes|no|ask ] [ -download ]"
45 echo "$spacer [ -repository repository-name ] [ -system ] [ pkg-name(s) ]"
46 echo
47 echo "pkg-name(s) are only optional if a repository is specified."
48 echo
52 # ---- Parse options + config
55 if [ $# = 0 ]; then
56 help_msg
57 exit 1
60 while [ "$1" ]; do
61 case "$1" in
62 -cfg) options="$options $1 $2" config="$2"; shift ;;
63 -deps=*) deps=${1/-deps=/} ;;
64 -missing=*) missing=${1/-missing=/} ;;
65 -optional-deps=*) optional=${1/-optional-deps=/} ;;
66 -dry-run) dryrun=1 ;;
67 -f|-force) force=1 ;;
68 -debug) debug=1 ;;
69 -nobackup) backup=0 ;;
70 -consider-chksum) ignore_chksum=0 ;;
71 -norebuild) rebuild=0 ;;
72 -download|-download-only) downloadonly=1 ;;
73 -repository) repositories="$repositories $2"; shift ;;
74 -prefix) options="$options -prefix $2"; shift ;;
75 -v) options="$options -v" ;;
76 -noclearsrc) options="$options -noclearsrc" ;;
77 -xtrace) options="$options -xtrace" ;;
78 -system) system=1 deps=none ;;
79 -*) help_msg; exit 1 ;;
80 */\*) repositories="$repositories ${1%/*}" ;;
81 *) break ;;
82 esac
83 shift
84 done
86 case "$deps" in
87 fast|indirect*|none) : ;;
89 echo "Unknown dependency resolution mode. Valid are none, fast and indirect."
90 exit 1
91 esac
93 if [ ! -f config/$config/config -a $config = "default" ]; then
94 scripts/Config -oldconfig
97 . scripts/parse-config
99 noautolist=" 00-dirtree $SDECFG_DEFAULT_CC $SDECFG_LIBC ${SDECFG_LIBC}32 "
100 declare -A packages
101 declare -A alternatives
102 declare -A scanned
103 declare -A deplist
105 read_packages() {
106 local sel pkg _
107 while read sel _ _ _ pkg _; do
108 packages[$pkg]=$sel
109 done < <(cat config/$config/packages)
112 read_alternatives() {
113 local pkg alt
114 while read pkg alt; do
115 alternatives[$pkg]=$alt
116 done < <(cat misc/share/PKG-ALTERNATIVES )
119 add_if_req() {
120 local pkg=$1 msg="$2" typ=$3
121 local buildtime=$(pkgbuildtime $pkg)
123 [ "$verbose" = 1 ] && echo -n "$msg"
125 # some more check for packages not manually specified
126 if [ $depth != 0 ]; then
127 # no auto update list
128 if [ "$noautolist" != "${noautolist/ $pkg /}" ]; then
129 [ $verbose = 1 ] && echo " Vital, skipped by default."
130 return
134 if [ $depth -gt 0 ]; then
135 # optional dep, not yet installed?
136 if [ "$typ" = '[OPT]' ]; then
137 if [ "$optional" = ask ]; then
138 echo -n " Add optional dep? (y/N$(fmt_time $buildtime)) "
139 read in
140 # force further updates? TODO: limit input validation
141 [[ "$in" = *\* ]] && optional=$in
142 else
143 in="$optional"
144 [[ "$in" = y* ]] &&
145 echo " Optional added. $(fmt_time $buildtime)" ||
146 echo " Optional, skipped."
149 if [[ "$in" = y* ]]; then
150 deplist[$pkg]=1
151 esttime=$((esttime + buildtime))
152 [ "$deps" = indirect ] && dep4pkg "$pkg"
153 [ "$deps" = indirect2 -a $depth -le 3 ] && dep4pkg "$pkg"
155 return
158 # missing ones? yes, no, only TODO: maybe delete
159 if [ ! -f /var/adm/packages/$pkg ] ||
160 grep -a -q '\[BUILDTIME\] .* ERROR' /var/adm/cache/$pkg 2>/dev/null; then
161 if [ "$missing" = 'no' ]; then
162 [ $verbose = 1 ] && echo " Not missing, skipped."
163 return
165 elif [ "$missing" = 'only' ]; then
166 [ $verbose = 1 ] && echo " Only missing selected, skipped."
167 return
171 [ $verbose = 1 ] && echo " Added.$(fmt_time $buildtime)"
172 deplist[$pkg]=1
173 esttime=$((esttime + buildtime))
174 [ "$deps" = indirect ] && dep4pkg "$pkg"
175 [ "$deps" = indirect2 -a $depth -le 3 ] && dep4pkg "$pkg"
178 similar() {
179 ls -d package/*/*${1,,}/ 2>/dev/null | cut -d '/' -f3
182 add_if_updated() {
183 local pkg=$1
184 local typ=$2
186 if [ "${scanned[$pkg]}" = 1 ]; then
187 [ $debug = 1 ] && echo "already been at $pkg ..."
188 return
189 else
190 scanned[$pkg]=1
193 # read in pkg list?
194 [ ${#packages[@]} = 0 ] && read_packages && read_alternatives
196 [ $verbose = 1 ] && echo -n "$deptree$pkg:"
197 confdir=
198 for x in package/*/$pkg/$pkg.desc; do
199 if [ -f "$x" ]; then
200 if [ "$confdir" ]; then
201 echo " Warning: Package in multiple trees! Skipped."
202 return
204 confdir=${x/$pkg.desc/}
206 done
207 if [ -z "$confdir" ]; then
208 if [ $depth = 0 ]; then
209 local close=$(similar $pkg)
210 if [ "$close" ]; then
211 echo " Error: No such package. Did you mean \"${close%%
212 *}\"?"
213 else
214 echo " Error: No such package."
216 exit 1
217 else
218 echo " Warning: No such package."
219 return
223 # TODO: keep unselected in the config, to avoid re-config for masked pkgs
224 if [ -z "${packages[$pkg]}" ]; then
225 if [ $depth = 0 ]; then
226 local desc=$(echo package/*/$pkg/$pkg.desc)
227 if [ -e "$desc" ]; then
228 echo " Package not cached, re-reading config:"
229 scripts/Config -oldconfig -cfg $config
230 read_packages
233 if [ -z "${packages[$pkg]}" ]; then
234 echo " Error: No such package."
235 exit 1
237 else
238 echo " Warning: No such package."
239 return
243 # switch to alternative pkg if selected
244 local alt="${alternatives[$pkg]}"
246 if [ "$alt" ] && [ "${packages[$alt]}" = X ]; then
247 echo -n " (alt: $alt) "
248 pkg=$alt
249 confdir=package/*/$pkg
250 elif [ "${packages[$pkg]}" != X ]; then
251 echo " Not selected."
252 return
255 if [ ! -f /var/adm/packages/$pkg ]; then
256 if [ "$typ" = "[OPT]" ]; then
257 add_if_req $pkg ' Not installed.' $typ
258 else
259 add_if_req $pkg ' Not installed.'
261 return
264 o_ver=$(grep -a '^Package Name and Version' \
265 /var/adm/packages/$pkg | cut -f6 -d' ')
266 # we avoid parse_desc here, because it is ~50x slower
267 n_ver=$(grep -a '^\[V\] ' $confdir/$pkg.desc \
268 architecture/$SDECFG_ARCH/package/$pkg/$pkg.desc \
269 target/$SDECFG_TARGET/package/$pkg/$pkg.desc \
270 2> /dev/null | cut -f2 -d' ' | tail -n 1)
271 if [ "$o_ver" != "$n_ver" -a "$n_ver" != "0000" ]; then
272 add_if_req $pkg " New version ($o_ver -> $n_ver)."
273 return
276 o_ck=$(grep -a '^\(ROCK Linux\|T2\) Package Source Checksum' \
277 /var/adm/packages/$pkg | sed 's,.*: ,,')
278 n_ck=$(pkgchksum package/*/$pkg)
279 if [ $ignore_chksum = 0 -a "$o_ck" != "$n_ck" ]; then
280 add_if_req $pkg " New source checksum."
281 return
284 if [ -f /var/adm/cache/$pkg ] &&
285 grep -a -q '\[BUILDTIME\] .* ERROR' /var/adm/cache/$pkg; then
286 [ $verbose = 1 ] && echo -n " Former build was broken."
287 if [ $rebuild = 1 ]; then
288 add_if_req $pkg ''
289 else
290 [ $verbose = 1 ] && echo " Skipped."
292 return
295 if [ $force = 1 -a $depth = 0 ]; then
296 add_if_req $pkg ' Build forced.'
297 return
300 if [ $debug = 1 ]; then
301 echo " Installed and up-to-date."
302 else
303 echo -ne \
304 "\r \r"
308 dep4pkg() {
309 ((depth++))
310 local _deptree="$deptree"
311 deptree="$deptree$1|"
313 local IFS=$'\n'
314 for dep in `grep -a '\[\(DEP\|OPT\)\]' package/*/$1/$1.cache 2>/dev/null`; do
315 add_if_updated ${dep#* } ${dep% *}
316 done
318 deptree="$_deptree"
319 ((depth--))
322 # the remaining arguments are packages to be built
323 for pkg in $*; do
324 # override previously unselected dependency scan
325 [ "${deplist[$pkg]}" ] || scanned[$pkg]=
326 add_if_updated $pkg
327 done
329 # packages from repositories
330 for x in $repositories; do
331 for pkg in `egrep -a "^X .* $x .*" config/$config/packages |
332 cut -d ' ' -f 5`; do
333 add_if_updated $pkg
334 done
335 done
337 # all installed packages if a system update
338 if [ "$system" ]; then
339 depth=-1
340 for pkg in `cd /var/adm/packages/; ls *`; do
341 add_if_updated $pkg
342 done
343 depth=0
346 # The deplist is unsorted: sort by priority and convert to string.
348 deplist=`echo -n "${!deplist[@]}" | tr '\n' ' ' | tr -s ' '`
349 deplist=$(grep -a "^. .* .* .* \\(${deplist// /\\|}\\) " \
350 config/$config/packages | sort -k 3 | cut -d ' ' -f 5 | tr '\n' ' ')
352 if [ "$deplist" ]; then
353 echo "$(echo "$deplist" |
354 wc -w) packages scheduled to build$(fmt_time $esttime): $deplist" | fold -s
355 echo
356 else
357 echo "No package scheduled to build."
360 [ $dryrun = 1 ] && exit
361 [ $backup = 1 ] && options="$options -update"
364 pkgs=$(echo "$deplist" | wc -w)
365 for pkg in $deplist; do
366 if scripts/Download -cfg $config $dloptions $pkg; then
367 if [ $downloadonly != 1 ] &&
368 ! scripts/Build-Pkg $options -progress $((++i))/$pkgs $pkg; then
369 if [ $SDECFG_CONTINUE_ON_ERROR_AFTER -gt 8 ]; then
370 echo "Aborting further builds due to config setting CONTINUE_ON_ERROR_AFTER."
371 exit 1
374 else
375 echo "The download for package $pkg failed!"
376 #exit 1
379 [ "${dloptions/-quiet-mirror/}" = "$dloptions" ] &&
380 var_append dloptions " " "-quiet-mirror"
381 done