pkgmeek: added fix for unintuitive bash handling of 'set -e' in subshells

This commit is contained in:
John McQuah 2022-06-15 13:24:04 -04:00
parent e2bd920f7c
commit 7e03c42638
2 changed files with 58 additions and 48 deletions

View File

@ -30,7 +30,7 @@ fi
# #
[ "$PKGMK_UPDATE_SIG" = "yes" ] || validate_pkgfile || exit $E_PKGFILE [ "$PKGMK_UPDATE_SIG" = "yes" ] || validate_pkgfile || exit $E_PKGFILE
[ -f .32bit ] && PGKMK_ARCH=32 || PKGMK_ARCH=64 [ -f .32bit ] && PGKMK_ARCH=32 || PKGMK_ARCH=64
. "Pkgfile"; . "$PKGMK_CONF"; set -e . "Pkgfile"; . "$PKGMK_CONF"
# respect the settings for centralized source and package directories ... # respect the settings for centralized source and package directories ...
[ -v pkg_dir ] || pkg_dir="$PKGMK_PACKAGE_DIR"/ [ -v pkg_dir ] || pkg_dir="$PKGMK_PACKAGE_DIR"/
@ -154,9 +154,12 @@ if [ "$pkg_utd" = 0 ] || [ "$PKGMK_FORCE" = "yes" ]; then
# The actual build step! (use fakeroot when building daemon ports as an ordinary user, # The actual build step! (use fakeroot when building daemon ports as an ordinary user,
# otherwise the owner and group might not be correct) # otherwise the owner and group might not be correct)
(SRC=$(pwd)/src; PKG=$(pwd)/pkg; cd src; set -x; build) && (SRC=$(pwd)/src; PKG=$(pwd)/pkg; cd src; set -e -x; build)
info "Build succeeded. Moving on to compression." || if [ $? = 0 ]; then
{ error "Unsuccessful build!"; cleanup_work; exit "$E_BUILD"; } echo "Build successful. Moving on to compression."
else
error "Unsuccessful build!"; cleanup_work; exit "$E_BUILD"
fi
[ -f "$PKGMK_ROOT/.nostrip" ] && ns_filter="| grep -v -f $PKGMK_ROOT/.nostrip" [ -f "$PKGMK_ROOT/.nostrip" ] && ns_filter="| grep -v -f $PKGMK_ROOT/.nostrip"
find pkg -type f $ns_filter | while read -r f; do find pkg -type f $ns_filter | while read -r f; do
@ -183,7 +186,7 @@ if [ "$pkg_utd" = 0 ] || [ "$PKGMK_FORCE" = "yes" ]; then
# Ensure that $work/ contains the package or a symlink to it, then check the footprint # Ensure that $work/ contains the package or a symlink to it, then check the footprint
[ "$pkg_dir" = "$(pwd)/" ] || ln -sf "$pkg_dir$package" . [ "$pkg_dir" = "$(pwd)/" ] || ln -sf "$pkg_dir$package" .
[ "$PKGMK_IGNORE_FOOTPRINT" = "yes" ] || check_manifest footprint || exit $E_MANIFEST [ "$PKGMK_IGNORE_FOOTPRINT" = "yes" ] || check_manifest footprint
# Clean up the work directory # Clean up the work directory
find . -maxdepth 1 -mindepth 1 -type l -delete; cleanup_work find . -maxdepth 1 -mindepth 1 -type l -delete; cleanup_work
@ -429,9 +432,9 @@ cat_manifest() {
check_manifest() { check_manifest() {
local FILTER CN CM local FILTER CN CM
local TRUTH="$PKGMK_ROOT/.$1"; local retval=0; local severity=error; local TRUTH="$PKGMK_ROOT/.$1"; local diffs=0; local severity=error;
[ -f "$pkg_dir$package" ] || [ "$1" = "md5sum" ] || \ [ -f "$pkg_dir$package" ] || [ "$1" = "md5sum" ] || \
{ error "$package not found. Cannot check $1."; return "$E_MANIFEST"; } { error "$package not found. Cannot check $1."; exit "$E_MANIFEST"; }
[ "$1" = "md5sum" ] && FILTER="-k 3" || FILTER="" [ "$1" = "md5sum" ] && FILTER="-k 3" || FILTER=""
if [ -f "$TRUTH" ]; then if [ -f "$TRUTH" ]; then
@ -440,12 +443,9 @@ check_manifest() {
if [ -s ".$1.diff" ]; then if [ -s ".$1.diff" ]; then
CN=$(grep -c ^NEW ".$1.diff"); CM=$(grep -c ^MISSING ".$1.diff") CN=$(grep -c ^NEW ".$1.diff"); CM=$(grep -c ^MISSING ".$1.diff")
if [ "$1" = "footprint" ]; then if [ "$1" = "footprint" ]; then
[ "$PKGMK_IGNORE_MISSING" = "yes" ] || retval=$CM [ "$PKGMK_IGNORE_MISSING" = "yes" ] || diffs=$CM
[ "$PKGMK_IGNORE_NEW" = "yes" ] || retval+=$CN [ "$PKGMK_IGNORE_NEW" = "yes" ] || diffs=$(( diffs+CN ))
[ $retval -gt 0 ] || severity=warning [ $diffs = 0 ] && severity=warning
retval=$(( E_MANIFEST*( retval>0 ) ))
else
retval=$E_MANIFEST
fi fi
$severity "$1 mismatch found:"; cat ".$1.diff" >&2 $severity "$1 mismatch found:"; cat ".$1.diff" >&2
fi fi
@ -453,7 +453,7 @@ check_manifest() {
else else
warning ".$1 not found, creating new."; cat_manifest $1 > "$TRUTH" warning ".$1 not found, creating new."; cat_manifest $1 > "$TRUTH"
fi fi
return $retval [ $diffs = 0 ] || exit $E_MANIFEST
} }
parse_signify_output() { # chomps the output of check_signature() parse_signify_output() { # chomps the output of check_signature()

View File

@ -22,6 +22,7 @@ my %odepends = ( tree => 0, recursive => 0, all => 0 );
my %opkg = ( margs => "", aargs => "", rargs => "", runscripts => "yes", my %opkg = ( margs => "", aargs => "", rargs => "", runscripts => "yes",
makecommand => "/usr/bin/pkgmk", addcommand => "/usr/bin/pkgadd", makecommand => "/usr/bin/pkgmk", addcommand => "/usr/bin/pkgadd",
removecommand => "/usr/bin/pkgrm", test => "no" ); removecommand => "/usr/bin/pkgrm", test => "no" );
my %olog = ( write => "disabled", mode => "overwrite", rm_on_success => "yes");
my $prtconf = "/etc/prt-get.conf"; my @bldirs = parse_prt_conf($prtconf); my $prtconf = "/etc/prt-get.conf"; my @bldirs = parse_prt_conf($prtconf);
my @basedirs = @{$bldirs[0]}; my @localports = @{$bldirs[1]}; my @basedirs = @{$bldirs[0]}; my @localports = @{$bldirs[1]};
@ -91,8 +92,8 @@ if (($action =~ /^(listinst|listorphans)/)
foreach my $result (@results) { foreach my $result (@results) {
chomp $result; next if ($result =~ /^\s*$/); chomp $result; next if ($result =~ /^\s*$/);
$result =~ s/.*\/(.*)$/$1/ if (($action ne "path") and ($osearch{path}==0)); $result =~ s/.*\/(.*)$/$1/ if (($action ne "path") and ($osearch{path}==0));
$result .= " $V_REPO{$result}" if $osearch{verbose}==1; $result .= " $V_REPO{$result}" if (($osearch{verbose}==1) and ($action ne "path"));
$result .= " $V_REPO{$result}\n$DESC{$result}\n" if $osearch{verbose}>1; $result .= " $V_REPO{$result}\n$DESC{$result}\n" if (($osearch{verbose}>1) and ($action ne "path"));
printf $strf, $result; printf $strf, $result;
} }
} elsif ($action =~ /^(fsearch)/) { } elsif ($action =~ /^(fsearch)/) {
@ -212,11 +213,6 @@ sub parse_args {
($action =~ /^(search|dsearch|fsearch|info|readme|path|ls)$/)) { ($action =~ /^(search|dsearch|fsearch|info|readme|path|ls)$/)) {
print "$1 requires an argument.\n"; exit 1; print "$1 requires an argument.\n"; exit 1;
} }
if (($action =~ /^(search|dsearch|fsearch|info|readme|path|ls)$/) and ($osearch{regex}==0)) {
$query[0] =~ s/\+/\\\+/g; # plus signs in the pattern must be escaped,
$query[0] =~ s/\./\\\./g; # since the user did not request 'regex'.
$query[0] =~ s/\//\\\//g; # same goes for slash and period.
}
if (($#query != 0) and if (($#query != 0) and
($action =~ /^(deptree|dependent)$/)) { ($action =~ /^(deptree|dependent)$/)) {
print "$1 requires exactly one argument.\n"; exit 1; print "$1 requires exactly one argument.\n"; exit 1;
@ -249,10 +245,15 @@ sub parse_prt_conf {
} }
} }
} }
$opkg{runscripts} = $1 if /^runscripts\s+(yes|no)\s+#/; $opkg{runscripts} = $1 if /^runscripts\s+(yes|no)/;
$opkg{makecommand} = $1 if /^makecommand\s+(.*)#/; $opkg{makecommand} = $1 if /^makecommand\s+(.*)#/;
$opkg{addcommand} = $1 if /^addcommand\s+(.*)#/; $opkg{addcommand} = $1 if /^addcommand\s+(.*)#/;
$opkg{removecommand} =$1 if /^removecommand\s+(.*)#/; $opkg{removecommand} = $1 if /^removecommand\s+(.*)#/;
$olog{write} = $1 if /^writelog\s+(enabled|disabled)/;
$olog{mode} = $1 if /^logmode\s+(append|overwrite)/;
$olog{rm_on_success} = $1 if /^rmlog_on_success\s+(no|yes)/;
$olog{file} = $1 if /^logfile\s+(.*)#/;
$prtcache = $1 if /^cachefile\s+(.*)#/;
} }
close(PORTS); close(PORTS);
return \@basedirs, \@localports; return \@basedirs, \@localports;
@ -433,6 +434,8 @@ sub find_port_by_desc {
sub find_port_by_name { sub find_port_by_name {
my $query = shift; my $exact=shift; my $fullpath=shift; my $exhaustive=shift; my $query = shift; my $exact=shift; my $fullpath=shift; my $exhaustive=shift;
$query =~ s/\+/\\\+/g unless (($action =~ /^(search|dsearch)$/) and ($osearch{regex}==1));
$query =~ s/\./\\\./g unless (($action =~ /^(search|dsearch)$/) and ($osearch{regex}==1));
my $pattern = ($exact==1) ? qr/^$query$/s : qr/$query/is; my $pattern = ($exact==1) ? qr/^$query$/s : qr/$query/is;
my %names_only = map { ($_ => (split /\//, $_)[-1]) } @allports; my %names_only = map { ($_ => (split /\//, $_)[-1]) } @allports;
my @hits = grep { $names_only{$_} =~ $pattern } @allports; my @hits = grep { $names_only{$_} =~ $pattern } @allports;
@ -640,6 +643,7 @@ sub deporder {
sub up_inst { # returns scalar references to five arrays; sub up_inst { # returns scalar references to five arrays;
my $type=shift; my @requested=@_; my %EXEMPT; my %WANTED; my $type=shift; my @requested=@_; my %EXEMPT; my %WANTED;
my $logfile; my $logdir; my %pdirs;
my $PKGMK=$opkg{makecommand}; my $PKGADD=$opkg{addcommand}; my $PKGMK=$opkg{makecommand}; my $PKGADD=$opkg{addcommand};
my $SUDO="/usr/bin/doas"; my $FAKEROOT="/usr/bin/fakeroot"; my $SUDO="/usr/bin/doas"; my $FAKEROOT="/usr/bin/fakeroot";
@ -662,17 +666,26 @@ sub up_inst { # returns scalar references to five arrays;
@targets = grep {(! defined $EXEMPT{$_}) or ($WANTED{$_})} @targets; @targets = grep {(! defined $EXEMPT{$_}) or ($WANTED{$_})} @targets;
} }
# first determine the directories from which pkgmk must be called # first determine the directories from which pkgmk must be called,
# and the package that will appear after a successful build # the package that will appear after a successful build,
my %pdirs; my %builtpkg; my %mkcmd; my %addcmd; my %status; # and where to save the build log.
my %builtpkg; my %mkcmd; my %addcmd; my %status; my %logfile; my %logfh; my %pvars;
my ($COMPRESSION, $PKG_DIR) = parse_pkgmk_conf();
foreach my $t (@targets) { foreach my $t (@targets) {
$opkg{$t} = $opkg{margs}; $opkg{$t} = $opkg{margs}; $pvars{'%n'}=$t;
$opkg{$t} =~ s/-f// unless ($WANTED{$t}); $opkg{$t} =~ s/-f// unless ($WANTED{$t});
$pdirs{$t} = find_port_by_name($t,1,1,0); $pvars{'%p'} = find_port_by_name($t,1,1,0); $pdirs{$t} = $pvars{'%p'};
$builtpkg{$t} = find_built_pkg($t); ($pvars{'%v'}, $pvars{'%r'}) = (get_pkgfile_fields($pvars{'%p'}))[0,1];
$builtpkg{$t} = ($PKG_DIR) ? "$PKG_DIR/$t#$pvars{'%v'}-$pvars{'%r'}.pkg.tar.$COMPRESSION" : "$pvars{'%p'}/$t#$pvars{'%v'}-$pvars{'%r'}.pkg.tar.$COMPRESSION";
$builtpkg{$t} =~ s/\$name/$t/g; $builtpkg{$t} =~ s/\$\{name\}/$t/g;
$mkcmd{$t} = "$PKGMK -d $opkg{$t}"; $mkcmd{$t} = "$PKGMK -d $opkg{$t}";
$addcmd{$t} = "$PKGADD -u $builtpkg{$t}"; $addcmd{$t} = "$PKGADD -u $builtpkg{$t}";
$status{$t} = "not done"; $status{$t} = "not done";
if ($olog{write} eq "enabled") {
$logfile{$t} = ($olog{file}) ? $olog{file} : "/var/log/pkgmk/%n.log";
$logfile{$t} =~ s/(%n|%v|%r|%p)/$pvars{$1}/g;
$mkcmd{$t} .= ($olog{mode} eq "append") ? " >>$logfile{$t} 2>&1" : " >$logfile{$t} 2>&1";
}
} }
# build each package, unless already installed or satisfied by an alias # build each package, unless already installed or satisfied by an alias
@ -692,13 +705,20 @@ sub up_inst { # returns scalar references to five arrays;
$status{$t} .= ( $?>>8 == 0 ) ? "pre-install ok. " : "pre-install failed. "; $status{$t} .= ( $?>>8 == 0 ) ? "pre-install ok. " : "pre-install failed. ";
} }
($opkg{test} eq "no") ? chdir $pdirs{$t} : print "cd $pdirs{$t}\n"; ($opkg{test} eq "no") ? chdir $pdirs{$t} : print "cd $pdirs{$t}\n";
print "target $t ... waiting for the log to be written\n" if (($opkg{test} eq "no") and ($logfile{$t}));
($opkg{test} eq "no") ? system("$mkcmd{$t}") : print "$mkcmd{$t}\n"; ($opkg{test} eq "no") ? system("$mkcmd{$t}") : print "$mkcmd{$t}\n";
$status{$t} .= ( $?>>8 == 0 ) ? "build ok. " : "build failed. "; $status{$t} .= ( $?>>8 == 0 ) ? "build ok. " : "build failed. ";
if (($logfile{$t}) and (-r $logfile{$t}) and (-M $logfile{$t} < 0)) {
open (my $tailf, "$logfile{$t}");
while (<$tailf>) { print $_; }
close ($tailf); print "\n";
}
$status{$t} = ( $mkcmd{$t} =~ /skipped/ ) ? "build skipped. " : $status{$t}; $status{$t} = ( $mkcmd{$t} =~ /skipped/ ) ? "build skipped. " : $status{$t};
if ($status{$t} =~ /build ok/) { if ($status{$t} =~ /build ok/) {
$addcmd{$t} =~ s/ -u / / if (port_diff("utd",$t)<0); $addcmd{$t} =~ s/ -u / / if (port_diff("utd",$t)<0);
($opkg{test} eq "no") ? system("$addcmd{$t}") : print "$addcmd{$t}\n"; ($opkg{test} eq "no") ? system("$addcmd{$t}") : print "$addcmd{$t}\n";
$status{$t} .= ( $?>>8 == 0 ) ? "pkgadd ok. " : "pkgadd failed. "; $status{$t} .= ( $?>>8 == 0 ) ? "pkgadd ok. " : "pkgadd failed. ";
unlink($logfile{$t}) if ((-f $logfile{$t}) and ($olog{rm_on_success} eq "yes"));
} }
if (($status{$t} =~ /pkgadd ok/) and (-f "$pdirs{$t}/post-install") if (($status{$t} =~ /pkgadd ok/) and (-f "$pdirs{$t}/post-install")
and ($opkg{runscripts} eq "yes")) { and ($opkg{runscripts} eq "yes")) {
@ -726,10 +746,8 @@ sub sysup {
return up_inst("sysup",@targets); return up_inst("sysup",@targets);
} }
sub find_built_pkg { sub parse_pkgmk_conf {
my $target = shift; my $CONF="/etc/pkgmk.conf"; my $CONF="/etc/pkgmk.conf"; my $COMPRESSION; my $PKG_DIR="";
my $COMPRESSION; my $PKG_DIR; my $portpath = (find_port_by_name($target,1,1,0));
my ($version, $release) = (get_pkgfile_fields($portpath))[0,1];
open (CF,$CONF) or return; open (CF,$CONF) or return;
while (<CF>) { while (<CF>) {
@ -740,16 +758,10 @@ sub find_built_pkg {
if ($COMPRESSION) { if ($COMPRESSION) {
$COMPRESSION =~ s/#(.*)$//; # remove same-line comments like this one $COMPRESSION =~ s/#(.*)$//; # remove same-line comments like this one
$COMPRESSION =~ s/"//g; # remove double-quotes (thanks jaeger!) $COMPRESSION =~ s/"//g; # remove double-quotes (thanks jaeger!)
$COMPRESSION =~ s/'//g; # and single-quotes? who writes conf files like that?
} else { $COMPRESSION = "gz"; } } else { $COMPRESSION = "gz"; }
if ($PKG_DIR) { $PKG_DIR =~ s/"//g;
$PKG_DIR =~ s/"//g; $PKG_DIR =~ s/'//g; return $COMPRESSION, $PKG_DIR;
$PKG_DIR =~ s/\$\{name\}/$target/g;
$PKG_DIR =~ s/\$name/$target/g;
} else { $PKG_DIR = $portpath; }
return "$PKG_DIR/$target#$version-$release.pkg.tar.$COMPRESSION";
} }
sub port_ls { sub port_ls {
@ -809,26 +821,24 @@ DIFFERENCES / DEPENDENCIES
INSTALL, UPDATE and REMOVAL INSTALL, UPDATE and REMOVAL
install [opt] <port1 port2...> install ports and their dependencies install [opt] <port1 port2...> install ports and their dependencies
update [opt] <port1 port2...> update ports and their dependencies update [opt] <port1 port2...> update ports and their dependencies
grpinst [opt] <port1 port2...> install these ports, do not resolve dependencies
remove [opt] <port1 port2...> remove ports remove [opt] <port1 port2...> remove ports
lock <port1 port2...> lock each <port> at its current version
unlock <port1 port2...> release the lock on each <port>
sysup update all outdated ports, except those that are locked
GENERAL INFORMATION GENERAL INFORMATION
list ports in the active repositories list ports in the active repositories
listinst ports currently installed listinst ports currently installed
listlocked ports that are locked at their current version
listorphans installed ports that no other port claims as a hard dependency listorphans installed ports that no other port claims as a hard dependency
dup ports that appear more than once in the active collections dup ports that appear more than once in the active collections
info <port> version, description, dependencies of <port> info <port> version, description, dependencies of <port>
path <port> location from which pkgmk would be called to build <port> path <port> location from which pkgmk would be called to build <port>
ls <port> the files in the <port> directory
cat <port> <file> the contents of <port>/<file> on STDOUT cat <port> <file> the contents of <port>/<file> on STDOUT
isinst <port> whether port is installed isinst <port> whether port is installed
current <port> installed version of port current <port> installed version of port
SYSTEM UPDATE
sysup update all outdated ports, except those that are locked
lock <port1 port2...> lock each <port> at its current version
unlock <port1 port2...> release the lock on each <port>
listlocked list locked ports
COMMON OPTIONS COMMON OPTIONS
-v show version in listing -v show version in listing
-vv show version and decription in listing -vv show version and decription in listing