From 761aec05c50550a1a4bd625066833f986ee5e56c Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 06:21:17 +0000 Subject: [PATCH 01/37] lintpkgsrc: format code No functional change. --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 3240 +++++++++++------------ 1 file changed, 1586 insertions(+), 1654 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 642c60e5d05a..c8d0a2914a7f 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.23 2022/07/29 19:00:36 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.24 2022/07/30 06:21:17 rillig Exp $ # Written by David Brownlee . # @@ -23,19 +23,19 @@ use Cwd 'realpath', 'getcwd'; # Buildtime configuration -my $conf_make = '@MAKE@'; -my $conf_pkgsrcdir = '@PKGSRCDIR@'; -my $conf_prefix = '@PREFIX@'; +my $conf_make = '@MAKE@'; +my $conf_pkgsrcdir = '@PKGSRCDIR@'; +my $conf_prefix = '@PREFIX@'; my $conf_sysconfdir = '@PKG_SYSCONFDIR@'; my ( - $pkglist, # list of Pkg packages - $pkg_installver, # installed version of pkg_install pseudo-pkg - $default_vars, # Set for Makefiles, inc PACKAGES & PKGSRCDIR - %opt, # Command line options - @matched_prebuiltpackages, # List of obsolete prebuilt package paths - @prebuilt_pkgdirs, # Use to follow symlinks in prebuilt pkgdirs - %prebuilt_pkgdir_cache, # To avoid symlink loops in prebuilt_pkgdirs + $pkglist, # list of Pkg packages + $pkg_installver, # installed version of pkg_install pseudo-pkg + $default_vars, # Set for Makefiles, inc PACKAGES & PKGSRCDIR + %opt, # Command line options + @matched_prebuiltpackages, # List of obsolete prebuilt package paths + @prebuilt_pkgdirs, # Use to follow symlinks in prebuilt pkgdirs + %prebuilt_pkgdir_cache, # To avoid symlink loops in prebuilt_pkgdirs ); sub usage_and_exit(); @@ -45,33 +45,28 @@ sub parse_makefile_pkgsrc($); $ENV{PATH} .= - ":/bin:/usr/bin:/sbin:/usr/sbin:${conf_prefix}/sbin:${conf_prefix}/bin"; + ":/bin:/usr/bin:/sbin:/usr/sbin:${conf_prefix}/sbin:${conf_prefix}/bin"; if ( - !getopts( 'BDE:I:K:LM:OP:RSVdg:himopruyz', \%opt ) - || $opt{h} - || !( - defined $opt{d} - || defined $opt{g} - || defined $opt{i} - || defined $opt{m} - || defined $opt{o} - || defined $opt{p} - || defined $opt{r} - || defined $opt{u} - || defined $opt{B} - || defined $opt{D} - || defined $opt{R} - || defined $opt{O} - || defined $opt{S} - || defined $opt{E} - || defined $opt{y} - || defined $opt{z} - ) - ) -{ - - usage_and_exit(); + !getopts('BDE:I:K:LM:OP:RSVdg:himopruyz', \%opt) + || $opt{h} + || !(defined $opt{d} + || defined $opt{g} + || defined $opt{i} + || defined $opt{m} + || defined $opt{o} + || defined $opt{p} + || defined $opt{r} + || defined $opt{u} + || defined $opt{B} + || defined $opt{D} + || defined $opt{R} + || defined $opt{O} + || defined $opt{S} + || defined $opt{E} + || defined $opt{y} + || defined $opt{z})) { + usage_and_exit(); } $| = 1; @@ -79,630 +74,598 @@ # gets removed in the final evaluation my $magic_undefined = 'M_a_G_i_C_uNdEfInEd'; -get_default_makefile_vars(); # $default_vars - -if ( $opt{D} && @ARGV ) { - foreach my $file (@ARGV) { - if ( -d $file ) { - $file .= "/Makefile"; - } - if ( !-f $file ) { - fail("No such file: $file"); - } - my ( $pkgname, $vars ) = parse_makefile_pkgsrc($file); - $pkgname ||= 'uNDEFINEd'; - print "$file -> $pkgname\n"; - foreach my $varname ( sort keys %{$vars} ) { - print "\t$varname = $vars->{$varname}\n"; - } - - #if ($opt{d}) { - # pkgsrc_check_depends(); - #} - } - exit; +get_default_makefile_vars(); # $default_vars + +if ($opt{D} && @ARGV) { + foreach my $file (@ARGV) { + if (-d $file) { + $file .= "/Makefile"; + } + if (!-f $file) { + fail("No such file: $file"); + } + my ($pkgname, $vars) = parse_makefile_pkgsrc($file); + $pkgname ||= 'uNDEFINEd'; + print "$file -> $pkgname\n"; + foreach my $varname (sort keys %{$vars}) { + print "\t$varname = $vars->{$varname}\n"; + } + + #if ($opt{d}) { + # pkgsrc_check_depends(); + #} + } + exit; } sub main() { - my ( $pkgsrcdir, $pkgdistdir ); - - $pkgsrcdir = $default_vars->{PKGSRCDIR}; - $pkgdistdir = $default_vars->{DISTDIR}; - - if ( $opt{r} && !$opt{o} && !$opt{m} && !$opt{p} ) { - $opt{o} = $opt{m} = $opt{p} = 1; - } - if ( $opt{o} || $opt{m} ) { - my (@baddist); - - @baddist = - scan_pkgsrc_distfiles_vs_distinfo( $pkgsrcdir, $pkgdistdir, $opt{o}, - $opt{m} ); - if ( $opt{r} ) { - verbose("Unlinking 'bad' distfiles\n"); - foreach my $distfile (@baddist) { - unlink("$pkgdistdir/$distfile"); - } - } - } - - # Remove all distfiles that are / are not part of an installed package - if ($opt{y} || $opt{z}) - { - my(@pkgs, @installed, %distfiles, @pkgdistfiles, @dldistfiles); - my(@tmpdistfiles, @orphan, $found, @parent); - - @pkgs = list_installed_packages(); - scan_pkgsrc_makefiles($pkgsrcdir); - - # list the installed packages and the directory they live in - foreach my $pkgname (sort @pkgs) - { - if ($pkgname =~ /^([^*?[]+)-([\d*?[].*)/) - { - foreach my $pkgver ($pkglist->pkgver($1)) - { - $pkgver->var('dir') =~ /-current/ && next; - push(@installed, $pkgver); - last; - } - } - } - - # distfiles belonging to the currently installed packages - foreach my $pkgver (sort @installed) - { - if (open(DISTINFO, "$pkgsrcdir/" .$pkgver->var('dir'). "/distinfo")) - { - while( ) - { - if (m/^(\w+) ?\(([^\)]+)\) = (\S+)/) - { - my($dn); - if ($2 =~ /^patch-[\w.+\-]+$/) - { next; } - $dn = $2; - # Strip leading ./ which sometimes gets added - # because of DISTSUBDIR=. - $dn =~ s/^(\.\/)*//; - if (!defined $distfiles{$dn}) - { - $distfiles{$dn}{name} = $dn; - push (@pkgdistfiles, $dn); - } + my ($pkgsrcdir, $pkgdistdir); + + $pkgsrcdir = $default_vars->{PKGSRCDIR}; + $pkgdistdir = $default_vars->{DISTDIR}; + + if ($opt{r} && !$opt{o} && !$opt{m} && !$opt{p}) { + $opt{o} = $opt{m} = $opt{p} = 1; + } + if ($opt{o} || $opt{m}) { + my (@baddist); + + @baddist = scan_pkgsrc_distfiles_vs_distinfo( + $pkgsrcdir, $pkgdistdir, $opt{o}, $opt{m}); + if ($opt{r}) { + verbose("Unlinking 'bad' distfiles\n"); + foreach my $distfile (@baddist) { + unlink("$pkgdistdir/$distfile"); } - } - close(DISTINFO); - } - } - - # distfiles downloaded on the current system - @tmpdistfiles = listdir("$pkgdistdir", undef); - foreach my $tmppkg (@tmpdistfiles) - { - if ($tmppkg ne "pkg-vulnerabilities") - { push (@dldistfiles, $tmppkg); } - } - - # sort the two arrays to make searching a bit faster - @dldistfiles = sort { $a cmp $b } @dldistfiles; - @pkgdistfiles = sort { $a cmp $b } @pkgdistfiles; - - if ($opt{y}) - { - # looking for files that are downloaded on the current system - # but do not belong to any currently installed package i.e. orphaned - $found = 0; - foreach my $dldf (@dldistfiles) - { - foreach my $pkgdf (@pkgdistfiles) - { - if ($dldf eq $pkgdf) - { $found = 1; } - } - if ($found != 1) - { - push (@orphan, $dldf); - print "Orphaned file: $dldf\n"; + } + } + + # Remove all distfiles that are / are not part of an installed package + if ($opt{y} || $opt{z}) { + my (@pkgs, @installed, %distfiles, @pkgdistfiles, @dldistfiles); + my (@tmpdistfiles, @orphan, $found, @parent); + + @pkgs = list_installed_packages(); + scan_pkgsrc_makefiles($pkgsrcdir); + + # list the installed packages and the directory they live in + foreach my $pkgname (sort @pkgs) { + if ($pkgname =~ /^([^*?[]+)-([\d*?[].*)/) { + foreach my $pkgver ($pkglist->pkgver($1)) { + $pkgver->var('dir') =~ /-current/ && next; + push(@installed, $pkgver); + last; + } } - $found = 0; - } - - if ($opt{r}) - { - safe_chdir("$pkgdistdir"); - verbose("Unlinking 'orphaned' distfiles\n"); - foreach my $distfile (@orphan) - { unlink($distfile) } - } - } - - if ($opt{z}) - { - # looking for files that are downloaded on the current system - # but belong to a currently installed package i.e. parented - $found = 0; - foreach my $pkgdf (@pkgdistfiles) - { - foreach my $dldf (@dldistfiles) - { - if ($pkgdf eq $dldf) - { $found = 1; } - } - if ($found == 1) - { - push (@parent, $pkgdf); - print "Parented file: $pkgdf\n"; + } + + # distfiles belonging to the currently installed packages + foreach my $pkgver (sort @installed) { + if (open(DISTINFO, "$pkgsrcdir/" . $pkgver->var('dir') . "/distinfo")) { + while () { + if (m/^(\w+) ?\(([^\)]+)\) = (\S+)/) { + my ($dn); + if ($2 =~ /^patch-[\w.+\-]+$/) { next; } + $dn = $2; + # Strip leading ./ which sometimes gets added + # because of DISTSUBDIR=. + $dn =~ s/^(\.\/)*//; + if (!defined $distfiles{$dn}) { + $distfiles{$dn}{name} = $dn; + push(@pkgdistfiles, $dn); + } + } + } + close(DISTINFO); + } + } + + # distfiles downloaded on the current system + @tmpdistfiles = listdir("$pkgdistdir", undef); + foreach my $tmppkg (@tmpdistfiles) { + if ($tmppkg ne "pkg-vulnerabilities") { + push(@dldistfiles, $tmppkg); + } + } + + # sort the two arrays to make searching a bit faster + @dldistfiles = sort { $a cmp $b } @dldistfiles; + @pkgdistfiles = sort { $a cmp $b } @pkgdistfiles; + + if ($opt{y}) { + # looking for files that are downloaded on the current system + # but do not belong to any currently installed package i.e. orphaned + $found = 0; + foreach my $dldf (@dldistfiles) { + foreach my $pkgdf (@pkgdistfiles) { + if ($dldf eq $pkgdf) { + $found = 1; + } + } + if ($found != 1) { + push(@orphan, $dldf); + print "Orphaned file: $dldf\n"; + } + $found = 0; + } + + if ($opt{r}) { + safe_chdir("$pkgdistdir"); + verbose("Unlinking 'orphaned' distfiles\n"); + foreach my $distfile (@orphan) { + unlink($distfile) + } + } + } + + if ($opt{z}) { + # looking for files that are downloaded on the current system + # but belong to a currently installed package i.e. parented + $found = 0; + foreach my $pkgdf (@pkgdistfiles) { + foreach my $dldf (@dldistfiles) { + if ($pkgdf eq $dldf) { + $found = 1; + } + } + if ($found == 1) { + push(@parent, $pkgdf); + print "Parented file: $pkgdf\n"; + } + $found = 0; + } + } + + if ($opt{r}) { + safe_chdir("$pkgdistdir"); + verbose("Unlinking 'parented' distfiles\n"); + foreach my $distfile (@parent) { + unlink($distfile); + } + } + } + + # List BROKEN packages + if ($opt{B}) { + scan_pkgsrc_makefiles($pkgsrcdir); + foreach my $pkgver ($pkglist->pkgver) { + $pkgver->var('BROKEN') || next; + print $pkgver->pkgname . ': ' . $pkgver->var('BROKEN') . "\n"; + } + } + + # List obsolete or NO_BIN_ON_FTP/RESTRICTED prebuilt packages + # + if ($opt{p} || $opt{O} || $opt{R}) { + scan_pkgsrc_makefiles($pkgsrcdir); + + @prebuilt_pkgdirs = ($default_vars->{PACKAGES}); + %prebuilt_pkgdir_cache = (); + + while (@prebuilt_pkgdirs) { + find(\&check_prebuilt_packages, shift @prebuilt_pkgdirs); + } + + if ($opt{r}) { + verbose("Unlinking listed prebuilt packages\n"); + foreach my $pkgfile (@matched_prebuiltpackages) { + unlink($pkgfile); + } + } + } + + if ($opt{S}) { + my (%in_subdir); + + foreach my $cat (list_pkgsrc_categories($pkgsrcdir)) { + my $vars = parse_makefile_vars("$pkgsrcdir/$cat/Makefile"); + + if (!$vars->{SUBDIR}) { + print "Warning - no SUBDIR for $cat\n"; + next; + } + foreach my $pkgdir (split(/\s+/, $vars->{SUBDIR})) { + $in_subdir{"$cat/$pkgdir"} = 1; + } + } + + scan_pkgsrc_makefiles($pkgsrcdir); + foreach my $pkgver ($pkglist->pkgver) { + if (!defined $in_subdir{ $pkgver->var('dir') }) { + print $pkgver->var('dir') . ": Not in SUBDIR\n"; } - $found = 0; - } - } - - if ($opt{r}) - { - safe_chdir("$pkgdistdir"); - verbose("Unlinking 'parented' distfiles\n"); - foreach my $distfile (@parent) - { unlink($distfile) } - } - } - - # List BROKEN packages - if ( $opt{B} ) { - scan_pkgsrc_makefiles($pkgsrcdir); - foreach my $pkgver ( $pkglist->pkgver ) { - $pkgver->var('BROKEN') || next; - print $pkgver->pkgname . ': ' . $pkgver->var('BROKEN') . "\n"; - } - } - - # List obsolete or NO_BIN_ON_FTP/RESTRICTED prebuilt packages - # - if ( $opt{p} || $opt{O} || $opt{R} ) { - scan_pkgsrc_makefiles($pkgsrcdir); - - @prebuilt_pkgdirs = ( $default_vars->{PACKAGES} ); - %prebuilt_pkgdir_cache = (); - - while (@prebuilt_pkgdirs) { - find( \&check_prebuilt_packages, shift @prebuilt_pkgdirs ); - } - - if ( $opt{r} ) { - verbose("Unlinking listed prebuilt packages\n"); - foreach my $pkgfile (@matched_prebuiltpackages) { - unlink($pkgfile); - } - } - } - - if ( $opt{S} ) { - my (%in_subdir); - - foreach my $cat ( list_pkgsrc_categories($pkgsrcdir) ) { - my $vars = parse_makefile_vars("$pkgsrcdir/$cat/Makefile"); - - if ( !$vars->{SUBDIR} ) { - print "Warning - no SUBDIR for $cat\n"; - next; - } - foreach my $pkgdir ( split( /\s+/, $vars->{SUBDIR} ) ) { - $in_subdir{"$cat/$pkgdir"} = 1; - } - } - - scan_pkgsrc_makefiles($pkgsrcdir); - foreach my $pkgver ( $pkglist->pkgver ) { - if ( !defined $in_subdir{ $pkgver->var('dir') } ) { - print $pkgver->var('dir') . ": Not in SUBDIR\n"; - } - } - } - - if ( $opt{g} ) { - my $tmpfile = "$opt{g}.tmp.$$"; - - scan_pkgsrc_makefiles($pkgsrcdir); - if ( !open( TABLE, ">$tmpfile" ) ) { - fail("Unable to write '$tmpfile': $!"); - } - foreach my $pkgver ( $pkglist->pkgver ) { - print TABLE $pkgver->pkg . "\t" - . $pkgver->var('dir') . "\t" - . $pkgver->ver . "\n"; - } - if ( !close(TABLE) ) { - fail("Error while writing '$tmpfile': $!"); - } - if ( !rename( $tmpfile, $opt{g} ) ) { - fail("Error in rename('$tmpfile','$opt{g}'): $!"); - } - } - - if ( $opt{d} ) { - scan_pkgsrc_makefiles($pkgsrcdir); - pkgsrc_check_depends(); - } - - if ( $opt{i} || $opt{u} ) { - my ( @pkgs, @update ); - - @pkgs = list_installed_packages(); - scan_pkgsrc_makefiles($pkgsrcdir); - - foreach my $pkgname ( sort @pkgs ) { - if ( $_ = invalid_version($pkgname) ) { - print $_; - - if ( $pkgname =~ /^([^*?[]+)-([\d*?[].*)/ ) { - foreach my $pkgver ( $pkglist->pkgver($1) ) { - $pkgver->var('dir') =~ /-current/ && next; - push( @update, $pkgver ); - last; - } - } - } - } - - if ( $opt{u} ) { - print "\nREQUIRED details for packages that could be updated:\n"; - - foreach my $pkgver (@update) { - print $pkgver->pkg . ':'; - if ( open( PKGINFO, 'pkg_info -R ' . $pkgver->pkg . '|' ) ) { - my ($list); - - while () { - if (/Required by:/) { - $list = 1; - } - elsif ($list) { - chomp; - s/-\d.*//; - print " $_"; - } - } - close(PKGINFO); - } - print "\n"; - } - - print - "\nRunning '${conf_make} fetch-list | sh' for each package:\n"; - foreach my $pkgver (@update) { - my ($pkgdir); - - $pkgdir = $pkgver->var('dir'); - if ( !defined($pkgdir) ) { - fail( - 'Unable to determine ' . $pkgver->pkg . ' directory' ); - } - - print "$pkgsrcdir/$pkgdir\n"; - safe_chdir("$pkgsrcdir/$pkgdir"); - system("${conf_make} fetch-list | sh"); - } - } - } - - if ( $opt{E} ) { - scan_pkgsrc_makefiles($pkgsrcdir); - store_pkgsrc_makefiles( $opt{E} ); - } + } + } + + if ($opt{g}) { + my $tmpfile = "$opt{g}.tmp.$$"; + + scan_pkgsrc_makefiles($pkgsrcdir); + if (!open(TABLE, ">$tmpfile")) { + fail("Unable to write '$tmpfile': $!"); + } + foreach my $pkgver ($pkglist->pkgver) { + print TABLE $pkgver->pkg . "\t" + . $pkgver->var('dir') . "\t" + . $pkgver->ver . "\n"; + } + if (!close(TABLE)) { + fail("Error while writing '$tmpfile': $!"); + } + if (!rename($tmpfile, $opt{g})) { + fail("Error in rename('$tmpfile','$opt{g}'): $!"); + } + } + + if ($opt{d}) { + scan_pkgsrc_makefiles($pkgsrcdir); + pkgsrc_check_depends(); + } + + if ($opt{i} || $opt{u}) { + my (@pkgs, @update); + + @pkgs = list_installed_packages(); + scan_pkgsrc_makefiles($pkgsrcdir); + + foreach my $pkgname (sort @pkgs) { + if ($_ = invalid_version($pkgname)) { + print $_; + + if ($pkgname =~ /^([^*?[]+)-([\d*?[].*)/) { + foreach my $pkgver ($pkglist->pkgver($1)) { + $pkgver->var('dir') =~ /-current/ && next; + push(@update, $pkgver); + last; + } + } + } + } + + if ($opt{u}) { + print "\nREQUIRED details for packages that could be updated:\n"; + + foreach my $pkgver (@update) { + print $pkgver->pkg . ':'; + if (open(PKGINFO, 'pkg_info -R ' . $pkgver->pkg . '|')) { + my ($list); + + while () { + if (/Required by:/) { + $list = 1; + } + elsif ($list) { + chomp; + s/-\d.*//; + print " $_"; + } + } + close(PKGINFO); + } + print "\n"; + } + + print "\nRunning '${conf_make} fetch-list | sh' for each package:\n"; + foreach my $pkgver (@update) { + my ($pkgdir); + + $pkgdir = $pkgver->var('dir'); + if (!defined($pkgdir)) { + fail('Unable to determine ' . $pkgver->pkg . ' directory'); + } + + print "$pkgsrcdir/$pkgdir\n"; + safe_chdir("$pkgsrcdir/$pkgdir"); + system("${conf_make} fetch-list | sh"); + } + } + } + + if ($opt{E}) { + scan_pkgsrc_makefiles($pkgsrcdir); + store_pkgsrc_makefiles($opt{E}); + } } sub canonicalize_pkgname($) { - my ($pkgname) = @_; + my ($pkgname) = @_; - $pkgname =~ s,^py\d+(?:pth|)-,py-,; - $pkgname =~ s,^ruby\d+-,ruby-,; - $pkgname =~ s,^php\d+-,php-,; - return $pkgname; + $pkgname =~ s,^py\d+(?:pth|)-,py-,; + $pkgname =~ s,^ruby\d+-,ruby-,; + $pkgname =~ s,^php\d+-,php-,; + return $pkgname; } # Could speed up by building a cache of package names to paths, then processing # each package name once against the tests. sub check_prebuilt_packages() { - if ( $_ eq 'distfiles' || $_ eq 'pkgsrc' ) { - - # Skip these subdirs if present - $File::Find::prune = 1; - - } - elsif (/(.+)-(\d.*)\.t[bg]z$/) { - my ( $pkg, $ver ) = ( $1, $2 ); - - $pkg = canonicalize_pkgname($pkg); - - my ($pkgs); - if ( $pkgs = $pkglist->pkgs($pkg) ) { - my ($pkgver) = $pkgs->pkgver($ver); - - if ( !defined $pkgver ) { - if ( $opt{p} ) { - print "$File::Find::dir/$_\n"; - push( @matched_prebuiltpackages, "$File::Find::dir/$_" ); - } - - # Pick probably the last version - $pkgver = $pkgs->latestver; - } - - if ( $opt{R} && $pkgver->var('RESTRICTED') ) { - print "$File::Find::dir/$_\n"; - push( @matched_prebuiltpackages, "$File::Find::dir/$_" ); - } - - if ( $opt{O} && $pkgver->var('OSVERSION_SPECIFIC') ) { - print "$File::Find::dir/$_\n"; - push( @matched_prebuiltpackages, "$File::Find::dir/$_" ); - } - } - - } - elsif ( -d $_ ) { - if ( $prebuilt_pkgdir_cache{"$File::Find::dir/$_"} ) { - $File::Find::prune = 1; - return; - } - - $prebuilt_pkgdir_cache{"$File::Find::dir/$_"} = 1; - if ( -l $_ ) { - my ($dest) = readlink($_); - - if ( substr( $dest, 0, 1 ) ne '/' ) { - $dest = "$File::Find::dir/$dest"; - } - if ( !$prebuilt_pkgdir_cache{$dest} ) { - push( @prebuilt_pkgdirs, $dest ); - } - } - } + if ($_ eq 'distfiles' || $_ eq 'pkgsrc') { + # Skip these subdirs if present + $File::Find::prune = 1; + + } + elsif (/(.+)-(\d.*)\.t[bg]z$/) { + my ($pkg, $ver) = ($1, $2); + + $pkg = canonicalize_pkgname($pkg); + + my ($pkgs); + if ($pkgs = $pkglist->pkgs($pkg)) { + my ($pkgver) = $pkgs->pkgver($ver); + + if (!defined $pkgver) { + if ($opt{p}) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); + } + + # Pick probably the last version + $pkgver = $pkgs->latestver; + } + + if ($opt{R} && $pkgver->var('RESTRICTED')) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); + } + + if ($opt{O} && $pkgver->var('OSVERSION_SPECIFIC')) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); + } + } + + } + elsif (-d $_) { + if ($prebuilt_pkgdir_cache{"$File::Find::dir/$_"}) { + $File::Find::prune = 1; + return; + } + + $prebuilt_pkgdir_cache{"$File::Find::dir/$_"} = 1; + if (-l $_) { + my ($dest) = readlink($_); + + if (substr($dest, 0, 1) ne '/') { + $dest = "$File::Find::dir/$dest"; + } + if (!$prebuilt_pkgdir_cache{$dest}) { + push(@prebuilt_pkgdirs, $dest); + } + } + } } # Dewey decimal verson number matching - or thereabouts # Also handles 'nb' suffix (checked iff values otherwise identical) # sub deweycmp($$$) { - my ( $match, $test, $val ) = @_; - my ( $cmp, $match_nb, $val_nb ); - - $match_nb = $val_nb = 0; - if ( $match =~ /(.*)nb(.*)/ ) { - - # Handle nb suffix - $match = $1; - $match_nb = $2; - } - - if ( $val =~ /(.*)nb(.*)/ ) { - - # Handle nb suffix - $val = $1; - $val_nb = $2; - } + my ($match, $test, $val) = @_; + my ($cmp, $match_nb, $val_nb); + + $match_nb = $val_nb = 0; + if ($match =~ /(.*)nb(.*)/) { + # Handle nb suffix + $match = $1; + $match_nb = $2; + } - $cmp = deweycmp_extract( $match, $val ); + if ($val =~ /(.*)nb(.*)/) { + # Handle nb suffix + $val = $1; + $val_nb = $2; + } - if ( !$cmp ) { + $cmp = deweycmp_extract($match, $val); - # Iff otherwise identical, check nb suffix - $cmp = deweycmp_extract( $match_nb, $val_nb ); - } + if (!$cmp) { + # Iff otherwise identical, check nb suffix + $cmp = deweycmp_extract($match_nb, $val_nb); + } - debug("eval deweycmp $cmp $test 0\n"); - eval "$cmp $test 0"; + debug("eval deweycmp $cmp $test 0\n"); + eval "$cmp $test 0"; } sub convert_to_standard_dewey(@) { - my ( $elem, $underscore, @temp ); - - # According to the current implementation in pkg_install/lib/str.c - # as of 2002/06/02, '_' before a number, '.', and 'pl' get treated as 0, - # while 'rc' and 'pre' get treated as -1; beta as '-2', alpha as '-3'. - # Other characters are converted to lower - # case and then to a number: a->1, b->2, c->3, etc. Numbers stay the same. - # 'nb' is a special case that's already been handled when we are here. - foreach $elem (@_) { - if ( $elem =~ /\d+/ ) { - push( @temp, $elem ); - - } - elsif ( $elem =~ /^pl$/ or $elem =~ /^\.$/ ) { - push( @temp, 0 ); - - } - elsif ( $elem =~ /^_$/ ) { - push( @temp, 0 ); - - } - elsif ( $elem =~ /^pre$/ ) { - push( @temp, -1 ); - - } - elsif ( $elem =~ /^rc$/ ) { - push( @temp, -1 ); - - } - elsif ( $elem =~ /^beta$/ ) { - push( @temp, -2 ); - - } - elsif ( $elem =~ /^alpha$/ ) { - push( @temp, -3 ); - - } - else { - push( @temp, 0 ); - push( @temp, ord($elem) - ord("a") + 1 ); - } - } - @temp; + my ($elem, $underscore, @temp); + + # According to the current implementation in pkg_install/lib/str.c + # as of 2002/06/02, '_' before a number, '.', and 'pl' get treated as 0, + # while 'rc' and 'pre' get treated as -1; beta as '-2', alpha as '-3'. + # Other characters are converted to lower + # case and then to a number: a->1, b->2, c->3, etc. Numbers stay the same. + # 'nb' is a special case that's already been handled when we are here. + foreach $elem (@_) { + if ($elem =~ /\d+/) { + push(@temp, $elem); + } + elsif ($elem =~ /^pl$/ or $elem =~ /^\.$/) { + push(@temp, 0); + } + elsif ($elem =~ /^_$/) { + push(@temp, 0); + } + elsif ($elem =~ /^pre$/) { + push(@temp, -1); + } + elsif ($elem =~ /^rc$/) { + push(@temp, -1); + } + elsif ($elem =~ /^beta$/) { + push(@temp, -2); + } + elsif ($elem =~ /^alpha$/) { + push(@temp, -3); + } + else { + push(@temp, 0); + push(@temp, ord($elem) - ord("a") + 1); + } + } + @temp; } sub deweycmp_extract($$) { - my ( $match, $val ) = @_; - my ( $cmp, @matchlist, @vallist, $i, $len ); - - @matchlist = convert_to_standard_dewey( split( /(\D+)/, lc($match) ) ); - @vallist = convert_to_standard_dewey( split( /(\D+)/, lc($val) ) ); - $cmp = 0; - $i = 0; - if ( $#matchlist > $#vallist ) { - $len = $#matchlist; - } - else { - $len = $#vallist; - } - while ( !$cmp && ( $i++ <= $len ) ) { - if ( !@matchlist ) { - push( @matchlist, 0 ); - } - if ( !@vallist ) { - push( @vallist, 0 ); - } - $cmp = ( shift @matchlist <=> shift @vallist ); - } - $cmp; + my ($match, $val) = @_; + my ($cmp, @matchlist, @vallist, $i, $len); + + @matchlist = convert_to_standard_dewey(split(/(\D+)/, lc($match))); + @vallist = convert_to_standard_dewey(split(/(\D+)/, lc($val))); + $cmp = 0; + $i = 0; + if ($#matchlist > $#vallist) { + $len = $#matchlist; + } + else { + $len = $#vallist; + } + while (!$cmp && ($i++ <= $len)) { + if (!@matchlist) { + push(@matchlist, 0); + } + if (!@vallist) { + push(@vallist, 0); + } + $cmp = (shift @matchlist <=> shift @vallist); + } + $cmp; } sub fail($) { - print STDERR shift(), "\n"; - exit(3); + print STDERR shift(), "\n"; + exit(3); } sub get_default_makefile_vars() { - chomp( $pkg_installver = `pkg_info -V 2>/dev/null || echo 20010302` ); - - chomp( $_ = `uname -srm` ); - ( - $default_vars->{OPSYS}, - $default_vars->{OS_VERSION}, - $default_vars->{MACHINE} - ) = (split); - if ( !$default_vars->{MACHINE} ) { - die('Unable to extract machine from uname'); - } - - # Handle systems without uname -p (NetBSD pre 1.4) - chomp( $default_vars->{MACHINE_ARCH} = `uname -p 2>/dev/null` ); - - if ( !$default_vars->{MACHINE_ARCH} - && $default_vars->{OS_VERSION} eq 'NetBSD' ) - { - chomp( $default_vars->{MACHINE_ARCH} = `sysctl -n hw.machine_arch` ); - } - - if ( !$default_vars->{MACHINE_ARCH} ) { - $default_vars->{MACHINE_ARCH} = $default_vars->{MACHINE}; - } - - $default_vars->{OBJECT_FMT} = 'x'; - $default_vars->{LOWER_OPSYS} = lc( $default_vars->{OPSYS} ); - - if ( $opt{P} ) { - $default_vars->{PKGSRCDIR} = realpath($opt{P}); - } - else { - $default_vars->{PKGSRCDIR} = $conf_pkgsrcdir; - } - - $default_vars->{DESTDIR} = ''; - $default_vars->{LOCALBASE} = '/usr/pkg'; - $default_vars->{X11BASE} = '/usr/X11R6'; - - my ($vars); - if ( -f '/etc/mk.conf' && ( $vars = parse_makefile_vars('/etc/mk.conf') ) ) - { - foreach my $var ( keys %{$vars} ) { - $default_vars->{$var} = $vars->{$var}; - } - } - elsif ( -f ${conf_sysconfdir} . '/mk.conf' && ( $vars = parse_makefile_vars(${conf_sysconfdir} . '/mk.conf') ) ) - { - foreach my $var ( keys %{$vars} ) { - $default_vars->{$var} = $vars->{$var}; - } - } - - if ( $opt{P} ) { - $default_vars->{PKGSRCDIR} = realpath($opt{P}); - } - - if ( $opt{M} ) { - $default_vars->{DISTDIR} = realpath($opt{M}); - } - else { - $default_vars->{DISTDIR} ||= $default_vars->{PKGSRCDIR} . '/distfiles'; - } - - if ( $opt{K} ) { - $default_vars->{PACKAGES} = realpath($opt{K}); - } - - # Extract some variables from bsd.pkg.mk - my ($mkvars); - $mkvars = parse_makefile_vars( - "$default_vars->{PKGSRCDIR}/mk/bsd.pkg.mk", - "$default_vars->{PKGSRCDIR}/mk/scripts" - ); - foreach my $varname ( keys %{$mkvars} ) { - if ( $varname =~ /_REQD$/ || $varname eq 'EXTRACT_SUFX' ) { - $default_vars->{$varname} = $mkvars->{$varname}; - } - } - - $default_vars->{PACKAGES} ||= $default_vars->{PKGSRCDIR} . '/packages'; + chomp($pkg_installver = `pkg_info -V 2>/dev/null || echo 20010302`); + + chomp($_ = `uname -srm`); + ( + $default_vars->{OPSYS}, + $default_vars->{OS_VERSION}, + $default_vars->{MACHINE} + ) = (split); + if (!$default_vars->{MACHINE}) { + die('Unable to extract machine from uname'); + } + + # Handle systems without uname -p (NetBSD pre 1.4) + chomp($default_vars->{MACHINE_ARCH} = `uname -p 2>/dev/null`); + + if (!$default_vars->{MACHINE_ARCH} + && $default_vars->{OS_VERSION} eq 'NetBSD') { + chomp($default_vars->{MACHINE_ARCH} = `sysctl -n hw.machine_arch`); + } + + if (!$default_vars->{MACHINE_ARCH}) { + $default_vars->{MACHINE_ARCH} = $default_vars->{MACHINE}; + } + + $default_vars->{OBJECT_FMT} = 'x'; + $default_vars->{LOWER_OPSYS} = lc($default_vars->{OPSYS}); + + if ($opt{P}) { + $default_vars->{PKGSRCDIR} = realpath($opt{P}); + } + else { + $default_vars->{PKGSRCDIR} = $conf_pkgsrcdir; + } + + $default_vars->{DESTDIR} = ''; + $default_vars->{LOCALBASE} = '/usr/pkg'; + $default_vars->{X11BASE} = '/usr/X11R6'; + + my ($vars); + if (-f '/etc/mk.conf' && ($vars = parse_makefile_vars('/etc/mk.conf'))) { + foreach my $var (keys %{$vars}) { + $default_vars->{$var} = $vars->{$var}; + } + } + elsif (-f ${conf_sysconfdir} . '/mk.conf' && + ($vars = parse_makefile_vars(${conf_sysconfdir} . '/mk.conf'))) { + foreach my $var (keys %{$vars}) { + $default_vars->{$var} = $vars->{$var}; + } + } + + if ($opt{P}) { + $default_vars->{PKGSRCDIR} = realpath($opt{P}); + } + + if ($opt{M}) { + $default_vars->{DISTDIR} = realpath($opt{M}); + } + else { + $default_vars->{DISTDIR} ||= $default_vars->{PKGSRCDIR} . '/distfiles'; + } + + if ($opt{K}) { + $default_vars->{PACKAGES} = realpath($opt{K}); + } + + # Extract some variables from bsd.pkg.mk + my ($mkvars); + $mkvars = parse_makefile_vars( + "$default_vars->{PKGSRCDIR}/mk/bsd.pkg.mk", + "$default_vars->{PKGSRCDIR}/mk/scripts" + ); + foreach my $varname (keys %{$mkvars}) { + if ($varname =~ /_REQD$/ || $varname eq 'EXTRACT_SUFX') { + $default_vars->{$varname} = $mkvars->{$varname}; + } + } + + $default_vars->{PACKAGES} ||= $default_vars->{PKGSRCDIR} . '/packages'; } # Determine if a package version is current. If not, report correct version # if found # sub invalid_version($) { - my ($pkgmatch) = @_; - my ( $fail, $ok ); - my ( @pkgmatches, @todo ); - - @todo = ($pkgmatch); - - # We handle {} here, everything else in package_globmatch - while ( $pkgmatch = shift @todo ) { - if ( $pkgmatch =~ /(.*)\{([^{}]+)}(.*)/ ) { - foreach ( split( ',', $2 ) ) { - push( @todo, "$1$_$3" ); - } - } - else { - push( @pkgmatches, $pkgmatch ); - } - } - - foreach $pkgmatch (@pkgmatches) { - my ( $pkg, $badver ) = package_globmatch($pkgmatch); - - if ( defined($badver) ) { - my ($pkgs); - - if ( $pkgs = $pkglist->pkgs($pkg) ) { - $fail .= - "Version mismatch: '$pkg' $badver vs " - . join( ',', $pkgs->versions ) . "\n"; - } - else { - $fail .= "Unknown package: '$pkg' version $badver\n"; - } - } - else { - - # If we find one match, don't bitch about others - $ok = 1; - } - } - $ok && ( $fail = undef ); - $fail; + my ($pkgmatch) = @_; + my ($fail, $ok); + my (@pkgmatches, @todo); + + @todo = ($pkgmatch); + + # We handle {} here, everything else in package_globmatch + while ($pkgmatch = shift @todo) { + if ($pkgmatch =~ /(.*)\{([^{}]+)}(.*)/) { + foreach (split(',', $2)) { + push(@todo, "$1$_$3"); + } + } + else { + push(@pkgmatches, $pkgmatch); + } + } + + foreach $pkgmatch (@pkgmatches) { + my ($pkg, $badver) = package_globmatch($pkgmatch); + + if (defined($badver)) { + my ($pkgs); + + if ($pkgs = $pkglist->pkgs($pkg)) { + $fail .= + "Version mismatch: '$pkg' $badver vs " + . join(',', $pkgs->versions) . "\n"; + } + else { + $fail .= "Unknown package: '$pkg' version $badver\n"; + } + } + else { + + # If we find one match, don't bitch about others + $ok = 1; + } + } + $ok && ($fail = undef); + $fail; } # List (recursive) non directory contents of specified directory @@ -710,138 +673,136 @@ ($) #TODO this entire sub should be replaced with direct calls to # File::Find sub listdir($$) { - my ( $base, $dir ) = @_; - my ($thisdir); - my ( @list, @thislist ); - - $thisdir = $base; - if ( defined($dir) ) { - $thisdir .= "/$dir"; - $dir .= '/'; - } - else { - $dir = ''; - } - - opendir( DIR, $thisdir ) || fail("Unable to opendir($thisdir): $!"); - @thislist = grep( substr( $_, 0, 1 ) ne '.' && $_ ne 'CVS', readdir(DIR) ); - closedir(DIR); - foreach my $entry (@thislist) { - if ( -d "$thisdir/$entry" ) { - push( @list, listdir( $base, "$dir$entry" ) ); - } - else { - push( @list, "$dir$entry" ); - } - } - @list; + my ($base, $dir) = @_; + my ($thisdir); + my (@list, @thislist); + + $thisdir = $base; + if (defined($dir)) { + $thisdir .= "/$dir"; + $dir .= '/'; + } + else { + $dir = ''; + } + + opendir(DIR, $thisdir) || fail("Unable to opendir($thisdir): $!"); + @thislist = grep(substr($_, 0, 1) ne '.' && $_ ne 'CVS', readdir(DIR)); + closedir(DIR); + foreach my $entry (@thislist) { + if (-d "$thisdir/$entry") { + push(@list, listdir($base, "$dir$entry")); + } + else { + push(@list, "$dir$entry"); + } + } + @list; } # Use pkg_info to list installed packages # sub list_installed_packages() { - my (@pkgs); + my (@pkgs); - open( PKG_INFO, 'pkg_info -e "*" |' ) || fail("Unable to run pkg_info: $!"); - while ( defined( my $pkg = ) ) { - chomp($pkg); - push( @pkgs, canonicalize_pkgname($pkg) ); - } - close(PKG_INFO); + open(PKG_INFO, 'pkg_info -e "*" |') || fail("Unable to run pkg_info: $!"); + while (defined(my $pkg = )) { + chomp($pkg); + push(@pkgs, canonicalize_pkgname($pkg)); + } + close(PKG_INFO); - @pkgs; + @pkgs; } # List top level pkgsrc categories # sub list_pkgsrc_categories($) { - my ($pkgsrcdir) = @_; - my (@categories); - - opendir( BASE, $pkgsrcdir ) || die("Unable to opendir($pkgsrcdir): $!"); - @categories = - grep( substr( $_, 0, 1 ) ne '.' - && $_ ne 'CVS' - && -f "$pkgsrcdir/$_/Makefile", - readdir(BASE) ); - closedir(BASE); - @categories; + my ($pkgsrcdir) = @_; + my (@categories); + + opendir(BASE, $pkgsrcdir) || die("Unable to opendir($pkgsrcdir): $!"); + @categories = + grep(substr($_, 0, 1) ne '.' + && $_ ne 'CVS' + && -f "$pkgsrcdir/$_/Makefile", + readdir(BASE)); + closedir(BASE); + @categories; } # For a given category, list potentially valid pkgdirs # sub list_pkgsrc_pkgdirs($$) { - my ( $pkgsrcdir, $cat ) = @_; - my (@pkgdirs); - - if ( !opendir( CAT, "$pkgsrcdir/$cat" ) ) { - die("Unable to opendir($pkgsrcdir/cat): $!"); - } - @pkgdirs = - sort grep( $_ ne 'Makefile' - && $_ ne 'pkg' - && $_ ne 'CVS' - && substr( $_, 0, 1 ) ne '.', - readdir(CAT) ); - closedir(CAT); - @pkgdirs; + my ($pkgsrcdir, $cat) = @_; + my (@pkgdirs); + + if (!opendir(CAT, "$pkgsrcdir/$cat")) { + die("Unable to opendir($pkgsrcdir/cat): $!"); + } + @pkgdirs = + sort grep($_ ne 'Makefile' + && $_ ne 'pkg' + && $_ ne 'CVS' + && substr($_, 0, 1) ne '.', + readdir(CAT)); + closedir(CAT); + @pkgdirs; } sub glob2regex($) { - my ($glob) = @_; - my ( @chars, $in_alt ); - my ($regex); - - @chars = split( //, $glob ); - while ( defined( $_ = shift @chars ) ) { - if ( $_ eq '*' ) { - $regex .= '.*'; - } - elsif ( $_ eq '?' ) { - $regex .= '.'; - } - elsif ( $_ eq '+' ) { - $regex .= '.'; - } - elsif ( $_ eq '\\+' ) { - $regex .= $_ . shift @chars; - } - elsif ( $_ eq '.' || $_ eq '|' ) { - $regex .= quotemeta; - } - elsif ( $_ eq '{' ) { - $regex .= '('; - ++$in_alt; - } - elsif ( $_ eq '}' ) { - if ( !$in_alt ) { - - # Error - return undef; - } - $regex .= ')'; - --$in_alt; - } - elsif ( $_ eq ',' && $in_alt ) { - $regex .= '|'; - } - else { - $regex .= $_; - } - } - - if ($in_alt) { - - # Error - return undef; - } - if ( $regex eq $glob ) { - return (''); - } - if ( $opt{D} ) { - print "glob2regex: $glob -> $regex\n"; - } - '^' . $regex . '$'; + my ($glob) = @_; + my (@chars, $in_alt); + my ($regex); + + @chars = split(//, $glob); + while (defined($_ = shift @chars)) { + if ($_ eq '*') { + $regex .= '.*'; + } + elsif ($_ eq '?') { + $regex .= '.'; + } + elsif ($_ eq '+') { + $regex .= '.'; + } + elsif ($_ eq '\\+') { + $regex .= $_ . shift @chars; + } + elsif ($_ eq '.' || $_ eq '|') { + $regex .= quotemeta; + } + elsif ($_ eq '{') { + $regex .= '('; + ++$in_alt; + } + elsif ($_ eq '}') { + if (!$in_alt) { + # Error + return undef; + } + $regex .= ')'; + --$in_alt; + } + elsif ($_ eq ',' && $in_alt) { + $regex .= '|'; + } + else { + $regex .= $_; + } + } + + if ($in_alt) { + # Error + return undef; + } + if ($regex eq $glob) { + return (''); + } + if ($opt{D}) { + print "glob2regex: $glob -> $regex\n"; + } + '^' . $regex . '$'; } # Perform some (reasonable) subset of 'pkg_info -e' / glob(3) @@ -849,877 +810,850 @@ ($) # and either 'problem version' or undef if all OK # sub package_globmatch($) { - my ($pkgmatch) = @_; - my ( $matchpkgname, $matchver, $regex ); - - if ( $pkgmatch =~ /^([^*?[]+)(<|>|<=|>=|-)(\d[^*?[{]*)$/ ) { - - # (package)(cmp)(dewey) - my ( $test, @pkgvers ); - - ( $matchpkgname, $test, $matchver ) = ( $1, $2, $3 ); - if ( @pkgvers = $pkglist->pkgver($matchpkgname) ) { - foreach my $pkgver (@pkgvers) { - if ( $test eq '-' ) { - if ( $pkgver->ver eq $matchver ) { - $matchver = undef; - last; - } - } - else { - if ( deweycmp( $pkgver->ver, $test, $matchver ) ) { - $matchver = undef; - last; - } - } - } - - if ( $matchver && $test ne '-' ) { - $matchver = "$test$matchver"; - } - } - - } - elsif ( $pkgmatch =~ /^([^[]+)-([\d*?{[].*)$/ ) { - - # (package)-(globver) - my (@pkgnames); - - ( $matchpkgname, $matchver ) = ( $1, $2 ); - - if ( defined $pkglist->pkgs($matchpkgname) ) { - push( @pkgnames, $matchpkgname ); - - } - elsif ( $regex = glob2regex($matchpkgname) ) { - foreach my $pkg ( $pkglist->pkgs ) { - ( $pkg->pkg() =~ /$regex/ ) && push( @pkgnames, $pkg->pkg() ); - } - } - - # Try to convert $matchver into regex version - # - $regex = glob2regex($matchver); - - foreach my $pkg (@pkgnames) { - if ( defined $pkglist->pkgver( $pkg, $matchver ) ) { - return ($matchver); - } - - if ($regex) { - foreach my $ver ( $pkglist->pkgs($pkg)->versions ) { - if ( $ver =~ /$regex/ ) { - $matchver = undef; - last; - } - } - } - - $matchver || last; - } - - # last ditch attempt to handle the whole DEPENDS as a glob - # - if ( $matchver && ( $regex = glob2regex($pkgmatch) ) ) { - - # (large-glob) - foreach my $pkgver ( $pkglist->pkgver ) { - if ( $pkgver->pkgname =~ /$regex/ ) { - $matchver = undef; - last; - } - } - } - - } - else { - ( $matchpkgname, $matchver ) = ( $pkgmatch, 'missing' ); - } - - ( $matchpkgname, $matchver ); + my ($pkgmatch) = @_; + my ($matchpkgname, $matchver, $regex); + + if ($pkgmatch =~ /^([^*?[]+)(<|>|<=|>=|-)(\d[^*?[{]*)$/) { + + # (package)(cmp)(dewey) + my ($test, @pkgvers); + + ($matchpkgname, $test, $matchver) = ($1, $2, $3); + if (@pkgvers = $pkglist->pkgver($matchpkgname)) { + foreach my $pkgver (@pkgvers) { + if ($test eq '-') { + if ($pkgver->ver eq $matchver) { + $matchver = undef; + last; + } + } + else { + if (deweycmp($pkgver->ver, $test, $matchver)) { + $matchver = undef; + last; + } + } + } + + if ($matchver && $test ne '-') { + $matchver = "$test$matchver"; + } + } + + } + elsif ($pkgmatch =~ /^([^[]+)-([\d*?{[].*)$/) { + + # (package)-(globver) + my (@pkgnames); + + ($matchpkgname, $matchver) = ($1, $2); + + if (defined $pkglist->pkgs($matchpkgname)) { + push(@pkgnames, $matchpkgname); + + } + elsif ($regex = glob2regex($matchpkgname)) { + foreach my $pkg ($pkglist->pkgs) { + ($pkg->pkg() =~ /$regex/) && push(@pkgnames, $pkg->pkg()); + } + } + + # Try to convert $matchver into regex version + # + $regex = glob2regex($matchver); + + foreach my $pkg (@pkgnames) { + if (defined $pkglist->pkgver($pkg, $matchver)) { + return ($matchver); + } + + if ($regex) { + foreach my $ver ($pkglist->pkgs($pkg)->versions) { + if ($ver =~ /$regex/) { + $matchver = undef; + last; + } + } + } + + $matchver || last; + } + + # last ditch attempt to handle the whole DEPENDS as a glob + # + if ($matchver && ($regex = glob2regex($pkgmatch))) { + + # (large-glob) + foreach my $pkgver ($pkglist->pkgver) { + if ($pkgver->pkgname =~ /$regex/) { + $matchver = undef; + last; + } + } + } + + } + else { + ($matchpkgname, $matchver) = ($pkgmatch, 'missing'); + } + + ($matchpkgname, $matchver); } # Parse a pkgsrc package makefile and return the pkgname and set variables # sub parse_makefile_pkgsrc($) { - my ($file) = @_; - my ( $pkgname, $vars ); - - $vars = parse_makefile_vars($file); - - if ( !$vars ) { - - # Missing Makefile - return undef; - } - - if ( defined $vars->{PKGNAME} ) { - $pkgname = $vars->{PKGNAME}; - - } - elsif ( defined $vars->{DISTNAME} ) { - $pkgname = $vars->{DISTNAME}; - } - - if ( defined $vars->{PKGNAME} ) { - debug("$file: PKGNAME=$vars->{PKGNAME}\n"); - } - if ( defined $vars->{DISTNAME} ) { - debug("$file: DISTNAME=$vars->{DISTNAME}\n"); - } - - if ( !defined $pkgname || $pkgname =~ /\$/ || $pkgname !~ /(.*)-(\d.*)/ ) { - - # invoke make here as a last resort - my ($pkgsrcdir) = ( $file =~ m:(/.*)/: ); - debug("Running '$conf_make' in '$pkgsrcdir'\n"); - my $pid = open3( \*WTR, \*RDR, \*ERR, - "cd $pkgsrcdir || exit 1; ${conf_make} show-vars VARNAMES=PKGNAME" ); - if ( !$pid ) { - warn "$file: Unable to run make: $!"; - } - else { - close(WTR); - my @errors = ; - close(ERR); - my ($makepkgname) = ; - close(RDR); - wait; - chomp @errors; - if (@errors) { warn "\n$file: @errors\n"; } - - if ( $makepkgname =~ /(.*)-(\d.*)/ ) { - $pkgname = $makepkgname; - } - } - } - - if ( defined $pkgname ) { - if ( $pkgname =~ /^pkg_install-(\d+)$/ && $1 < $pkg_installver ) { - $pkgname = "pkg_install-$pkg_installver"; - } - - $pkgname = canonicalize_pkgname($pkgname); - - if ( defined $vars->{PKGREVISION} - and not $vars->{PKGREVISION} =~ /^\s*$/ ) - { - if ( $vars->{PKGREVISION} =~ /^\$\{(_(CVS|GIT|HG|SVN)_PKGVERSION):.*\}$/ ) { - # See wip/mk/*-package.mk. - } - elsif ( $vars->{PKGREVISION} =~ /\D/ ) { - print - "\nBogus: PKGREVISION $vars->{PKGREVISION} (from $file)\n"; - - } - elsif ( $vars->{PKGREVISION} ) { - $pkgname .= "nb"; - $pkgname .= $vars->{PKGREVISION}; - } - } - - if ( $pkgname =~ /\$/ ) { - print "\nBogus: $pkgname (from $file)\n"; - - } - elsif ( $pkgname =~ /(.*)-(\d.*)/ ) { - if ($pkglist) { - my ($pkgver) = $pkglist->add( $1, $2 ); - - debug("add $1 $2\n"); - - foreach - my $var (qw(DEPENDS RESTRICTED OSVERSION_SPECIFIC BROKEN)) - { - $pkgver->var( $var, $vars->{$var} ); - } - - if ( defined $vars->{NO_BIN_ON_FTP} ) { - $pkgver->var( 'RESTRICTED', 'NO_BIN_ON_FTP' ); - } - - if ( $file =~ m:([^/]+/[^/]+)/Makefile$: ) { - $pkgver->var( 'dir', $1 ); - } - else { - $pkgver->var( 'dir', 'unknown' ); - } - } - } - else { - print "Cannot extract $pkgname version ($file)\n"; - } - - return ( $pkgname, $vars ); - - } - else { - return (undef); - } + my ($file) = @_; + my ($pkgname, $vars); + + $vars = parse_makefile_vars($file); + + if (!$vars) { + + # Missing Makefile + return undef; + } + + if (defined $vars->{PKGNAME}) { + $pkgname = $vars->{PKGNAME}; + } + elsif (defined $vars->{DISTNAME}) { + $pkgname = $vars->{DISTNAME}; + } + + if (defined $vars->{PKGNAME}) { + debug("$file: PKGNAME=$vars->{PKGNAME}\n"); + } + if (defined $vars->{DISTNAME}) { + debug("$file: DISTNAME=$vars->{DISTNAME}\n"); + } + + if (!defined $pkgname || $pkgname =~ /\$/ || $pkgname !~ /(.*)-(\d.*)/) { + + # invoke make here as a last resort + my ($pkgsrcdir) = ($file =~ m:(/.*)/:); + debug("Running '$conf_make' in '$pkgsrcdir'\n"); + my $pid = open3(\*WTR, \*RDR, \*ERR, + "cd $pkgsrcdir || exit 1; ${conf_make} show-vars VARNAMES=PKGNAME"); + if (!$pid) { + warn "$file: Unable to run make: $!"; + } + else { + close(WTR); + my @errors = ; + close(ERR); + my ($makepkgname) = ; + close(RDR); + wait; + chomp @errors; + if (@errors) { warn "\n$file: @errors\n"; } + + if ($makepkgname =~ /(.*)-(\d.*)/) { + $pkgname = $makepkgname; + } + } + } + + if (defined $pkgname) { + if ($pkgname =~ /^pkg_install-(\d+)$/ && $1 < $pkg_installver) { + $pkgname = "pkg_install-$pkg_installver"; + } + + $pkgname = canonicalize_pkgname($pkgname); + + if (defined $vars->{PKGREVISION} + and not $vars->{PKGREVISION} =~ /^\s*$/) { + if ($vars->{PKGREVISION} =~ /^\$\{(_(CVS|GIT|HG|SVN)_PKGVERSION):.*\}$/) { + # See wip/mk/*-package.mk. + } + elsif ($vars->{PKGREVISION} =~ /\D/) { + print "\nBogus: PKGREVISION $vars->{PKGREVISION} (from $file)\n"; + + } + elsif ($vars->{PKGREVISION}) { + $pkgname .= "nb"; + $pkgname .= $vars->{PKGREVISION}; + } + } + + if ($pkgname =~ /\$/) { + print "\nBogus: $pkgname (from $file)\n"; + + } + elsif ($pkgname =~ /(.*)-(\d.*)/) { + if ($pkglist) { + my ($pkgver) = $pkglist->add($1, $2); + + debug("add $1 $2\n"); + + foreach my $var (qw(DEPENDS RESTRICTED OSVERSION_SPECIFIC BROKEN)) { + $pkgver->var($var, $vars->{$var}); + } + + if (defined $vars->{NO_BIN_ON_FTP}) { + $pkgver->var('RESTRICTED', 'NO_BIN_ON_FTP'); + } + + if ($file =~ m:([^/]+/[^/]+)/Makefile$:) { + $pkgver->var('dir', $1); + } + else { + $pkgver->var('dir', 'unknown'); + } + } + } + else { + print "Cannot extract $pkgname version ($file)\n"; + } + + return ($pkgname, $vars); + + } + else { + return (undef); + } } # Extract variable assignments from Makefile # Much unpalatable magic to avoid having to use make (all for speed) # sub parse_makefile_vars($$) { - my ( $file, $cwd ) = @_; - my ( - $pkgname, %vars, $plus, $value, @data, - %incfiles, # Cache of previously included fils - %incdirs, # Directories in which to check for includes - @if_false - ); # 0:true 1:false 2:nested-false&nomore-elsif - - if ( !open( FILE, $file ) ) { - return (undef); - } - @data = map { chomp; $_ } ; - close(FILE); - - $incdirs{"."} = 1; - $incdirs{ dirname($file) } = 1; - - # Some Makefiles depend on these being set - if ( $file eq '/etc/mk.conf' ) { - $vars{LINTPKGSRC} = 'YES'; - } - else { - %vars = %{$default_vars}; - } - $vars{BSD_PKG_MK} = 'YES'; - - if ($cwd) { - $vars{'.CURDIR'} = $cwd; - - } - elsif ( $file =~ m#(.*)/# ) { - $vars{'.CURDIR'} = $1; - - } - else { - $vars{'.CURDIR'} = getcwd; - } - - $incdirs{ $vars{'.CURDIR'} } = 1; - if ( $opt{L} ) { - print "$file\n"; - } - - while ( defined( $_ = shift(@data) ) ) { - s/\s*[^\\]#.*//; - - # Continuation lines - # - while ( substr( $_, -1 ) eq "\\" ) { - substr( $_, -2 ) = shift @data; - } - - # Conditionals - # - if (m#^\.\s*if(|def|ndef)\s+(.*)#) { - my ( $type, $false ); - - $type = $1; - if ( $if_false[$#if_false] ) { - push( @if_false, 2 ); - - } - elsif ( $type eq '' ) { - - # Straight if - push( @if_false, parse_eval_make_false( $2, \%vars ) ); - - } - else { - $false = !defined( $vars{ parse_expand_vars( $2, \%vars ) } ); - if ( $type eq 'ndef' ) { - $false = !$false; - } - push( @if_false, $false ? 1 : 0 ); - } - debug("$file: .if$type (! @if_false)\n"); - next; - } - - if ( m#^\.\s*elif\s+(.*)# && @if_false ) { - if ( $if_false[$#if_false] == 0 ) { - $if_false[$#if_false] = 2; - } - elsif ( $if_false[$#if_false] == 1 - && !parse_eval_make_false( $1, \%vars ) ) - { - $if_false[$#if_false] = 0; - } - debug("$file: .elif (! @if_false)\n"); - next; - } - - if ( m#^\.\s*else\b# && @if_false ) { - $if_false[$#if_false] = $if_false[$#if_false] == 1 ? 0 : 1; - debug("$file: .else (! @if_false)\n"); - next; - } - - if (m#^\.\s*endif\b#) { - pop(@if_false); - debug("$file: .endif (! @if_false)\n"); - next; - } - - $if_false[$#if_false] && next; - - # Included files (just unshift onto @data) - # - if (m#^\.\s*include\s+"([^"]+)"#) { - my ($incfile) = parse_expand_vars( $1, \%vars ); - - # At this point just skip any includes which we were not able to - # fully expand - if ( $incfile =~ m#/mk/bsd# - || $incfile =~ /$magic_undefined/ - || $incfile =~ /\$\{/ - || ( !$opt{d} && $incfile =~ m#/(buildlink[^/]*\.mk)# ) ) - { - debug("$file: .include \"$incfile\" skipped\n"); - } - else { - debug("$file: .include \"$incfile\"\n"); - - # Expand any simple vars in $incfile - # - - if ( substr( $incfile, 0, 1 ) ne '/' ) { - foreach my $dir ( keys %incdirs ) { - if ( -f "$dir/$incfile" ) { - $incfile = "$dir/$incfile"; - last; - } - } - } - - # perl 5.6.1 realpath() cannot handle files, only directories - # If the last component is a symlink this will give a false - # negative, but that is not a problem as the duplicate check - # is for performance - $incfile =~ m#^(.+)(/[^/]+)$#; - - if ( !-f $incfile ) { - if ( !$opt{L} ) { - verbose("\n"); - } - - verbose("$file: Cannot locate $incfile in " - . join( " ", sort keys %incdirs ) - . "\n" ); - - } - else { - $incfile = realpath($1) . $2; - - if ( !$incfiles{$incfile} ) { - if ( $opt{L} ) { - print "inc $incfile\n"; - } - $incfiles{$incfile} = 1; - - if ( !open( FILE, $incfile ) ) { - verbose( - "Cannot open '$incfile' (from $file): $_ $!\n"); - } - else { - my $NEWCURDIR = $incfile; - $NEWCURDIR =~ s#/[^/]*$##; - $incdirs{$NEWCURDIR} = 1; - unshift( @data, ".CURDIR=$vars{'.CURDIR'}" ); - unshift( @data, map { chomp; $_ } ); - unshift( @data, ".CURDIR=$NEWCURDIR" ); - close(FILE); - } - } - } - } - next; - } - - if (/^ *([-\w\.]+)\s*([:+?]?)=\s*(.*)/) { - my ($key); - - $key = $1; - $plus = $2; - $value = $3; - - if ( $plus eq ':' ) { - $vars{$key} = parse_expand_vars( $value, \%vars ); - } - elsif ( $plus eq '+' && defined $vars{$key} ) { - $vars{$key} .= " $value"; - } - elsif ( $plus ne '?' || !defined $vars{$key} ) { - $vars{$key} = $value; - } - debug("assignment: $key$plus=[$value] ($vars{$key})\n"); - - # Give python a little hand (XXX - do we wanna consider actually - # implementing make .for loops, etc? - # - if ( $key eq "PYTHON_VERSIONS_ACCEPTED" ) { - my ($pv); - - foreach $pv ( split( /\s+/, $vars{PYTHON_VERSIONS_ACCEPTED} ) ) - { - $vars{"_PYTHON_VERSION_FIRSTACCEPTED"} ||= $pv; - $vars{"_PYTHON_VERSION_${pv}_OK"} = "yes"; - } - } - } - } - - debug("$file: expand\n"); - - # Handle variable substitutions FRED = a-${JIM:S/-/-b-/} - # - my ($loop); - - for ( $loop = 1 ; $loop ; ) { - $loop = 0; - foreach my $key ( keys %vars ) { - if ( index( $vars{$key}, '$' ) == -1 ) { - next; - } - - $_ = parse_expand_vars( $vars{$key}, \%vars ); - if ( $_ ne $vars{$key} ) { - $vars{$key} = $_; - $loop = 1; - - } - elsif ( $vars{$key} =~ - m#\$\{([\w.]+):([CS]([^{}])[^{}\3]+\3[^{}\3]*\3[g1]*(|:[^{}]+)|U[^{}]+)\}# ) - { - my ( $left, $subvar, $right ) = ( $`, $1, $' ); - my (@patterns) = split( ':', $2 ); - my ($result); - - $result = $vars{$subvar}; - $result ||= ''; - - # If $vars{$subvar} contains a $ skip it on this pass. - # Hopefully it will get substituted and we can catch it - # next time around. - if ( index( $result, '${' ) != -1 ) { - next; - } - - debug( - "$file: substitutelist $key ($result) $subvar (@patterns)\n" - ); - foreach (@patterns) { - if (m#(U)(.*)#) { - $result ||= $2; - } elsif (m#([CS])(.)([^/@]+)\2([^/@]*)\2([1g]*)#) { - - my ( $how, $from, $to, $global ) = ( $1, $3, $4, $5 ); - - debug( -"$file: substituteglob $subvar, $how, $from, $to, $global\n" - ); - if ( $how eq 'S' ) { - - # Limited substitution - keep ^ and $ - $from =~ s/([?.{}\]\[*+])/\\$1/g; - } - $to =~ s/\\(\d)/\$$1/g; # Change \1 etc to $1 - $to =~ s/\&/\$&/g; # Change & to $1 - - my ($notfirst); - if ( $global =~ s/1// ) { - ( $from, $notfirst ) = split( '\s', $from, 2 ); - } - - debug( - "$file: substituteperl $subvar, $how, $from, $to\n" - ); - debug("eval substitute <$from> <$to> <$global>\n"); - eval "\$result =~ s/$from/$to/$global"; - if ( defined $notfirst ) { - $result .= " $notfirst"; - } - } - else { - next; - } - } - - $vars{$key} = $left . $result . $right; - $loop = 1; - } - } - } - - foreach my $key ( keys %vars ) { - $vars{$key} =~ s/$magic_undefined//; - } - \%vars; + my ($file, $cwd) = @_; + my ( + $pkgname, %vars, $plus, $value, @data, + %incfiles, # Cache of previously included fils + %incdirs, # Directories in which to check for includes + @if_false + ); # 0:true 1:false 2:nested-false&nomore-elsif + + if (!open(FILE, $file)) { + return (undef); + } + @data = map { chomp; + $_; } ; + close(FILE); + + $incdirs{"."} = 1; + $incdirs{ dirname($file) } = 1; + + # Some Makefiles depend on these being set + if ($file eq '/etc/mk.conf') { + $vars{LINTPKGSRC} = 'YES'; + } + else { + %vars = %{$default_vars}; + } + $vars{BSD_PKG_MK} = 'YES'; + + if ($cwd) { + $vars{'.CURDIR'} = $cwd; + } + elsif ($file =~ m#(.*)/#) { + $vars{'.CURDIR'} = $1; + } + else { + $vars{'.CURDIR'} = getcwd; + } + + $incdirs{ $vars{'.CURDIR'} } = 1; + if ($opt{L}) { + print "$file\n"; + } + + while (defined($_ = shift(@data))) { + s/\s*[^\\]#.*//; + + # Continuation lines + # + while (substr($_, -1) eq "\\") { + substr($_, -2) = shift @data; + } + + # Conditionals + # + if (m#^\.\s*if(|def|ndef)\s+(.*)#) { + my ($type, $false); + + $type = $1; + if ($if_false[$#if_false]) { + push(@if_false, 2); + + } + elsif ($type eq '') { + # Straight if + push(@if_false, parse_eval_make_false($2, \%vars)); + + } + else { + $false = !defined($vars{ parse_expand_vars($2, \%vars) }); + if ($type eq 'ndef') { + $false = !$false; + } + push(@if_false, $false ? 1 : 0); + } + debug("$file: .if$type (! @if_false)\n"); + next; + } + + if (m#^\.\s*elif\s+(.*)# && @if_false) { + if ($if_false[$#if_false] == 0) { + $if_false[$#if_false] = 2; + } + elsif ($if_false[$#if_false] == 1 + && !parse_eval_make_false($1, \%vars)) { + $if_false[$#if_false] = 0; + } + debug("$file: .elif (! @if_false)\n"); + next; + } + + if (m#^\.\s*else\b# && @if_false) { + $if_false[$#if_false] = $if_false[$#if_false] == 1 ? 0 : 1; + debug("$file: .else (! @if_false)\n"); + next; + } + + if (m#^\.\s*endif\b#) { + pop(@if_false); + debug("$file: .endif (! @if_false)\n"); + next; + } + + $if_false[$#if_false] && next; + + # Included files (just unshift onto @data) + # + if (m#^\.\s*include\s+"([^"]+)"#) { + my ($incfile) = parse_expand_vars($1, \%vars); + + # At this point just skip any includes which we were not able to + # fully expand + if ($incfile =~ m#/mk/bsd# + || $incfile =~ /$magic_undefined/ + || $incfile =~ /\$\{/ + || (!$opt{d} && $incfile =~ m#/(buildlink[^/]*\.mk)#)) { + debug("$file: .include \"$incfile\" skipped\n"); + + } + else { + debug("$file: .include \"$incfile\"\n"); + + # Expand any simple vars in $incfile + # + + if (substr($incfile, 0, 1) ne '/') { + foreach my $dir (keys %incdirs) { + if (-f "$dir/$incfile") { + $incfile = "$dir/$incfile"; + last; + } + } + } + + # perl 5.6.1 realpath() cannot handle files, only directories + # If the last component is a symlink this will give a false + # negative, but that is not a problem as the duplicate check + # is for performance + $incfile =~ m#^(.+)(/[^/]+)$#; + + if (!-f $incfile) { + if (!$opt{L}) { + verbose("\n"); + } + + verbose("$file: Cannot locate $incfile in " + . join(" ", sort keys %incdirs) + . "\n"); + + } + else { + $incfile = realpath($1) . $2; + + if (!$incfiles{$incfile}) { + if ($opt{L}) { + print "inc $incfile\n"; + } + $incfiles{$incfile} = 1; + + if (!open(FILE, $incfile)) { + verbose("Cannot open '$incfile' (from $file): $_ $!\n"); + } + else { + my $NEWCURDIR = $incfile; + $NEWCURDIR =~ s#/[^/]*$##; + $incdirs{$NEWCURDIR} = 1; + unshift(@data, ".CURDIR=$vars{'.CURDIR'}"); + unshift(@data, map { chomp; + $_ } ); + unshift(@data, ".CURDIR=$NEWCURDIR"); + close(FILE); + } + } + } + } + next; + } + + if (/^ *([-\w\.]+)\s*([:+?]?)=\s*(.*)/) { + my ($key); + + $key = $1; + $plus = $2; + $value = $3; + + if ($plus eq ':') { + $vars{$key} = parse_expand_vars($value, \%vars); + } + elsif ($plus eq '+' && defined $vars{$key}) { + $vars{$key} .= " $value"; + } + elsif ($plus ne '?' || !defined $vars{$key}) { + $vars{$key} = $value; + } + debug("assignment: $key$plus=[$value] ($vars{$key})\n"); + + # Give python a little hand (XXX - do we wanna consider actually + # implementing make .for loops, etc? + # + if ($key eq "PYTHON_VERSIONS_ACCEPTED") { + my ($pv); + + foreach $pv (split(/\s+/, $vars{PYTHON_VERSIONS_ACCEPTED})) { + $vars{"_PYTHON_VERSION_FIRSTACCEPTED"} ||= $pv; + $vars{"_PYTHON_VERSION_${pv}_OK"} = "yes"; + } + } + } + } + + debug("$file: expand\n"); + + # Handle variable substitutions FRED = a-${JIM:S/-/-b-/} + # + my ($loop); + + for ($loop = 1; $loop;) { + $loop = 0; + foreach my $key (keys %vars) { + if (index($vars{$key}, '$') == -1) { + next; + } + + $_ = parse_expand_vars($vars{$key}, \%vars); + if ($_ ne $vars{$key}) { + $vars{$key} = $_; + $loop = 1; + + } + elsif ($vars{$key} =~ m#\$\{([\w.]+):([CS]([^{}])[^{}\3]+\3[^{}\3]*\3[g1]*(|:[^{}]+)|U[^{}]+)\}#) { + my ($left, $subvar, $right) = ($`, $1, $'); + my (@patterns) = split(':', $2); + my ($result); + + $result = $vars{$subvar}; + $result ||= ''; + + # If $vars{$subvar} contains a $ skip it on this pass. + # Hopefully it will get substituted and we can catch it + # next time around. + if (index($result, '${') != -1) { + next; + } + + debug("$file: substitutelist $key ($result) $subvar (@patterns)\n"); + foreach (@patterns) { + if (m#(U)(.*)#) { + $result ||= $2; + } + elsif (m#([CS])(.)([^/@]+)\2([^/@]*)\2([1g]*)#) { + + my ($how, $from, $to, $global) = ($1, $3, $4, $5); + + debug("$file: substituteglob $subvar, $how, $from, $to, $global\n"); + if ($how eq 'S') { + # Limited substitution - keep ^ and $ + $from =~ s/([?.{}\]\[*+])/\\$1/g; + } + $to =~ s/\\(\d)/\$$1/g; # Change \1 etc to $1 + $to =~ s/\&/\$&/g; # Change & to $1 + + my ($notfirst); + if ($global =~ s/1//) { + ($from, $notfirst) = split('\s', $from, 2); + } + + debug("$file: substituteperl $subvar, $how, $from, $to\n"); + debug("eval substitute <$from> <$to> <$global>\n"); + eval "\$result =~ s/$from/$to/$global"; + if (defined $notfirst) { + $result .= " $notfirst"; + } + } + else { + next; + } + } + + $vars{$key} = $left . $result . $right; + $loop = 1; + } + } + } + + foreach my $key (keys %vars) { + $vars{$key} =~ s/$magic_undefined//; + } + \%vars; } sub parse_expand_vars($$) { - my ( $line, $vars ) = @_; - - while ( $line =~ /\$\{([-\w.]+)\}/ ) { - if ( defined( ${$vars}{$1} ) ) { - $line = $` . ${$vars}{$1} . $'; - } - else { - $line = $` . $magic_undefined . $'; - } - } - $line; + my ($line, $vars) = @_; + + while ($line =~ /\$\{([-\w.]+)\}/) { + if (defined(${$vars}{$1})) { + $line = $` . ${$vars}{$1} . $'; + } + else { + $line = $` . $magic_undefined . $'; + } + } + $line; } sub parse_expand_vars_dumb($$) { - my ( $line, $vars ) = @_; - - while ( $line =~ /\$\{([-\w.]+)\}/ ) { - if ( defined( ${$vars}{$1} ) ) { - $line = $` . ${$vars}{$1} . $'; - } - else { - $line = $` . $magic_undefined . $'; - } - } - $line; + my ($line, $vars) = @_; + + while ($line =~ /\$\{([-\w.]+)\}/) { + if (defined(${$vars}{$1})) { + $line = $` . ${$vars}{$1} . $'; + } + else { + $line = $` . $magic_undefined . $'; + } + } + $line; } sub parse_eval_make_false($$) { - my ( $line, $vars ) = @_; - my ( $false, $test ); - - $false = 0; - $test = parse_expand_vars_dumb( $line, $vars ); - - # XXX This is _so_ wrong - need to parse this correctly - $test =~ s/""/\r/g; - $test =~ s/"//g; # " - $test =~ s/\r/""/g; - - debug("conditional: $test\n"); - - # XXX Could do something with target - while ( $test =~ /(target|empty|make|defined|exists)\s*\(([^()]+)\)/ ) { - my $testname = $1; - my $varname = $2; - my $var; - - # Implement (some of) make's :M modifier - if ( $varname =~ /^([^:]+):M(.+)$/ ) { - $varname = $1; - my $match = $2; - - $var = $${vars}{$varname}; - $var = parse_expand_vars( $var, $vars ) if defined $var; - - $match =~ s/([{.+])/\\$1/g; - $match =~ s/\*/.*/g; - $match =~ s/\?/./g; - $match = '^' . $match . '$'; - $var = ( $var =~ /$match/ ) if defined $var; - } - else { - $var = $${vars}{$varname}; - $var = parse_expand_vars( $var, $vars ) if defined $var; - } - - if ( defined $var && $var eq $magic_undefined ) { - $var = undef; - } - - if ( $testname eq 'exists' ) { - $_ = ( -e $varname ) ? 1 : 0; - - } - elsif ( $testname eq 'defined' ) { - $_ = defined($var) ? 1 : 0; - - } - elsif ( $testname eq 'empty' ) { - $_ = ( ( not defined($var) or ( length($var) == 0 ) ) ? 1 : 0 ); - - } - else { - $_ = 0; - } - - $test =~ s/$testname\s*\([^()]+\)/$_/; - debug("conditional: update to $test\n"); - } - - while ( $test =~ /([^\s()\|\&]+)\s+(!=|==)\s+([^\s()]+)/ ) { - if ( $2 eq '==' ) { - $_ = ( $1 eq $3 ) ? 1 : 0; - } - else { - $_ = ( $1 ne $3 ) ? 1 : 0; - } - $test =~ s/[^\s()\|\&]+\s+(!=|==)\s+[^\s()]+/$_/; - } - - if ( $test !~ /[^<>\d()\s&|.!]/ ) { - debug("eval test $test\n"); - $false = eval "($test)?0:1"; - if ( !defined $false ) { - fail("Eval failed $line - $test"); - } - debug( "conditional: evaluated to " . ( $false ? 0 : 1 ) . "\n" ); - - } - else { - $false = 0; - debug("conditional: defaulting to 0\n"); - } - $false; + my ($line, $vars) = @_; + my ($false, $test); + + $false = 0; + $test = parse_expand_vars_dumb($line, $vars); + + # XXX This is _so_ wrong - need to parse this correctly + $test =~ s/""/\r/g; + $test =~ s/"//g; # " + $test =~ s/\r/""/g; + + debug("conditional: $test\n"); + + # XXX Could do something with target + while ($test =~ /(target|empty|make|defined|exists)\s*\(([^()]+)\)/) { + my $testname = $1; + my $varname = $2; + my $var; + + # Implement (some of) make's :M modifier + if ($varname =~ /^([^:]+):M(.+)$/) { + $varname = $1; + my $match = $2; + + $var = $${vars}{$varname}; + $var = parse_expand_vars($var, $vars) + if defined $var; + + $match =~ s/([{.+])/\\$1/g; + $match =~ s/\*/.*/g; + $match =~ s/\?/./g; + $match = '^' . $match . '$'; + $var = ($var =~ /$match/) + if defined $var; + } + else { + $var = $${vars}{$varname}; + $var = parse_expand_vars($var, $vars) + if defined $var; + } + + if (defined $var && $var eq $magic_undefined) { + $var = undef; + } + + if ($testname eq 'exists') { + $_ = (-e $varname) ? 1 : 0; + + } elsif ($testname eq 'defined') { + $_ = defined($var) ? 1 : 0; + + } elsif ($testname eq 'empty') { + $_ = ((not defined($var) or (length($var) == 0)) ? 1 : 0); + + } else { + $_ = 0; + } + + $test =~ s/$testname\s*\([^()]+\)/$_/; + debug("conditional: update to $test\n"); + } + + while ($test =~ /([^\s()\|\&]+)\s+(!=|==)\s+([^\s()]+)/) { + if ($2 eq '==') { + $_ = ($1 eq $3) ? 1 : 0; + } else { + $_ = ($1 ne $3) ? 1 : 0; + } + $test =~ s/[^\s()\|\&]+\s+(!=|==)\s+[^\s()]+/$_/; + } + + if ($test !~ /[^<>\d()\s&|.!]/) { + debug("eval test $test\n"); + $false = eval "($test)?0:1"; + if (!defined $false) { + fail("Eval failed $line - $test"); + } + debug("conditional: evaluated to " . ($false ? 0 : 1) . "\n"); + + } else { + $false = 0; + debug("conditional: defaulting to 0\n"); + } + $false; } # chdir() || fail() # sub safe_chdir($) { - my ($dir) = @_; + my ($dir) = @_; - debug("chdir: $dir"); - if ( !chdir($dir) ) { - fail("Unable to chdir($dir): $!"); - } + debug("chdir: $dir"); + if (!chdir($dir)) { + fail("Unable to chdir($dir): $!"); + } } # Generate pkgname->category/pkg mapping, optionally check DEPENDS # sub scan_pkgsrc_makefiles($$) { - my ( $pkgsrcdir, $check_depends ) = @_; - my (@categories); - - if ($pkglist) { - - # Already done - return; - } - - if ( $opt{I} ) { - load_pkgsrc_makefiles( $opt{I} ); - return; - } - - $pkglist = new PkgList; - @categories = list_pkgsrc_categories($pkgsrcdir); - verbose('Scan Makefiles: '); - - if ( !$opt{L} ) { - verbose( '_' x @categories . "\b" x @categories ); - } - else { - verbose("\n"); - } - - foreach my $cat ( sort @categories ) { - foreach my $pkgdir ( list_pkgsrc_pkgdirs( $pkgsrcdir, $cat ) ) { - my ( $pkg, $vars ) = - parse_makefile_pkgsrc("$pkgsrcdir/$cat/$pkgdir/Makefile"); - } - - if ( !$opt{L} ) { - verbose('.'); - } - } - - if ( !$opt{L} ) { - my ($len); - - $_ = $pkglist->numpkgver() . ' packages'; - $len = @categories - length($_); - verbose( "\b" x @categories, $_, ' ' x $len, "\b" x $len, "\n" ); - } + my ($pkgsrcdir, $check_depends) = @_; + my (@categories); + + if ($pkglist) { + + # Already done + return; + } + + if ($opt{I}) { + load_pkgsrc_makefiles($opt{I}); + return; + } + + $pkglist = new PkgList; + @categories = list_pkgsrc_categories($pkgsrcdir); + verbose('Scan Makefiles: '); + + if (!$opt{L}) { + verbose('_' x @categories . "\b" x @categories); + } else { + verbose("\n"); + } + + foreach my $cat (sort @categories) { + foreach my $pkgdir (list_pkgsrc_pkgdirs($pkgsrcdir, $cat)) { + my ($pkg, $vars) = parse_makefile_pkgsrc("$pkgsrcdir/$cat/$pkgdir/Makefile"); + } + + if (!$opt{L}) { + verbose('.'); + } + } + + if (!$opt{L}) { + my ($len); + + $_ = $pkglist->numpkgver() . ' packages'; + $len = @categories - length($_); + verbose("\b" x @categories, $_, ' ' x $len, "\b" x $len, "\n"); + } } # Cross reference all depends # sub pkgsrc_check_depends() { - foreach my $pkgver ( $pkglist->pkgver ) { - my ( $err, $msg ); - - defined $pkgver->var('DEPENDS') || next; - foreach my $depend ( split( " ", $pkgver->var('DEPENDS') ) ) { - - $depend =~ s/:.*// || next; - - $depend = canonicalize_pkgname($depend); - if ( ( $msg = invalid_version($depend) ) ) { - if ( !defined($err) ) { - print $pkgver->pkgname . " DEPENDS errors:\n"; - } - $err = 1; - $msg =~ s/(\n)(.)/$1\t$2/g; - print "\t$msg"; - } - } - } + foreach my $pkgver ($pkglist->pkgver) { + my ($err, $msg); + + defined $pkgver->var('DEPENDS') || next; + foreach my $depend (split(" ", $pkgver->var('DEPENDS'))) { + + $depend =~ s/:.*// || next; + + $depend = canonicalize_pkgname($depend); + if (($msg = invalid_version($depend))) { + if (!defined($err)) { + print $pkgver->pkgname . " DEPENDS errors:\n"; + } + $err = 1; + $msg =~ s/(\n)(.)/$1\t$2/g; + print "\t$msg"; + } + } + } } # Extract all distinfo entries, then verify contents of distfiles # sub scan_pkgsrc_distfiles_vs_distinfo($$$$) { - my ( $pkgsrcdir, $pkgdistdir, $check_unref, $check_distinfo ) = @_; - my (@categories); - my ( %distfiles, %sumfiles, @distwarn, $numpkg ); - my (%bad_distfiles); - - @categories = list_pkgsrc_categories($pkgsrcdir); - - verbose( 'Scan distinfo: ' . '_' x @categories . "\b" x @categories ); - $numpkg = 0; - foreach my $cat ( sort @categories ) { - foreach my $pkgdir ( list_pkgsrc_pkgdirs( $pkgsrcdir, $cat ) ) { - if ( open( DISTINFO, "$pkgsrcdir/$cat/$pkgdir/distinfo" ) ) { - ++$numpkg; - while () { - if (m/^(\w+) ?\(([^\)]+)\) = (\S+)/) { - my ( $dn, $ds, $dt ); - $dt = $1; - $dn = $2; - $ds = $3; - if ( $dn =~ /^patch-[\w.+\-]+$/ ) { - next; - } - - # Strip leading ./ which sometimes gets added - # because of DISTSUBDIR=. - $dn =~ s/^(\.\/)*//; - if ( !defined $distfiles{$dn} ) { - $distfiles{$dn}{sumtype} = $dt; - $distfiles{$dn}{sum} = $ds; - $distfiles{$dn}{path} = "$cat/$pkgdir"; - - } - elsif ($distfiles{$dn}{sumtype} eq $dt - && $distfiles{$dn}{sum} ne $ds ) - { - push( @distwarn, - "checksum mismatch between '$dt' for '$dn' " - . "in $cat/$pkgdir and $distfiles{$dn}{path}\n" - ); - } - } - } - close(DISTINFO); - } - } - verbose('.'); - } - verbose(" ($numpkg packages)\n"); - -# check each file in $pkgdistdir - find ( { wanted => sub { - my ($dist); - if ( -f $File::Find::name ) - { - my $distn = $File::Find::name; - $distn =~ s/$pkgdistdir\/?//g; - #pkg/47516 ignore cvs dirs - return if $distn =~ m/^\.cvsignore/; - return if $distn =~ m/^CVS\//; - if ( !defined ($dist = $distfiles{$distn} ) ) { - $bad_distfiles{$distn} = 1; - } - else { - if ( $dist->{sum} ne 'IGNORE' ) { - push( @{ $sumfiles{ $dist->{sumtype} } }, $distn ); - } - } - } - } }, - ($pkgdistdir) ); - - if ( $check_unref && %bad_distfiles ) { - verbose( scalar( keys %bad_distfiles ), - " unreferenced file(s) in '$pkgdistdir':\n" ); - print join( "\n", sort keys %bad_distfiles ), "\n"; - } - - if ($check_distinfo) { - if (@distwarn) { - verbose(@distwarn); - } - - verbose("checksum mismatches\n"); - safe_chdir($pkgdistdir); - foreach my $sum ( keys %sumfiles ) { - if ( $sum eq 'Size' ) { - foreach my $file ( @{ $sumfiles{$sum} } ) { - if ( !-f $file || -S $file != $distfiles{$file}{sum} ) { - print $file, " (Size)\n"; - $bad_distfiles{$file} = 1; - } - } - next; - } - - my $pid = open3(my $in, my $out, undef, "xargs", "digest", $sum); - defined($pid) || fail "fork"; - my $pid2 = fork(); - defined($pid2) || fail "fork"; - if ($pid2) { - close($in); - } else { - print $in "@{$sumfiles{$sum}}"; - exit 0; - } - while (<$out>) { - if (m/^$sum ?\(([^\)]+)\) = (\S+)/) { - if ( $distfiles{$1}{sum} ne $2 ) { - print $1, " ($sum)\n"; - $bad_distfiles{$1} = 1; - } - } - } - close($out); - waitpid( $pid, 0 ) || fail "xargs digest $sum"; - waitpid( $pid2, 0 ) || fail "pipe write to xargs"; - } - safe_chdir('/'); # Do not want to stay in $pkgdistdir - } - ( sort keys %bad_distfiles ); + my ($pkgsrcdir, $pkgdistdir, $check_unref, $check_distinfo) = @_; + my (@categories); + my (%distfiles, %sumfiles, @distwarn, $numpkg); + my (%bad_distfiles); + + @categories = list_pkgsrc_categories($pkgsrcdir); + + verbose('Scan distinfo: ' . '_' x @categories . "\b" x @categories); + $numpkg = 0; + foreach my $cat (sort @categories) { + foreach my $pkgdir (list_pkgsrc_pkgdirs($pkgsrcdir, $cat)) { + if (open(DISTINFO, "$pkgsrcdir/$cat/$pkgdir/distinfo")) { + ++$numpkg; + while () { + if (m/^(\w+) ?\(([^\)]+)\) = (\S+)/) { + my ($dn, $ds, $dt); + $dt = $1; + $dn = $2; + $ds = $3; + if ($dn =~ /^patch-[\w.+\-]+$/) { + next; + } + + # Strip leading ./ which sometimes gets added + # because of DISTSUBDIR=. + $dn =~ s/^(\.\/)*//; + if (!defined $distfiles{$dn}) { + $distfiles{$dn}{sumtype} = $dt; + $distfiles{$dn}{sum} = $ds; + $distfiles{$dn}{path} = "$cat/$pkgdir"; + + } + elsif ($distfiles{$dn}{sumtype} eq $dt && $distfiles{$dn}{sum} ne $ds) { + push(@distwarn, + "checksum mismatch between '$dt' for '$dn' " + . "in $cat/$pkgdir and $distfiles{$dn}{path}\n" + ); + } + } + } + close(DISTINFO); + } + } + verbose('.'); + } + verbose(" ($numpkg packages)\n"); + + # check each file in $pkgdistdir + find({ wanted => sub { + my ($dist); + if (-f $File::Find::name) { + my $distn = $File::Find::name; + $distn =~ s/$pkgdistdir\/?//g; + #pkg/47516 ignore cvs dirs + return if $distn =~ m/^\.cvsignore/; + return if $distn =~ m/^CVS\//; + if (!defined($dist = $distfiles{$distn})) { + $bad_distfiles{$distn} = 1; + } elsif ($dist->{sum} ne 'IGNORE') { + push(@{$sumfiles{ $dist->{sumtype} }}, $distn); + } + } + } }, + ($pkgdistdir)); + + if ($check_unref && %bad_distfiles) { + verbose(scalar(keys %bad_distfiles), + " unreferenced file(s) in '$pkgdistdir':\n"); + print join("\n", sort keys %bad_distfiles), "\n"; + } + + if ($check_distinfo) { + if (@distwarn) { + verbose(@distwarn); + } + + verbose("checksum mismatches\n"); + safe_chdir($pkgdistdir); + foreach my $sum (keys %sumfiles) { + if ($sum eq 'Size') { + foreach my $file (@{$sumfiles{$sum}}) { + if (!-f $file || -S $file != $distfiles{$file}{sum}) { + print $file, " (Size)\n"; + $bad_distfiles{$file} = 1; + } + } + next; + } + + my $pid = open3(my $in, my $out, undef, "xargs", "digest", $sum); + defined($pid) || fail "fork"; + my $pid2 = fork(); + defined($pid2) || fail "fork"; + if ($pid2) { + close($in); + } else { + print $in "@{$sumfiles{$sum}}"; + exit 0; + } + while (<$out>) { + if (m/^$sum ?\(([^\)]+)\) = (\S+)/) { + if ($distfiles{$1}{sum} ne $2) { + print $1, " ($sum)\n"; + $bad_distfiles{$1} = 1; + } + } + } + close($out); + waitpid($pid, 0) || fail "xargs digest $sum"; + waitpid($pid2, 0) || fail "pipe write to xargs"; + } + safe_chdir('/'); # Do not want to stay in $pkgdistdir + } + (sort keys %bad_distfiles); } sub load_pkgsrc_makefiles() { - open( STORE, "<$_[0]" ) || die("Cannot read pkgsrc store from $_[0]: $!\n"); - my ($pkgver); - our ( $pkgcnt, $pkgnum, $subpkgcnt, $subpkgnum ); - $pkglist = new PkgList; - while () { - debug("eval store $_"); - eval $_; - } - close(STORE); + open(STORE, "<$_[0]") || die("Cannot read pkgsrc store from $_[0]: $!\n"); + my ($pkgver); + our ($pkgcnt, $pkgnum, $subpkgcnt, $subpkgnum); + $pkglist = new PkgList; + while () { + debug("eval store $_"); + eval $_; + } + close(STORE); } sub store_pkgsrc_makefiles() { - open( STORE, ">$_[0]" ) || die("Cannot save pkgsrc store to $_[0]: $!\n"); - my $was = select(STORE); - print( - 'sub __pkgcount { $subpkgnum += $_[0]; ', - 'verbose("\rReading pkgsrc database: ', - '$pkgnum / $pkgcnt ($subpkgnum / $subpkgcnt) pkgs"); }', - "\n" - ); - $pkglist->store; - print("verbose(\"...done\\n\");\n"); - select($was); - close(STORE); + open(STORE, ">$_[0]") || die("Cannot save pkgsrc store to $_[0]: $!\n"); + my $was = select(STORE); + print( + 'sub __pkgcount { $subpkgnum += $_[0]; ', + 'verbose("\rReading pkgsrc database: ', + '$pkgnum / $pkgcnt ($subpkgnum / $subpkgcnt) pkgs"); }', + "\n" + ); + $pkglist->store; + print("verbose(\"...done\\n\");\n"); + select($was); + close(STORE); } # Remember to update manual page when modifying option list # sub usage_and_exit() { - print "Usage: lintpkgsrc [opts] [makefiles] + print "Usage: lintpkgsrc [opts] [makefiles] opts: -h : This help. [see lintpkgsrc(1) for more information] @@ -1747,19 +1681,19 @@ () -D : Debug makefile and glob parsing -L : List each Makefile when scanned "; - exit; + exit; } sub verbose(@) { - if ( -t STDERR ) { - print STDERR @_; - } + if (-t STDERR) { + print STDERR @_; + } } sub debug(@) { - ( $opt{D} ) && print STDERR 'DEBUG: ', @_; + ($opt{D}) && print STDERR 'DEBUG: ', @_; } # PkgList is the master list of all packages in pkgsrc. @@ -1767,76 +1701,74 @@ (@) package PkgList; sub add($@) { - my $self = shift; + my $self = shift; - if ( !$self->pkgs( $_[0] ) ) { - $self->{_pkgs}{ $_[0] } = new Pkgs $_[0]; - } - $self->pkgs( $_[0] )->add(@_); + if (!$self->pkgs($_[0])) { + $self->{_pkgs}{ $_[0] } = new Pkgs $_[0]; + } + $self->pkgs($_[0])->add(@_); } sub new($) { - my $class = shift; - my $self = {}; - bless $self, $class; - return $self; + my $class = shift; + my $self = {}; + bless $self, $class; + return $self; } sub numpkgver($) { - my $self = shift; - scalar( $self->pkgver ); + my $self = shift; + scalar($self->pkgver); } sub pkgver($@) { - my $self = shift; - - if ( @_ == 0 ) { - my (@list); - foreach my $pkg ( $self->pkgs ) { - push( @list, $pkg->pkgver ); - } - return (@list); - } - - if ( defined $self->{_pkgs}{ $_[0] } ) { - return ( @_ > 1 ) - ? $self->{_pkgs}{ $_[0] }->pkgver( $_[1] ) - : $self->{_pkgs}{ $_[0] }->pkgver(); - } - return; + my $self = shift; + + if (@_ == 0) { + my (@list); + foreach my $pkg ($self->pkgs) { + push(@list, $pkg->pkgver); + } + return (@list); + } + + if (defined $self->{_pkgs}{$_[0]}) { + return (@_ > 1) + ? $self->{_pkgs}{$_[0]}->pkgver($_[1]) + : $self->{_pkgs}{$_[0]}->pkgver(); + } + return; } sub pkgs($@) { - my $self = shift; - - if (@_) { - return $self->{_pkgs}{ $_[0] }; - } - else { - return ( sort { $a->pkg cmp $b->pkg } values %{ $self->{_pkgs} } ); - } - return; + my $self = shift; + + if (@_) { + return $self->{_pkgs}{$_[0]}; + } else { + return (sort { $a->pkg cmp $b->pkg } values %{$self->{_pkgs}}); + } } sub store($) { - my $self = shift; - my @pkgs = keys %{ $self->{_pkgs} }; - my ( $cnt, $subcnt ) = $self->count; + my $self = shift; + my @pkgs = keys %{$self->{_pkgs}}; + my ($cnt, $subcnt) = $self->count; - print("\$pkgcnt = $cnt;\n"); - print("\$subpkgcnt = $subcnt;\n"); - map( $self->{_pkgs}{$_}->store, keys %{ $self->{_pkgs} } ); + print("\$pkgcnt = $cnt;\n"); + print("\$subpkgcnt = $subcnt;\n"); + map($self->{_pkgs}{$_}->store, keys %{$self->{_pkgs}}); } sub count($) { - my $self = shift; - my ( $pkgcnt, $pkgsubcnt ); - - map { - $pkgcnt++; - $pkgsubcnt += $self->{_pkgs}{$_}->count; - } keys %{ $self->{_pkgs} }; - wantarray ? ( $pkgcnt, $pkgsubcnt ) : $pkgcnt; + my $self = shift; + my ($pkgcnt, $pkgsubcnt); + + map { + $pkgcnt++; + $pkgsubcnt += $self->{_pkgs}{$_}->count; + } keys %{$self->{_pkgs}}; + wantarray ? ($pkgcnt, $pkgsubcnt) : $pkgcnt; } # Pkgs is all versions of a given package (eg: apache-1.x and apache-2.x) @@ -1844,60 +1776,60 @@ ($) package Pkgs; sub add($@) { - my $self = shift; + my $self = shift; - $self->{_pkgver}{ $_[1] } = new PkgVer @_; + $self->{_pkgver}{$_[1]} = new PkgVer @_; } sub new($@) { - my $class = shift; - my $self = {}; + my $class = shift; + my $self = {}; - bless $self, $class; - $self->{_pkg} = $_[0]; - return $self; + bless $self, $class; + $self->{_pkg} = $_[0]; + return $self; } sub versions($) { - my $self = shift; + my $self = shift; - return sort { $b cmp $a } keys %{ $self->{_pkgver} }; + return sort { $b cmp $a } keys %{$self->{_pkgver}}; } sub pkg($) { - my $self = shift; - $self->{_pkg}; + my $self = shift; + $self->{_pkg}; } sub pkgver($@) { - my $self = shift; - - if (@_) { - if ( $self->{_pkgver}{ $_[0] } ) { - return ( $self->{_pkgver}{ $_[0] } ); - } - return; - } - return sort { $b->ver() cmp $a->ver() } values %{ $self->{_pkgver} }; + my $self = shift; + + if (@_) { + if ($self->{_pkgver}{$_[0]}) { + return ($self->{_pkgver}{$_[0]}); + } + return; + } + return sort { $b->ver() cmp $a->ver() } values %{$self->{_pkgver}}; } sub latestver($) { - my $self = shift; + my $self = shift; - ( $self->pkgver() )[0]; + ($self->pkgver())[0]; } sub store($) { - my $self = shift; + my $self = shift; - print("\$pkgnum++;\n"); - map( $self->{_pkgver}{$_}->store, keys %{ $self->{_pkgver} } ); + print("\$pkgnum++;\n"); + map($self->{_pkgver}{$_}->store, keys %{$self->{_pkgver}}); } sub count($) { - my $self = shift; + my $self = shift; - scalar( keys %{ $self->{_pkgver} } ); + scalar(keys %{$self->{_pkgver}}); } # PkgVer is a unique package+version @@ -1905,62 +1837,62 @@ ($) package PkgVer; sub new($$$) { - my $class = shift; - my $self = {}; + my $class = shift; + my $self = {}; - bless $self, $class; - $self->{_pkg} = $_[0]; - $self->{_ver} = $_[1]; - return $self; + bless $self, $class; + $self->{_pkg} = $_[0]; + $self->{_ver} = $_[1]; + return $self; } sub pkgname($) { - my $self = shift; + my $self = shift; - $self->pkg . '-' . $self->ver; + $self->pkg . '-' . $self->ver; } sub pkg($) { - my $self = shift; + my $self = shift; - $self->{_pkg}; + $self->{_pkg}; } sub var($$$) { - my $self = shift; - my ( $key, $val ) = @_; + my $self = shift; + my ($key, $val) = @_; - ( defined $val ) - ? ( $self->{$key} = $val ) - : $self->{$key}; + (defined $val) + ? ($self->{$key} = $val) + : $self->{$key}; } sub ver($) { - my $self = shift; + my $self = shift; - $self->{_ver}; + $self->{_ver}; } sub vars($) { - my $self = shift; + my $self = shift; - grep( !/^_(pkg|ver)$/, keys %{$self} ); + grep(!/^_(pkg|ver)$/, keys %{$self}); } sub store($) { - my $self = shift; - my $data; + my $self = shift; + my $data; - ( $data = $self->{_pkg} ) =~ s/([\\\$\@\%\"])/\\$1/g; - print("\$pkgver = \$pkglist->add(\"$data\", \""); + ($data = $self->{_pkg}) =~ s/([\\\$\@\%\"])/\\$1/g; + print("\$pkgver = \$pkglist->add(\"$data\", \""); - ( $data = $self->{_ver} ) =~ s/([\\\$\@\%\"])/\\$1/g; - print("$data\"); __pkgcount(1);\n"); + ($data = $self->{_ver}) =~ s/([\\\$\@\%\"])/\\$1/g; + print("$data\"); __pkgcount(1);\n"); - foreach ( $self->vars ) { - ( $data = $self->{$_} ) =~ s/([\\\$\@\%\"])/\\$1/g; - print("\$pkgver->var(\"$_\", \"$data\");\n"); - } + foreach ($self->vars) { + ($data = $self->{$_}) =~ s/([\\\$\@\%\"])/\\$1/g; + print("\$pkgver->var(\"$_\", \"$data\");\n"); + } } package main; From f57b2280fbdaf44cdba23e692933b7982776b248 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 06:25:51 +0000 Subject: [PATCH 02/37] lintpkgsrc: condense 'else' and 'elsif' --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 174 ++++++++---------------- 1 file changed, 58 insertions(+), 116 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index c8d0a2914a7f..ae20650b08bb 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.24 2022/07/30 06:21:17 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.25 2022/07/30 06:25:51 rillig Exp $ # Written by David Brownlee . # @@ -333,8 +333,7 @@ () while () { if (/Required by:/) { $list = 1; - } - elsif ($list) { + } elsif ($list) { chomp; s/-\d.*//; print " $_"; @@ -384,8 +383,7 @@ () # Skip these subdirs if present $File::Find::prune = 1; - } - elsif (/(.+)-(\d.*)\.t[bg]z$/) { + } elsif (/(.+)-(\d.*)\.t[bg]z$/) { my ($pkg, $ver) = ($1, $2); $pkg = canonicalize_pkgname($pkg); @@ -415,8 +413,7 @@ () } } - } - elsif (-d $_) { + } elsif (-d $_) { if ($prebuilt_pkgdir_cache{"$File::Find::dir/$_"}) { $File::Find::prune = 1; return; @@ -479,26 +476,19 @@ (@) foreach $elem (@_) { if ($elem =~ /\d+/) { push(@temp, $elem); - } - elsif ($elem =~ /^pl$/ or $elem =~ /^\.$/) { + } elsif ($elem =~ /^pl$/ or $elem =~ /^\.$/) { push(@temp, 0); - } - elsif ($elem =~ /^_$/) { + } elsif ($elem =~ /^_$/) { push(@temp, 0); - } - elsif ($elem =~ /^pre$/) { + } elsif ($elem =~ /^pre$/) { push(@temp, -1); - } - elsif ($elem =~ /^rc$/) { + } elsif ($elem =~ /^rc$/) { push(@temp, -1); - } - elsif ($elem =~ /^beta$/) { + } elsif ($elem =~ /^beta$/) { push(@temp, -2); - } - elsif ($elem =~ /^alpha$/) { + } elsif ($elem =~ /^alpha$/) { push(@temp, -3); - } - else { + } else { push(@temp, 0); push(@temp, ord($elem) - ord("a") + 1); } @@ -516,8 +506,7 @@ ($$) $i = 0; if ($#matchlist > $#vallist) { $len = $#matchlist; - } - else { + } else { $len = $#vallist; } while (!$cmp && ($i++ <= $len)) { @@ -569,8 +558,7 @@ () if ($opt{P}) { $default_vars->{PKGSRCDIR} = realpath($opt{P}); - } - else { + } else { $default_vars->{PKGSRCDIR} = $conf_pkgsrcdir; } @@ -583,8 +571,7 @@ () foreach my $var (keys %{$vars}) { $default_vars->{$var} = $vars->{$var}; } - } - elsif (-f ${conf_sysconfdir} . '/mk.conf' && + } elsif (-f ${conf_sysconfdir} . '/mk.conf' && ($vars = parse_makefile_vars(${conf_sysconfdir} . '/mk.conf'))) { foreach my $var (keys %{$vars}) { $default_vars->{$var} = $vars->{$var}; @@ -597,8 +584,7 @@ () if ($opt{M}) { $default_vars->{DISTDIR} = realpath($opt{M}); - } - else { + } else { $default_vars->{DISTDIR} ||= $default_vars->{PKGSRCDIR} . '/distfiles'; } @@ -637,8 +623,7 @@ ($) foreach (split(',', $2)) { push(@todo, "$1$_$3"); } - } - else { + } else { push(@pkgmatches, $pkgmatch); } } @@ -653,12 +638,10 @@ ($) $fail .= "Version mismatch: '$pkg' $badver vs " . join(',', $pkgs->versions) . "\n"; - } - else { + } else { $fail .= "Unknown package: '$pkg' version $badver\n"; } - } - else { + } else { # If we find one match, don't bitch about others $ok = 1; @@ -681,8 +664,7 @@ ($$) if (defined($dir)) { $thisdir .= "/$dir"; $dir .= '/'; - } - else { + } else { $dir = ''; } @@ -692,8 +674,7 @@ ($$) foreach my $entry (@thislist) { if (-d "$thisdir/$entry") { push(@list, listdir($base, "$dir$entry")); - } - else { + } else { push(@list, "$dir$entry"); } } @@ -759,35 +740,27 @@ ($) while (defined($_ = shift @chars)) { if ($_ eq '*') { $regex .= '.*'; - } - elsif ($_ eq '?') { + } elsif ($_ eq '?') { $regex .= '.'; - } - elsif ($_ eq '+') { + } elsif ($_ eq '+') { $regex .= '.'; - } - elsif ($_ eq '\\+') { + } elsif ($_ eq '\\+') { $regex .= $_ . shift @chars; - } - elsif ($_ eq '.' || $_ eq '|') { + } elsif ($_ eq '.' || $_ eq '|') { $regex .= quotemeta; - } - elsif ($_ eq '{') { + } elsif ($_ eq '{') { $regex .= '('; ++$in_alt; - } - elsif ($_ eq '}') { + } elsif ($_ eq '}') { if (!$in_alt) { # Error return undef; } $regex .= ')'; --$in_alt; - } - elsif ($_ eq ',' && $in_alt) { + } elsif ($_ eq ',' && $in_alt) { $regex .= '|'; - } - else { + } else { $regex .= $_; } } @@ -826,8 +799,7 @@ ($) $matchver = undef; last; } - } - else { + } else { if (deweycmp($pkgver->ver, $test, $matchver)) { $matchver = undef; last; @@ -840,8 +812,7 @@ ($) } } - } - elsif ($pkgmatch =~ /^([^[]+)-([\d*?{[].*)$/) { + } elsif ($pkgmatch =~ /^([^[]+)-([\d*?{[].*)$/) { # (package)-(globver) my (@pkgnames); @@ -851,8 +822,7 @@ ($) if (defined $pkglist->pkgs($matchpkgname)) { push(@pkgnames, $matchpkgname); - } - elsif ($regex = glob2regex($matchpkgname)) { + } elsif ($regex = glob2regex($matchpkgname)) { foreach my $pkg ($pkglist->pkgs) { ($pkg->pkg() =~ /$regex/) && push(@pkgnames, $pkg->pkg()); } @@ -892,8 +862,7 @@ ($) } } - } - else { + } else { ($matchpkgname, $matchver) = ($pkgmatch, 'missing'); } @@ -916,8 +885,7 @@ ($) if (defined $vars->{PKGNAME}) { $pkgname = $vars->{PKGNAME}; - } - elsif (defined $vars->{DISTNAME}) { + } elsif (defined $vars->{DISTNAME}) { $pkgname = $vars->{DISTNAME}; } @@ -937,8 +905,7 @@ ($) "cd $pkgsrcdir || exit 1; ${conf_make} show-vars VARNAMES=PKGNAME"); if (!$pid) { warn "$file: Unable to run make: $!"; - } - else { + } else { close(WTR); my @errors = ; close(ERR); @@ -965,12 +932,10 @@ ($) and not $vars->{PKGREVISION} =~ /^\s*$/) { if ($vars->{PKGREVISION} =~ /^\$\{(_(CVS|GIT|HG|SVN)_PKGVERSION):.*\}$/) { # See wip/mk/*-package.mk. - } - elsif ($vars->{PKGREVISION} =~ /\D/) { + } elsif ($vars->{PKGREVISION} =~ /\D/) { print "\nBogus: PKGREVISION $vars->{PKGREVISION} (from $file)\n"; - } - elsif ($vars->{PKGREVISION}) { + } elsif ($vars->{PKGREVISION}) { $pkgname .= "nb"; $pkgname .= $vars->{PKGREVISION}; } @@ -979,8 +944,7 @@ ($) if ($pkgname =~ /\$/) { print "\nBogus: $pkgname (from $file)\n"; - } - elsif ($pkgname =~ /(.*)-(\d.*)/) { + } elsif ($pkgname =~ /(.*)-(\d.*)/) { if ($pkglist) { my ($pkgver) = $pkglist->add($1, $2); @@ -996,20 +960,17 @@ ($) if ($file =~ m:([^/]+/[^/]+)/Makefile$:) { $pkgver->var('dir', $1); - } - else { + } else { $pkgver->var('dir', 'unknown'); } } - } - else { + } else { print "Cannot extract $pkgname version ($file)\n"; } return ($pkgname, $vars); - } - else { + } else { return (undef); } } @@ -1039,19 +1000,16 @@ ($$) # Some Makefiles depend on these being set if ($file eq '/etc/mk.conf') { $vars{LINTPKGSRC} = 'YES'; - } - else { + } else { %vars = %{$default_vars}; } $vars{BSD_PKG_MK} = 'YES'; if ($cwd) { $vars{'.CURDIR'} = $cwd; - } - elsif ($file =~ m#(.*)/#) { + } elsif ($file =~ m#(.*)/#) { $vars{'.CURDIR'} = $1; - } - else { + } else { $vars{'.CURDIR'} = getcwd; } @@ -1078,13 +1036,11 @@ ($$) if ($if_false[$#if_false]) { push(@if_false, 2); - } - elsif ($type eq '') { + } elsif ($type eq '') { # Straight if push(@if_false, parse_eval_make_false($2, \%vars)); - } - else { + } else { $false = !defined($vars{ parse_expand_vars($2, \%vars) }); if ($type eq 'ndef') { $false = !$false; @@ -1098,8 +1054,7 @@ ($$) if (m#^\.\s*elif\s+(.*)# && @if_false) { if ($if_false[$#if_false] == 0) { $if_false[$#if_false] = 2; - } - elsif ($if_false[$#if_false] == 1 + } elsif ($if_false[$#if_false] == 1 && !parse_eval_make_false($1, \%vars)) { $if_false[$#if_false] = 0; } @@ -1134,8 +1089,7 @@ ($$) || (!$opt{d} && $incfile =~ m#/(buildlink[^/]*\.mk)#)) { debug("$file: .include \"$incfile\" skipped\n"); - } - else { + } else { debug("$file: .include \"$incfile\"\n"); # Expand any simple vars in $incfile @@ -1165,8 +1119,7 @@ ($$) . join(" ", sort keys %incdirs) . "\n"); - } - else { + } else { $incfile = realpath($1) . $2; if (!$incfiles{$incfile}) { @@ -1177,8 +1130,7 @@ ($$) if (!open(FILE, $incfile)) { verbose("Cannot open '$incfile' (from $file): $_ $!\n"); - } - else { + } else { my $NEWCURDIR = $incfile; $NEWCURDIR =~ s#/[^/]*$##; $incdirs{$NEWCURDIR} = 1; @@ -1203,11 +1155,9 @@ ($$) if ($plus eq ':') { $vars{$key} = parse_expand_vars($value, \%vars); - } - elsif ($plus eq '+' && defined $vars{$key}) { + } elsif ($plus eq '+' && defined $vars{$key}) { $vars{$key} .= " $value"; - } - elsif ($plus ne '?' || !defined $vars{$key}) { + } elsif ($plus ne '?' || !defined $vars{$key}) { $vars{$key} = $value; } debug("assignment: $key$plus=[$value] ($vars{$key})\n"); @@ -1244,8 +1194,7 @@ ($$) $vars{$key} = $_; $loop = 1; - } - elsif ($vars{$key} =~ m#\$\{([\w.]+):([CS]([^{}])[^{}\3]+\3[^{}\3]*\3[g1]*(|:[^{}]+)|U[^{}]+)\}#) { + } elsif ($vars{$key} =~ m#\$\{([\w.]+):([CS]([^{}])[^{}\3]+\3[^{}\3]*\3[g1]*(|:[^{}]+)|U[^{}]+)\}#) { my ($left, $subvar, $right) = ($`, $1, $'); my (@patterns) = split(':', $2); my ($result); @@ -1264,9 +1213,7 @@ ($$) foreach (@patterns) { if (m#(U)(.*)#) { $result ||= $2; - } - elsif (m#([CS])(.)([^/@]+)\2([^/@]*)\2([1g]*)#) { - + } elsif (m#([CS])(.)([^/@]+)\2([^/@]*)\2([1g]*)#) { my ($how, $from, $to, $global) = ($1, $3, $4, $5); debug("$file: substituteglob $subvar, $how, $from, $to, $global\n"); @@ -1288,8 +1235,7 @@ ($$) if (defined $notfirst) { $result .= " $notfirst"; } - } - else { + } else { next; } } @@ -1312,8 +1258,7 @@ ($$) while ($line =~ /\$\{([-\w.]+)\}/) { if (defined(${$vars}{$1})) { $line = $` . ${$vars}{$1} . $'; - } - else { + } else { $line = $` . $magic_undefined . $'; } } @@ -1326,8 +1271,7 @@ ($$) while ($line =~ /\$\{([-\w.]+)\}/) { if (defined(${$vars}{$1})) { $line = $` . ${$vars}{$1} . $'; - } - else { + } else { $line = $` . $magic_undefined . $'; } } @@ -1369,8 +1313,7 @@ ($$) $match = '^' . $match . '$'; $var = ($var =~ /$match/) if defined $var; - } - else { + } else { $var = $${vars}{$varname}; $var = parse_expand_vars($var, $vars) if defined $var; @@ -1537,8 +1480,7 @@ ($$$$) $distfiles{$dn}{sum} = $ds; $distfiles{$dn}{path} = "$cat/$pkgdir"; - } - elsif ($distfiles{$dn}{sumtype} eq $dt && $distfiles{$dn}{sum} ne $ds) { + } elsif ($distfiles{$dn}{sumtype} eq $dt && $distfiles{$dn}{sum} ne $ds) { push(@distwarn, "checksum mismatch between '$dt' for '$dn' " . "in $cat/$pkgdir and $distfiles{$dn}{path}\n" From df17666bc28d79ae44d3be76b9f4d91f5f2881ed Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 06:49:04 +0000 Subject: [PATCH 03/37] p5-Moose: fix typo "can to" in DESCR, re-wrap description --- devel/p5-Moose/DESCR | 18 +++++++++--------- devel/p5-Moose/Makefile | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/devel/p5-Moose/DESCR b/devel/p5-Moose/DESCR index 83d70bf585e2..845f2c28e972 100644 --- a/devel/p5-Moose/DESCR +++ b/devel/p5-Moose/DESCR @@ -1,9 +1,9 @@ -Moose is an extension of the Perl 5 object system. -The main goal of Moose is to make Perl 5 Object Oriented programming -easier, more consistent and less tedious. With Moose you can to -think more about what you want to do and less about the mechanics -of OOP. -Additionally, Moose is built on top of Class::MOP, which is a -metaclass system for Perl 5. This means that Moose not only makes -building normal Perl 5 objects better, but it provides the power -of metaclass programming as well. +Moose is an extension of the Perl 5 object system. The main goal of +Moose is to make Perl 5 Object Oriented programming easier, more +consistent and less tedious. With Moose you can think more about what +you want to do and less about the mechanics of OOP. + +Additionally, Moose is built on top of Class::MOP, which is a metaclass +system for Perl 5. This means that Moose not only makes building normal +Perl 5 objects better, but it provides the power of metaclass +programming as well. diff --git a/devel/p5-Moose/Makefile b/devel/p5-Moose/Makefile index 61212fff1f76..b7370fdeea23 100644 --- a/devel/p5-Moose/Makefile +++ b/devel/p5-Moose/Makefile @@ -1,8 +1,8 @@ -# $NetBSD: Makefile,v 1.124 2022/06/28 11:32:51 wiz Exp $ +# $NetBSD: Makefile,v 1.125 2022/07/30 06:49:04 rillig Exp $ DISTNAME= Moose-2.2201 PKGNAME= p5-${DISTNAME} -PKGREVISION= 1 +PKGREVISION= 2 CATEGORIES= devel perl5 MASTER_SITES= ${MASTER_SITE_PERL_CPAN:=Test/} From be34e6ee7b823fd71f1a69f2f910ab4ebbe73fb1 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 06:56:40 +0000 Subject: [PATCH 04/37] lintpkgsrc: cleanup: remove redundant curly braces around variable names --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index ae20650b08bb..73c645505329 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.25 2022/07/30 06:25:51 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.26 2022/07/30 06:56:40 rillig Exp $ # Written by David Brownlee . # @@ -45,7 +45,7 @@ sub parse_makefile_pkgsrc($); $ENV{PATH} .= - ":/bin:/usr/bin:/sbin:/usr/sbin:${conf_prefix}/sbin:${conf_prefix}/bin"; + ":/bin:/usr/bin:/sbin:/usr/sbin:$conf_prefix/sbin:$conf_prefix/bin"; if ( !getopts('BDE:I:K:LM:OP:RSVdg:himopruyz', \%opt) @@ -344,7 +344,7 @@ () print "\n"; } - print "\nRunning '${conf_make} fetch-list | sh' for each package:\n"; + print "\nRunning '$conf_make fetch-list | sh' for each package:\n"; foreach my $pkgver (@update) { my ($pkgdir); @@ -355,7 +355,7 @@ () print "$pkgsrcdir/$pkgdir\n"; safe_chdir("$pkgsrcdir/$pkgdir"); - system("${conf_make} fetch-list | sh"); + system("$conf_make fetch-list | sh"); } } } @@ -571,8 +571,8 @@ () foreach my $var (keys %{$vars}) { $default_vars->{$var} = $vars->{$var}; } - } elsif (-f ${conf_sysconfdir} . '/mk.conf' && - ($vars = parse_makefile_vars(${conf_sysconfdir} . '/mk.conf'))) { + } elsif (-f "$conf_sysconfdir/mk.conf" && + ($vars = parse_makefile_vars("$conf_sysconfdir/mk.conf"))) { foreach my $var (keys %{$vars}) { $default_vars->{$var} = $vars->{$var}; } @@ -902,7 +902,7 @@ ($) my ($pkgsrcdir) = ($file =~ m:(/.*)/:); debug("Running '$conf_make' in '$pkgsrcdir'\n"); my $pid = open3(\*WTR, \*RDR, \*ERR, - "cd $pkgsrcdir || exit 1; ${conf_make} show-vars VARNAMES=PKGNAME"); + "cd $pkgsrcdir || exit 1; $conf_make show-vars VARNAMES=PKGNAME"); if (!$pid) { warn "$file: Unable to run make: $!"; } else { From 949a293bb1a021acecd0ea4116eeecf639c1e8d5 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 07:37:03 +0000 Subject: [PATCH 05/37] lintpkgsrc: cleanup: move main code to the bottom Moving the code revealed some more mismatches in the prototypes of the subs. In order to detect them properly, the sub must be declared before it is called. No functional change. --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 847 ++++++++++++------------ 1 file changed, 423 insertions(+), 424 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 73c645505329..ea0165c46f7e 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.26 2022/07/30 06:56:40 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.27 2022/07/30 07:37:03 rillig Exp $ # Written by David Brownlee . # @@ -44,461 +44,143 @@ sub fail($); sub parse_makefile_pkgsrc($); -$ENV{PATH} .= - ":/bin:/usr/bin:/sbin:/usr/sbin:$conf_prefix/sbin:$conf_prefix/bin"; - -if ( - !getopts('BDE:I:K:LM:OP:RSVdg:himopruyz', \%opt) - || $opt{h} - || !(defined $opt{d} - || defined $opt{g} - || defined $opt{i} - || defined $opt{m} - || defined $opt{o} - || defined $opt{p} - || defined $opt{r} - || defined $opt{u} - || defined $opt{B} - || defined $opt{D} - || defined $opt{R} - || defined $opt{O} - || defined $opt{S} - || defined $opt{E} - || defined $opt{y} - || defined $opt{z})) { - usage_and_exit(); -} -$| = 1; - # Horrible kludge to ensure we have a value for testing in conditionals, but # gets removed in the final evaluation my $magic_undefined = 'M_a_G_i_C_uNdEfInEd'; -get_default_makefile_vars(); # $default_vars - -if ($opt{D} && @ARGV) { - foreach my $file (@ARGV) { - if (-d $file) { - $file .= "/Makefile"; - } - if (!-f $file) { - fail("No such file: $file"); - } - my ($pkgname, $vars) = parse_makefile_pkgsrc($file); - $pkgname ||= 'uNDEFINEd'; - print "$file -> $pkgname\n"; - foreach my $varname (sort keys %{$vars}) { - print "\t$varname = $vars->{$varname}\n"; - } +sub canonicalize_pkgname($) { + my ($pkgname) = @_; - #if ($opt{d}) { - # pkgsrc_check_depends(); - #} - } - exit; + $pkgname =~ s,^py\d+(?:pth|)-,py-,; + $pkgname =~ s,^ruby\d+-,ruby-,; + $pkgname =~ s,^php\d+-,php-,; + return $pkgname; } -sub main() { - my ($pkgsrcdir, $pkgdistdir); - - $pkgsrcdir = $default_vars->{PKGSRCDIR}; - $pkgdistdir = $default_vars->{DISTDIR}; - - if ($opt{r} && !$opt{o} && !$opt{m} && !$opt{p}) { - $opt{o} = $opt{m} = $opt{p} = 1; - } - if ($opt{o} || $opt{m}) { - my (@baddist); +# Could speed up by building a cache of package names to paths, then processing +# each package name once against the tests. +sub check_prebuilt_packages() { - @baddist = scan_pkgsrc_distfiles_vs_distinfo( - $pkgsrcdir, $pkgdistdir, $opt{o}, $opt{m}); - if ($opt{r}) { - verbose("Unlinking 'bad' distfiles\n"); - foreach my $distfile (@baddist) { - unlink("$pkgdistdir/$distfile"); - } - } - } + if ($_ eq 'distfiles' || $_ eq 'pkgsrc') { + # Skip these subdirs if present + $File::Find::prune = 1; - # Remove all distfiles that are / are not part of an installed package - if ($opt{y} || $opt{z}) { - my (@pkgs, @installed, %distfiles, @pkgdistfiles, @dldistfiles); - my (@tmpdistfiles, @orphan, $found, @parent); + } elsif (/(.+)-(\d.*)\.t[bg]z$/) { + my ($pkg, $ver) = ($1, $2); - @pkgs = list_installed_packages(); - scan_pkgsrc_makefiles($pkgsrcdir); + $pkg = canonicalize_pkgname($pkg); - # list the installed packages and the directory they live in - foreach my $pkgname (sort @pkgs) { - if ($pkgname =~ /^([^*?[]+)-([\d*?[].*)/) { - foreach my $pkgver ($pkglist->pkgver($1)) { - $pkgver->var('dir') =~ /-current/ && next; - push(@installed, $pkgver); - last; - } - } - } + my ($pkgs); + if ($pkgs = $pkglist->pkgs($pkg)) { + my ($pkgver) = $pkgs->pkgver($ver); - # distfiles belonging to the currently installed packages - foreach my $pkgver (sort @installed) { - if (open(DISTINFO, "$pkgsrcdir/" . $pkgver->var('dir') . "/distinfo")) { - while () { - if (m/^(\w+) ?\(([^\)]+)\) = (\S+)/) { - my ($dn); - if ($2 =~ /^patch-[\w.+\-]+$/) { next; } - $dn = $2; - # Strip leading ./ which sometimes gets added - # because of DISTSUBDIR=. - $dn =~ s/^(\.\/)*//; - if (!defined $distfiles{$dn}) { - $distfiles{$dn}{name} = $dn; - push(@pkgdistfiles, $dn); - } - } + if (!defined $pkgver) { + if ($opt{p}) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); } - close(DISTINFO); - } - } - # distfiles downloaded on the current system - @tmpdistfiles = listdir("$pkgdistdir", undef); - foreach my $tmppkg (@tmpdistfiles) { - if ($tmppkg ne "pkg-vulnerabilities") { - push(@dldistfiles, $tmppkg); + # Pick probably the last version + $pkgver = $pkgs->latestver; } - } - - # sort the two arrays to make searching a bit faster - @dldistfiles = sort { $a cmp $b } @dldistfiles; - @pkgdistfiles = sort { $a cmp $b } @pkgdistfiles; - if ($opt{y}) { - # looking for files that are downloaded on the current system - # but do not belong to any currently installed package i.e. orphaned - $found = 0; - foreach my $dldf (@dldistfiles) { - foreach my $pkgdf (@pkgdistfiles) { - if ($dldf eq $pkgdf) { - $found = 1; - } - } - if ($found != 1) { - push(@orphan, $dldf); - print "Orphaned file: $dldf\n"; - } - $found = 0; + if ($opt{R} && $pkgver->var('RESTRICTED')) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); } - if ($opt{r}) { - safe_chdir("$pkgdistdir"); - verbose("Unlinking 'orphaned' distfiles\n"); - foreach my $distfile (@orphan) { - unlink($distfile) - } + if ($opt{O} && $pkgver->var('OSVERSION_SPECIFIC')) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); } } - if ($opt{z}) { - # looking for files that are downloaded on the current system - # but belong to a currently installed package i.e. parented - $found = 0; - foreach my $pkgdf (@pkgdistfiles) { - foreach my $dldf (@dldistfiles) { - if ($pkgdf eq $dldf) { - $found = 1; - } - } - if ($found == 1) { - push(@parent, $pkgdf); - print "Parented file: $pkgdf\n"; - } - $found = 0; - } + } elsif (-d $_) { + if ($prebuilt_pkgdir_cache{"$File::Find::dir/$_"}) { + $File::Find::prune = 1; + return; } - if ($opt{r}) { - safe_chdir("$pkgdistdir"); - verbose("Unlinking 'parented' distfiles\n"); - foreach my $distfile (@parent) { - unlink($distfile); + $prebuilt_pkgdir_cache{"$File::Find::dir/$_"} = 1; + if (-l $_) { + my ($dest) = readlink($_); + + if (substr($dest, 0, 1) ne '/') { + $dest = "$File::Find::dir/$dest"; + } + if (!$prebuilt_pkgdir_cache{$dest}) { + push(@prebuilt_pkgdirs, $dest); } } } +} - # List BROKEN packages - if ($opt{B}) { - scan_pkgsrc_makefiles($pkgsrcdir); - foreach my $pkgver ($pkglist->pkgver) { - $pkgver->var('BROKEN') || next; - print $pkgver->pkgname . ': ' . $pkgver->var('BROKEN') . "\n"; - } - } +# Dewey decimal verson number matching - or thereabouts +# Also handles 'nb' suffix (checked iff values otherwise identical) +# +sub deweycmp($$$) { + my ($match, $test, $val) = @_; + my ($cmp, $match_nb, $val_nb); - # List obsolete or NO_BIN_ON_FTP/RESTRICTED prebuilt packages - # - if ($opt{p} || $opt{O} || $opt{R}) { - scan_pkgsrc_makefiles($pkgsrcdir); + $match_nb = $val_nb = 0; + if ($match =~ /(.*)nb(.*)/) { + # Handle nb suffix + $match = $1; + $match_nb = $2; + } - @prebuilt_pkgdirs = ($default_vars->{PACKAGES}); - %prebuilt_pkgdir_cache = (); + if ($val =~ /(.*)nb(.*)/) { + # Handle nb suffix + $val = $1; + $val_nb = $2; + } - while (@prebuilt_pkgdirs) { - find(\&check_prebuilt_packages, shift @prebuilt_pkgdirs); - } + $cmp = deweycmp_extract($match, $val); - if ($opt{r}) { - verbose("Unlinking listed prebuilt packages\n"); - foreach my $pkgfile (@matched_prebuiltpackages) { - unlink($pkgfile); - } - } + if (!$cmp) { + # Iff otherwise identical, check nb suffix + $cmp = deweycmp_extract($match_nb, $val_nb); } - if ($opt{S}) { - my (%in_subdir); - - foreach my $cat (list_pkgsrc_categories($pkgsrcdir)) { - my $vars = parse_makefile_vars("$pkgsrcdir/$cat/Makefile"); + debug("eval deweycmp $cmp $test 0\n"); + eval "$cmp $test 0"; +} - if (!$vars->{SUBDIR}) { - print "Warning - no SUBDIR for $cat\n"; - next; - } - foreach my $pkgdir (split(/\s+/, $vars->{SUBDIR})) { - $in_subdir{"$cat/$pkgdir"} = 1; - } - } +sub convert_to_standard_dewey(@) { + my ($elem, $underscore, @temp); - scan_pkgsrc_makefiles($pkgsrcdir); - foreach my $pkgver ($pkglist->pkgver) { - if (!defined $in_subdir{ $pkgver->var('dir') }) { - print $pkgver->var('dir') . ": Not in SUBDIR\n"; - } + # According to the current implementation in pkg_install/lib/str.c + # as of 2002/06/02, '_' before a number, '.', and 'pl' get treated as 0, + # while 'rc' and 'pre' get treated as -1; beta as '-2', alpha as '-3'. + # Other characters are converted to lower + # case and then to a number: a->1, b->2, c->3, etc. Numbers stay the same. + # 'nb' is a special case that's already been handled when we are here. + foreach $elem (@_) { + if ($elem =~ /\d+/) { + push(@temp, $elem); + } elsif ($elem =~ /^pl$/ or $elem =~ /^\.$/) { + push(@temp, 0); + } elsif ($elem =~ /^_$/) { + push(@temp, 0); + } elsif ($elem =~ /^pre$/) { + push(@temp, -1); + } elsif ($elem =~ /^rc$/) { + push(@temp, -1); + } elsif ($elem =~ /^beta$/) { + push(@temp, -2); + } elsif ($elem =~ /^alpha$/) { + push(@temp, -3); + } else { + push(@temp, 0); + push(@temp, ord($elem) - ord("a") + 1); } } + @temp; +} - if ($opt{g}) { - my $tmpfile = "$opt{g}.tmp.$$"; - - scan_pkgsrc_makefiles($pkgsrcdir); - if (!open(TABLE, ">$tmpfile")) { - fail("Unable to write '$tmpfile': $!"); - } - foreach my $pkgver ($pkglist->pkgver) { - print TABLE $pkgver->pkg . "\t" - . $pkgver->var('dir') . "\t" - . $pkgver->ver . "\n"; - } - if (!close(TABLE)) { - fail("Error while writing '$tmpfile': $!"); - } - if (!rename($tmpfile, $opt{g})) { - fail("Error in rename('$tmpfile','$opt{g}'): $!"); - } - } - - if ($opt{d}) { - scan_pkgsrc_makefiles($pkgsrcdir); - pkgsrc_check_depends(); - } - - if ($opt{i} || $opt{u}) { - my (@pkgs, @update); - - @pkgs = list_installed_packages(); - scan_pkgsrc_makefiles($pkgsrcdir); - - foreach my $pkgname (sort @pkgs) { - if ($_ = invalid_version($pkgname)) { - print $_; - - if ($pkgname =~ /^([^*?[]+)-([\d*?[].*)/) { - foreach my $pkgver ($pkglist->pkgver($1)) { - $pkgver->var('dir') =~ /-current/ && next; - push(@update, $pkgver); - last; - } - } - } - } - - if ($opt{u}) { - print "\nREQUIRED details for packages that could be updated:\n"; - - foreach my $pkgver (@update) { - print $pkgver->pkg . ':'; - if (open(PKGINFO, 'pkg_info -R ' . $pkgver->pkg . '|')) { - my ($list); - - while () { - if (/Required by:/) { - $list = 1; - } elsif ($list) { - chomp; - s/-\d.*//; - print " $_"; - } - } - close(PKGINFO); - } - print "\n"; - } - - print "\nRunning '$conf_make fetch-list | sh' for each package:\n"; - foreach my $pkgver (@update) { - my ($pkgdir); - - $pkgdir = $pkgver->var('dir'); - if (!defined($pkgdir)) { - fail('Unable to determine ' . $pkgver->pkg . ' directory'); - } - - print "$pkgsrcdir/$pkgdir\n"; - safe_chdir("$pkgsrcdir/$pkgdir"); - system("$conf_make fetch-list | sh"); - } - } - } - - if ($opt{E}) { - scan_pkgsrc_makefiles($pkgsrcdir); - store_pkgsrc_makefiles($opt{E}); - } -} - -sub canonicalize_pkgname($) { - my ($pkgname) = @_; - - $pkgname =~ s,^py\d+(?:pth|)-,py-,; - $pkgname =~ s,^ruby\d+-,ruby-,; - $pkgname =~ s,^php\d+-,php-,; - return $pkgname; -} - -# Could speed up by building a cache of package names to paths, then processing -# each package name once against the tests. -sub check_prebuilt_packages() { - - if ($_ eq 'distfiles' || $_ eq 'pkgsrc') { - # Skip these subdirs if present - $File::Find::prune = 1; - - } elsif (/(.+)-(\d.*)\.t[bg]z$/) { - my ($pkg, $ver) = ($1, $2); - - $pkg = canonicalize_pkgname($pkg); - - my ($pkgs); - if ($pkgs = $pkglist->pkgs($pkg)) { - my ($pkgver) = $pkgs->pkgver($ver); - - if (!defined $pkgver) { - if ($opt{p}) { - print "$File::Find::dir/$_\n"; - push(@matched_prebuiltpackages, "$File::Find::dir/$_"); - } - - # Pick probably the last version - $pkgver = $pkgs->latestver; - } - - if ($opt{R} && $pkgver->var('RESTRICTED')) { - print "$File::Find::dir/$_\n"; - push(@matched_prebuiltpackages, "$File::Find::dir/$_"); - } - - if ($opt{O} && $pkgver->var('OSVERSION_SPECIFIC')) { - print "$File::Find::dir/$_\n"; - push(@matched_prebuiltpackages, "$File::Find::dir/$_"); - } - } - - } elsif (-d $_) { - if ($prebuilt_pkgdir_cache{"$File::Find::dir/$_"}) { - $File::Find::prune = 1; - return; - } - - $prebuilt_pkgdir_cache{"$File::Find::dir/$_"} = 1; - if (-l $_) { - my ($dest) = readlink($_); - - if (substr($dest, 0, 1) ne '/') { - $dest = "$File::Find::dir/$dest"; - } - if (!$prebuilt_pkgdir_cache{$dest}) { - push(@prebuilt_pkgdirs, $dest); - } - } - } -} - -# Dewey decimal verson number matching - or thereabouts -# Also handles 'nb' suffix (checked iff values otherwise identical) -# -sub deweycmp($$$) { - my ($match, $test, $val) = @_; - my ($cmp, $match_nb, $val_nb); - - $match_nb = $val_nb = 0; - if ($match =~ /(.*)nb(.*)/) { - # Handle nb suffix - $match = $1; - $match_nb = $2; - } - - if ($val =~ /(.*)nb(.*)/) { - # Handle nb suffix - $val = $1; - $val_nb = $2; - } - - $cmp = deweycmp_extract($match, $val); - - if (!$cmp) { - # Iff otherwise identical, check nb suffix - $cmp = deweycmp_extract($match_nb, $val_nb); - } - - debug("eval deweycmp $cmp $test 0\n"); - eval "$cmp $test 0"; -} - -sub convert_to_standard_dewey(@) { - my ($elem, $underscore, @temp); - - # According to the current implementation in pkg_install/lib/str.c - # as of 2002/06/02, '_' before a number, '.', and 'pl' get treated as 0, - # while 'rc' and 'pre' get treated as -1; beta as '-2', alpha as '-3'. - # Other characters are converted to lower - # case and then to a number: a->1, b->2, c->3, etc. Numbers stay the same. - # 'nb' is a special case that's already been handled when we are here. - foreach $elem (@_) { - if ($elem =~ /\d+/) { - push(@temp, $elem); - } elsif ($elem =~ /^pl$/ or $elem =~ /^\.$/) { - push(@temp, 0); - } elsif ($elem =~ /^_$/) { - push(@temp, 0); - } elsif ($elem =~ /^pre$/) { - push(@temp, -1); - } elsif ($elem =~ /^rc$/) { - push(@temp, -1); - } elsif ($elem =~ /^beta$/) { - push(@temp, -2); - } elsif ($elem =~ /^alpha$/) { - push(@temp, -3); - } else { - push(@temp, 0); - push(@temp, ord($elem) - ord("a") + 1); - } - } - @temp; -} - -sub deweycmp_extract($$) { - my ($match, $val) = @_; - my ($cmp, @matchlist, @vallist, $i, $len); +sub deweycmp_extract($$) { + my ($match, $val) = @_; + my ($cmp, @matchlist, @vallist, $i, $len); @matchlist = convert_to_standard_dewey(split(/(\D+)/, lc($match))); @vallist = convert_to_standard_dewey(split(/(\D+)/, lc($val))); @@ -567,12 +249,12 @@ () $default_vars->{X11BASE} = '/usr/X11R6'; my ($vars); - if (-f '/etc/mk.conf' && ($vars = parse_makefile_vars('/etc/mk.conf'))) { + if (-f '/etc/mk.conf' && ($vars = parse_makefile_vars('/etc/mk.conf', undef))) { foreach my $var (keys %{$vars}) { $default_vars->{$var} = $vars->{$var}; } } elsif (-f "$conf_sysconfdir/mk.conf" && - ($vars = parse_makefile_vars("$conf_sysconfdir/mk.conf"))) { + ($vars = parse_makefile_vars("$conf_sysconfdir/mk.conf", undef))) { foreach my $var (keys %{$vars}) { $default_vars->{$var} = $vars->{$var}; } @@ -875,7 +557,7 @@ ($) my ($file) = @_; my ($pkgname, $vars); - $vars = parse_makefile_vars($file); + $vars = parse_makefile_vars($file, undef); if (!$vars) { @@ -1377,8 +1059,8 @@ ($) # Generate pkgname->category/pkg mapping, optionally check DEPENDS # -sub scan_pkgsrc_makefiles($$) { - my ($pkgsrcdir, $check_depends) = @_; +sub scan_pkgsrc_makefiles($) { + my ($pkgsrcdir) = @_; my (@categories); if ($pkglist) { @@ -1577,7 +1259,7 @@ () close(STORE); } -sub store_pkgsrc_makefiles() { +sub store_pkgsrc_makefiles($) { open(STORE, ">$_[0]") || die("Cannot save pkgsrc store to $_[0]: $!\n"); my $was = select(STORE); print( @@ -1839,4 +1521,321 @@ ($) package main; +sub main() { + + $ENV{PATH} .= + ":/bin:/usr/bin:/sbin:/usr/sbin:$conf_prefix/sbin:$conf_prefix/bin"; + + if ( + !getopts('BDE:I:K:LM:OP:RSVdg:himopruyz', \%opt) + || $opt{h} + || !(defined $opt{d} + || defined $opt{g} + || defined $opt{i} + || defined $opt{m} + || defined $opt{o} + || defined $opt{p} + || defined $opt{r} + || defined $opt{u} + || defined $opt{B} + || defined $opt{D} + || defined $opt{R} + || defined $opt{O} + || defined $opt{S} + || defined $opt{E} + || defined $opt{y} + || defined $opt{z})) { + usage_and_exit(); + } + $| = 1; + + get_default_makefile_vars(); # $default_vars + + if ($opt{D} && @ARGV) { + foreach my $file (@ARGV) { + if (-d $file) { + $file .= "/Makefile"; + } + if (!-f $file) { + fail("No such file: $file"); + } + my ($pkgname, $vars) = parse_makefile_pkgsrc($file); + $pkgname ||= 'uNDEFINEd'; + print "$file -> $pkgname\n"; + foreach my $varname (sort keys %{$vars}) { + print "\t$varname = $vars->{$varname}\n"; + } + + #if ($opt{d}) { + # pkgsrc_check_depends(); + #} + } + exit; + } + + my $pkgsrcdir = $default_vars->{PKGSRCDIR}; + my $pkgdistdir = $default_vars->{DISTDIR}; + + if ($opt{r} && !$opt{o} && !$opt{m} && !$opt{p}) { + $opt{o} = $opt{m} = $opt{p} = 1; + } + if ($opt{o} || $opt{m}) { + my (@baddist); + + @baddist = scan_pkgsrc_distfiles_vs_distinfo( + $pkgsrcdir, $pkgdistdir, $opt{o}, $opt{m}); + if ($opt{r}) { + verbose("Unlinking 'bad' distfiles\n"); + foreach my $distfile (@baddist) { + unlink("$pkgdistdir/$distfile"); + } + } + } + + # Remove all distfiles that are / are not part of an installed package + if ($opt{y} || $opt{z}) { + my (@pkgs, @installed, %distfiles, @pkgdistfiles, @dldistfiles); + my (@tmpdistfiles, @orphan, $found, @parent); + + @pkgs = list_installed_packages(); + scan_pkgsrc_makefiles($pkgsrcdir); + + # list the installed packages and the directory they live in + foreach my $pkgname (sort @pkgs) { + if ($pkgname =~ /^([^*?[]+)-([\d*?[].*)/) { + foreach my $pkgver ($pkglist->pkgver($1)) { + $pkgver->var('dir') =~ /-current/ && next; + push(@installed, $pkgver); + last; + } + } + } + + # distfiles belonging to the currently installed packages + foreach my $pkgver (sort @installed) { + if (open(DISTINFO, "$pkgsrcdir/" . $pkgver->var('dir') . "/distinfo")) { + while () { + if (m/^(\w+) ?\(([^\)]+)\) = (\S+)/) { + my ($dn); + if ($2 =~ /^patch-[\w.+\-]+$/) { next; } + $dn = $2; + # Strip leading ./ which sometimes gets added + # because of DISTSUBDIR=. + $dn =~ s/^(\.\/)*//; + if (!defined $distfiles{$dn}) { + $distfiles{$dn}{name} = $dn; + push(@pkgdistfiles, $dn); + } + } + } + close(DISTINFO); + } + } + + # distfiles downloaded on the current system + @tmpdistfiles = listdir("$pkgdistdir", undef); + foreach my $tmppkg (@tmpdistfiles) { + if ($tmppkg ne "pkg-vulnerabilities") { + push(@dldistfiles, $tmppkg); + } + } + + # sort the two arrays to make searching a bit faster + @dldistfiles = sort { $a cmp $b } @dldistfiles; + @pkgdistfiles = sort { $a cmp $b } @pkgdistfiles; + + if ($opt{y}) { + # looking for files that are downloaded on the current system + # but do not belong to any currently installed package i.e. orphaned + $found = 0; + foreach my $dldf (@dldistfiles) { + foreach my $pkgdf (@pkgdistfiles) { + if ($dldf eq $pkgdf) { + $found = 1; + } + } + if ($found != 1) { + push(@orphan, $dldf); + print "Orphaned file: $dldf\n"; + } + $found = 0; + } + + if ($opt{r}) { + safe_chdir("$pkgdistdir"); + verbose("Unlinking 'orphaned' distfiles\n"); + foreach my $distfile (@orphan) { + unlink($distfile) + } + } + } + + if ($opt{z}) { + # looking for files that are downloaded on the current system + # but belong to a currently installed package i.e. parented + $found = 0; + foreach my $pkgdf (@pkgdistfiles) { + foreach my $dldf (@dldistfiles) { + if ($pkgdf eq $dldf) { + $found = 1; + } + } + if ($found == 1) { + push(@parent, $pkgdf); + print "Parented file: $pkgdf\n"; + } + $found = 0; + } + } + + if ($opt{r}) { + safe_chdir("$pkgdistdir"); + verbose("Unlinking 'parented' distfiles\n"); + foreach my $distfile (@parent) { + unlink($distfile); + } + } + } + + # List BROKEN packages + if ($opt{B}) { + scan_pkgsrc_makefiles($pkgsrcdir); + foreach my $pkgver ($pkglist->pkgver) { + $pkgver->var('BROKEN') || next; + print $pkgver->pkgname . ': ' . $pkgver->var('BROKEN') . "\n"; + } + } + + # List obsolete or NO_BIN_ON_FTP/RESTRICTED prebuilt packages + # + if ($opt{p} || $opt{O} || $opt{R}) { + scan_pkgsrc_makefiles($pkgsrcdir); + + @prebuilt_pkgdirs = ($default_vars->{PACKAGES}); + %prebuilt_pkgdir_cache = (); + + while (@prebuilt_pkgdirs) { + find(\&check_prebuilt_packages, shift @prebuilt_pkgdirs); + } + + if ($opt{r}) { + verbose("Unlinking listed prebuilt packages\n"); + foreach my $pkgfile (@matched_prebuiltpackages) { + unlink($pkgfile); + } + } + } + + if ($opt{S}) { + my (%in_subdir); + + foreach my $cat (list_pkgsrc_categories($pkgsrcdir)) { + my $vars = parse_makefile_vars("$pkgsrcdir/$cat/Makefile", undef); + + if (!$vars->{SUBDIR}) { + print "Warning - no SUBDIR for $cat\n"; + next; + } + foreach my $pkgdir (split(/\s+/, $vars->{SUBDIR})) { + $in_subdir{"$cat/$pkgdir"} = 1; + } + } + + scan_pkgsrc_makefiles($pkgsrcdir); + foreach my $pkgver ($pkglist->pkgver) { + if (!defined $in_subdir{ $pkgver->var('dir') }) { + print $pkgver->var('dir') . ": Not in SUBDIR\n"; + } + } + } + + if ($opt{g}) { + my $tmpfile = "$opt{g}.tmp.$$"; + + scan_pkgsrc_makefiles($pkgsrcdir); + if (!open(TABLE, ">$tmpfile")) { + fail("Unable to write '$tmpfile': $!"); + } + foreach my $pkgver ($pkglist->pkgver) { + print TABLE $pkgver->pkg . "\t" + . $pkgver->var('dir') . "\t" + . $pkgver->ver . "\n"; + } + if (!close(TABLE)) { + fail("Error while writing '$tmpfile': $!"); + } + if (!rename($tmpfile, $opt{g})) { + fail("Error in rename('$tmpfile','$opt{g}'): $!"); + } + } + + if ($opt{d}) { + scan_pkgsrc_makefiles($pkgsrcdir); + pkgsrc_check_depends(); + } + + if ($opt{i} || $opt{u}) { + my (@pkgs, @update); + + @pkgs = list_installed_packages(); + scan_pkgsrc_makefiles($pkgsrcdir); + + foreach my $pkgname (sort @pkgs) { + if ($_ = invalid_version($pkgname)) { + print $_; + + if ($pkgname =~ /^([^*?[]+)-([\d*?[].*)/) { + foreach my $pkgver ($pkglist->pkgver($1)) { + $pkgver->var('dir') =~ /-current/ && next; + push(@update, $pkgver); + last; + } + } + } + } + + if ($opt{u}) { + print "\nREQUIRED details for packages that could be updated:\n"; + + foreach my $pkgver (@update) { + print $pkgver->pkg . ':'; + if (open(PKGINFO, 'pkg_info -R ' . $pkgver->pkg . '|')) { + my ($list); + + while () { + if (/Required by:/) { + $list = 1; + } elsif ($list) { + chomp; + s/-\d.*//; + print " $_"; + } + } + close(PKGINFO); + } + print "\n"; + } + + print "\nRunning '$conf_make fetch-list | sh' for each package:\n"; + foreach my $pkgver (@update) { + my ($pkgdir); + + $pkgdir = $pkgver->var('dir'); + if (!defined($pkgdir)) { + fail('Unable to determine ' . $pkgver->pkg . ' directory'); + } + + print "$pkgsrcdir/$pkgdir\n"; + safe_chdir("$pkgsrcdir/$pkgdir"); + system("$conf_make fetch-list | sh"); + } + } + } + + if ($opt{E}) { + scan_pkgsrc_makefiles($pkgsrcdir); + store_pkgsrc_makefiles($opt{E}); + } +} + main(); From cd6360a15cf42f01b0e4457b80f4c917e3f24fb2 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 08:18:31 +0000 Subject: [PATCH 06/37] lintpkgsrc: cleanup: sort subs from small to big This way, perl properly checks the sub prototypes. No functional change. --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 1718 +++++++++++------------ 1 file changed, 857 insertions(+), 861 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index ea0165c46f7e..4cc07aba3515 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.27 2022/07/30 07:37:03 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.28 2022/07/30 08:18:31 rillig Exp $ # Written by David Brownlee . # @@ -22,321 +22,250 @@ use IPC::Open3; use Cwd 'realpath', 'getcwd'; -# Buildtime configuration -my $conf_make = '@MAKE@'; -my $conf_pkgsrcdir = '@PKGSRCDIR@'; -my $conf_prefix = '@PREFIX@'; -my $conf_sysconfdir = '@PKG_SYSCONFDIR@'; - -my ( - $pkglist, # list of Pkg packages - $pkg_installver, # installed version of pkg_install pseudo-pkg - $default_vars, # Set for Makefiles, inc PACKAGES & PKGSRCDIR - %opt, # Command line options - @matched_prebuiltpackages, # List of obsolete prebuilt package paths - @prebuilt_pkgdirs, # Use to follow symlinks in prebuilt pkgdirs - %prebuilt_pkgdir_cache, # To avoid symlink loops in prebuilt_pkgdirs -); +# PkgList is the master list of all packages in pkgsrc. +# +package PkgList; -sub usage_and_exit(); -sub listdir($$); -sub get_default_makefile_vars(); -sub fail($); -sub parse_makefile_pkgsrc($); +sub add($@) { + my $self = shift; -# Horrible kludge to ensure we have a value for testing in conditionals, but -# gets removed in the final evaluation -my $magic_undefined = 'M_a_G_i_C_uNdEfInEd'; + if (!$self->pkgs($_[0])) { + $self->{_pkgs}{ $_[0] } = new Pkgs $_[0]; + } + $self->pkgs($_[0])->add(@_); +} -sub canonicalize_pkgname($) { - my ($pkgname) = @_; +sub new($) { + my $class = shift; + my $self = {}; + bless $self, $class; + return $self; +} - $pkgname =~ s,^py\d+(?:pth|)-,py-,; - $pkgname =~ s,^ruby\d+-,ruby-,; - $pkgname =~ s,^php\d+-,php-,; - return $pkgname; +sub numpkgver($) { + my $self = shift; + scalar($self->pkgver); } -# Could speed up by building a cache of package names to paths, then processing -# each package name once against the tests. -sub check_prebuilt_packages() { +sub pkgver($@) { + my $self = shift; - if ($_ eq 'distfiles' || $_ eq 'pkgsrc') { - # Skip these subdirs if present - $File::Find::prune = 1; + if (@_ == 0) { + my (@list); + foreach my $pkg ($self->pkgs) { + push(@list, $pkg->pkgver); + } + return (@list); + } - } elsif (/(.+)-(\d.*)\.t[bg]z$/) { - my ($pkg, $ver) = ($1, $2); + if (defined $self->{_pkgs}{$_[0]}) { + return (@_ > 1) + ? $self->{_pkgs}{$_[0]}->pkgver($_[1]) + : $self->{_pkgs}{$_[0]}->pkgver(); + } + return; +} - $pkg = canonicalize_pkgname($pkg); +sub pkgs($@) { + my $self = shift; - my ($pkgs); - if ($pkgs = $pkglist->pkgs($pkg)) { - my ($pkgver) = $pkgs->pkgver($ver); + if (@_) { + return $self->{_pkgs}{$_[0]}; + } else { + return (sort { $a->pkg cmp $b->pkg } values %{$self->{_pkgs}}); + } +} - if (!defined $pkgver) { - if ($opt{p}) { - print "$File::Find::dir/$_\n"; - push(@matched_prebuiltpackages, "$File::Find::dir/$_"); - } +sub store($) { + my $self = shift; + my @pkgs = keys %{$self->{_pkgs}}; + my ($cnt, $subcnt) = $self->count; - # Pick probably the last version - $pkgver = $pkgs->latestver; - } + print("\$pkgcnt = $cnt;\n"); + print("\$subpkgcnt = $subcnt;\n"); + map($self->{_pkgs}{$_}->store, keys %{$self->{_pkgs}}); +} - if ($opt{R} && $pkgver->var('RESTRICTED')) { - print "$File::Find::dir/$_\n"; - push(@matched_prebuiltpackages, "$File::Find::dir/$_"); - } +sub count($) { + my $self = shift; + my ($pkgcnt, $pkgsubcnt); - if ($opt{O} && $pkgver->var('OSVERSION_SPECIFIC')) { - print "$File::Find::dir/$_\n"; - push(@matched_prebuiltpackages, "$File::Find::dir/$_"); - } - } + map { + $pkgcnt++; + $pkgsubcnt += $self->{_pkgs}{$_}->count; + } keys %{$self->{_pkgs}}; + wantarray ? ($pkgcnt, $pkgsubcnt) : $pkgcnt; +} - } elsif (-d $_) { - if ($prebuilt_pkgdir_cache{"$File::Find::dir/$_"}) { - $File::Find::prune = 1; - return; - } +# Pkgs is all versions of a given package (eg: apache-1.x and apache-2.x) +# +package Pkgs; - $prebuilt_pkgdir_cache{"$File::Find::dir/$_"} = 1; - if (-l $_) { - my ($dest) = readlink($_); +sub add($@) { + my $self = shift; - if (substr($dest, 0, 1) ne '/') { - $dest = "$File::Find::dir/$dest"; - } - if (!$prebuilt_pkgdir_cache{$dest}) { - push(@prebuilt_pkgdirs, $dest); - } - } - } + $self->{_pkgver}{$_[1]} = new PkgVer @_; } -# Dewey decimal verson number matching - or thereabouts -# Also handles 'nb' suffix (checked iff values otherwise identical) -# -sub deweycmp($$$) { - my ($match, $test, $val) = @_; - my ($cmp, $match_nb, $val_nb); - - $match_nb = $val_nb = 0; - if ($match =~ /(.*)nb(.*)/) { - # Handle nb suffix - $match = $1; - $match_nb = $2; - } +sub new($@) { + my $class = shift; + my $self = {}; - if ($val =~ /(.*)nb(.*)/) { - # Handle nb suffix - $val = $1; - $val_nb = $2; - } + bless $self, $class; + $self->{_pkg} = $_[0]; + return $self; +} - $cmp = deweycmp_extract($match, $val); +sub versions($) { + my $self = shift; - if (!$cmp) { - # Iff otherwise identical, check nb suffix - $cmp = deweycmp_extract($match_nb, $val_nb); - } + return sort { $b cmp $a } keys %{$self->{_pkgver}}; +} - debug("eval deweycmp $cmp $test 0\n"); - eval "$cmp $test 0"; +sub pkg($) { + my $self = shift; + $self->{_pkg}; } -sub convert_to_standard_dewey(@) { - my ($elem, $underscore, @temp); +sub pkgver($@) { + my $self = shift; - # According to the current implementation in pkg_install/lib/str.c - # as of 2002/06/02, '_' before a number, '.', and 'pl' get treated as 0, - # while 'rc' and 'pre' get treated as -1; beta as '-2', alpha as '-3'. - # Other characters are converted to lower - # case and then to a number: a->1, b->2, c->3, etc. Numbers stay the same. - # 'nb' is a special case that's already been handled when we are here. - foreach $elem (@_) { - if ($elem =~ /\d+/) { - push(@temp, $elem); - } elsif ($elem =~ /^pl$/ or $elem =~ /^\.$/) { - push(@temp, 0); - } elsif ($elem =~ /^_$/) { - push(@temp, 0); - } elsif ($elem =~ /^pre$/) { - push(@temp, -1); - } elsif ($elem =~ /^rc$/) { - push(@temp, -1); - } elsif ($elem =~ /^beta$/) { - push(@temp, -2); - } elsif ($elem =~ /^alpha$/) { - push(@temp, -3); - } else { - push(@temp, 0); - push(@temp, ord($elem) - ord("a") + 1); + if (@_) { + if ($self->{_pkgver}{$_[0]}) { + return ($self->{_pkgver}{$_[0]}); } + return; } - @temp; + return sort { $b->ver() cmp $a->ver() } values %{$self->{_pkgver}}; } -sub deweycmp_extract($$) { - my ($match, $val) = @_; - my ($cmp, @matchlist, @vallist, $i, $len); +sub latestver($) { + my $self = shift; - @matchlist = convert_to_standard_dewey(split(/(\D+)/, lc($match))); - @vallist = convert_to_standard_dewey(split(/(\D+)/, lc($val))); - $cmp = 0; - $i = 0; - if ($#matchlist > $#vallist) { - $len = $#matchlist; - } else { - $len = $#vallist; - } - while (!$cmp && ($i++ <= $len)) { - if (!@matchlist) { - push(@matchlist, 0); - } - if (!@vallist) { - push(@vallist, 0); - } - $cmp = (shift @matchlist <=> shift @vallist); - } - $cmp; + ($self->pkgver())[0]; } -sub fail($) { +sub store($) { + my $self = shift; - print STDERR shift(), "\n"; - exit(3); + print("\$pkgnum++;\n"); + map($self->{_pkgver}{$_}->store, keys %{$self->{_pkgver}}); } -sub get_default_makefile_vars() { - - chomp($pkg_installver = `pkg_info -V 2>/dev/null || echo 20010302`); +sub count($) { + my $self = shift; - chomp($_ = `uname -srm`); - ( - $default_vars->{OPSYS}, - $default_vars->{OS_VERSION}, - $default_vars->{MACHINE} - ) = (split); - if (!$default_vars->{MACHINE}) { - die('Unable to extract machine from uname'); - } + scalar(keys %{$self->{_pkgver}}); +} - # Handle systems without uname -p (NetBSD pre 1.4) - chomp($default_vars->{MACHINE_ARCH} = `uname -p 2>/dev/null`); +# PkgVer is a unique package+version +# +package PkgVer; - if (!$default_vars->{MACHINE_ARCH} - && $default_vars->{OS_VERSION} eq 'NetBSD') { - chomp($default_vars->{MACHINE_ARCH} = `sysctl -n hw.machine_arch`); - } +sub new($$$) { + my $class = shift; + my $self = {}; - if (!$default_vars->{MACHINE_ARCH}) { - $default_vars->{MACHINE_ARCH} = $default_vars->{MACHINE}; - } + bless $self, $class; + $self->{_pkg} = $_[0]; + $self->{_ver} = $_[1]; + return $self; +} - $default_vars->{OBJECT_FMT} = 'x'; - $default_vars->{LOWER_OPSYS} = lc($default_vars->{OPSYS}); +sub pkgname($) { + my $self = shift; - if ($opt{P}) { - $default_vars->{PKGSRCDIR} = realpath($opt{P}); - } else { - $default_vars->{PKGSRCDIR} = $conf_pkgsrcdir; - } + $self->pkg . '-' . $self->ver; +} - $default_vars->{DESTDIR} = ''; - $default_vars->{LOCALBASE} = '/usr/pkg'; - $default_vars->{X11BASE} = '/usr/X11R6'; +sub pkg($) { + my $self = shift; - my ($vars); - if (-f '/etc/mk.conf' && ($vars = parse_makefile_vars('/etc/mk.conf', undef))) { - foreach my $var (keys %{$vars}) { - $default_vars->{$var} = $vars->{$var}; - } - } elsif (-f "$conf_sysconfdir/mk.conf" && - ($vars = parse_makefile_vars("$conf_sysconfdir/mk.conf", undef))) { - foreach my $var (keys %{$vars}) { - $default_vars->{$var} = $vars->{$var}; - } - } + $self->{_pkg}; +} - if ($opt{P}) { - $default_vars->{PKGSRCDIR} = realpath($opt{P}); - } +sub var($$$) { + my $self = shift; + my ($key, $val) = @_; - if ($opt{M}) { - $default_vars->{DISTDIR} = realpath($opt{M}); - } else { - $default_vars->{DISTDIR} ||= $default_vars->{PKGSRCDIR} . '/distfiles'; - } + (defined $val) + ? ($self->{$key} = $val) + : $self->{$key}; +} - if ($opt{K}) { - $default_vars->{PACKAGES} = realpath($opt{K}); - } +sub ver($) { + my $self = shift; - # Extract some variables from bsd.pkg.mk - my ($mkvars); - $mkvars = parse_makefile_vars( - "$default_vars->{PKGSRCDIR}/mk/bsd.pkg.mk", - "$default_vars->{PKGSRCDIR}/mk/scripts" - ); - foreach my $varname (keys %{$mkvars}) { - if ($varname =~ /_REQD$/ || $varname eq 'EXTRACT_SUFX') { - $default_vars->{$varname} = $mkvars->{$varname}; - } - } + $self->{_ver}; +} - $default_vars->{PACKAGES} ||= $default_vars->{PKGSRCDIR} . '/packages'; +sub vars($) { + my $self = shift; + + grep(!/^_(pkg|ver)$/, keys %{$self}); } -# Determine if a package version is current. If not, report correct version -# if found -# -sub invalid_version($) { - my ($pkgmatch) = @_; - my ($fail, $ok); - my (@pkgmatches, @todo); +sub store($) { + my $self = shift; + my $data; - @todo = ($pkgmatch); + ($data = $self->{_pkg}) =~ s/([\\\$\@\%\"])/\\$1/g; + print("\$pkgver = \$pkglist->add(\"$data\", \""); - # We handle {} here, everything else in package_globmatch - while ($pkgmatch = shift @todo) { - if ($pkgmatch =~ /(.*)\{([^{}]+)}(.*)/) { - foreach (split(',', $2)) { - push(@todo, "$1$_$3"); - } - } else { - push(@pkgmatches, $pkgmatch); - } + ($data = $self->{_ver}) =~ s/([\\\$\@\%\"])/\\$1/g; + print("$data\"); __pkgcount(1);\n"); + + foreach ($self->vars) { + ($data = $self->{$_}) =~ s/([\\\$\@\%\"])/\\$1/g; + print("\$pkgver->var(\"$_\", \"$data\");\n"); } +} - foreach $pkgmatch (@pkgmatches) { - my ($pkg, $badver) = package_globmatch($pkgmatch); +package main; - if (defined($badver)) { - my ($pkgs); +# Buildtime configuration +my $conf_make = '@MAKE@'; +my $conf_pkgsrcdir = '@PKGSRCDIR@'; +my $conf_prefix = '@PREFIX@'; +my $conf_sysconfdir = '@PKG_SYSCONFDIR@'; - if ($pkgs = $pkglist->pkgs($pkg)) { - $fail .= - "Version mismatch: '$pkg' $badver vs " - . join(',', $pkgs->versions) . "\n"; - } else { - $fail .= "Unknown package: '$pkg' version $badver\n"; - } - } else { +my ( + $pkglist, # list of Pkg packages + $pkg_installver, # installed version of pkg_install pseudo-pkg + $default_vars, # Set for Makefiles, inc PACKAGES & PKGSRCDIR + %opt, # Command line options + @matched_prebuiltpackages, # List of obsolete prebuilt package paths + @prebuilt_pkgdirs, # Use to follow symlinks in prebuilt pkgdirs + %prebuilt_pkgdir_cache, # To avoid symlink loops in prebuilt_pkgdirs +); - # If we find one match, don't bitch about others - $ok = 1; - } +# Horrible kludge to ensure we have a value for testing in conditionals, but +# gets removed in the final evaluation +my $magic_undefined = 'M_a_G_i_C_uNdEfInEd'; + +sub debug(@) { + + ($opt{D}) && print STDERR 'DEBUG: ', @_; +} + +sub verbose(@) { + + if (-t STDERR) { + print STDERR @_; } - $ok && ($fail = undef); - $fail; +} + +sub fail($) { + + print STDERR shift(), "\n"; + exit(3); } # List (recursive) non directory contents of specified directory # #TODO this entire sub should be replaced with direct calls to # File::Find +sub listdir($$); sub listdir($$) { my ($base, $dir) = @_; my ($thisdir); @@ -363,321 +292,236 @@ ($$) @list; } -# Use pkg_info to list installed packages -# -sub list_installed_packages() { - my (@pkgs); - - open(PKG_INFO, 'pkg_info -e "*" |') || fail("Unable to run pkg_info: $!"); - while (defined(my $pkg = )) { - chomp($pkg); - push(@pkgs, canonicalize_pkgname($pkg)); - } - close(PKG_INFO); - - @pkgs; -} - -# List top level pkgsrc categories -# -sub list_pkgsrc_categories($) { - my ($pkgsrcdir) = @_; - my (@categories); +sub canonicalize_pkgname($) { + my ($pkgname) = @_; - opendir(BASE, $pkgsrcdir) || die("Unable to opendir($pkgsrcdir): $!"); - @categories = - grep(substr($_, 0, 1) ne '.' - && $_ ne 'CVS' - && -f "$pkgsrcdir/$_/Makefile", - readdir(BASE)); - closedir(BASE); - @categories; + $pkgname =~ s,^py\d+(?:pth|)-,py-,; + $pkgname =~ s,^ruby\d+-,ruby-,; + $pkgname =~ s,^php\d+-,php-,; + return $pkgname; } -# For a given category, list potentially valid pkgdirs -# -sub list_pkgsrc_pkgdirs($$) { - my ($pkgsrcdir, $cat) = @_; - my (@pkgdirs); +sub convert_to_standard_dewey(@) { + my ($elem, $underscore, @temp); - if (!opendir(CAT, "$pkgsrcdir/$cat")) { - die("Unable to opendir($pkgsrcdir/cat): $!"); + # According to the current implementation in pkg_install/lib/str.c + # as of 2002/06/02, '_' before a number, '.', and 'pl' get treated as 0, + # while 'rc' and 'pre' get treated as -1; beta as '-2', alpha as '-3'. + # Other characters are converted to lower + # case and then to a number: a->1, b->2, c->3, etc. Numbers stay the same. + # 'nb' is a special case that's already been handled when we are here. + foreach $elem (@_) { + if ($elem =~ /\d+/) { + push(@temp, $elem); + } elsif ($elem =~ /^pl$/ or $elem =~ /^\.$/) { + push(@temp, 0); + } elsif ($elem =~ /^_$/) { + push(@temp, 0); + } elsif ($elem =~ /^pre$/) { + push(@temp, -1); + } elsif ($elem =~ /^rc$/) { + push(@temp, -1); + } elsif ($elem =~ /^beta$/) { + push(@temp, -2); + } elsif ($elem =~ /^alpha$/) { + push(@temp, -3); + } else { + push(@temp, 0); + push(@temp, ord($elem) - ord("a") + 1); + } } - @pkgdirs = - sort grep($_ ne 'Makefile' - && $_ ne 'pkg' - && $_ ne 'CVS' - && substr($_, 0, 1) ne '.', - readdir(CAT)); - closedir(CAT); - @pkgdirs; + @temp; } -sub glob2regex($) { - my ($glob) = @_; - my (@chars, $in_alt); - my ($regex); +sub deweycmp_extract($$) { + my ($match, $val) = @_; + my ($cmp, @matchlist, @vallist, $i, $len); - @chars = split(//, $glob); - while (defined($_ = shift @chars)) { - if ($_ eq '*') { - $regex .= '.*'; - } elsif ($_ eq '?') { - $regex .= '.'; - } elsif ($_ eq '+') { - $regex .= '.'; - } elsif ($_ eq '\\+') { - $regex .= $_ . shift @chars; - } elsif ($_ eq '.' || $_ eq '|') { - $regex .= quotemeta; - } elsif ($_ eq '{') { - $regex .= '('; - ++$in_alt; - } elsif ($_ eq '}') { - if (!$in_alt) { - # Error - return undef; - } - $regex .= ')'; - --$in_alt; - } elsif ($_ eq ',' && $in_alt) { - $regex .= '|'; - } else { - $regex .= $_; + @matchlist = convert_to_standard_dewey(split(/(\D+)/, lc($match))); + @vallist = convert_to_standard_dewey(split(/(\D+)/, lc($val))); + $cmp = 0; + $i = 0; + if ($#matchlist > $#vallist) { + $len = $#matchlist; + } else { + $len = $#vallist; + } + while (!$cmp && ($i++ <= $len)) { + if (!@matchlist) { + push(@matchlist, 0); + } + if (!@vallist) { + push(@vallist, 0); } + $cmp = (shift @matchlist <=> shift @vallist); } + $cmp; +} - if ($in_alt) { - # Error - return undef; +# Dewey decimal version number matching - or thereabouts +# Also handles 'nb' suffix (checked iff values otherwise identical) +# +sub deweycmp($$$) { + my ($match, $test, $val) = @_; + my ($cmp, $match_nb, $val_nb); + + $match_nb = $val_nb = 0; + if ($match =~ /(.*)nb(.*)/) { + # Handle nb suffix + $match = $1; + $match_nb = $2; } - if ($regex eq $glob) { - return (''); + + if ($val =~ /(.*)nb(.*)/) { + # Handle nb suffix + $val = $1; + $val_nb = $2; } - if ($opt{D}) { - print "glob2regex: $glob -> $regex\n"; + + $cmp = deweycmp_extract($match, $val); + + if (!$cmp) { + # Iff otherwise identical, check nb suffix + $cmp = deweycmp_extract($match_nb, $val_nb); } - '^' . $regex . '$'; -} -# Perform some (reasonable) subset of 'pkg_info -e' / glob(3) -# Returns (sometimes best guess at) package name, -# and either 'problem version' or undef if all OK -# -sub package_globmatch($) { - my ($pkgmatch) = @_; - my ($matchpkgname, $matchver, $regex); + debug("eval deweycmp $cmp $test 0\n"); + eval "$cmp $test 0"; +} - if ($pkgmatch =~ /^([^*?[]+)(<|>|<=|>=|-)(\d[^*?[{]*)$/) { +sub parse_expand_vars_dumb($$) { + my ($line, $vars) = @_; - # (package)(cmp)(dewey) - my ($test, @pkgvers); + while ($line =~ /\$\{([-\w.]+)\}/) { + if (defined(${$vars}{$1})) { + $line = $` . ${$vars}{$1} . $'; + } else { + $line = $` . $magic_undefined . $'; + } + } + $line; +} - ($matchpkgname, $test, $matchver) = ($1, $2, $3); - if (@pkgvers = $pkglist->pkgver($matchpkgname)) { - foreach my $pkgver (@pkgvers) { - if ($test eq '-') { - if ($pkgver->ver eq $matchver) { - $matchver = undef; - last; - } - } else { - if (deweycmp($pkgver->ver, $test, $matchver)) { - $matchver = undef; - last; - } - } - } +sub parse_expand_vars($$) { + my ($line, $vars) = @_; - if ($matchver && $test ne '-') { - $matchver = "$test$matchver"; - } + while ($line =~ /\$\{([-\w.]+)\}/) { + if (defined(${$vars}{$1})) { + $line = $` . ${$vars}{$1} . $'; + } else { + $line = $` . $magic_undefined . $'; } + } + $line; +} - } elsif ($pkgmatch =~ /^([^[]+)-([\d*?{[].*)$/) { +sub parse_eval_make_false($$) { + my ($line, $vars) = @_; + my ($false, $test); - # (package)-(globver) - my (@pkgnames); + $false = 0; + $test = parse_expand_vars_dumb($line, $vars); - ($matchpkgname, $matchver) = ($1, $2); + # XXX This is _so_ wrong - need to parse this correctly + $test =~ s/""/\r/g; + $test =~ s/"//g; # " + $test =~ s/\r/""/g; - if (defined $pkglist->pkgs($matchpkgname)) { - push(@pkgnames, $matchpkgname); + debug("conditional: $test\n"); - } elsif ($regex = glob2regex($matchpkgname)) { - foreach my $pkg ($pkglist->pkgs) { - ($pkg->pkg() =~ /$regex/) && push(@pkgnames, $pkg->pkg()); - } + # XXX Could do something with target + while ($test =~ /(target|empty|make|defined|exists)\s*\(([^()]+)\)/) { + my $testname = $1; + my $varname = $2; + my $var; + + # Implement (some of) make's :M modifier + if ($varname =~ /^([^:]+):M(.+)$/) { + $varname = $1; + my $match = $2; + + $var = $${vars}{$varname}; + $var = parse_expand_vars($var, $vars) + if defined $var; + + $match =~ s/([{.+])/\\$1/g; + $match =~ s/\*/.*/g; + $match =~ s/\?/./g; + $match = '^' . $match . '$'; + $var = ($var =~ /$match/) + if defined $var; + } else { + $var = $${vars}{$varname}; + $var = parse_expand_vars($var, $vars) + if defined $var; } - # Try to convert $matchver into regex version - # - $regex = glob2regex($matchver); + if (defined $var && $var eq $magic_undefined) { + $var = undef; + } - foreach my $pkg (@pkgnames) { - if (defined $pkglist->pkgver($pkg, $matchver)) { - return ($matchver); - } + if ($testname eq 'exists') { + $_ = (-e $varname) ? 1 : 0; - if ($regex) { - foreach my $ver ($pkglist->pkgs($pkg)->versions) { - if ($ver =~ /$regex/) { - $matchver = undef; - last; - } - } - } + } elsif ($testname eq 'defined') { + $_ = defined($var) ? 1 : 0; - $matchver || last; + } elsif ($testname eq 'empty') { + $_ = ((not defined($var) or (length($var) == 0)) ? 1 : 0); + + } else { + $_ = 0; } - # last ditch attempt to handle the whole DEPENDS as a glob - # - if ($matchver && ($regex = glob2regex($pkgmatch))) { + $test =~ s/$testname\s*\([^()]+\)/$_/; + debug("conditional: update to $test\n"); + } - # (large-glob) - foreach my $pkgver ($pkglist->pkgver) { - if ($pkgver->pkgname =~ /$regex/) { - $matchver = undef; - last; - } - } + while ($test =~ /([^\s()\|\&]+)\s+(!=|==)\s+([^\s()]+)/) { + if ($2 eq '==') { + $_ = ($1 eq $3) ? 1 : 0; + } else { + $_ = ($1 ne $3) ? 1 : 0; + } + $test =~ s/[^\s()\|\&]+\s+(!=|==)\s+[^\s()]+/$_/; + } + + if ($test !~ /[^<>\d()\s&|.!]/) { + debug("eval test $test\n"); + $false = eval "($test)?0:1"; + if (!defined $false) { + fail("Eval failed $line - $test"); } + debug("conditional: evaluated to " . ($false ? 0 : 1) . "\n"); } else { - ($matchpkgname, $matchver) = ($pkgmatch, 'missing'); + $false = 0; + debug("conditional: defaulting to 0\n"); } - - ($matchpkgname, $matchver); + $false; } -# Parse a pkgsrc package makefile and return the pkgname and set variables +# Extract variable assignments from Makefile +# Much unpalatable magic to avoid having to use make (all for speed) # -sub parse_makefile_pkgsrc($) { - my ($file) = @_; - my ($pkgname, $vars); - - $vars = parse_makefile_vars($file, undef); - - if (!$vars) { +sub parse_makefile_vars($$) { + my ($file, $cwd) = @_; + my ( + $pkgname, %vars, $plus, $value, @data, + %incfiles, # Cache of previously included fils + %incdirs, # Directories in which to check for includes + @if_false + ); # 0:true 1:false 2:nested-false&nomore-elsif - # Missing Makefile - return undef; + if (!open(FILE, $file)) { + return (undef); } - - if (defined $vars->{PKGNAME}) { - $pkgname = $vars->{PKGNAME}; - } elsif (defined $vars->{DISTNAME}) { - $pkgname = $vars->{DISTNAME}; - } - - if (defined $vars->{PKGNAME}) { - debug("$file: PKGNAME=$vars->{PKGNAME}\n"); - } - if (defined $vars->{DISTNAME}) { - debug("$file: DISTNAME=$vars->{DISTNAME}\n"); - } - - if (!defined $pkgname || $pkgname =~ /\$/ || $pkgname !~ /(.*)-(\d.*)/) { - - # invoke make here as a last resort - my ($pkgsrcdir) = ($file =~ m:(/.*)/:); - debug("Running '$conf_make' in '$pkgsrcdir'\n"); - my $pid = open3(\*WTR, \*RDR, \*ERR, - "cd $pkgsrcdir || exit 1; $conf_make show-vars VARNAMES=PKGNAME"); - if (!$pid) { - warn "$file: Unable to run make: $!"; - } else { - close(WTR); - my @errors = ; - close(ERR); - my ($makepkgname) = ; - close(RDR); - wait; - chomp @errors; - if (@errors) { warn "\n$file: @errors\n"; } - - if ($makepkgname =~ /(.*)-(\d.*)/) { - $pkgname = $makepkgname; - } - } - } - - if (defined $pkgname) { - if ($pkgname =~ /^pkg_install-(\d+)$/ && $1 < $pkg_installver) { - $pkgname = "pkg_install-$pkg_installver"; - } - - $pkgname = canonicalize_pkgname($pkgname); - - if (defined $vars->{PKGREVISION} - and not $vars->{PKGREVISION} =~ /^\s*$/) { - if ($vars->{PKGREVISION} =~ /^\$\{(_(CVS|GIT|HG|SVN)_PKGVERSION):.*\}$/) { - # See wip/mk/*-package.mk. - } elsif ($vars->{PKGREVISION} =~ /\D/) { - print "\nBogus: PKGREVISION $vars->{PKGREVISION} (from $file)\n"; - - } elsif ($vars->{PKGREVISION}) { - $pkgname .= "nb"; - $pkgname .= $vars->{PKGREVISION}; - } - } - - if ($pkgname =~ /\$/) { - print "\nBogus: $pkgname (from $file)\n"; - - } elsif ($pkgname =~ /(.*)-(\d.*)/) { - if ($pkglist) { - my ($pkgver) = $pkglist->add($1, $2); - - debug("add $1 $2\n"); - - foreach my $var (qw(DEPENDS RESTRICTED OSVERSION_SPECIFIC BROKEN)) { - $pkgver->var($var, $vars->{$var}); - } - - if (defined $vars->{NO_BIN_ON_FTP}) { - $pkgver->var('RESTRICTED', 'NO_BIN_ON_FTP'); - } - - if ($file =~ m:([^/]+/[^/]+)/Makefile$:) { - $pkgver->var('dir', $1); - } else { - $pkgver->var('dir', 'unknown'); - } - } - } else { - print "Cannot extract $pkgname version ($file)\n"; - } - - return ($pkgname, $vars); - - } else { - return (undef); - } -} - -# Extract variable assignments from Makefile -# Much unpalatable magic to avoid having to use make (all for speed) -# -sub parse_makefile_vars($$) { - my ($file, $cwd) = @_; - my ( - $pkgname, %vars, $plus, $value, @data, - %incfiles, # Cache of previously included fils - %incdirs, # Directories in which to check for includes - @if_false - ); # 0:true 1:false 2:nested-false&nomore-elsif - - if (!open(FILE, $file)) { - return (undef); - } - @data = map { chomp; - $_; } ; - close(FILE); + @data = map { chomp; + $_; } ; + close(FILE); $incdirs{"."} = 1; - $incdirs{ dirname($file) } = 1; + $incdirs{dirname($file)} = 1; # Some Makefiles depend on these being set if ($file eq '/etc/mk.conf') { @@ -695,7 +539,7 @@ ($$) $vars{'.CURDIR'} = getcwd; } - $incdirs{ $vars{'.CURDIR'} } = 1; + $incdirs{$vars{'.CURDIR'}} = 1; if ($opt{L}) { print "$file\n"; } @@ -876,176 +720,483 @@ ($$) $vars{$key} = $_; $loop = 1; - } elsif ($vars{$key} =~ m#\$\{([\w.]+):([CS]([^{}])[^{}\3]+\3[^{}\3]*\3[g1]*(|:[^{}]+)|U[^{}]+)\}#) { - my ($left, $subvar, $right) = ($`, $1, $'); - my (@patterns) = split(':', $2); - my ($result); + } elsif ($vars{$key} =~ m#\$\{([\w.]+):([CS]([^{}])[^{}\3]+\3[^{}\3]*\3[g1]*(|:[^{}]+)|U[^{}]+)\}#) { + my ($left, $subvar, $right) = ($`, $1, $'); + my (@patterns) = split(':', $2); + my ($result); + + $result = $vars{$subvar}; + $result ||= ''; + + # If $vars{$subvar} contains a $ skip it on this pass. + # Hopefully it will get substituted and we can catch it + # next time around. + if (index($result, '${') != -1) { + next; + } + + debug("$file: substitutelist $key ($result) $subvar (@patterns)\n"); + foreach (@patterns) { + if (m#(U)(.*)#) { + $result ||= $2; + } elsif (m#([CS])(.)([^/@]+)\2([^/@]*)\2([1g]*)#) { + my ($how, $from, $to, $global) = ($1, $3, $4, $5); + + debug("$file: substituteglob $subvar, $how, $from, $to, $global\n"); + if ($how eq 'S') { + # Limited substitution - keep ^ and $ + $from =~ s/([?.{}\]\[*+])/\\$1/g; + } + $to =~ s/\\(\d)/\$$1/g; # Change \1 etc to $1 + $to =~ s/\&/\$&/g; # Change & to $1 + + my ($notfirst); + if ($global =~ s/1//) { + ($from, $notfirst) = split('\s', $from, 2); + } + + debug("$file: substituteperl $subvar, $how, $from, $to\n"); + debug("eval substitute <$from> <$to> <$global>\n"); + eval "\$result =~ s/$from/$to/$global"; + if (defined $notfirst) { + $result .= " $notfirst"; + } + } else { + next; + } + } + + $vars{$key} = $left . $result . $right; + $loop = 1; + } + } + } + + foreach my $key (keys %vars) { + $vars{$key} =~ s/$magic_undefined//; + } + \%vars; +} + +sub get_default_makefile_vars() { + + chomp($pkg_installver = `pkg_info -V 2>/dev/null || echo 20010302`); + + chomp($_ = `uname -srm`); + ( + $default_vars->{OPSYS}, + $default_vars->{OS_VERSION}, + $default_vars->{MACHINE} + ) = (split); + if (!$default_vars->{MACHINE}) { + die('Unable to extract machine from uname'); + } + + # Handle systems without uname -p (NetBSD pre 1.4) + chomp($default_vars->{MACHINE_ARCH} = `uname -p 2>/dev/null`); + + if (!$default_vars->{MACHINE_ARCH} + && $default_vars->{OS_VERSION} eq 'NetBSD') { + chomp($default_vars->{MACHINE_ARCH} = `sysctl -n hw.machine_arch`); + } + + if (!$default_vars->{MACHINE_ARCH}) { + $default_vars->{MACHINE_ARCH} = $default_vars->{MACHINE}; + } + + $default_vars->{OBJECT_FMT} = 'x'; + $default_vars->{LOWER_OPSYS} = lc($default_vars->{OPSYS}); + + if ($opt{P}) { + $default_vars->{PKGSRCDIR} = realpath($opt{P}); + } else { + $default_vars->{PKGSRCDIR} = $conf_pkgsrcdir; + } + + $default_vars->{DESTDIR} = ''; + $default_vars->{LOCALBASE} = '/usr/pkg'; + $default_vars->{X11BASE} = '/usr/X11R6'; + + my ($vars); + if (-f '/etc/mk.conf' && ($vars = parse_makefile_vars('/etc/mk.conf', undef))) { + foreach my $var (keys %{$vars}) { + $default_vars->{$var} = $vars->{$var}; + } + } elsif (-f "$conf_sysconfdir/mk.conf" && + ($vars = parse_makefile_vars("$conf_sysconfdir/mk.conf", undef))) { + foreach my $var (keys %{$vars}) { + $default_vars->{$var} = $vars->{$var}; + } + } + + if ($opt{P}) { + $default_vars->{PKGSRCDIR} = realpath($opt{P}); + } + + if ($opt{M}) { + $default_vars->{DISTDIR} = realpath($opt{M}); + } else { + $default_vars->{DISTDIR} ||= $default_vars->{PKGSRCDIR} . '/distfiles'; + } + + if ($opt{K}) { + $default_vars->{PACKAGES} = realpath($opt{K}); + } + + # Extract some variables from bsd.pkg.mk + my ($mkvars); + $mkvars = parse_makefile_vars( + "$default_vars->{PKGSRCDIR}/mk/bsd.pkg.mk", + "$default_vars->{PKGSRCDIR}/mk/scripts" + ); + foreach my $varname (keys %{$mkvars}) { + if ($varname =~ /_REQD$/ || $varname eq 'EXTRACT_SUFX') { + $default_vars->{$varname} = $mkvars->{$varname}; + } + } + + $default_vars->{PACKAGES} ||= $default_vars->{PKGSRCDIR} . '/packages'; +} + +# Determine if a package version is current. If not, report correct version +# if found +# +sub invalid_version($) { + my ($pkgmatch) = @_; + my ($fail, $ok); + my (@pkgmatches, @todo); + + @todo = ($pkgmatch); + + # We handle {} here, everything else in package_globmatch + while ($pkgmatch = shift @todo) { + if ($pkgmatch =~ /(.*)\{([^{}]+)}(.*)/) { + foreach (split(',', $2)) { + push(@todo, "$1$_$3"); + } + } else { + push(@pkgmatches, $pkgmatch); + } + } + + foreach $pkgmatch (@pkgmatches) { + my ($pkg, $badver) = package_globmatch($pkgmatch); + + if (defined($badver)) { + my ($pkgs); + + if ($pkgs = $pkglist->pkgs($pkg)) { + $fail .= + "Version mismatch: '$pkg' $badver vs " + . join(',', $pkgs->versions) . "\n"; + } else { + $fail .= "Unknown package: '$pkg' version $badver\n"; + } + } else { + + # If we find one match, don't bitch about others + $ok = 1; + } + } + $ok && ($fail = undef); + $fail; +} + +# Use pkg_info to list installed packages +# +sub list_installed_packages() { + my (@pkgs); + + open(PKG_INFO, 'pkg_info -e "*" |') || fail("Unable to run pkg_info: $!"); + while (defined(my $pkg = )) { + chomp($pkg); + push(@pkgs, canonicalize_pkgname($pkg)); + } + close(PKG_INFO); + + @pkgs; +} + +# List top level pkgsrc categories +# +sub list_pkgsrc_categories($) { + my ($pkgsrcdir) = @_; + my (@categories); + + opendir(BASE, $pkgsrcdir) || die("Unable to opendir($pkgsrcdir): $!"); + @categories = + grep(substr($_, 0, 1) ne '.' + && $_ ne 'CVS' + && -f "$pkgsrcdir/$_/Makefile", + readdir(BASE)); + closedir(BASE); + @categories; +} + +# For a given category, list potentially valid pkgdirs +# +sub list_pkgsrc_pkgdirs($$) { + my ($pkgsrcdir, $cat) = @_; + my (@pkgdirs); + + if (!opendir(CAT, "$pkgsrcdir/$cat")) { + die("Unable to opendir($pkgsrcdir/cat): $!"); + } + @pkgdirs = + sort grep($_ ne 'Makefile' + && $_ ne 'pkg' + && $_ ne 'CVS' + && substr($_, 0, 1) ne '.', + readdir(CAT)); + closedir(CAT); + @pkgdirs; +} + +sub glob2regex($) { + my ($glob) = @_; + my (@chars, $in_alt); + my ($regex); + + @chars = split(//, $glob); + while (defined($_ = shift @chars)) { + if ($_ eq '*') { + $regex .= '.*'; + } elsif ($_ eq '?') { + $regex .= '.'; + } elsif ($_ eq '+') { + $regex .= '.'; + } elsif ($_ eq '\\+') { + $regex .= $_ . shift @chars; + } elsif ($_ eq '.' || $_ eq '|') { + $regex .= quotemeta; + } elsif ($_ eq '{') { + $regex .= '('; + ++$in_alt; + } elsif ($_ eq '}') { + if (!$in_alt) { + # Error + return undef; + } + $regex .= ')'; + --$in_alt; + } elsif ($_ eq ',' && $in_alt) { + $regex .= '|'; + } else { + $regex .= $_; + } + } + + if ($in_alt) { + # Error + return undef; + } + if ($regex eq $glob) { + return (''); + } + if ($opt{D}) { + print "glob2regex: $glob -> $regex\n"; + } + '^' . $regex . '$'; +} + +# Perform some (reasonable) subset of 'pkg_info -e' / glob(3) +# Returns (sometimes best guess at) package name, +# and either 'problem version' or undef if all OK +# +sub package_globmatch($) { + my ($pkgmatch) = @_; + my ($matchpkgname, $matchver, $regex); + + if ($pkgmatch =~ /^([^*?[]+)(<|>|<=|>=|-)(\d[^*?[{]*)$/) { + + # (package)(cmp)(dewey) + my ($test, @pkgvers); + + ($matchpkgname, $test, $matchver) = ($1, $2, $3); + if (@pkgvers = $pkglist->pkgver($matchpkgname)) { + foreach my $pkgver (@pkgvers) { + if ($test eq '-') { + if ($pkgver->ver eq $matchver) { + $matchver = undef; + last; + } + } else { + if (deweycmp($pkgver->ver, $test, $matchver)) { + $matchver = undef; + last; + } + } + } + + if ($matchver && $test ne '-') { + $matchver = "$test$matchver"; + } + } + + } elsif ($pkgmatch =~ /^([^[]+)-([\d*?{[].*)$/) { - $result = $vars{$subvar}; - $result ||= ''; + # (package)-(globver) + my (@pkgnames); - # If $vars{$subvar} contains a $ skip it on this pass. - # Hopefully it will get substituted and we can catch it - # next time around. - if (index($result, '${') != -1) { - next; - } + ($matchpkgname, $matchver) = ($1, $2); - debug("$file: substitutelist $key ($result) $subvar (@patterns)\n"); - foreach (@patterns) { - if (m#(U)(.*)#) { - $result ||= $2; - } elsif (m#([CS])(.)([^/@]+)\2([^/@]*)\2([1g]*)#) { - my ($how, $from, $to, $global) = ($1, $3, $4, $5); + if (defined $pkglist->pkgs($matchpkgname)) { + push(@pkgnames, $matchpkgname); - debug("$file: substituteglob $subvar, $how, $from, $to, $global\n"); - if ($how eq 'S') { - # Limited substitution - keep ^ and $ - $from =~ s/([?.{}\]\[*+])/\\$1/g; - } - $to =~ s/\\(\d)/\$$1/g; # Change \1 etc to $1 - $to =~ s/\&/\$&/g; # Change & to $1 + } elsif ($regex = glob2regex($matchpkgname)) { + foreach my $pkg ($pkglist->pkgs) { + ($pkg->pkg() =~ /$regex/) && push(@pkgnames, $pkg->pkg()); + } + } - my ($notfirst); - if ($global =~ s/1//) { - ($from, $notfirst) = split('\s', $from, 2); - } + # Try to convert $matchver into regex version + # + $regex = glob2regex($matchver); - debug("$file: substituteperl $subvar, $how, $from, $to\n"); - debug("eval substitute <$from> <$to> <$global>\n"); - eval "\$result =~ s/$from/$to/$global"; - if (defined $notfirst) { - $result .= " $notfirst"; - } - } else { - next; + foreach my $pkg (@pkgnames) { + if (defined $pkglist->pkgver($pkg, $matchver)) { + return ($matchver); + } + + if ($regex) { + foreach my $ver ($pkglist->pkgs($pkg)->versions) { + if ($ver =~ /$regex/) { + $matchver = undef; + last; } } + } - $vars{$key} = $left . $result . $right; - $loop = 1; + $matchver || last; + } + + # last ditch attempt to handle the whole DEPENDS as a glob + # + if ($matchver && ($regex = glob2regex($pkgmatch))) { + + # (large-glob) + foreach my $pkgver ($pkglist->pkgver) { + if ($pkgver->pkgname =~ /$regex/) { + $matchver = undef; + last; + } } } - } - foreach my $key (keys %vars) { - $vars{$key} =~ s/$magic_undefined//; + } else { + ($matchpkgname, $matchver) = ($pkgmatch, 'missing'); } - \%vars; + + ($matchpkgname, $matchver); } -sub parse_expand_vars($$) { - my ($line, $vars) = @_; +# Parse a pkgsrc package makefile and return the pkgname and set variables +# +sub parse_makefile_pkgsrc($) { + my ($file) = @_; + my ($pkgname, $vars); - while ($line =~ /\$\{([-\w.]+)\}/) { - if (defined(${$vars}{$1})) { - $line = $` . ${$vars}{$1} . $'; - } else { - $line = $` . $magic_undefined . $'; - } - } - $line; -} + $vars = parse_makefile_vars($file, undef); -sub parse_expand_vars_dumb($$) { - my ($line, $vars) = @_; + if (!$vars) { - while ($line =~ /\$\{([-\w.]+)\}/) { - if (defined(${$vars}{$1})) { - $line = $` . ${$vars}{$1} . $'; - } else { - $line = $` . $magic_undefined . $'; - } + # Missing Makefile + return undef; } - $line; -} -sub parse_eval_make_false($$) { - my ($line, $vars) = @_; - my ($false, $test); + if (defined $vars->{PKGNAME}) { + $pkgname = $vars->{PKGNAME}; + } elsif (defined $vars->{DISTNAME}) { + $pkgname = $vars->{DISTNAME}; + } - $false = 0; - $test = parse_expand_vars_dumb($line, $vars); + if (defined $vars->{PKGNAME}) { + debug("$file: PKGNAME=$vars->{PKGNAME}\n"); + } + if (defined $vars->{DISTNAME}) { + debug("$file: DISTNAME=$vars->{DISTNAME}\n"); + } - # XXX This is _so_ wrong - need to parse this correctly - $test =~ s/""/\r/g; - $test =~ s/"//g; # " - $test =~ s/\r/""/g; + if (!defined $pkgname || $pkgname =~ /\$/ || $pkgname !~ /(.*)-(\d.*)/) { - debug("conditional: $test\n"); + # invoke make here as a last resort + my ($pkgsrcdir) = ($file =~ m:(/.*)/:); + debug("Running '$conf_make' in '$pkgsrcdir'\n"); + my $pid = open3(\*WTR, \*RDR, \*ERR, + "cd $pkgsrcdir || exit 1; $conf_make show-vars VARNAMES=PKGNAME"); + if (!$pid) { + warn "$file: Unable to run make: $!"; + } else { + close(WTR); + my @errors = ; + close(ERR); + my ($makepkgname) = ; + close(RDR); + wait; + chomp @errors; + if (@errors) { warn "\n$file: @errors\n"; } - # XXX Could do something with target - while ($test =~ /(target|empty|make|defined|exists)\s*\(([^()]+)\)/) { - my $testname = $1; - my $varname = $2; - my $var; + if ($makepkgname =~ /(.*)-(\d.*)/) { + $pkgname = $makepkgname; + } + } + } - # Implement (some of) make's :M modifier - if ($varname =~ /^([^:]+):M(.+)$/) { - $varname = $1; - my $match = $2; + if (defined $pkgname) { + if ($pkgname =~ /^pkg_install-(\d+)$/ && $1 < $pkg_installver) { + $pkgname = "pkg_install-$pkg_installver"; + } - $var = $${vars}{$varname}; - $var = parse_expand_vars($var, $vars) - if defined $var; + $pkgname = canonicalize_pkgname($pkgname); - $match =~ s/([{.+])/\\$1/g; - $match =~ s/\*/.*/g; - $match =~ s/\?/./g; - $match = '^' . $match . '$'; - $var = ($var =~ /$match/) - if defined $var; - } else { - $var = $${vars}{$varname}; - $var = parse_expand_vars($var, $vars) - if defined $var; - } + if (defined $vars->{PKGREVISION} + and not $vars->{PKGREVISION} =~ /^\s*$/) { + if ($vars->{PKGREVISION} =~ /^\$\{(_(CVS|GIT|HG|SVN)_PKGVERSION):.*\}$/) { + # See wip/mk/*-package.mk. + } elsif ($vars->{PKGREVISION} =~ /\D/) { + print "\nBogus: PKGREVISION $vars->{PKGREVISION} (from $file)\n"; - if (defined $var && $var eq $magic_undefined) { - $var = undef; + } elsif ($vars->{PKGREVISION}) { + $pkgname .= "nb"; + $pkgname .= $vars->{PKGREVISION}; + } } - if ($testname eq 'exists') { - $_ = (-e $varname) ? 1 : 0; + if ($pkgname =~ /\$/) { + print "\nBogus: $pkgname (from $file)\n"; - } elsif ($testname eq 'defined') { - $_ = defined($var) ? 1 : 0; + } elsif ($pkgname =~ /(.*)-(\d.*)/) { + if ($pkglist) { + my ($pkgver) = $pkglist->add($1, $2); - } elsif ($testname eq 'empty') { - $_ = ((not defined($var) or (length($var) == 0)) ? 1 : 0); + debug("add $1 $2\n"); - } else { - $_ = 0; - } + foreach my $var (qw(DEPENDS RESTRICTED OSVERSION_SPECIFIC BROKEN)) { + $pkgver->var($var, $vars->{$var}); + } - $test =~ s/$testname\s*\([^()]+\)/$_/; - debug("conditional: update to $test\n"); - } + if (defined $vars->{NO_BIN_ON_FTP}) { + $pkgver->var('RESTRICTED', 'NO_BIN_ON_FTP'); + } - while ($test =~ /([^\s()\|\&]+)\s+(!=|==)\s+([^\s()]+)/) { - if ($2 eq '==') { - $_ = ($1 eq $3) ? 1 : 0; + if ($file =~ m:([^/]+/[^/]+)/Makefile$:) { + $pkgver->var('dir', $1); + } else { + $pkgver->var('dir', 'unknown'); + } + } } else { - $_ = ($1 ne $3) ? 1 : 0; + print "Cannot extract $pkgname version ($file)\n"; } - $test =~ s/[^\s()\|\&]+\s+(!=|==)\s+[^\s()]+/$_/; - } - if ($test !~ /[^<>\d()\s&|.!]/) { - debug("eval test $test\n"); - $false = eval "($test)?0:1"; - if (!defined $false) { - fail("Eval failed $line - $test"); - } - debug("conditional: evaluated to " . ($false ? 0 : 1) . "\n"); + return ($pkgname, $vars); } else { - $false = 0; - debug("conditional: defaulting to 0\n"); + return (undef); } - $false; } + # chdir() || fail() # sub safe_chdir($) { @@ -1057,6 +1208,19 @@ ($) } } +sub load_pkgsrc_makefiles($) { + + open(STORE, "<$_[0]") || die("Cannot read pkgsrc store from $_[0]: $!\n"); + my ($pkgver); + our ($pkgcnt, $pkgnum, $subpkgcnt, $subpkgnum); + $pkglist = new PkgList; + while () { + debug("eval store $_"); + eval $_; + } + close(STORE); +} + # Generate pkgname->category/pkg mapping, optionally check DEPENDS # sub scan_pkgsrc_makefiles($) { @@ -1192,7 +1356,7 @@ ($$$$) push(@{$sumfiles{ $dist->{sumtype} }}, $distn); } } - } }, + } }, ($pkgdistdir)); if ($check_unref && %bad_distfiles) { @@ -1246,19 +1410,6 @@ ($$$$) (sort keys %bad_distfiles); } -sub load_pkgsrc_makefiles() { - - open(STORE, "<$_[0]") || die("Cannot read pkgsrc store from $_[0]: $!\n"); - my ($pkgver); - our ($pkgcnt, $pkgnum, $subpkgcnt, $subpkgnum); - $pkglist = new PkgList; - while () { - debug("eval store $_"); - eval $_; - } - close(STORE); -} - sub store_pkgsrc_makefiles($) { open(STORE, ">$_[0]") || die("Cannot save pkgsrc store to $_[0]: $!\n"); my $was = select(STORE); @@ -1308,219 +1459,64 @@ () exit; } -sub verbose(@) { - - if (-t STDERR) { - print STDERR @_; - } -} - -sub debug(@) { +# Could speed up by building a cache of package names to paths, then processing +# each package name once against the tests. +sub check_prebuilt_packages() { - ($opt{D}) && print STDERR 'DEBUG: ', @_; -} + if ($_ eq 'distfiles' || $_ eq 'pkgsrc') { + # Skip these subdirs if present + $File::Find::prune = 1; -# PkgList is the master list of all packages in pkgsrc. -# -package PkgList; + } elsif (/(.+)-(\d.*)\.t[bg]z$/) { + my ($pkg, $ver) = ($1, $2); -sub add($@) { - my $self = shift; + $pkg = canonicalize_pkgname($pkg); - if (!$self->pkgs($_[0])) { - $self->{_pkgs}{ $_[0] } = new Pkgs $_[0]; - } - $self->pkgs($_[0])->add(@_); -} + my ($pkgs); + if ($pkgs = $pkglist->pkgs($pkg)) { + my ($pkgver) = $pkgs->pkgver($ver); -sub new($) { - my $class = shift; - my $self = {}; - bless $self, $class; - return $self; -} + if (!defined $pkgver) { + if ($opt{p}) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); + } -sub numpkgver($) { - my $self = shift; - scalar($self->pkgver); -} + # Pick probably the last version + $pkgver = $pkgs->latestver; + } -sub pkgver($@) { - my $self = shift; + if ($opt{R} && $pkgver->var('RESTRICTED')) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); + } - if (@_ == 0) { - my (@list); - foreach my $pkg ($self->pkgs) { - push(@list, $pkg->pkgver); + if ($opt{O} && $pkgver->var('OSVERSION_SPECIFIC')) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); + } } - return (@list); - } - - if (defined $self->{_pkgs}{$_[0]}) { - return (@_ > 1) - ? $self->{_pkgs}{$_[0]}->pkgver($_[1]) - : $self->{_pkgs}{$_[0]}->pkgver(); - } - return; -} - -sub pkgs($@) { - my $self = shift; - - if (@_) { - return $self->{_pkgs}{$_[0]}; - } else { - return (sort { $a->pkg cmp $b->pkg } values %{$self->{_pkgs}}); - } -} - -sub store($) { - my $self = shift; - my @pkgs = keys %{$self->{_pkgs}}; - my ($cnt, $subcnt) = $self->count; - - print("\$pkgcnt = $cnt;\n"); - print("\$subpkgcnt = $subcnt;\n"); - map($self->{_pkgs}{$_}->store, keys %{$self->{_pkgs}}); -} - -sub count($) { - my $self = shift; - my ($pkgcnt, $pkgsubcnt); - - map { - $pkgcnt++; - $pkgsubcnt += $self->{_pkgs}{$_}->count; - } keys %{$self->{_pkgs}}; - wantarray ? ($pkgcnt, $pkgsubcnt) : $pkgcnt; -} - -# Pkgs is all versions of a given package (eg: apache-1.x and apache-2.x) -# -package Pkgs; - -sub add($@) { - my $self = shift; - - $self->{_pkgver}{$_[1]} = new PkgVer @_; -} - -sub new($@) { - my $class = shift; - my $self = {}; - - bless $self, $class; - $self->{_pkg} = $_[0]; - return $self; -} - -sub versions($) { - my $self = shift; - return sort { $b cmp $a } keys %{$self->{_pkgver}}; -} - -sub pkg($) { - my $self = shift; - $self->{_pkg}; -} - -sub pkgver($@) { - my $self = shift; - - if (@_) { - if ($self->{_pkgver}{$_[0]}) { - return ($self->{_pkgver}{$_[0]}); + } elsif (-d $_) { + if ($prebuilt_pkgdir_cache{"$File::Find::dir/$_"}) { + $File::Find::prune = 1; + return; } - return; - } - return sort { $b->ver() cmp $a->ver() } values %{$self->{_pkgver}}; -} - -sub latestver($) { - my $self = shift; - - ($self->pkgver())[0]; -} - -sub store($) { - my $self = shift; - - print("\$pkgnum++;\n"); - map($self->{_pkgver}{$_}->store, keys %{$self->{_pkgver}}); -} - -sub count($) { - my $self = shift; - - scalar(keys %{$self->{_pkgver}}); -} - -# PkgVer is a unique package+version -# -package PkgVer; - -sub new($$$) { - my $class = shift; - my $self = {}; - - bless $self, $class; - $self->{_pkg} = $_[0]; - $self->{_ver} = $_[1]; - return $self; -} - -sub pkgname($) { - my $self = shift; - - $self->pkg . '-' . $self->ver; -} - -sub pkg($) { - my $self = shift; - - $self->{_pkg}; -} - -sub var($$$) { - my $self = shift; - my ($key, $val) = @_; - - (defined $val) - ? ($self->{$key} = $val) - : $self->{$key}; -} - -sub ver($) { - my $self = shift; - - $self->{_ver}; -} - -sub vars($) { - my $self = shift; - - grep(!/^_(pkg|ver)$/, keys %{$self}); -} -sub store($) { - my $self = shift; - my $data; - - ($data = $self->{_pkg}) =~ s/([\\\$\@\%\"])/\\$1/g; - print("\$pkgver = \$pkglist->add(\"$data\", \""); - - ($data = $self->{_ver}) =~ s/([\\\$\@\%\"])/\\$1/g; - print("$data\"); __pkgcount(1);\n"); + $prebuilt_pkgdir_cache{"$File::Find::dir/$_"} = 1; + if (-l $_) { + my ($dest) = readlink($_); - foreach ($self->vars) { - ($data = $self->{$_}) =~ s/([\\\$\@\%\"])/\\$1/g; - print("\$pkgver->var(\"$_\", \"$data\");\n"); + if (substr($dest, 0, 1) ne '/') { + $dest = "$File::Find::dir/$dest"; + } + if (!$prebuilt_pkgdir_cache{$dest}) { + push(@prebuilt_pkgdirs, $dest); + } + } } } -package main; - sub main() { $ENV{PATH} .= From fc8ceca878afb94d44718c37f7f8180e7dfd7555 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 08:21:31 +0000 Subject: [PATCH 07/37] lintpkgsrc: cleanup: rename 'dewey' to 'pkgversion' The Dewey Decimal Classification is a classification for books in libraries, based on decimal numbers. It has nothing to do with version numbers. No functional change. --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 4cc07aba3515..9f79743a785e 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.28 2022/07/30 08:18:31 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.29 2022/07/30 08:21:31 rillig Exp $ # Written by David Brownlee . # @@ -301,7 +301,7 @@ ($) return $pkgname; } -sub convert_to_standard_dewey(@) { +sub convert_to_standard_pkgversion(@) { my ($elem, $underscore, @temp); # According to the current implementation in pkg_install/lib/str.c @@ -333,12 +333,12 @@ (@) @temp; } -sub deweycmp_extract($$) { +sub pkgversioncmp_extract($$) { my ($match, $val) = @_; my ($cmp, @matchlist, @vallist, $i, $len); - @matchlist = convert_to_standard_dewey(split(/(\D+)/, lc($match))); - @vallist = convert_to_standard_dewey(split(/(\D+)/, lc($val))); + @matchlist = convert_to_standard_pkgversion(split(/(\D+)/, lc($match))); + @vallist = convert_to_standard_pkgversion(split(/(\D+)/, lc($val))); $cmp = 0; $i = 0; if ($#matchlist > $#vallist) { @@ -358,10 +358,10 @@ ($$) $cmp; } -# Dewey decimal version number matching - or thereabouts +# Package version number matching - or thereabouts # Also handles 'nb' suffix (checked iff values otherwise identical) # -sub deweycmp($$$) { +sub pkgversioncmp($$$) { my ($match, $test, $val) = @_; my ($cmp, $match_nb, $val_nb); @@ -378,14 +378,14 @@ ($$$) $val_nb = $2; } - $cmp = deweycmp_extract($match, $val); + $cmp = pkgversioncmp_extract($match, $val); if (!$cmp) { # Iff otherwise identical, check nb suffix - $cmp = deweycmp_extract($match_nb, $val_nb); + $cmp = pkgversioncmp_extract($match_nb, $val_nb); } - debug("eval deweycmp $cmp $test 0\n"); + debug("eval pkgversioncmp $cmp $test 0\n"); eval "$cmp $test 0"; } @@ -1009,7 +1009,7 @@ ($) if ($pkgmatch =~ /^([^*?[]+)(<|>|<=|>=|-)(\d[^*?[{]*)$/) { - # (package)(cmp)(dewey) + # (package)(cmp)(pkgversion) my ($test, @pkgvers); ($matchpkgname, $test, $matchver) = ($1, $2, $3); @@ -1021,7 +1021,7 @@ ($) last; } } else { - if (deweycmp($pkgver->ver, $test, $matchver)) { + if (pkgversioncmp($pkgver->ver, $test, $matchver)) { $matchver = undef; last; } From f215aeb8e8407dfc4b46e4035a9601bd6d462d48 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 08:25:45 +0000 Subject: [PATCH 08/37] lintpkgsrc: fix error message for accessing category directory --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 9f79743a785e..63e8ce310049 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.29 2022/07/30 08:21:31 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.30 2022/07/30 08:25:45 rillig Exp $ # Written by David Brownlee . # @@ -940,7 +940,7 @@ ($$) my (@pkgdirs); if (!opendir(CAT, "$pkgsrcdir/$cat")) { - die("Unable to opendir($pkgsrcdir/cat): $!"); + die("Unable to opendir($pkgsrcdir/$cat): $!"); } @pkgdirs = sort grep($_ ne 'Makefile' From b4dc34ca104028ec2becf52ceada87420a66cc58 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 08:33:29 +0000 Subject: [PATCH 09/37] pkg_install: modern computers can handle words longer than 6 letters --- pkgtools/pkg_install/files/tkpkg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgtools/pkg_install/files/tkpkg b/pkgtools/pkg_install/files/tkpkg index 73f2f2907e32..d6804a7ea916 100644 --- a/pkgtools/pkg_install/files/tkpkg +++ b/pkgtools/pkg_install/files/tkpkg @@ -15,7 +15,7 @@ listbox .frame.list -yscroll ".frame.scroll set" -relief sunken -setgrid 1 pack append .frame .frame.scroll {right filly} \ .frame.list {left expand fill} -# build the lower window shoing the complete description of a pacage +# build the lower window showing the complete description of a package frame .f -borderwidth 4 text .f.t -width 80 -height 20 -yscrollcommand ".f.s set" -relief sunken From d777ce2ac735523ac4895bcdd5cfe7d14e3b3ecc Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 08:35:07 +0000 Subject: [PATCH 10/37] pkg_install: remove trailing whitespace --- pkgtools/pkg_install/files/tkpkg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgtools/pkg_install/files/tkpkg b/pkgtools/pkg_install/files/tkpkg index d6804a7ea916..baf9c12400b5 100644 --- a/pkgtools/pkg_install/files/tkpkg +++ b/pkgtools/pkg_install/files/tkpkg @@ -22,7 +22,7 @@ text .f.t -width 80 -height 20 -yscrollcommand ".f.s set" -relief sunken # Initially display instructions in this window. Erase the # instructions and show the package description when the user clicks # on a package. -# +# .f.t insert end "Double click on a package above to see its complete description here." scrollbar .f.s -relief sunken -command ".f.t yview" From f86e10aaf6b891e0faf63b8e34e6deb23e4fd795 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 08:41:25 +0000 Subject: [PATCH 11/37] pkg_install: clean up leading, intermediate and trailing whitespace --- pkgtools/pkg_install/files/lib/dewey.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/pkgtools/pkg_install/files/lib/dewey.c b/pkgtools/pkg_install/files/lib/dewey.c index 56c73b70dfee..b7c74aea0f34 100644 --- a/pkgtools/pkg_install/files/lib/dewey.c +++ b/pkgtools/pkg_install/files/lib/dewey.c @@ -1,7 +1,7 @@ -/* $NetBSD: dewey.c,v 1.11 2009/03/06 15:18:42 joerg Exp $ */ +/* $NetBSD: dewey.c,v 1.12 2022/07/30 08:41:25 rillig Exp $ */ /* - * Copyright © 2002 Alistair G. Crooks. All rights reserved. + * Copyright (c) 2002 Alistair G. Crooks. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -71,7 +71,7 @@ typedef struct test_t { /* the tests that are recognised. */ - const test_t tests[] = { +const test_t tests[] = { { "<=", 2, DEWEY_LE }, { "<", 1, DEWEY_LT }, { ">=", 2, DEWEY_GE }, @@ -81,7 +81,7 @@ typedef struct test_t { { NULL, 0, 0 } }; - const test_t modifiers[] = { +const test_t modifiers[] = { { "alpha", 5, Alpha }, { "beta", 4, Beta }, { "pre", 3, RC }, @@ -122,10 +122,10 @@ dewey_mktest(int *op, const char *test) static int mkcomponent(arr_t *ap, const char *num) { - static const char alphas[] = "abcdefghijklmnopqrstuvwxyz"; - const test_t *modp; - int n; - const char *cp; + static const char alphas[] = "abcdefghijklmnopqrstuvwxyz"; + const test_t *modp; + int n; + const char *cp; if (ap->c == ap->size) { if (ap->size == 0) { @@ -281,7 +281,7 @@ dewey_match(const char *pattern, const char *pkg) strncmp(pkg, pattern, (size_t)(version-pkg)) != 0) return 0; version++; - + /* extract comparison operator */ if ((n = dewey_mktest(&op, sep)) < 0) { return 0; @@ -317,4 +317,3 @@ dewey_match(const char *pattern, const char *pkg) return 0; } - From 939680acfd8c9c8a5433a92ad5baff7ab010c6bd Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 08:53:42 +0000 Subject: [PATCH 12/37] pkg_install: use tabs for indentation, not spaces --- pkgtools/pkg_install/files/lib/dewey.c | 46 +++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/pkgtools/pkg_install/files/lib/dewey.c b/pkgtools/pkg_install/files/lib/dewey.c index b7c74aea0f34..51721f93e16b 100644 --- a/pkgtools/pkg_install/files/lib/dewey.c +++ b/pkgtools/pkg_install/files/lib/dewey.c @@ -1,4 +1,4 @@ -/* $NetBSD: dewey.c,v 1.12 2022/07/30 08:41:25 rillig Exp $ */ +/* $NetBSD: dewey.c,v 1.13 2022/07/30 08:53:42 rillig Exp $ */ /* * Copyright (c) 2002 Alistair G. Crooks. All rights reserved. @@ -47,38 +47,38 @@ /* do not modify these values, or things will NOT work */ enum { - Alpha = -3, - Beta = -2, - RC = -1, - Dot = 0, - Patch = 1 + Alpha = -3, + Beta = -2, + RC = -1, + Dot = 0, + Patch = 1 }; /* this struct defines a version number */ typedef struct arr_t { - unsigned c; /* # of version numbers */ - unsigned size; /* size of array */ - int *v; /* array of decimal numbers */ - int netbsd; /* any "nb" suffix */ + unsigned c; /* # of version numbers */ + unsigned size; /* size of array */ + int *v; /* array of decimal numbers */ + int netbsd; /* any "nb" suffix */ } arr_t; /* this struct describes a test */ typedef struct test_t { - const char *s; /* string representation */ - unsigned len; /* length of string */ - int t; /* enumerated type of test */ + const char *s; /* string representation */ + unsigned len; /* length of string */ + int t; /* enumerated type of test */ } test_t; /* the tests that are recognised. */ const test_t tests[] = { - { "<=", 2, DEWEY_LE }, - { "<", 1, DEWEY_LT }, - { ">=", 2, DEWEY_GE }, - { ">", 1, DEWEY_GT }, - { "==", 2, DEWEY_EQ }, - { "!=", 2, DEWEY_NE }, - { NULL, 0, 0 } + { "<=", 2, DEWEY_LE }, + { "<", 1, DEWEY_LT }, + { ">=", 2, DEWEY_GE }, + { ">", 1, DEWEY_GT }, + { "==", 2, DEWEY_EQ }, + { "!=", 2, DEWEY_NE }, + { NULL, 0, 0 } }; const test_t modifiers[] = { @@ -252,7 +252,7 @@ dewey_cmp(const char *lhs, int op, const char *rhs) freeversion(&left); return 0; } - retval = vtest(&left, op, &right); + retval = vtest(&left, op, &right); freeversion(&left); freeversion(&right); return retval; @@ -283,9 +283,9 @@ dewey_match(const char *pattern, const char *pkg) version++; /* extract comparison operator */ - if ((n = dewey_mktest(&op, sep)) < 0) { + if ((n = dewey_mktest(&op, sep)) < 0) { return 0; - } + } /* skip operator */ sep += n; From 41cc5b00419c35d1feb7f1e06a4ebaafe0fc0cf6 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 09:21:41 +0000 Subject: [PATCH 13/37] lintpkgsrc: clean up comparison of version numbers No functional change. --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 63e8ce310049..97e9b1cce17a 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.30 2022/07/30 08:25:45 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.31 2022/07/30 09:21:41 rillig Exp $ # Written by David Brownlee . # @@ -304,13 +304,10 @@ ($) sub convert_to_standard_pkgversion(@) { my ($elem, $underscore, @temp); - # According to the current implementation in pkg_install/lib/str.c - # as of 2002/06/02, '_' before a number, '.', and 'pl' get treated as 0, - # while 'rc' and 'pre' get treated as -1; beta as '-2', alpha as '-3'. - # Other characters are converted to lower - # case and then to a number: a->1, b->2, c->3, etc. Numbers stay the same. - # 'nb' is a special case that's already been handled when we are here. + # See pkg_install/lib/dewey.c. + # 'nb' has already been handled when we are here. foreach $elem (@_) { + print STDERR "convert elem '$elem'\n"; if ($elem =~ /\d+/) { push(@temp, $elem); } elsif ($elem =~ /^pl$/ or $elem =~ /^\.$/) { @@ -358,9 +355,8 @@ ($$) $cmp; } -# Package version number matching - or thereabouts -# Also handles 'nb' suffix (checked iff values otherwise identical) -# +# Package version number matching. +# Also handles 'nb' suffix (checked iff values otherwise identical). sub pkgversioncmp($$$) { my ($match, $test, $val) = @_; my ($cmp, $match_nb, $val_nb); From 4e7865180150b07e3bae6333db3483fc7f6e83d8 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 09:23:19 +0000 Subject: [PATCH 14/37] lintpkgsrc: fix up previous commit for cleaning up version numbers --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 97e9b1cce17a..27e0642d258e 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.31 2022/07/30 09:21:41 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.32 2022/07/30 09:23:19 rillig Exp $ # Written by David Brownlee . # @@ -307,7 +307,6 @@ (@) # See pkg_install/lib/dewey.c. # 'nb' has already been handled when we are here. foreach $elem (@_) { - print STDERR "convert elem '$elem'\n"; if ($elem =~ /\d+/) { push(@temp, $elem); } elsif ($elem =~ /^pl$/ or $elem =~ /^\.$/) { @@ -332,25 +331,13 @@ (@) sub pkgversioncmp_extract($$) { my ($match, $val) = @_; - my ($cmp, @matchlist, @vallist, $i, $len); + my ($cmp, @matchlist, @vallist); @matchlist = convert_to_standard_pkgversion(split(/(\D+)/, lc($match))); @vallist = convert_to_standard_pkgversion(split(/(\D+)/, lc($val))); $cmp = 0; - $i = 0; - if ($#matchlist > $#vallist) { - $len = $#matchlist; - } else { - $len = $#vallist; - } - while (!$cmp && ($i++ <= $len)) { - if (!@matchlist) { - push(@matchlist, 0); - } - if (!@vallist) { - push(@vallist, 0); - } - $cmp = (shift @matchlist <=> shift @vallist); + while ($cmp == 0 && (@matchlist || @vallist)) { + $cmp = ((shift @matchlist || 0) <=> (shift @vallist || 0)); } $cmp; } From 54dc4e082179abb27658cf2dcd3f07592543bae8 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 09:32:05 +0000 Subject: [PATCH 15/37] lintpkgsrc: cleanup: replace regular expressions with string comparison --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 27e0642d258e..e6f3d4ff656f 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.32 2022/07/30 09:23:19 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.33 2022/07/30 09:32:05 rillig Exp $ # Written by David Brownlee . # @@ -307,19 +307,15 @@ (@) # See pkg_install/lib/dewey.c. # 'nb' has already been handled when we are here. foreach $elem (@_) { - if ($elem =~ /\d+/) { + if ($elem =~ /\d/) { push(@temp, $elem); - } elsif ($elem =~ /^pl$/ or $elem =~ /^\.$/) { + } elsif ($elem eq "pl" || $elem eq "." || $elem eq "_") { push(@temp, 0); - } elsif ($elem =~ /^_$/) { - push(@temp, 0); - } elsif ($elem =~ /^pre$/) { - push(@temp, -1); - } elsif ($elem =~ /^rc$/) { + } elsif ($elem eq "pre" || $elem eq "rc") { push(@temp, -1); - } elsif ($elem =~ /^beta$/) { + } elsif ($elem eq "beta") { push(@temp, -2); - } elsif ($elem =~ /^alpha$/) { + } elsif ($elem eq "alpha") { push(@temp, -3); } else { push(@temp, 0); From d7e37fef837cbcf2d45a37cd93ff0d1fda02f361 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 09:37:21 +0000 Subject: [PATCH 16/37] lintpkgsrc: merge duplicate code --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index e6f3d4ff656f..824d99677324 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.33 2022/07/30 09:32:05 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.34 2022/07/30 09:37:21 rillig Exp $ # Written by David Brownlee . # @@ -368,19 +368,6 @@ ($$$) eval "$cmp $test 0"; } -sub parse_expand_vars_dumb($$) { - my ($line, $vars) = @_; - - while ($line =~ /\$\{([-\w.]+)\}/) { - if (defined(${$vars}{$1})) { - $line = $` . ${$vars}{$1} . $'; - } else { - $line = $` . $magic_undefined . $'; - } - } - $line; -} - sub parse_expand_vars($$) { my ($line, $vars) = @_; @@ -399,7 +386,7 @@ ($$) my ($false, $test); $false = 0; - $test = parse_expand_vars_dumb($line, $vars); + $test = parse_expand_vars($line, $vars); # XXX This is _so_ wrong - need to parse this correctly $test =~ s/""/\r/g; From cf6b91fb2e7357f6b6f956806d8d7a25d590712c Mon Sep 17 00:00:00 2001 From: leot Date: Sat, 30 Jul 2022 09:56:08 +0000 Subject: [PATCH 17/37] doc: Add missing category to latest u-boot-pinecube entry --- doc/CHANGES-2022 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/CHANGES-2022 b/doc/CHANGES-2022 index 0d07bf049554..00ed5d06dee1 100644 --- a/doc/CHANGES-2022 +++ b/doc/CHANGES-2022 @@ -1,4 +1,4 @@ -$NetBSD: CHANGES-2022,v 1.3598 2022/07/30 01:22:38 tnn Exp $ +$NetBSD: CHANGES-2022,v 1.3599 2022/07/30 09:56:08 leot Exp $ Changes to the packages collection and infrastructure in 2022: @@ -5377,7 +5377,7 @@ Changes to the packages collection and infrastructure in 2022: Updated www/py-uvicorn to 0.18.2 [adam 2022-07-29] Updated devel/cmake to 3.23.3 [adam 2022-07-29] Updated finance/py-braintree to 4.16.0 [adam 2022-07-29] - Added u-boot-pinecube version 2022.04 [thorpej 2022-07-29] + Added sysutils/u-boot-pinecube version 2022.04 [thorpej 2022-07-29] Updated x11/gtk4 to 4.6.6 [wiz 2022-07-29] Added devel/libadwaita version 1.0.5 [wiz 2022-07-29] Updated devel/libadwaita to 1.1.3 [wiz 2022-07-29] From b6eb76114e3309dabf004548d3a2fa60755e6234 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 10:11:45 +0000 Subject: [PATCH 18/37] lintpkgsrc: add automatic tests Not sure whether this form of running tests is the idiomatic one, as lintpkgsrc is not a Perl module but a Perl program, but it works. The number of planned tests (5 for now) seems to be ignored, no idea why. --- pkgtools/lintpkgsrc/Makefile | 20 ++++++++++++-------- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 6 +++--- pkgtools/lintpkgsrc/files/t/pkgversion.t | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 pkgtools/lintpkgsrc/files/t/pkgversion.t diff --git a/pkgtools/lintpkgsrc/Makefile b/pkgtools/lintpkgsrc/Makefile index 453015b1337f..cdbd6ff22ac7 100644 --- a/pkgtools/lintpkgsrc/Makefile +++ b/pkgtools/lintpkgsrc/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.39 2022/06/28 11:35:24 wiz Exp $ +# $NetBSD: Makefile,v 1.40 2022/07/30 10:11:45 rillig Exp $ PKGNAME= lintpkgsrc-4.98 PKGREVISION= 1 @@ -14,18 +14,13 @@ CONFLICTS+= pkglint<4.82 USE_TOOLS+= perl:run WRKSRC= ${WRKDIR} -NO_BUILD= yes USE_LANGUAGES= # none AUTO_MKDIRS= yes SUBST_CLASSES+= lp SUBST_STAGE.lp= post-configure SUBST_FILES.lp+= lintpkgsrc.0 lintpkgsrc.1 lintpkgsrc.pl -.if defined(BATCH) -SUBST_SED.lp+= -e 's;@PKGSRCDIR@;/usr/pkgsrc;g' -.else -SUBST_VARS.lp+= PKGSRCDIR -.endif +SUBST_SED.lp+= -e 's;@PKGSRCDIR@;${BATCH:D/usr/pkgsrc:U${PKGSRCDIR}};g' SUBST_VARS.lp+= MAKE SUBST_VARS.lp+= PERL5 SUBST_VARS.lp+= PKG_SYSCONFDIR @@ -34,7 +29,16 @@ SUBST_VARS.lp+= PREFIX .include "../../mk/bsd.prefs.mk" do-extract: - cd ${FILESDIR} && cp lintpkgsrc.* ${WRKSRC}/ + cd ${FILESDIR} && cp -R lintpkgsrc.* t ${WRKSRC}/ + +do-build: + # Nothing + +do-test: + ${RUN} cd ${WRKSRC}/t; \ + for test in ./*.t; do \ + perl "$$test"; \ + done do-install: ${INSTALL_SCRIPT} ${WRKSRC}/lintpkgsrc.pl ${DESTDIR}${PREFIX}/bin/lintpkgsrc diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 824d99677324..21ea5d3d6fbd 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.34 2022/07/30 09:37:21 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.35 2022/07/30 10:11:45 rillig Exp $ # Written by David Brownlee . # @@ -302,7 +302,7 @@ ($) } sub convert_to_standard_pkgversion(@) { - my ($elem, $underscore, @temp); + my ($elem, @temp); # See pkg_install/lib/dewey.c. # 'nb' has already been handled when we are here. @@ -1800,4 +1800,4 @@ () } } -main(); +main() unless $ENV{'TESTING_LINTPKGSRC'} eq 'yes'; diff --git a/pkgtools/lintpkgsrc/files/t/pkgversion.t b/pkgtools/lintpkgsrc/files/t/pkgversion.t new file mode 100644 index 000000000000..77ffd9aade2c --- /dev/null +++ b/pkgtools/lintpkgsrc/files/t/pkgversion.t @@ -0,0 +1,15 @@ +# $NetBSD: pkgversion.t,v 1.1 2022/07/30 10:11:45 rillig Exp $ +use strict; +use warnings; +use Test; + +BEGIN { plan tests => 5; } + +$ENV{'TESTING_LINTPKGSRC'} = 'yes'; +require('../lintpkgsrc.pl'); + +ok(pkgversioncmp('3.4', '<', '3.4'), ''); +ok(pkgversioncmp('3.4', '<=', '3.4'), 1); +ok(pkgversioncmp('3.4', '>=', '3.4.0.0.0'), 1); +ok(pkgversioncmp('3.4nb13', '>=', '3.4'), 1); +ok(pkgversioncmp('3.4nb13', '<', '3.4'), ''); From 283660af495129ac06647cbb7d7d1e313fd9ad6c Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 10:55:51 +0000 Subject: [PATCH 19/37] lintpkgsrc: fix warning about string comparison with undefined Since today. --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 21ea5d3d6fbd..1007edab109e 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.35 2022/07/30 10:11:45 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.36 2022/07/30 10:55:51 rillig Exp $ # Written by David Brownlee . # @@ -1800,4 +1800,4 @@ () } } -main() unless $ENV{'TESTING_LINTPKGSRC'} eq 'yes'; +main() unless defined $ENV{'TESTING_LINTPKGSRC'}; From 2df7860627c40e533de2fa983ef2e52668c63c1a Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 11:33:23 +0000 Subject: [PATCH 20/37] lintpkgsrc: use plain text cache format Previously, the cache format was Perl code. Now it is a list of lines, each line containing tab-separated data. The new format reduces the storage needs by around 50%. It also ensures that only well-formed data is written to the cache. The previous format contained lots of IO requests, which made loading the cache incredibly slow. Bump version. --- pkgtools/lintpkgsrc/Makefile | 5 +- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 97 +++++++++++-------------- 2 files changed, 46 insertions(+), 56 deletions(-) diff --git a/pkgtools/lintpkgsrc/Makefile b/pkgtools/lintpkgsrc/Makefile index cdbd6ff22ac7..78bf7d05301e 100644 --- a/pkgtools/lintpkgsrc/Makefile +++ b/pkgtools/lintpkgsrc/Makefile @@ -1,7 +1,6 @@ -# $NetBSD: Makefile,v 1.40 2022/07/30 10:11:45 rillig Exp $ +# $NetBSD: Makefile,v 1.41 2022/07/30 11:33:23 rillig Exp $ -PKGNAME= lintpkgsrc-4.98 -PKGREVISION= 1 +PKGNAME= lintpkgsrc-4.99 CATEGORIES= pkgtools MAINTAINER= pkgsrc-users@NetBSD.org diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 1007edab109e..6be465269c9a 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.36 2022/07/30 10:55:51 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.37 2022/07/30 11:33:23 rillig Exp $ # Written by David Brownlee . # @@ -78,23 +78,11 @@ ($@) sub store($) { my $self = shift; - my @pkgs = keys %{$self->{_pkgs}}; - my ($cnt, $subcnt) = $self->count; - print("\$pkgcnt = $cnt;\n"); - print("\$subpkgcnt = $subcnt;\n"); - map($self->{_pkgs}{$_}->store, keys %{$self->{_pkgs}}); -} - -sub count($) { - my $self = shift; - my ($pkgcnt, $pkgsubcnt); - - map { - $pkgcnt++; - $pkgsubcnt += $self->{_pkgs}{$_}->count; - } keys %{$self->{_pkgs}}; - wantarray ? ($pkgcnt, $pkgsubcnt) : $pkgcnt; + my $pkgs = $self->{_pkgs}; + foreach my $pkg (sort keys %$pkgs) { + $pkgs->{$pkg}->store(); + } } # Pkgs is all versions of a given package (eg: apache-1.x and apache-2.x) @@ -148,14 +136,10 @@ ($) sub store($) { my $self = shift; - print("\$pkgnum++;\n"); - map($self->{_pkgver}{$_}->store, keys %{$self->{_pkgver}}); -} - -sub count($) { - my $self = shift; - - scalar(keys %{$self->{_pkgver}}); + my $pkgvers = $self->{_pkgver}; + foreach my $pkgver (sort keys %$pkgvers) { + $pkgvers->{$pkgver}->store(); + } } # PkgVer is a unique package+version @@ -207,17 +191,19 @@ ($) sub store($) { my $self = shift; - my $data; - ($data = $self->{_pkg}) =~ s/([\\\$\@\%\"])/\\$1/g; - print("\$pkgver = \$pkglist->add(\"$data\", \""); + my $name = $self->{_pkg}; + my $ver = $self->{_ver}; - ($data = $self->{_ver}) =~ s/([\\\$\@\%\"])/\\$1/g; - print("$data\"); __pkgcount(1);\n"); + $name =~ /\s/ and die "cannot store package name '$name'\n"; + $ver =~ /\s/ and die "cannot store package version '$ver'\n"; + printf("package\t%s\t%s\n", $name, $ver); - foreach ($self->vars) { - ($data = $self->{$_}) =~ s/([\\\$\@\%\"])/\\$1/g; - print("\$pkgver->var(\"$_\", \"$data\");\n"); + foreach my $varname (sort $self->vars) { + my $value = $self->{$varname}; + $varname =~ /\s/ and die "cannot store variable name '$varname'\n"; + $value =~ /\n/ and die "cannot store variable value '$value'\n"; + printf("var\t%s\t%s\n", $varname, $value); } } @@ -397,8 +383,7 @@ ($$) # XXX Could do something with target while ($test =~ /(target|empty|make|defined|exists)\s*\(([^()]+)\)/) { - my $testname = $1; - my $varname = $2; + my ($testname, $varname) = ($1, $2); my $var; # Implement (some of) make's :M modifier @@ -1175,14 +1160,23 @@ ($) } sub load_pkgsrc_makefiles($) { + my ($fname) = @_; - open(STORE, "<$_[0]") || die("Cannot read pkgsrc store from $_[0]: $!\n"); + open(STORE, "<", $fname) + or die("Cannot read pkgsrc store from $fname: $!\n"); my ($pkgver); - our ($pkgcnt, $pkgnum, $subpkgcnt, $subpkgnum); - $pkglist = new PkgList; - while () { - debug("eval store $_"); - eval $_; + $pkglist = PkgList->new; + while (defined(my $line = )) { + chomp($line); + if ($line =~ qr"^package\t([^\t]+)\t([^\t]+$)$") { + $pkgver = $pkglist->add($1, $2); + } elsif ($line =~ qr"^var\t([^\t]+)\t(.*)$") { + $pkgver->var($1, $2); + } elsif ($line =~ qr"^sub ") { + die "Outdated cache format in '$fname'\n"; + } else { + die "Invalid line '$line' in cache '$fname'\n"; + } } close(STORE); } @@ -1377,18 +1371,15 @@ ($$$$) } sub store_pkgsrc_makefiles($) { - open(STORE, ">$_[0]") || die("Cannot save pkgsrc store to $_[0]: $!\n"); - my $was = select(STORE); - print( - 'sub __pkgcount { $subpkgnum += $_[0]; ', - 'verbose("\rReading pkgsrc database: ', - '$pkgnum / $pkgcnt ($subpkgnum / $subpkgcnt) pkgs"); }', - "\n" - ); - $pkglist->store; - print("verbose(\"...done\\n\");\n"); - select($was); - close(STORE); + my ($fname) = @_; + + open(STORE, ">", $fname) + or die("Cannot save pkgsrc store to $fname: $!\n"); + my $prev = select(STORE); + $pkglist->store(); + select($prev); + close(STORE) + or die("Cannot save pkgsrc store to $fname: $!\n"); } # Remember to update manual page when modifying option list From b159941c414330b37e63b71709e74fd0d2c57ee1 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 11:33:33 +0000 Subject: [PATCH 21/37] doc: Updated pkgtools/lintpkgsrc to 4.99 --- doc/CHANGES-2022 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/CHANGES-2022 b/doc/CHANGES-2022 index 00ed5d06dee1..1baed575f140 100644 --- a/doc/CHANGES-2022 +++ b/doc/CHANGES-2022 @@ -1,4 +1,4 @@ -$NetBSD: CHANGES-2022,v 1.3599 2022/07/30 09:56:08 leot Exp $ +$NetBSD: CHANGES-2022,v 1.3600 2022/07/30 11:33:33 rillig Exp $ Changes to the packages collection and infrastructure in 2022: @@ -5383,3 +5383,4 @@ Changes to the packages collection and infrastructure in 2022: Updated devel/libadwaita to 1.1.3 [wiz 2022-07-29] Updated security/mit-krb5 to 1.19.3 [jperkin 2022-07-29] Updated time/ntpsec to 1.2.1 [tnn 2022-07-30] + Updated pkgtools/lintpkgsrc to 4.99 [rillig 2022-07-30] From bfc85e09ba7d587c5da121d83c4336cda089f041 Mon Sep 17 00:00:00 2001 From: taca Date: Sat, 30 Jul 2022 14:20:41 +0000 Subject: [PATCH 22/37] time/ruby-tzinfo1: update to 1.2.10 1.2.10 (2022-07-19) * Fixed a relative path traversal bug that could cause arbitrary files to be loaded with require when used with RubyDataSource. Please refer to GHSA-5cm2-9h8c-rvfx for details. CVE-2022-31163. * Ignore the SECURITY file from Arch Linux's tzdata package. #134. --- time/ruby-tzinfo1/Makefile | 4 ++-- time/ruby-tzinfo1/PLIST | 3 ++- time/ruby-tzinfo1/distinfo | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/time/ruby-tzinfo1/Makefile b/time/ruby-tzinfo1/Makefile index b6ab24d54c8c..f42a3415e56d 100644 --- a/time/ruby-tzinfo1/Makefile +++ b/time/ruby-tzinfo1/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.5 2021/01/03 08:19:42 taca Exp $ +# $NetBSD: Makefile,v 1.6 2022/07/30 14:20:41 taca Exp $ DISTNAME= tzinfo-${VERS} PKGNAME= ${RUBY_PKGPREFIX}-tzinfo1-${VERS} @@ -11,7 +11,7 @@ LICENSE= mit DEPENDS+= ${RUBY_PKGPREFIX}-thread_safe>=0.1<1:../../misc/ruby-thread_safe -VERS= 1.2.9 +VERS= 1.2.10 USE_LANGUAGES= # none .include "../../lang/ruby/gem.mk" diff --git a/time/ruby-tzinfo1/PLIST b/time/ruby-tzinfo1/PLIST index 7fb286de240c..7d52308d10c3 100644 --- a/time/ruby-tzinfo1/PLIST +++ b/time/ruby-tzinfo1/PLIST @@ -1,4 +1,4 @@ -@comment $NetBSD: PLIST,v 1.2 2020/11/10 14:30:00 taca Exp $ +@comment $NetBSD: PLIST,v 1.3 2022/07/30 14:20:41 taca Exp $ ${GEM_HOME}/cache/${GEM_NAME}.gem ${GEM_LIBDIR}/.yardopts ${GEM_LIBDIR}/CHANGES.md @@ -37,6 +37,7 @@ ${GEM_LIBDIR}/lib/tzinfo/transition_rule.rb ${GEM_LIBDIR}/lib/tzinfo/zoneinfo_country_info.rb ${GEM_LIBDIR}/lib/tzinfo/zoneinfo_data_source.rb ${GEM_LIBDIR}/lib/tzinfo/zoneinfo_timezone_info.rb +${GEM_LIBDIR}/test/assets/payload.rb ${GEM_LIBDIR}/test/tc_annual_rules.rb ${GEM_LIBDIR}/test/tc_country.rb ${GEM_LIBDIR}/test/tc_country_index_definition.rb diff --git a/time/ruby-tzinfo1/distinfo b/time/ruby-tzinfo1/distinfo index 6eb7b8e4d7ad..25d6fe9f3e92 100644 --- a/time/ruby-tzinfo1/distinfo +++ b/time/ruby-tzinfo1/distinfo @@ -1,5 +1,5 @@ -$NetBSD: distinfo,v 1.7 2021/10/26 11:24:37 nia Exp $ +$NetBSD: distinfo,v 1.8 2022/07/30 14:20:41 taca Exp $ -BLAKE2s (tzinfo-1.2.9.gem) = 45299f538f11425b031b20503ba9edd80680d4393eba58cda8252670a37e69c0 -SHA512 (tzinfo-1.2.9.gem) = ddf28ad213f681a4e551cbd803873b279acef03fae894a3e6475030d4da5a59732b31af5d5944e8c62d15b7ec922816fede24f180fb20c55c1bd3d379c879cfe -Size (tzinfo-1.2.9.gem) = 166912 bytes +BLAKE2s (tzinfo-1.2.10.gem) = 01e5941266e63c42eb039c54e82724a8cda1a2e74c98cf2b84c0b8b9274b6e07 +SHA512 (tzinfo-1.2.10.gem) = 124d43d92bdf9b234523ff79bb574d4be098cc721768eb1fd8ac85bff11ccfdf21effb1e4300e80c50b0202beed67a9a0d1146a23e33a4bced6e985fc6be78a2 +Size (tzinfo-1.2.10.gem) = 167936 bytes From 57b9cbc39408ff13f40ae5ceadbe1d0d5bb54f03 Mon Sep 17 00:00:00 2001 From: taca Date: Sat, 30 Jul 2022 14:21:07 +0000 Subject: [PATCH 23/37] doc: Updated time/ruby-tzinfo1 to 1.2.10 --- doc/CHANGES-2022 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/CHANGES-2022 b/doc/CHANGES-2022 index 1baed575f140..1f1c6a0a3cfa 100644 --- a/doc/CHANGES-2022 +++ b/doc/CHANGES-2022 @@ -1,4 +1,4 @@ -$NetBSD: CHANGES-2022,v 1.3600 2022/07/30 11:33:33 rillig Exp $ +$NetBSD: CHANGES-2022,v 1.3601 2022/07/30 14:21:07 taca Exp $ Changes to the packages collection and infrastructure in 2022: @@ -5384,3 +5384,4 @@ Changes to the packages collection and infrastructure in 2022: Updated security/mit-krb5 to 1.19.3 [jperkin 2022-07-29] Updated time/ntpsec to 1.2.1 [tnn 2022-07-30] Updated pkgtools/lintpkgsrc to 4.99 [rillig 2022-07-30] + Updated time/ruby-tzinfo1 to 1.2.10 [taca 2022-07-30] From 6e19b305204f5063ac8eebba5a002fb5d15b6cab Mon Sep 17 00:00:00 2001 From: taca Date: Sat, 30 Jul 2022 14:24:09 +0000 Subject: [PATCH 24/37] time/ruby-tzinfo: update to 2.0.5 2.0.5 (2022-07-19) * Changed DateTime results to always use the proleptic Gregorian calendar. This affects DateTime results prior to 1582-10-15 and any arithmetic performed on the results that would produce a secondary result prior to 1582-10-15. * Added support for eager loading all the time zone and country data by calling either TZInfo::DataSource#eager_load! or TZInfo.eager_load!. Compatible with Ruby On Rails' eager_load_namespaces. #129. * Ignore the SECURITY file from Arch Linux's tzdata package. #134. --- time/ruby-tzinfo/DESCR | 30 ++++++++++++++++-------------- time/ruby-tzinfo/Makefile | 4 ++-- time/ruby-tzinfo/distinfo | 8 ++++---- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/time/ruby-tzinfo/DESCR b/time/ruby-tzinfo/DESCR index 274ef921588b..08427ddc144e 100644 --- a/time/ruby-tzinfo/DESCR +++ b/time/ruby-tzinfo/DESCR @@ -6,23 +6,25 @@ Data Sources TZInfo requires a source of timezone data. There are two built-in options: -1. The TZInfo::Data library (the tzinfo-data gem). TZInfo::Data contains a set - of Ruby modules that are generated from the [IANA Time Zone Database](http://www.iana.org/time-zones). -2. A zoneinfo directory. Most Unix-like systems include a zoneinfo directory - containing timezone definitions. These are also generated from the - [IANA Time Zone Database](http://www.iana.org/time-zones). - -By default, TZInfo::Data will be used. If TZInfo::Data is not available (i.e. -if `require 'tzinfo/data'` fails), then TZInfo will search for a zoneinfo -directory instead (using the search path specified by +1. The TZInfo::Data library (the tzinfo-data gem). TZInfo::Data contains a + set of Ruby modules that are generated from the [IANA Time Zone + Database](http://www.iana.org/time-zones). + +2. A zoneinfo directory. Most Unix-like systems include a zoneinfo directory + containing timezone definitions. These are also generated from the [IANA + Time Zone Database](http://www.iana.org/time-zones). + +By default, TZInfo::Data will be used. If TZInfo::Data is not available +(i.e. if `require 'tzinfo/data'` fails), then TZInfo will search for a +zoneinfo directory instead (using the search path specified by `TZInfo::ZoneinfoDataSource::DEFAULT_SEARCH_PATH`). -If no data source can be found, a `TZInfo::DataSourceNotFound` exception will be -raised when TZInfo is used. Further information is available -[in the wiki](http://tzinfo.github.io/datasourcenotfound) to help with -resolving `TZInfo::DataSourceNotFound` errors. +If no data source can be found, a `TZInfo::DataSourceNotFound` exception +will be raised when TZInfo is used. Further information is available [in the +wiki](http://tzinfo.github.io/datasourcenotfound) to help with resolving +`TZInfo::DataSourceNotFound` errors. -The default data source selection can be overridden using +The default data source selection can be overridden using `TZInfo::DataSource.set`. Custom data sources can also be used. See `TZInfo::DataSource.set` for diff --git a/time/ruby-tzinfo/Makefile b/time/ruby-tzinfo/Makefile index 58e0754644db..7ac14713a97f 100644 --- a/time/ruby-tzinfo/Makefile +++ b/time/ruby-tzinfo/Makefile @@ -1,6 +1,6 @@ -# $NetBSD: Makefile,v 1.48 2021/01/03 08:20:26 taca Exp $ +# $NetBSD: Makefile,v 1.49 2022/07/30 14:24:09 taca Exp $ -DISTNAME= tzinfo-2.0.4 +DISTNAME= tzinfo-2.0.5 CATEGORIES= time MAINTAINER= taca@NetBSD.org diff --git a/time/ruby-tzinfo/distinfo b/time/ruby-tzinfo/distinfo index e6f228c4ebe7..b8bd73b7692c 100644 --- a/time/ruby-tzinfo/distinfo +++ b/time/ruby-tzinfo/distinfo @@ -1,5 +1,5 @@ -$NetBSD: distinfo,v 1.46 2021/10/26 11:24:37 nia Exp $ +$NetBSD: distinfo,v 1.47 2022/07/30 14:24:09 taca Exp $ -BLAKE2s (tzinfo-2.0.4.gem) = ce93081599f52429c9c6c119da976f943be771fef1c4ab8d7fb94ffd0d265df2 -SHA512 (tzinfo-2.0.4.gem) = edae29820741b338c38dc13d58746f9798052167598d2eab7cefdde8769854d248573b112c7ad2481aef63a9258fbce477451f83f347640e00e2fc27feb10370 -Size (tzinfo-2.0.4.gem) = 78336 bytes +BLAKE2s (tzinfo-2.0.5.gem) = a375e7498f0aacb9f2a47386e263643474fcd5bcd038e4cad763191335b6b821 +SHA512 (tzinfo-2.0.5.gem) = d3248d9226b974095392c17916701c7318df895fb1d5581d3bafd73672fbb1ec30f4c1bac690379c714df66856558011c27bcedf2d53beb51031441f7bfee0ae +Size (tzinfo-2.0.5.gem) = 79360 bytes From 424d03e6146cab9f72b882c4c28c9be844582527 Mon Sep 17 00:00:00 2001 From: taca Date: Sat, 30 Jul 2022 14:25:11 +0000 Subject: [PATCH 25/37] doc: Updated time/ruby-tzinfo to 2.0.5 I forgot to mention that update of DESCR to reduce pkglint's warnings. --- doc/CHANGES-2022 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/CHANGES-2022 b/doc/CHANGES-2022 index 1f1c6a0a3cfa..4f4b5bbc48df 100644 --- a/doc/CHANGES-2022 +++ b/doc/CHANGES-2022 @@ -1,4 +1,4 @@ -$NetBSD: CHANGES-2022,v 1.3601 2022/07/30 14:21:07 taca Exp $ +$NetBSD: CHANGES-2022,v 1.3602 2022/07/30 14:25:11 taca Exp $ Changes to the packages collection and infrastructure in 2022: @@ -5385,3 +5385,4 @@ Changes to the packages collection and infrastructure in 2022: Updated time/ntpsec to 1.2.1 [tnn 2022-07-30] Updated pkgtools/lintpkgsrc to 4.99 [rillig 2022-07-30] Updated time/ruby-tzinfo1 to 1.2.10 [taca 2022-07-30] + Updated time/ruby-tzinfo to 2.0.5 [taca 2022-07-30] From e19c3805c964a40445aa9f715cd5604433a4c524 Mon Sep 17 00:00:00 2001 From: taca Date: Sat, 30 Jul 2022 14:50:01 +0000 Subject: [PATCH 26/37] security/pear-Crypt_GPG: correct dependency pear-Crypt_GPG depends on converters/php-mbstring. Bump PKGREVISION. --- security/pear-Crypt_GPG/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/security/pear-Crypt_GPG/Makefile b/security/pear-Crypt_GPG/Makefile index f03185bab77a..08ed3dc9d7c9 100644 --- a/security/pear-Crypt_GPG/Makefile +++ b/security/pear-Crypt_GPG/Makefile @@ -1,12 +1,14 @@ -# $NetBSD: Makefile,v 1.11 2022/02/20 13:15:14 taca Exp $ +# $NetBSD: Makefile,v 1.12 2022/07/30 14:50:01 taca Exp $ DISTNAME= Crypt_GPG-1.6.7 +PKGREVISION= 1 CATEGORIES= security MAINTAINER= pkgsrc-users@NetBSD.org COMMENT= Object oriented interface to GNU Privacy Guard LICENSE= gnu-lgpl-v2.1 +DEPENDS+= ${PHP_PKG_PREFIX}-mbstring>=${PHP_VERSION}:../../converters/php-mbstring DEPENDS+= ${PHP_PKG_PREFIX}-pear-Console_CommandLine>=1.1.10:../../devel/pear-Console_CommandLine # maybe resides in lang/php/phpversion.mk From 364e8a1ada5129d38c1b3cd4900b660f3223445e Mon Sep 17 00:00:00 2001 From: taca Date: Sat, 30 Jul 2022 14:50:22 +0000 Subject: [PATCH 27/37] doc: Updated security/pear-Crypt_GPG to 1.6.7nb1 --- doc/CHANGES-2022 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/CHANGES-2022 b/doc/CHANGES-2022 index 4f4b5bbc48df..ca4bb168c890 100644 --- a/doc/CHANGES-2022 +++ b/doc/CHANGES-2022 @@ -1,4 +1,4 @@ -$NetBSD: CHANGES-2022,v 1.3602 2022/07/30 14:25:11 taca Exp $ +$NetBSD: CHANGES-2022,v 1.3603 2022/07/30 14:50:22 taca Exp $ Changes to the packages collection and infrastructure in 2022: @@ -5386,3 +5386,4 @@ Changes to the packages collection and infrastructure in 2022: Updated pkgtools/lintpkgsrc to 4.99 [rillig 2022-07-30] Updated time/ruby-tzinfo1 to 1.2.10 [taca 2022-07-30] Updated time/ruby-tzinfo to 2.0.5 [taca 2022-07-30] + Updated security/pear-Crypt_GPG to 1.6.7nb1 [taca 2022-07-30] From 03e53f81a3bcb8dc5a92027f7d23a04ad833b514 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 14:55:51 +0000 Subject: [PATCH 28/37] lintpkgsrc: update homepage URL --- pkgtools/lintpkgsrc/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgtools/lintpkgsrc/Makefile b/pkgtools/lintpkgsrc/Makefile index 78bf7d05301e..f9a78db68d9e 100644 --- a/pkgtools/lintpkgsrc/Makefile +++ b/pkgtools/lintpkgsrc/Makefile @@ -1,10 +1,10 @@ -# $NetBSD: Makefile,v 1.41 2022/07/30 11:33:23 rillig Exp $ +# $NetBSD: Makefile,v 1.42 2022/07/30 14:55:51 rillig Exp $ PKGNAME= lintpkgsrc-4.99 CATEGORIES= pkgtools MAINTAINER= pkgsrc-users@NetBSD.org -HOMEPAGE= https://www.NetBSD.org/Documentation/pkgsrc/ +HOMEPAGE= https://www.NetBSD.org/docs/pkgsrc/ COMMENT= Sanity checks on the complete pkgsrc tree DEPENDS+= digest>=20010101:../../pkgtools/digest From dbf10f8cf5ed3c05d42c34032718cf460e641829 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 15:11:26 +0000 Subject: [PATCH 29/37] pkglint: cleanup: group classes from small to big No functional change. --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 154 ++++++++++++------------ 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 6be465269c9a..afc3d551eca7 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.37 2022/07/30 11:33:23 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.38 2022/07/30 15:11:26 rillig Exp $ # Written by David Brownlee . # @@ -22,66 +22,68 @@ use IPC::Open3; use Cwd 'realpath', 'getcwd'; -# PkgList is the master list of all packages in pkgsrc. +# PkgVer is a unique package + version. # -package PkgList; - -sub add($@) { - my $self = shift; - - if (!$self->pkgs($_[0])) { - $self->{_pkgs}{ $_[0] } = new Pkgs $_[0]; - } - $self->pkgs($_[0])->add(@_); -} +package PkgVer; -sub new($) { +sub new($$$) { my $class = shift; my $self = {}; + bless $self, $class; + $self->{_pkg} = $_[0]; + $self->{_ver} = $_[1]; return $self; } -sub numpkgver($) { +sub pkgname($) { my $self = shift; - scalar($self->pkgver); + + $self->pkg . '-' . $self->ver; } -sub pkgver($@) { +sub pkg($) { my $self = shift; - if (@_ == 0) { - my (@list); - foreach my $pkg ($self->pkgs) { - push(@list, $pkg->pkgver); - } - return (@list); - } + $self->{_pkg}; +} - if (defined $self->{_pkgs}{$_[0]}) { - return (@_ > 1) - ? $self->{_pkgs}{$_[0]}->pkgver($_[1]) - : $self->{_pkgs}{$_[0]}->pkgver(); - } - return; +sub var($$$) { + my $self = shift; + my ($key, $val) = @_; + + (defined $val) + ? ($self->{$key} = $val) + : $self->{$key}; } -sub pkgs($@) { +sub ver($) { my $self = shift; - if (@_) { - return $self->{_pkgs}{$_[0]}; - } else { - return (sort { $a->pkg cmp $b->pkg } values %{$self->{_pkgs}}); - } + $self->{_ver}; +} + +sub vars($) { + my $self = shift; + + grep(!/^_(pkg|ver)$/, keys %{$self}); } sub store($) { my $self = shift; - my $pkgs = $self->{_pkgs}; - foreach my $pkg (sort keys %$pkgs) { - $pkgs->{$pkg}->store(); + my $name = $self->{_pkg}; + my $ver = $self->{_ver}; + + $name =~ /\s/ and die "cannot store package name '$name'\n"; + $ver =~ /\s/ and die "cannot store package version '$ver'\n"; + printf("package\t%s\t%s\n", $name, $ver); + + foreach my $varname (sort $self->vars) { + my $value = $self->{$varname}; + $varname =~ /\s/ and die "cannot store variable name '$varname'\n"; + $value =~ /\n/ and die "cannot store variable value '$value'\n"; + printf("var\t%s\t%s\n", $varname, $value); } } @@ -142,68 +144,66 @@ ($) } } -# PkgVer is a unique package+version +# PkgList is the master list of all packages in pkgsrc. # -package PkgVer; +package PkgList; -sub new($$$) { +sub add($@) { + my $self = shift; + + if (!$self->pkgs($_[0])) { + $self->{_pkgs}{ $_[0] } = new Pkgs $_[0]; + } + $self->pkgs($_[0])->add(@_); +} + +sub new($) { my $class = shift; my $self = {}; - bless $self, $class; - $self->{_pkg} = $_[0]; - $self->{_ver} = $_[1]; return $self; } -sub pkgname($) { - my $self = shift; - - $self->pkg . '-' . $self->ver; -} - -sub pkg($) { +sub numpkgver($) { my $self = shift; - - $self->{_pkg}; + scalar($self->pkgver); } -sub var($$$) { +sub pkgver($@) { my $self = shift; - my ($key, $val) = @_; - (defined $val) - ? ($self->{$key} = $val) - : $self->{$key}; -} - -sub ver($) { - my $self = shift; + if (@_ == 0) { + my (@list); + foreach my $pkg ($self->pkgs) { + push(@list, $pkg->pkgver); + } + return (@list); + } - $self->{_ver}; + if (defined $self->{_pkgs}{$_[0]}) { + return (@_ > 1) + ? $self->{_pkgs}{$_[0]}->pkgver($_[1]) + : $self->{_pkgs}{$_[0]}->pkgver(); + } + return; } -sub vars($) { +sub pkgs($@) { my $self = shift; - grep(!/^_(pkg|ver)$/, keys %{$self}); + if (@_) { + return $self->{_pkgs}{$_[0]}; + } else { + return (sort { $a->pkg cmp $b->pkg } values %{$self->{_pkgs}}); + } } sub store($) { my $self = shift; - my $name = $self->{_pkg}; - my $ver = $self->{_ver}; - - $name =~ /\s/ and die "cannot store package name '$name'\n"; - $ver =~ /\s/ and die "cannot store package version '$ver'\n"; - printf("package\t%s\t%s\n", $name, $ver); - - foreach my $varname (sort $self->vars) { - my $value = $self->{$varname}; - $varname =~ /\s/ and die "cannot store variable name '$varname'\n"; - $value =~ /\n/ and die "cannot store variable value '$value'\n"; - printf("var\t%s\t%s\n", $varname, $value); + my $pkgs = $self->{_pkgs}; + foreach my $pkg (sort keys %$pkgs) { + $pkgs->{$pkg}->store(); } } From 2fbe236a05725c8fb7642b50ca0c35db4bed977f Mon Sep 17 00:00:00 2001 From: he Date: Sat, 30 Jul 2022 16:13:47 +0000 Subject: [PATCH 30/37] math/py-scipy: fix build on NetBSD/powerpc (at least!) In the unuran part, omit defining _ISOC99_SOURCE. I am told that the ieeefp.h header should not be used with _ISOC99_SOURCE. (Its use comes from pyport.h.) Lately I've seen this package fail to build also for aarch64, have not verified that this fixes it, though it's not entirely impossible. Fixes what triggered PR#56892. Bump PKGREVISION. --- math/py-scipy/Makefile | 4 ++-- math/py-scipy/distinfo | 3 ++- .../patches/patch-scipy_stats__unuran_setup.py | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 math/py-scipy/patches/patch-scipy_stats__unuran_setup.py diff --git a/math/py-scipy/Makefile b/math/py-scipy/Makefile index 656ddffcc002..b8cedb2382e9 100644 --- a/math/py-scipy/Makefile +++ b/math/py-scipy/Makefile @@ -1,7 +1,7 @@ -# $NetBSD: Makefile,v 1.59 2022/06/28 11:34:45 wiz Exp $ +# $NetBSD: Makefile,v 1.60 2022/07/30 16:13:47 he Exp $ DISTNAME= scipy-1.8.1 -PKGREVISION= 2 +PKGREVISION= 3 PKGNAME= ${PYPKGPREFIX}-${DISTNAME} CATEGORIES= math python MASTER_SITES= ${MASTER_SITE_PYPI:=s/scipy/} diff --git a/math/py-scipy/distinfo b/math/py-scipy/distinfo index 558b62541fb1..8590fad8946c 100644 --- a/math/py-scipy/distinfo +++ b/math/py-scipy/distinfo @@ -1,4 +1,4 @@ -$NetBSD: distinfo,v 1.36 2022/05/27 16:59:50 tnn Exp $ +$NetBSD: distinfo,v 1.37 2022/07/30 16:13:47 he Exp $ BLAKE2s (scipy-1.8.1.tar.gz) = 364d6645a49d897429094a406e6073e124c1ebca01f4be63ebe401b660d8df38 SHA512 (scipy-1.8.1.tar.gz) = f6fc71c209991fe82baa4b10d8ade0deb1057f6f5942a91dfb7ae45f3eb78a4535efa2861badf5e2d37239fa99dbd99de760aa7e4854b95991ade0263004e7ea @@ -6,3 +6,4 @@ Size (scipy-1.8.1.tar.gz) = 38196215 bytes SHA1 (patch-scipy_spatial_ckdtree_src_ckdtree__decl.h) = ad0e4a79af2a3b0667e61f205f5b8453ea440498 SHA1 (patch-scipy_special___logit.h) = c729c2b73de00cad4c9ad834a79b80dea7b05af3 SHA1 (patch-scipy_special___round.h) = bc05a935e6423ce8395450ad3b30e88826939422 +SHA1 (patch-scipy_stats__unuran_setup.py) = 9839f589fdfe7f1f74e84f32526a2ce96a28d04a diff --git a/math/py-scipy/patches/patch-scipy_stats__unuran_setup.py b/math/py-scipy/patches/patch-scipy_stats__unuran_setup.py new file mode 100644 index 000000000000..df9ec95d88af --- /dev/null +++ b/math/py-scipy/patches/patch-scipy_stats__unuran_setup.py @@ -0,0 +1,16 @@ +$NetBSD: patch-scipy_stats__unuran_setup.py,v 1.1 2022/07/30 16:13:48 he Exp $ + +On NetBSD/powerpc, you can't build with _ISOC99_SOURCE defined, +the include of deep down in the python headers will fail +with undefined types. + +--- ./scipy/stats/_unuran/setup.py.orig 2022-05-16 12:36:53.864307900 +0000 ++++ ./scipy/stats/_unuran/setup.py +@@ -95,7 +95,6 @@ def configuration(parent_package="", top + ("UNUR_ENABLE_INFO", "1"), + ("VERSION", '"%s"' % UNURAN_VERSION), + ("HAVE_CONFIG_H", "1"), +- ("_ISOC99_SOURCE", "1"), + ] + + UNURAN_DIRS = [ From 17f4deab8ac5ad6c663d5ad813a0b33cf19098be Mon Sep 17 00:00:00 2001 From: he Date: Sat, 30 Jul 2022 16:14:29 +0000 Subject: [PATCH 31/37] Note update of math/py-scipy to 1.8.1nb3. --- doc/CHANGES-2022 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/CHANGES-2022 b/doc/CHANGES-2022 index ca4bb168c890..be1948dffb14 100644 --- a/doc/CHANGES-2022 +++ b/doc/CHANGES-2022 @@ -1,4 +1,4 @@ -$NetBSD: CHANGES-2022,v 1.3603 2022/07/30 14:50:22 taca Exp $ +$NetBSD: CHANGES-2022,v 1.3604 2022/07/30 16:14:29 he Exp $ Changes to the packages collection and infrastructure in 2022: @@ -5387,3 +5387,4 @@ Changes to the packages collection and infrastructure in 2022: Updated time/ruby-tzinfo1 to 1.2.10 [taca 2022-07-30] Updated time/ruby-tzinfo to 2.0.5 [taca 2022-07-30] Updated security/pear-Crypt_GPG to 1.6.7nb1 [taca 2022-07-30] + Updated math/py-scipy to 1.8.1nb3 [he 2022-07-30] From 444502e67e82f9aa1a8129b12420156a7f81aca5 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 16:20:18 +0000 Subject: [PATCH 32/37] lintpkgsrc: test code for storing package data --- pkgtools/lintpkgsrc/Makefile | 3 +- pkgtools/lintpkgsrc/files/t/packages.t | 44 ++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 pkgtools/lintpkgsrc/files/t/packages.t diff --git a/pkgtools/lintpkgsrc/Makefile b/pkgtools/lintpkgsrc/Makefile index f9a78db68d9e..d058ed059dee 100644 --- a/pkgtools/lintpkgsrc/Makefile +++ b/pkgtools/lintpkgsrc/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.42 2022/07/30 14:55:51 rillig Exp $ +# $NetBSD: Makefile,v 1.43 2022/07/30 16:20:18 rillig Exp $ PKGNAME= lintpkgsrc-4.99 CATEGORIES= pkgtools @@ -8,6 +8,7 @@ HOMEPAGE= https://www.NetBSD.org/docs/pkgsrc/ COMMENT= Sanity checks on the complete pkgsrc tree DEPENDS+= digest>=20010101:../../pkgtools/digest +TEST_DEPENDS+= p5-Capture-Tiny>=0:../../devel/p5-Capture-Tiny CONFLICTS+= pkglint<4.82 USE_TOOLS+= perl:run diff --git a/pkgtools/lintpkgsrc/files/t/packages.t b/pkgtools/lintpkgsrc/files/t/packages.t new file mode 100644 index 000000000000..3b7bc94a2719 --- /dev/null +++ b/pkgtools/lintpkgsrc/files/t/packages.t @@ -0,0 +1,44 @@ +# $NetBSD: packages.t,v 1.1 2022/07/30 16:20:18 rillig Exp $ + +use strict; +use warnings; +use Capture::Tiny 'capture'; +use Test; + +BEGIN { plan tests => 1; } + +$ENV{'TESTING_LINTPKGSRC'} = 'yes'; +require('../lintpkgsrc.pl'); + +sub test_package_variables() { + my $pkglist = PkgList->new(); + my $pkgbase_1_0 = $pkglist->add('pkgbase', '1.0'); + + $pkgbase_1_0->var('NAME', 'value'); + + ok($pkgbase_1_0->var('NAME'), 'value'); + ok($pkgbase_1_0->var('undefined'), undef); +} + +# Demonstrate how the package data is stored in the cache file. +sub test_store_order() { + my $pkglist = PkgList->new(); + + my $pkgbase_1_0 = $pkglist->add('pkgbase', '1.0'); + my $pkgbase_1_3nb4 = $pkglist->add('pkgbase', '1.3nb4'); + my $pkgbase_1_15 = $pkglist->add('pkgbase', '1.15'); + + my $stdout = capture { + $pkglist->store(); + }; + + # XXX: 1.3nb4 should be sorted before 1.15. + # On the other hand, this is just an internal cache file format. + ok($stdout, '' + . "package\tpkgbase\t1.0\n" + . "package\tpkgbase\t1.15\n" + . "package\tpkgbase\t1.3nb4\n"); +} + +test_package_variables(); +test_store_order(); From 57ffca24cfad6f217c2487355cb0ea518e401b53 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 16:26:14 +0000 Subject: [PATCH 33/37] lintpkgsrc: rename safe_chdir to chdir_or_fail The word 'safe' was too ambiguous. While here, remove the source code location from the error message. This error is not expected to occur during normal usage. --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index afc3d551eca7..737702cfe76f 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.38 2022/07/30 15:11:26 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.39 2022/07/30 16:26:14 rillig Exp $ # Written by David Brownlee . # @@ -1148,15 +1148,11 @@ ($) } -# chdir() || fail() -# -sub safe_chdir($) { +sub chdir_or_fail($) { my ($dir) = @_; debug("chdir: $dir"); - if (!chdir($dir)) { - fail("Unable to chdir($dir): $!"); - } + chdir($dir) or fail("Cannot chdir($dir): $!\n"); } sub load_pkgsrc_makefiles($) { @@ -1331,7 +1327,7 @@ ($$$$) } verbose("checksum mismatches\n"); - safe_chdir($pkgdistdir); + chdir_or_fail($pkgdistdir); foreach my $sum (keys %sumfiles) { if ($sum eq 'Size') { foreach my $file (@{$sumfiles{$sum}}) { @@ -1365,7 +1361,7 @@ ($$$$) waitpid($pid, 0) || fail "xargs digest $sum"; waitpid($pid2, 0) || fail "pipe write to xargs"; } - safe_chdir('/'); # Do not want to stay in $pkgdistdir + chdir_or_fail('/'); # Do not want to stay in $pkgdistdir } (sort keys %bad_distfiles); } @@ -1615,7 +1611,7 @@ () } if ($opt{r}) { - safe_chdir("$pkgdistdir"); + chdir_or_fail("$pkgdistdir"); verbose("Unlinking 'orphaned' distfiles\n"); foreach my $distfile (@orphan) { unlink($distfile) @@ -1642,7 +1638,7 @@ () } if ($opt{r}) { - safe_chdir("$pkgdistdir"); + chdir_or_fail("$pkgdistdir"); verbose("Unlinking 'parented' distfiles\n"); foreach my $distfile (@parent) { unlink($distfile); @@ -1779,7 +1775,7 @@ () } print "$pkgsrcdir/$pkgdir\n"; - safe_chdir("$pkgsrcdir/$pkgdir"); + chdir_or_fail("$pkgsrcdir/$pkgdir"); system("$conf_make fetch-list | sh"); } } From d1b9876347f9f1c4ad9ced95744b21f240e97468 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 17:06:29 +0000 Subject: [PATCH 34/37] lintpkgsrc: test versioned packages, minor cleanup --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 21 ++++++++++++++------- pkgtools/lintpkgsrc/files/t/packages.t | 23 ++++++++++++++++++++--- pkgtools/lintpkgsrc/files/t/pkgversion.t | 3 +-- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 737702cfe76f..bd48e76cf996 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.39 2022/07/30 16:26:14 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.40 2022/07/30 17:06:29 rillig Exp $ # Written by David Brownlee . # @@ -22,7 +22,8 @@ use IPC::Open3; use Cwd 'realpath', 'getcwd'; -# PkgVer is a unique package + version. +# PkgVer is a PKGBASE + PKGVERSION, including some of the variables that +# have been extracted from the package Makefile. # package PkgVer; @@ -87,7 +88,8 @@ ($) } } -# Pkgs is all versions of a given package (eg: apache-1.x and apache-2.x) +# Pkgs collects all versions of a given PKGBASE, e.g. apache-1.3.27 and +# apache-2.0.46. # package Pkgs; @@ -106,6 +108,8 @@ ($@) return $self; } +# Returns all available versions of the package, in decreasing +# alphabetical(!) order. sub versions($) { my $self = shift; @@ -117,16 +121,19 @@ ($) $self->{_pkg}; } +# Returns all available versioned packages of this PKGBASE, in decreasing +# alphabetical(!) order. sub pkgver($@) { my $self = shift; + my $pkgvers = $self->{_pkgver}; if (@_) { - if ($self->{_pkgver}{$_[0]}) { - return ($self->{_pkgver}{$_[0]}); + if ($pkgvers->{$_[0]}) { + return ($pkgvers->{$_[0]}); } return; } - return sort { $b->ver() cmp $a->ver() } values %{$self->{_pkgver}}; + return sort { $b->ver cmp $a->ver } values %{$pkgvers}; } sub latestver($) { @@ -1787,4 +1794,4 @@ () } } -main() unless defined $ENV{'TESTING_LINTPKGSRC'}; +main() unless caller(); diff --git a/pkgtools/lintpkgsrc/files/t/packages.t b/pkgtools/lintpkgsrc/files/t/packages.t index 3b7bc94a2719..ab9e9163486f 100644 --- a/pkgtools/lintpkgsrc/files/t/packages.t +++ b/pkgtools/lintpkgsrc/files/t/packages.t @@ -1,13 +1,12 @@ -# $NetBSD: packages.t,v 1.1 2022/07/30 16:20:18 rillig Exp $ +# $NetBSD: packages.t,v 1.2 2022/07/30 17:06:29 rillig Exp $ use strict; use warnings; use Capture::Tiny 'capture'; use Test; -BEGIN { plan tests => 1; } +BEGIN { plan tests => 8; } -$ENV{'TESTING_LINTPKGSRC'} = 'yes'; require('../lintpkgsrc.pl'); sub test_package_variables() { @@ -18,6 +17,24 @@ sub test_package_variables() { ok($pkgbase_1_0->var('NAME'), 'value'); ok($pkgbase_1_0->var('undefined'), undef); + + my $pkgbase_2_0 = $pkglist->add('pkgbase', '2.0'); + my $pkgbase_1_5 = $pkglist->add('pkgbase', '1.5'); + my $pkgbase_1_10 = $pkglist->add('pkgbase', '1.10'); + + $pkgbase_2_0->var('COMMENT', 'Version 2 of the package'); + + ok($pkglist->pkgs('unknown-pkgbase'), undef); + + # The versions are sorted in decreasing alphabetical order. + my $versions = join(', ', $pkglist->pkgs('pkgbase')->versions()); + ok($versions, '2.0, 1.5, 1.10, 1.0'); + + # The versioned packages are sorted in decreasing alphabetical order. + my @pkgvers = $pkglist->pkgver('pkgbase'); + ok(join(', ', map { $_->ver } @pkgvers), '2.0, 1.5, 1.10, 1.0'); + ok($pkgvers[0], $pkgbase_2_0); + ok($pkgvers[3], $pkgbase_1_0); } # Demonstrate how the package data is stored in the cache file. diff --git a/pkgtools/lintpkgsrc/files/t/pkgversion.t b/pkgtools/lintpkgsrc/files/t/pkgversion.t index 77ffd9aade2c..e83a703aaae9 100644 --- a/pkgtools/lintpkgsrc/files/t/pkgversion.t +++ b/pkgtools/lintpkgsrc/files/t/pkgversion.t @@ -1,11 +1,10 @@ -# $NetBSD: pkgversion.t,v 1.1 2022/07/30 10:11:45 rillig Exp $ +# $NetBSD: pkgversion.t,v 1.2 2022/07/30 17:06:29 rillig Exp $ use strict; use warnings; use Test; BEGIN { plan tests => 5; } -$ENV{'TESTING_LINTPKGSRC'} = 'yes'; require('../lintpkgsrc.pl'); ok(pkgversioncmp('3.4', '<', '3.4'), ''); From 32b67e4bb1bedfacb2cf15001f2f0c3c35a1b58b Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 17:30:47 +0000 Subject: [PATCH 35/37] lintpkgsrc: condense code for checking mandatory command line options --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index bd48e76cf996..4a11d0ee23d3 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.40 2022/07/30 17:06:29 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.41 2022/07/30 17:30:47 rillig Exp $ # Written by David Brownlee . # @@ -1485,22 +1485,7 @@ () if ( !getopts('BDE:I:K:LM:OP:RSVdg:himopruyz', \%opt) || $opt{h} - || !(defined $opt{d} - || defined $opt{g} - || defined $opt{i} - || defined $opt{m} - || defined $opt{o} - || defined $opt{p} - || defined $opt{r} - || defined $opt{u} - || defined $opt{B} - || defined $opt{D} - || defined $opt{R} - || defined $opt{O} - || defined $opt{S} - || defined $opt{E} - || defined $opt{y} - || defined $opt{z})) { + || !grep(/[BDEORSdgimopruyz]/, keys %opt)) { usage_and_exit(); } $| = 1; From 3737b9e7020980ef16f7ad4d4277d9470ee933d3 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 30 Jul 2022 18:20:23 +0000 Subject: [PATCH 36/37] lintpkgsrc: cleanup: split main into smaller subroutines No functional change. --- pkgtools/lintpkgsrc/files/lintpkgsrc.pl | 476 +++++++++++++----------- 1 file changed, 252 insertions(+), 224 deletions(-) diff --git a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl index 4a11d0ee23d3..722d0d5f2d6b 100755 --- a/pkgtools/lintpkgsrc/files/lintpkgsrc.pl +++ b/pkgtools/lintpkgsrc/files/lintpkgsrc.pl @@ -1,6 +1,6 @@ #!@PERL5@ -# $NetBSD: lintpkgsrc.pl,v 1.41 2022/07/30 17:30:47 rillig Exp $ +# $NetBSD: lintpkgsrc.pl,v 1.42 2022/07/30 18:20:23 rillig Exp $ # Written by David Brownlee . # @@ -1477,156 +1477,128 @@ () } } -sub main() { +sub debug_parse_makefiles(@) { - $ENV{PATH} .= - ":/bin:/usr/bin:/sbin:/usr/sbin:$conf_prefix/sbin:$conf_prefix/bin"; + foreach my $file (@_) { + -d $file and $file .= "/Makefile"; + -f $file or fail("No such file: $file"); - if ( - !getopts('BDE:I:K:LM:OP:RSVdg:himopruyz', \%opt) - || $opt{h} - || !grep(/[BDEORSdgimopruyz]/, keys %opt)) { - usage_and_exit(); + my ($pkgname, $vars) = parse_makefile_pkgsrc($file); + $pkgname ||= 'uNDEFINEd'; + + print "$file -> $pkgname\n"; + foreach my $varname (sort keys %$vars) { + print "\t$varname = $vars->{$varname}\n"; + } + + #if ($opt{d}) { + # pkgsrc_check_depends(); + #} } - $| = 1; +} - get_default_makefile_vars(); # $default_vars +sub check_distfiles($$) { + my ($pkgsrcdir, $pkgdistdir) = @_; - if ($opt{D} && @ARGV) { - foreach my $file (@ARGV) { - if (-d $file) { - $file .= "/Makefile"; - } - if (!-f $file) { - fail("No such file: $file"); - } - my ($pkgname, $vars) = parse_makefile_pkgsrc($file); - $pkgname ||= 'uNDEFINEd'; - print "$file -> $pkgname\n"; - foreach my $varname (sort keys %{$vars}) { - print "\t$varname = $vars->{$varname}\n"; - } + my @baddist = scan_pkgsrc_distfiles_vs_distinfo( + $pkgsrcdir, $pkgdistdir, $opt{o}, $opt{m}); - #if ($opt{d}) { - # pkgsrc_check_depends(); - #} - } - exit; + return unless $opt{r}; + verbose("Unlinking 'bad' distfiles\n"); + foreach my $distfile (@baddist) { + unlink("$pkgdistdir/$distfile"); } +} - my $pkgsrcdir = $default_vars->{PKGSRCDIR}; - my $pkgdistdir = $default_vars->{DISTDIR}; +sub remove_distfiles($$) { + my ($pkgsrcdir, $pkgdistdir) = @_; - if ($opt{r} && !$opt{o} && !$opt{m} && !$opt{p}) { - $opt{o} = $opt{m} = $opt{p} = 1; + my @pkgs = list_installed_packages(); + scan_pkgsrc_makefiles($pkgsrcdir); + + # list the installed packages and the directory they live in + my @installed; + foreach my $pkgname (sort @pkgs) { + if ($pkgname =~ /^([^*?[]+)-([\d*?[].*)/) { + foreach my $pkgver ($pkglist->pkgver($1)) { + next if $pkgver->var('dir') =~ /-current/; + push(@installed, $pkgver); + last; + } + } } - if ($opt{o} || $opt{m}) { - my (@baddist); - @baddist = scan_pkgsrc_distfiles_vs_distinfo( - $pkgsrcdir, $pkgdistdir, $opt{o}, $opt{m}); - if ($opt{r}) { - verbose("Unlinking 'bad' distfiles\n"); - foreach my $distfile (@baddist) { - unlink("$pkgdistdir/$distfile"); + # distfiles belonging to the currently installed packages + my (%distfiles, @pkgdistfiles); + foreach my $pkgver (sort @installed) { + my $pkgpath = $pkgver->var('dir'); + next unless open(DISTINFO, "$pkgsrcdir/$pkgpath/distinfo"); + while () { + next unless m/^(\w+) ?\(([^\)]+)\) = (\S+)/; + my $dn = $2; + next if $dn =~ /^patch-[\w.+\-]+$/; + # Strip leading ./ which sometimes gets added + # because of DISTSUBDIR=. + $dn =~ s/^(\.\/)*//; + if (!defined $distfiles{$dn}) { + $distfiles{$dn}{name} = $dn; + push(@pkgdistfiles, $dn); } } + close(DISTINFO); } - # Remove all distfiles that are / are not part of an installed package - if ($opt{y} || $opt{z}) { - my (@pkgs, @installed, %distfiles, @pkgdistfiles, @dldistfiles); - my (@tmpdistfiles, @orphan, $found, @parent); + # distfiles downloaded on the current system + my @tmpdistfiles = listdir("$pkgdistdir", undef); + my @dldistfiles = grep { $_ ne "pkg-vulnerabilities" } @tmpdistfiles; - @pkgs = list_installed_packages(); - scan_pkgsrc_makefiles($pkgsrcdir); + # sort the two arrays to make searching a bit faster + @dldistfiles = sort { $a cmp $b } @dldistfiles; + @pkgdistfiles = sort { $a cmp $b } @pkgdistfiles; - # list the installed packages and the directory they live in - foreach my $pkgname (sort @pkgs) { - if ($pkgname =~ /^([^*?[]+)-([\d*?[].*)/) { - foreach my $pkgver ($pkglist->pkgver($1)) { - $pkgver->var('dir') =~ /-current/ && next; - push(@installed, $pkgver); - last; + if ($opt{y}) { + # looking for files that are downloaded on the current system + # but do not belong to any currently installed package i.e. orphaned + my $found = 0; + my @orphan; + foreach my $dldf (@dldistfiles) { + foreach my $pkgdf (@pkgdistfiles) { + if ($dldf eq $pkgdf) { + $found = 1; } } - } - - # distfiles belonging to the currently installed packages - foreach my $pkgver (sort @installed) { - if (open(DISTINFO, "$pkgsrcdir/" . $pkgver->var('dir') . "/distinfo")) { - while () { - if (m/^(\w+) ?\(([^\)]+)\) = (\S+)/) { - my ($dn); - if ($2 =~ /^patch-[\w.+\-]+$/) { next; } - $dn = $2; - # Strip leading ./ which sometimes gets added - # because of DISTSUBDIR=. - $dn =~ s/^(\.\/)*//; - if (!defined $distfiles{$dn}) { - $distfiles{$dn}{name} = $dn; - push(@pkgdistfiles, $dn); - } - } - } - close(DISTINFO); + if ($found != 1) { + push(@orphan, $dldf); + print "Orphaned file: $dldf\n"; } + $found = 0; } - # distfiles downloaded on the current system - @tmpdistfiles = listdir("$pkgdistdir", undef); - foreach my $tmppkg (@tmpdistfiles) { - if ($tmppkg ne "pkg-vulnerabilities") { - push(@dldistfiles, $tmppkg); + if ($opt{r}) { + chdir_or_fail("$pkgdistdir"); + verbose("Unlinking 'orphaned' distfiles\n"); + foreach my $distfile (@orphan) { + unlink($distfile) } } + } - # sort the two arrays to make searching a bit faster - @dldistfiles = sort { $a cmp $b } @dldistfiles; - @pkgdistfiles = sort { $a cmp $b } @pkgdistfiles; - - if ($opt{y}) { - # looking for files that are downloaded on the current system - # but do not belong to any currently installed package i.e. orphaned - $found = 0; + if ($opt{z}) { + # looking for files that are downloaded on the current system + # but belong to a currently installed package i.e. parented + my $found = 0; + my @parent; + foreach my $pkgdf (@pkgdistfiles) { foreach my $dldf (@dldistfiles) { - foreach my $pkgdf (@pkgdistfiles) { - if ($dldf eq $pkgdf) { - $found = 1; - } - } - if ($found != 1) { - push(@orphan, $dldf); - print "Orphaned file: $dldf\n"; + if ($pkgdf eq $dldf) { + $found = 1; } - $found = 0; } - - if ($opt{r}) { - chdir_or_fail("$pkgdistdir"); - verbose("Unlinking 'orphaned' distfiles\n"); - foreach my $distfile (@orphan) { - unlink($distfile) - } + if ($found == 1) { + push(@parent, $pkgdf); + print "Parented file: $pkgdf\n"; } - } - - if ($opt{z}) { - # looking for files that are downloaded on the current system - # but belong to a currently installed package i.e. parented $found = 0; - foreach my $pkgdf (@pkgdistfiles) { - foreach my $dldf (@dldistfiles) { - if ($pkgdf eq $dldf) { - $found = 1; - } - } - if ($found == 1) { - push(@parent, $pkgdf); - print "Parented file: $pkgdf\n"; - } - $found = 0; - } } if ($opt{r}) { @@ -1637,140 +1609,196 @@ () } } } +} - # List BROKEN packages - if ($opt{B}) { - scan_pkgsrc_makefiles($pkgsrcdir); - foreach my $pkgver ($pkglist->pkgver) { - $pkgver->var('BROKEN') || next; - print $pkgver->pkgname . ': ' . $pkgver->var('BROKEN') . "\n"; - } +sub list_broken_packages($) { + my ($pkgsrcdir) = @_; + + scan_pkgsrc_makefiles($pkgsrcdir); + foreach my $pkgver ($pkglist->pkgver) { + my $broken = $pkgver->var('BROKEN'); + next unless $broken; + print $pkgver->pkgname . ": $broken\n"; } +} - # List obsolete or NO_BIN_ON_FTP/RESTRICTED prebuilt packages - # - if ($opt{p} || $opt{O} || $opt{R}) { - scan_pkgsrc_makefiles($pkgsrcdir); +# List obsolete or NO_BIN_ON_FTP/RESTRICTED prebuilt packages +# +sub list_prebuilt_packages($) { + my ($pkgsrcdir) = @_; - @prebuilt_pkgdirs = ($default_vars->{PACKAGES}); - %prebuilt_pkgdir_cache = (); + scan_pkgsrc_makefiles($pkgsrcdir); - while (@prebuilt_pkgdirs) { - find(\&check_prebuilt_packages, shift @prebuilt_pkgdirs); - } + @prebuilt_pkgdirs = ($default_vars->{PACKAGES}); + %prebuilt_pkgdir_cache = (); - if ($opt{r}) { - verbose("Unlinking listed prebuilt packages\n"); - foreach my $pkgfile (@matched_prebuiltpackages) { - unlink($pkgfile); - } + while (@prebuilt_pkgdirs) { + find(\&check_prebuilt_packages, shift @prebuilt_pkgdirs); + } + + if ($opt{r}) { + verbose("Unlinking listed prebuilt packages\n"); + foreach my $pkgfile (@matched_prebuiltpackages) { + unlink($pkgfile); } } +} - if ($opt{S}) { - my (%in_subdir); +sub list_packages_not_in_SUBDIR($) { + my ($pkgsrcdir) = @_; - foreach my $cat (list_pkgsrc_categories($pkgsrcdir)) { - my $vars = parse_makefile_vars("$pkgsrcdir/$cat/Makefile", undef); + my (%in_subdir); + foreach my $cat (list_pkgsrc_categories($pkgsrcdir)) { + my $vars = parse_makefile_vars("$pkgsrcdir/$cat/Makefile", undef); - if (!$vars->{SUBDIR}) { - print "Warning - no SUBDIR for $cat\n"; - next; - } - foreach my $pkgdir (split(/\s+/, $vars->{SUBDIR})) { - $in_subdir{"$cat/$pkgdir"} = 1; - } + if (!$vars->{SUBDIR}) { + print "Warning - no SUBDIR for $cat\n"; + next; + } + foreach my $pkgdir (split(/\s+/, $vars->{SUBDIR})) { + $in_subdir{"$cat/$pkgdir"} = 1; } + } - scan_pkgsrc_makefiles($pkgsrcdir); - foreach my $pkgver ($pkglist->pkgver) { - if (!defined $in_subdir{ $pkgver->var('dir') }) { - print $pkgver->var('dir') . ": Not in SUBDIR\n"; - } + scan_pkgsrc_makefiles($pkgsrcdir); + foreach my $pkgver ($pkglist->pkgver) { + my $pkgpath = $pkgver->var('dir'); + if (!defined $in_subdir{$pkgpath}) { + print "$pkgpath: Not in SUBDIR\n"; } } +} - if ($opt{g}) { - my $tmpfile = "$opt{g}.tmp.$$"; +sub generate_map_file($$) { + my ($pkgsrcdir, $fname) = @_; - scan_pkgsrc_makefiles($pkgsrcdir); - if (!open(TABLE, ">$tmpfile")) { - fail("Unable to write '$tmpfile': $!"); - } - foreach my $pkgver ($pkglist->pkgver) { - print TABLE $pkgver->pkg . "\t" - . $pkgver->var('dir') . "\t" - . $pkgver->ver . "\n"; - } - if (!close(TABLE)) { - fail("Error while writing '$tmpfile': $!"); - } - if (!rename($tmpfile, $opt{g})) { - fail("Error in rename('$tmpfile','$opt{g}'): $!"); - } + my $tmpfile = "$fname.tmp.$$"; + + scan_pkgsrc_makefiles($pkgsrcdir); + open(TABLE, '>', $tmpfile) or fail("Cannot write '$tmpfile': $!"); + foreach my $pkgver ($pkglist->pkgver) { + print TABLE $pkgver->pkg . "\t" + . $pkgver->var('dir') . "\t" + . $pkgver->ver . "\n"; } + close(TABLE) or fail("close('$tmpfile'): $!"); + rename($tmpfile, $fname) + or fail("rename('$tmpfile', '$fname'): $!"); +} - if ($opt{d}) { - scan_pkgsrc_makefiles($pkgsrcdir); - pkgsrc_check_depends(); +sub check_outdated_installed_packages($) { + my ($pkgsrcdir) = @_; + + my @pkgs = list_installed_packages(); + scan_pkgsrc_makefiles($pkgsrcdir); + + my @update; + foreach my $pkgname (sort @pkgs) { + next unless $_ = invalid_version($pkgname); + + print $_; + next unless $pkgname =~ /^([^*?[]+)-([\d*?[].*)/; + + foreach my $pkgver ($pkglist->pkgver($1)) { + next if $pkgver->var('dir') =~ /-current/; + push(@update, $pkgver); + last; + } } - if ($opt{i} || $opt{u}) { - my (@pkgs, @update); + return unless $opt{u}; - @pkgs = list_installed_packages(); - scan_pkgsrc_makefiles($pkgsrcdir); + print "\nREQUIRED details for packages that could be updated:\n"; - foreach my $pkgname (sort @pkgs) { - if ($_ = invalid_version($pkgname)) { - print $_; + foreach my $pkgver (@update) { + print $pkgver->pkg . ':'; + if (open(PKGINFO, 'pkg_info -R ' . $pkgver->pkg . '|')) { + my ($list); - if ($pkgname =~ /^([^*?[]+)-([\d*?[].*)/) { - foreach my $pkgver ($pkglist->pkgver($1)) { - $pkgver->var('dir') =~ /-current/ && next; - push(@update, $pkgver); - last; - } + while () { + if (/Required by:/) { + $list = 1; + } elsif ($list) { + chomp; + s/-\d.*//; + print " $_"; } } + close(PKGINFO); } + print "\n"; + } - if ($opt{u}) { - print "\nREQUIRED details for packages that could be updated:\n"; - - foreach my $pkgver (@update) { - print $pkgver->pkg . ':'; - if (open(PKGINFO, 'pkg_info -R ' . $pkgver->pkg . '|')) { - my ($list); - - while () { - if (/Required by:/) { - $list = 1; - } elsif ($list) { - chomp; - s/-\d.*//; - print " $_"; - } - } - close(PKGINFO); - } - print "\n"; - } + print "\nRunning '$conf_make fetch-list | sh' for each package:\n"; + foreach my $pkgver (@update) { + my $pkgpath = $pkgver->var('dir'); + defined($pkgpath) + or fail('Cannot determine ' . $pkgver->pkg . ' directory'); - print "\nRunning '$conf_make fetch-list | sh' for each package:\n"; - foreach my $pkgver (@update) { - my ($pkgdir); + print "$pkgsrcdir/$pkgpath\n"; + chdir_or_fail("$pkgsrcdir/$pkgpath"); + system("$conf_make fetch-list | sh"); + } +} - $pkgdir = $pkgver->var('dir'); - if (!defined($pkgdir)) { - fail('Unable to determine ' . $pkgver->pkg . ' directory'); - } +sub main() { - print "$pkgsrcdir/$pkgdir\n"; - chdir_or_fail("$pkgsrcdir/$pkgdir"); - system("$conf_make fetch-list | sh"); - } - } + $ENV{PATH} .= + ":/bin:/usr/bin:/sbin:/usr/sbin:$conf_prefix/sbin:$conf_prefix/bin"; + + if ( + !getopts('BDE:I:K:LM:OP:RSVdg:himopruyz', \%opt) + || $opt{h} + || !grep(/[BDEORSdgimopruyz]/, keys %opt)) { + usage_and_exit(); + } + $| = 1; + + get_default_makefile_vars(); # $default_vars + + if ($opt{D} && @ARGV) { + debug_parse_makefiles(@ARGV); + exit; + } + + my $pkgsrcdir = $default_vars->{PKGSRCDIR}; + my $pkgdistdir = $default_vars->{DISTDIR}; + + if ($opt{r} && !$opt{o} && !$opt{m} && !$opt{p}) { + $opt{o} = $opt{m} = $opt{p} = 1; + } + if ($opt{o} || $opt{m}) { + check_distfiles($pkgsrcdir, $pkgdistdir); + } + + # Remove all distfiles that are / are not part of an installed package + if ($opt{y} || $opt{z}) { + remove_distfiles($pkgsrcdir, $pkgdistdir); + } + + if ($opt{B}) { + list_broken_packages($pkgsrcdir); + } + + if ($opt{p} || $opt{O} || $opt{R}) { + list_prebuilt_packages($pkgsrcdir); + } + + if ($opt{S}) { + list_packages_not_in_SUBDIR($pkgsrcdir); + } + + if ($opt{g}) { + generate_map_file($pkgsrcdir, $opt{g}); + } + + if ($opt{d}) { + scan_pkgsrc_makefiles($pkgsrcdir); + pkgsrc_check_depends(); + } + + if ($opt{i} || $opt{u}) { + check_outdated_installed_packages($pkgsrcdir); } if ($opt{E}) { From df47e0e3f489ce25edce538eaca547362774367a Mon Sep 17 00:00:00 2001 From: tnn Date: Sat, 30 Jul 2022 20:21:32 +0000 Subject: [PATCH 37/37] py-build: mark as BROKEN for py37 --- devel/py-build/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/devel/py-build/Makefile b/devel/py-build/Makefile index 58d8bc0c0cf7..7e123dc594bc 100644 --- a/devel/py-build/Makefile +++ b/devel/py-build/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.7 2022/06/23 07:26:26 wiz Exp $ +# $NetBSD: Makefile,v 1.8 2022/07/30 20:21:32 tnn Exp $ DISTNAME= build-0.8.0 PKGNAME= ${PYPKGPREFIX}-${DISTNAME} @@ -23,7 +23,8 @@ USE_PKG_RESOURCES= yes .include "../../lang/python/pyversion.mk" .if ${PYPKGPREFIX} == "py37" -DEPENDS+= ${PYPKGPREFIX}-importlib-metadata-[0-9]*:../../devel/py-importlib-metadata +#DEPENDS+= ${PYPKGPREFIX}-importlib-metadata-[0-9]*:../../devel/py-importlib-metadata +BROKEN+= "circular dependency" .endif post-install: