#!/usr/bin/env bash # # --- T2-COPYRIGHT-NOTE-BEGIN --- # T2 SDE: scripts/Emerge-Pkg # Copyright (C) 2004 - 2024 The T2 SDE Project # Copyright (C) 2004 - 2006 Rene Rebe # # This Copyright note is generated by scripts/Create-CopyPatch, # more information can be found in the files COPYING and README. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2. # --- T2-COPYRIGHT-NOTE-END --- exec 2>&1 options= dloptions= config='default' deps='indirect2' debug=0 downloadonly=0 verbose=1 ignore_chksum=1 backup=1 dryrun=0 force=0 rebuild=1 repositories= system= depth=0 missing='only' optional='ask' deptree= esttime=0 # # ---- Functions # . scripts/functions.in help_msg() { spacer=" " echo echo "Usage: Emerge-Pkg [ -cfg ] [ -dry-run ] [ -force ] [ -nobackup ]" echo "$spacer [ -consider-chksum ] [ -norebuild ] [ -deps=none|fast|indirect ]" echo "$spacer [ -missing=yes|no|only ] [ -optional-deps=yes|no|ask ] [ -download ]" echo "$spacer [ -repository repository-name ] [ -system ] [ pkg-name(s) ]" echo echo "pkg-name(s) are only optional if a repository is specified." echo } # # ---- Parse options + config # if [ $# = 0 ]; then help_msg exit 1 fi while [ "$1" ]; do case "$1" in -cfg) options="$options $1 $2" config="$2"; shift ;; -deps=*) deps=${1/-deps=/} ;; -missing=*) missing=${1/-missing=/} ;; -optional-deps=*) optional=${1/-optional-deps=/} ;; -dry-run) dryrun=1 ;; -f|-force) force=1 ;; -debug) debug=1 ;; -nobackup) backup=0 ;; -consider-chksum) ignore_chksum=0 ;; -norebuild) rebuild=0 ;; -download|-download-only) downloadonly=1 ;; -repository) repositories="$repositories $2"; shift ;; -prefix) options="$options -prefix $2"; shift ;; -v) options="$options -v" ;; -noclearsrc) options="$options -noclearsrc" ;; -xtrace) options="$options -xtrace" ;; -system) system=1 deps=none ;; -*) help_msg; exit 1 ;; *) break ;; esac shift done case "$deps" in fast|indirect*|none) : ;; *) echo "Unknown dependency resolution mode. Valid are none, fast and indirect." exit 1 esac if [ ! -f config/$config/config -a $config = "default" ]; then scripts/Config -oldconfig fi . scripts/parse-config noautolist=" 00-dirtree $SDECFG_DEFAULT_CC $SDECFG_LIBC ${SDECFG_LIBC}32 " declare -A packages declare -A scanned declare -A deplist read_packages() { local sel pkg _ while read sel _ _ _ pkg _; do packages[$pkg]=$sel done < <(cat config/$config/packages) } add_if_req() { local pkg=$1 msg="$2" typ=$3 local buildtime=$(pkgbuildtime $pkg) [ "$verbose" = 1 ] && echo -n "$msg" # some more check for packages not manually specified if [ $depth != 0 ]; then # no auto update list if [ "$noautolist" != "${noautolist/ $pkg /}" ]; then [ $verbose = 1 ] && echo " Vital, skipped by default." return fi fi if [ $depth -gt 0 ]; then # optional dep, not yet installed? if [ "$typ" = '[OPT]' ]; then if [ "$optional" = ask ]; then echo -n " Add optional dep? (y/N$(fmt_time $buildtime)) " read in # force further updates? TODO: limit input validation [[ "$in" = *\* ]] && optional=$in else in="$optional" [[ "$in" = y* ]] && echo " Optional added. $(fmt_time $buildtime)" || echo " Optional, skipped." fi if [[ "$in" = y* ]]; then deplist[$pkg]=1 esttime=$((esttime + buildtime)) [ "$deps" = indirect ] && dep4pkg "$pkg" [ "$deps" = indirect2 -a $depth -le 2 ] && dep4pkg "$pkg" fi return fi # missing ones? yes, no, only TODO: maybe delete if [ ! -f /var/adm/packages/$pkg ]; then if [ "$missing" = 'no' ]; then [ $verbose = 1 ] && echo " Not missing, skipped." return fi elif [ "$missing" = 'only' ]; then [ $verbose = 1 ] && echo " Only missing selected, skipped." return fi fi [ $verbose = 1 ] && echo " Added.$(fmt_time $buildtime)" deplist[$pkg]=1 esttime=$((esttime + buildtime)) [ "$deps" = indirect ] && dep4pkg "$pkg" [ "$deps" = indirect2 -a $depth -le 2 ] && dep4pkg "$pkg" } add_if_updated() { local pkg=$1 local typ=$2 if [ "${scanned[$pkg]}" = 1 ]; then [ $debug = 1 ] && echo "already been at $pkg ..." return else scanned[$pkg]=1 fi # read in pkg list? [ ${#packages[@]} = 0 ] && read_packages [ $verbose = 1 ] && echo -n "$deptree$pkg:" confdir= for x in package/*/$pkg/$pkg.desc; do if [ -f "$x" ]; then if [ "$confdir" ]; then echo " Warning: Package in multiple trees! Skipped." return fi confdir=${x/$pkg.desc/} fi done if [ -z "$confdir" ]; then if [ $depth = 0 ]; then echo " Error: No such package." exit 1 else echo " Warning: No such package." return fi fi # TODO: keep unselected in the config, to avoid re-config for masked pkgs if [ -z "${packages[$pkg]}" ]; then if [ $depth = 0 ]; then local desc=$(echo package/*/$pkg/$pkg.desc) if [ -e "$desc" ]; then echo " Package not cached, re-reading config:" scripts/Config -oldconfig -cfg $config read_packages fi if [ -z "${packages[$pkg]}" ]; then echo " Error: No such package." exit 1 fi else echo " Warning: No such package." return fi fi if [ "${packages[$pkg]}" != X ]; then echo " Not selected." return fi if [ ! -f /var/adm/packages/$pkg ]; then if [ "$typ" = "[OPT]" ]; then add_if_req $pkg ' Not installed.' $typ else add_if_req $pkg ' Not installed.' fi return fi o_ver=$(grep -a '^Package Name and Version' \ /var/adm/packages/$pkg | cut -f6 -d' ') # we avoid parse_desc here, because it is ~50x slower n_ver=$(grep -a '^\[V\] ' $confdir/$pkg.desc \ architecture/$SDECFG_ARCH/package/$pkg/$pkg.desc \ target/$SDECFG_TARGET/package/$pkg/$pkg.desc \ 2> /dev/null | cut -f2 -d' ' | tail -n 1) if [ "$o_ver" != "$n_ver" -a "$n_ver" != "0000" ]; then add_if_req $pkg " New version ($o_ver -> $n_ver)." return fi o_ck=$(grep -a '^\(ROCK Linux\|T2\) Package Source Checksum' \ /var/adm/packages/$pkg | sed 's,.*: ,,') n_ck=$(pkgchksum package/*/$pkg) if [ $ignore_chksum = 0 -a "$o_ck" != "$n_ck" ]; then add_if_req $pkg " New source checksum." return fi if [ -f /var/adm/cache/$pkg ] && grep -a -q '\[BUILDTIME\] .* ERROR' \ /var/adm/cache/$pkg; then [ $verbose = 1 ] && echo -n " Former build was broken." if [ $rebuild = 1 ]; then add_if_req $pkg '' else [ $verbose = 1 ] && echo " Skipped." fi return fi if [ $force = 1 -a $depth = 0 ]; then add_if_req $pkg ' Build forced.' return fi if [ $debug = 1 ]; then echo " Installed and up-to-date." else echo -ne \ "\r \r" fi } dep4pkg() { ((depth++)) local _deptree="$deptree" deptree="$deptree$1|" local IFS=$'\n' for dep in `grep -a '\[\(DEP\|OPT\)\]' package/*/$1/$1.cache 2>/dev/null`; do add_if_updated ${dep#* } ${dep% *} done deptree="$_deptree" ((depth--)) } # the remaining arguments are packages to be built for pkg in $*; do # override previously unselected dependency scan [ "${deplist[$pkg]}" ] || scanned[$pkg]= add_if_updated $pkg done # packages from repositories for x in $repositories; do for pkg in `egrep -a "^X .* $x .*" config/$config/packages | cut -d ' ' -f 5`; do add_if_updated $pkg done done # all installed packages if a system update if [ "$system" ]; then depth=-1 for pkg in `cd /var/adm/packages/; ls *`; do add_if_updated $pkg done depth=0 fi # The deplist is unsorted: sort by priority and convert to string. # deplist=`echo -n "${!deplist[@]}" | tr '\n' ' ' | tr -s ' '` deplist=$(grep -a "^. .* .* .* \\(${deplist// /\\|}\\) " \ config/$config/packages | sort -k 3 | cut -d ' ' -f 5 | tr '\n' ' ') if [ "$deplist" ]; then echo "$(echo "$deplist" | wc -w) packages scheduled to build$(fmt_time $esttime): $deplist" | fold -s echo else echo "No package scheduled to build." fi [ $dryrun = 1 ] && exit [ $backup = 1 ] && options="$options -update" for pkg in $deplist; do if scripts/Download -cfg $config $dloptions $pkg; then if [ $downloadonly != 1 ] && ! scripts/Build-Pkg $options $pkg; then if [ $SDECFG_CONTINUE_ON_ERROR_AFTER -gt 8 ]; then echo "Aborting further builds due to config setting CONTINUE_ON_ERROR_AFTER." exit 1 fi fi else echo "The download for package $pkg failed!" #exit 1 fi [ "${dloptions/-quiet-mirror/}" = "$dloptions" ] && var_append dloptions " " "-quiet-mirror" done