From c81645af30145752a7e10df3c9e22182ff9e1f67 Mon Sep 17 00:00:00 2001 From: John McQuah Date: Wed, 21 Jun 2023 04:59:50 -0400 Subject: [PATCH] pkg-repgen: change some function signatures pkg-get: account for dups within a single repository --- scripts/pkg-get.pl | 184 ++++++++++++++++++++++++------------------ scripts/pkg-repgen.pl | 32 ++++---- 2 files changed, 125 insertions(+), 91 deletions(-) diff --git a/scripts/pkg-get.pl b/scripts/pkg-get.pl index bdcc9fe..8dfddfc 100755 --- a/scripts/pkg-get.pl +++ b/scripts/pkg-get.pl @@ -67,12 +67,10 @@ get_locked() unless ($command =~ SWITCH: { if ($command eq "version") { version(); last SWITCH; } if ($command eq "sync") { sync(); last SWITCH; } - if ($command eq "info") { info(); last SWITCH; } + if ($command =~ /^(info|path|readme)$/) { info($1); last SWITCH; } if ($command eq "help") { help(); last SWITCH; } - if ($command eq "readme") { readme(); last SWITCH; } if ($command =~ /^(d|)search$/) { search(); last SWITCH; } if ($command eq "list") { list(); last SWITCH; } - if ($command eq "path") { path(); last SWITCH; } if ($command eq "remove") { remove(); last SWITCH; } if ($command eq "listinst") { listinst(); last SWITCH; } if ($command eq "lock") { dolock(); last SWITCH; } @@ -84,7 +82,6 @@ SWITCH: { if ($command eq "dup") { dup(); last SWITCH; } if ($command =~ /^(depends|quickdep)$/) { depends(); last SWITCH; } if ($command =~ /^(install|update)$/) { upinst(@ARGV); last SWITCH; } - if ($command eq "sysup") { sysup(); last SWITCH; } if ($command eq "dependent") { dependent(); last SWITCH; } if ($command eq "depinst") { depinst(); last SWITCH; } } @@ -160,14 +157,13 @@ sub get_locked { # Parse a line describing a package sub parsepackage { my @p = split(/\:/, $_[0]); - if ($#p != 6) {exiterr("$_[1]/PKGREPO appears to be in wrong format!\nAborting.")}; - my %pkg; - my ($name, $verrel) = ($p[0] =~ m/(.*)\#(.*)\.pkg\.tar\.[gbx]z.*/) ? - ($1,$2) : ("unnamed","1-1"); - $pkg{'name'} = $name; - ($pkg{'version'}, $pkg{'release'}) = ($verrel, $verrel); - $pkg{'version'} =~ s/-\w*//; + if ($#p < 6) {exiterr("$_[1]/PKGREPO appears to be in wrong format!\nAborting.")}; + my %pkg = ( 'name' => $p[0], 'version' => $p[0], 'release' => $p[0] ); + $pkg{'name'} =~ s/\#.*//; + $pkg{'version'} =~ s/.*\#//; + $pkg{'version'} =~ s/-\w*\.pkg\.tar.*//; $pkg{'release'} =~ s/^.*-//; + $pkg{'release'} =~ s/\.pkg\.tar.*//; if (not $_[2]) {$_[2] = $_[1]}; $pkg{'path'} = $_[1]; $pkg{'url'} = $_[2]; @@ -179,17 +175,13 @@ sub parsepackage { $pkg{'pre_install'} = $p[4]; $pkg{'post_install'} = $p[5]; $pkg{'readme'} = $p[6]; - if ($_[3] == 1) { - getinstalled() if (! %installed); - $pkg{'instversion'} = $installed{$name}; - } return %pkg; } # Parse a line describing a package (just the name) sub parsepackagelight { my @p = split(/\:/, $_[0]); - if ($#p != 6) {exiterr("$_[1]/PKGREPO appears to be in wrong format!\nAborting.")}; + if ($#p < 6) {exiterr("$_[1]/PKGREPO appears to be in wrong format!\nAborting.")}; my %pkg; $pkg{'name'} = $1 if ($p[0] =~ m/^(.*)\#/); return %pkg; @@ -240,17 +232,15 @@ sub printreadme { open(READ, "$pkg{'path'}/PKGREAD") or exiterr("could not open $pkg{'path'}/PKGREAD"); while () { - if ($finished == 1) {return;}; chomp; if (($found == 1) and ( /PKGREADME\:/ )) { $finished = 1; - close(READ); - return; } elsif ($found == 1) { print "$_\n"; - } elsif ( /PKGREADME: $pkg{'name'}$/ ) { + } elsif ( /PKGREADME\: $pkg{'name'}$/ ) { $found = 1; } + last if ($finished == 1); } close(READ); } @@ -324,7 +314,7 @@ sub formattedprint { $fmt =~ s|%R|$pkg{'readme'}|; $fmt =~ s|%E|$pkg{'pre_install'}|; $fmt =~ s|%O|$pkg{'post_install'}|; - $fmt =~ s|%M|Nobody|; # for prt-get compatibility + $fmt =~ s|%M|None|; # for prt-get compatibility $fmt =~ s|%P|None|; # for prt-get compatibility $fmt =~ s|\\n|\n|; $fmt =~ s|\\t|\t|; @@ -337,11 +327,11 @@ sub formattedprint { $fmt =~ s|%l|$locked|; } if (index($fmt,"%i") >=0) { - my $inst = ($pkg{'instversion'}) ? "yes" : "no"; - if ( ($inst eq "yes") and ($pkg{'instversion'} - ne $pkg{'version'}."-".$pkg{'release'}) ) { - $inst = "diff"; - } + (%installed) or getinstalled(); + my $inst = ($installed{$pkg{'name'}}) ? "yes" : "no"; + ($inst eq "no") or + ($installed{$pkg{'name'}} eq "$pkg{'version'}-$pkg{'release'}") + or $inst = "diff"; $fmt =~ s|%i|$inst|; } print "$fmt"; @@ -349,20 +339,34 @@ sub formattedprint { # Get package from the repo(s) sub getpackage { - my ($pkgname, $checkver) = @_; - my %found; my %res; + my $pkgname = $_[0]; + my $found; my @maybe; my %repver; my %res; foreach my $repo(@repos) { my ($dir, $url) = split(/\|/, $repo); open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); while () { chomp; - my %pkg = parsepackage($_, $dir, $url, $checkver); - if ($pkg{'name'} eq $pkgname) { - close (REPO); - return %pkg; - } + my %pkg = parsepackage($_, $dir, $url); + next if ($pkg{'name'} ne $pkgname); + $found = 1; + push @maybe, join("^", $pkg{'path'}, $pkg{'url'}, + $pkg{'version'}, $pkg{'release'}, $pkg{'description'}, + $pkg{'md5sum'}, $pkg{'size'}, + $pkg{'pre_install'}, $pkg{'post_install'}, $pkg{'readme'}); + ( ($repver{$pkgname}) and + ($repver{$pkgname} gt "$pkg{'version'}-$pkg{'release'}") ) + or $repver{$pkgname} = "$pkg{'version'}-$pkg{'release'}"; } close (REPO); + while (my $match = shift @maybe) { + my ($p,$u,$v,$r,$d,$m,$s,$E,$O,$R) = split /\^/, $match; + next if ("$v-$r" lt $repver{$pkgname}); + %res = ('name' => $pkgname, 'path' => $p, + 'url' => $u, 'version' => $v, 'release' => $r, + 'description' => $d, 'md5sum' => $m, 'size' => $s, + 'pre_install' => $E, 'post_install' => $O, 'readme' => $R); + } + last if ($found); } return %res; } @@ -370,9 +374,9 @@ sub getpackage { # Get short status for package, e.g. [i] sub getshortstatus { my %pkg = @_; - return "[ ]" if (! $pkg{'instversion'}); - return "[i]" if ($pkg{'instversion'} eq $pkg{'version'}."-".$pkg{'release'}); - return "[u]"; + ($installed{$pkg{'name'}}) or return "[ ]"; + ($installed{$pkg{'name'}} =~ /^$pkg{'version'}-$pkg{'release'}/) or return "[u]"; + return "[i]"; } # Get (recursive) dependencies for pkgname @@ -383,7 +387,7 @@ sub getdependencies { # no need to continue if there's already a value for this key return if ($deps{$pkgname}); - my %pkg = getpackage($pkgname, 1); + my %pkg = getpackage($pkgname); if (%pkg) { my $ddeps = getdirectdeps($pkg{'name'}, $pkg{'path'}); my @d = split(/,/, $ddeps); @@ -530,7 +534,7 @@ sub info { open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); while () { chomp; - my %pkg = parsepackage($_, $dir, $url, 0); + my %pkg = parsepackage($_, $dir, $url); if ($pkg{'name'} eq $arg) { ($type ne "info") or printinfo(%pkg); ($type ne "readme") or printreadme(%pkg); @@ -553,10 +557,10 @@ sub search { open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); while () { chomp; - my %pkg = parsepackage($_, $dir, $url, 0); + my %pkg = parsepackage($_, $dir, $url); next if ($found{$pkg{'name'}}); (index($pkg{'name'}, $arg) < 0) or $found{$pkg{'name'}} = 1; - ($found{$pkg{'name'}}==1) or ($type ne "desc") + ($found{$pkg{'name'}}==1) or ($type ne "desc") or (index($pkg{'description'}, $arg) < 0) or $found{$pkg{'name'}} = 1; } @@ -575,7 +579,7 @@ sub list { open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); while () { chomp; - my %pkg = parsepackage($_, $dir, $url, 0); + my %pkg = parsepackage($_, $dir, $url); $found{$pkg{'name'}} = 1; } close(REPO); @@ -673,63 +677,88 @@ sub listlocked { # Print formatted info ##################################################### sub doprintf { - my %found; + my %repver; my %found; foreach my $repo(@repos) { + my @toprint=(); my ($dir, $url) = split(/\|/, $repo); open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); while () { chomp; - my %pkg = (index($ARGV[1], "%i") >=0 ) ? - parsepackage($_, $dir, $url, 1) : - parsepackage($_, $dir, $url, 0) ; - if (($filter) and not $found{$pkg{'name'}}) { - my $match = $pkg{'name'}; - my $refilter = $filter; - $refilter =~ s/\*/\.\*/; - if ($match =~ /^$refilter$/) { - formattedprint(%pkg); - $found{$pkg{'name'}} = 1; - } - } elsif (not $found{$pkg{'name'}}) { - formattedprint(%pkg); - $found{$pkg{'name'}} = 1; + my %pkg = parsepackage($_, $dir, $url); + next if ($found{$pkg{'name'}}); + (! $filter) or $filter =~ s/\*/\.\*/; + if (($filter) and ($pkg{'name'} !~ /^$filter$/)) { + $found{$pkg{'name'}} = 1; next; } + + push @toprint, join("^", $pkg{'name'}, $pkg{'path'}, $pkg{'url'}, + $pkg{'version'}, $pkg{'release'}, $pkg{'description'}, + $pkg{'md5sum'}, $pkg{'size'}, + $pkg{'pre_install'}, $pkg{'post_install'}, $pkg{'readme'}); + + ( ($repver{$pkg{'name'}}) and + ($repver{$pkg{'name'}} gt "$pkg{'version'}-$pkg{'release'}") ) + or $repver{$pkg{'name'}} = "$pkg{'version'}-$pkg{'release'}"; + } + close(REPO); + + while (my $tpp = shift @toprint) { + my ($n,$p,$u,$v,$r,$d,$m,$s,$E,$O,$R) = split /\^/, $tpp; + my %printpkg = ('name' => $n, 'path' => $p, + 'url' => $u, 'version' => $v, 'release' => $r, + 'description' => $d, 'md5sum' => $m, 'size' => $s, + 'pre_install' => $E, 'post_install' => $O, 'readme' => $R); + next if ("$v-$r" lt $repver{$n}); + formattedprint(%printpkg); + $found{$n} = 1; } - close(REPO); } } # Show or resolve differences between installed and available packages ##### sub diff { my $format = shift; my %found; my @diff; + my $strf= ($format =~ /^quick/) ? "%s " : "%-19s %-19s %-19s\n"; + (%installed) or getinstalled(); foreach my $repo(@repos) { my ($dir, $url) = split(/\|/, $repo); open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); + my @multip=(); while () { chomp; - my %pkg = parsepackage($_, $dir, $url, 1); - next if (($found{$pkg{'name'}}) or (! $pkg{'instversion'})); - $found{$pkg{'name'}} = 1; - if ($pkg{'instversion'} ne $pkg{'version'}."-".$pkg{'release'}) { - next if (($locked{$pkg{'name'}}) and (! $all)); - if (($#diff < 0) and ($format !~ /^(quick|sysup)/)) { - print "Differences between installed packages and packages repo:\n\n"; - printf("%-19s %-19s %-19s\n\n","Package","Installed","Available in the repositories"); - } - my $lastcol = ($locked{$pkg{'name'}}) ? "locked" : $pkg{'version'}."-".$pkg{'release'}; - push @diff, $pkg{'name'}; - print "$pkg{'name'} " if ($format =~ /^quick/); - printf("%-19s %-19s %-19s\n", $pkg{'name'}, $pkg{'instversion'}, $lastcol) if ($format !~ /^(quick|sysup)/); - } + my %pkg = parsepackage($_, $dir, $url); + next if ( ($found{$pkg{'name'}}) or (! $installed{$pkg{'name'}}) ); + next if ( ($locked{$pkg{'name'}}) and (! $all) ); + my $lastcol = ($locked{$pkg{'name'}}) ? "locked" : ""; + ($lastcol eq "locked") or $lastcol = ($installed{$pkg{'name'}} + eq $pkg{'version'}."-".$pkg{'release'}) ? "uptodate" : + $pkg{'version'}."-".$pkg{'release'}; + push @multip, "$pkg{'name'}^$installed{$pkg{'name'}}^$lastcol"; } close(REPO); + while (my $mp = shift @multip) { + my ($mpname, $vinst, $mpinfo) = split /\^/, $mp; + next if ( (@multip) and ($multip[0] =~ m/^\Q$mpname\E\^/) ); + + $found{$mpname} = 1; + next if ($mpinfo eq "uptodate"); + ($format !~ /^(quick|sysup)/) or push @diff, $mpname; + ($format =~ /^(quick|sysup)/) or push @diff, join("^", + $mpname, $vinst, $mpinfo); + } } - print "\n" if (($format =~ /^quick/) and ($#diff >= 0)); - print "No differences found\n" if ($#diff < 0); + ($#diff < 0) or ($format =~ /^(quick|sysup)/) or + printf $strf, "Package","Installed", "Available in the repositories"; + if ($format ne "sysup") { + print "\n"; + foreach my $dl (@diff) { printf $strf, split /\^/, $dl; } + } + ($format !~ /^quick/) or ($#diff < 0) or print "\n"; + ($#diff >= 0) or print "No differences found\n"; # proceed with updates if sysup was requested - upinst("update",@diff) if (($#diff >= 0) and ($format eq "sysup")); + ($#diff < 0) or ($format ne "sysup") or upinst("update", @diff); } # Display duplicate packages (found in more than one repo) ################# @@ -740,7 +769,7 @@ sub dup { open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); while () { chomp; - my %pkg = parsepackage($_, $dir, $url, 0); + my %pkg = parsepackage($_, $dir, $url); $found{$pkg{'name'}} .= "###" . $pkg{'path'}."/". $pkg{'name'}.$pkg{'version'}."-".$pkg{'release'}; } close(REPO); @@ -759,6 +788,7 @@ sub dup { # Show list of dependencies for package #################################### sub depends { my ($j, $checkver) = ($ARGV[0] =~ /^quick/) ? (" ",0) : ("\n",1); + ($checkver == 0) or (%installed) or getinstalled(); getdependencies($ARGV[1], $checkver, "") or exiterr("package '$ARGV[1]' not found"); if ((@dependencies) and ($checkver)) {print "-- dependencies ([i] = installed, [u] = updatable)\n"} print join($j, @dependencies); @@ -804,7 +834,7 @@ sub upinst { getinstalled() if (! %installed); foreach my $pkgname(@args) { - my %pkg = getpackage($pkgname, 1); + my %pkg = getpackage($pkgname); if (not %pkg) { push(@failtasks, "not found,$pkgname"); } elsif ( ($cmd . getshortstatus(%pkg)) @@ -830,7 +860,7 @@ sub depinst { foreach my $dep(@dependencies) { next if ($seen{$dep}); $seen{$dep} = 1; next if ($locked{$dep}); - my %pkg = getpackage($dep, 1); + my %pkg = getpackage($dep); if ((%pkg) and (getshortstatus(%pkg) eq "[ ]")) { push(@toinst, $pkg{'name'}); } diff --git a/scripts/pkg-repgen.pl b/scripts/pkg-repgen.pl index de9086c..f26095d 100755 --- a/scripts/pkg-repgen.pl +++ b/scripts/pkg-repgen.pl @@ -40,6 +40,7 @@ if ($#ARGV >= 0) { # single packages } } else { @packages = @dirlist; + %isDup = map { $_ => 0 } @packages; } # hashes to determine the package name ... @@ -79,7 +80,7 @@ my %parity = ( 0 => "even", 1 => "odd" ); # Generate README and PKGINST pkgreadscripts(); -######################## individual packages ######################## +###################### individual packages ########################## sub pkg_single { my ($oR, $oD, $oH, $nR, $nD, $nH, $oline, $oname); my $count = 0; # needed for the html index @@ -148,14 +149,6 @@ sub pkg_single { last if ($oname ge $pname{$p}); } - if ( (! $isDup{$p}) and ($isDup{$pname{$p}}) ) { - $count++; - (! $followH{$pname{$p}}) or $followH{$pname{$p}} =~ - s/class="(even|odd)"/class="$parity{($count %2)}"/; - (! $followH{$pname{$p}}) or print $nH $followH{$pname{$p}}; - (! $followR{$pname{$p}}) or print $nR $followR{$pname{$p}}; - } - # Likewise for the dependency map, but avoid creating duplicate entries while ($firstrun{"PKGDEPS"}==0 and $oline = <$oD>) { chomp($oline); $oname = $oline; @@ -169,6 +162,16 @@ sub pkg_single { last if ($oname ge $pname{$p}); } + # after reaching the last in a sequence of dups, copy the + # successor line from the old {html index, repository} + if ( (! $isDup{$p}) and ($isDup{$pname{$p}}) and ($followH{$pname{$p}}) ) { + $count++; + $followH{$pname{$p}} =~ s/class="(even|odd)"/class="$parity{($count %2)}"/; + print $nH $followH{$pname{$p}}; + } + ($isDup{$p}) or (! $isDup{$pname{$p}}) or (! $followR{$pname{$p}}) + or print $nR $followR{$pname{$p}}; + # Restart the loop with the next package in the queue } @@ -203,12 +206,11 @@ sub pkg_dir { my $count = 0; open (my $ih, '>>index.html'); foreach my $p (@packages) { - chomp($p); - $count++; my ($pver, $url, $du, $md5, $desc, $ppr, $pdeps, $date) = metadata($p); - ($pdeps eq "") or ($isDup{$p}) or (! $isDup{$pname{$p}}) + ($pdeps eq "") or ($isDup{$p}) or printf $iD "%-30s : %-s\n", $pname{$p}, $pdeps; printf $iR "%-s:%-s:%-s:%-s:%-s\n", $p,$du,$md5,$desc,$ppr; + $count++; htmlrow($ih,$count,$pname{$p},$url,$pver,$desc,$date); } close($ih); @@ -233,8 +235,10 @@ run_script() { case "$1" in '; + my %seen; foreach my $name (@dirlist) { - $name =~ s/\#.*//; + $name =~ s/\#.*//; next if ($seen{$name}); + $seen{$name} = 1; if (-f "$path{$name}/README"){ print $fR "##### PKGREADME: $name\n"; open(my $readme, "$path{$name}/README"); @@ -250,7 +254,7 @@ run_script() { (m/^\#(!.*sh|\s*EOF|\s*End)/) or print $fS " $_\n"; } close($rs); - print $fS " ;;\n"; + print $fS " ;;\n"; } } }