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/} 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: diff --git a/doc/CHANGES-2022 b/doc/CHANGES-2022 index 0d07bf049554..be1948dffb14 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.3604 2022/07/30 16:14:29 he Exp $ Changes to the packages collection and infrastructure in 2022: @@ -5377,9 +5377,14 @@ 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] 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] + 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] 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 = [ diff --git a/pkgtools/lintpkgsrc/Makefile b/pkgtools/lintpkgsrc/Makefile index 453015b1337f..d058ed059dee 100644 --- a/pkgtools/lintpkgsrc/Makefile +++ b/pkgtools/lintpkgsrc/Makefile @@ -1,31 +1,26 @@ -# $NetBSD: Makefile,v 1.39 2022/06/28 11:35:24 wiz Exp $ +# $NetBSD: Makefile,v 1.43 2022/07/30 16:20:18 rillig Exp $ -PKGNAME= lintpkgsrc-4.98 -PKGREVISION= 1 +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 +TEST_DEPENDS+= p5-Capture-Tiny>=0:../../devel/p5-Capture-Tiny 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 642c60e5d05a..722d0d5f2d6b 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.42 2022/07/30 18:20:23 rillig Exp $ # Written by David Brownlee . # @@ -22,1704 +22,1373 @@ use IPC::Open3; use Cwd 'realpath', 'getcwd'; +# PkgVer is a PKGBASE + PKGVERSION, including some of the variables that +# have been extracted from the package Makefile. +# +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 $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); + } +} + +# Pkgs collects all versions of a given PKGBASE, e.g. apache-1.3.27 and +# apache-2.0.46. +# +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; +} + +# Returns all available versions of the package, in decreasing +# alphabetical(!) order. +sub versions($) { + my $self = shift; + + return sort { $b cmp $a } keys %{$self->{_pkgver}}; +} + +sub pkg($) { + my $self = shift; + $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 ($pkgvers->{$_[0]}) { + return ($pkgvers->{$_[0]}); + } + return; + } + return sort { $b->ver cmp $a->ver } values %{$pkgvers}; +} + +sub latestver($) { + my $self = shift; + + ($self->pkgver())[0]; +} + +sub store($) { + my $self = shift; + + my $pkgvers = $self->{_pkgver}; + foreach my $pkgver (sort keys %$pkgvers) { + $pkgvers->{$pkgver}->store(); + } +} + +# PkgList is the master list of all packages in pkgsrc. +# +package PkgList; + +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; + return $self; +} + +sub numpkgver($) { + 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; +} + +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 = $self->{_pkgs}; + foreach my $pkg (sort keys %$pkgs) { + $pkgs->{$pkg}->store(); + } +} + +package main; + # 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(); -sub listdir($$); -sub get_default_makefile_vars(); -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"; - } - - #if ($opt{d}) { - # pkgsrc_check_depends(); - #} - } - exit; +sub debug(@) { + + ($opt{D}) && print STDERR 'DEBUG: ', @_; } -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); +sub verbose(@) { - # 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 (-t STDERR) { + print STDERR @_; + } +} - # 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); - } +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); + 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; +} + +sub canonicalize_pkgname($) { + my ($pkgname) = @_; + + $pkgname =~ s,^py\d+(?:pth|)-,py-,; + $pkgname =~ s,^ruby\d+-,ruby-,; + $pkgname =~ s,^php\d+-,php-,; + return $pkgname; +} + +sub convert_to_standard_pkgversion(@) { + my ($elem, @temp); + + # See pkg_install/lib/dewey.c. + # 'nb' has already been handled when we are here. + foreach $elem (@_) { + if ($elem =~ /\d/) { + push(@temp, $elem); + } elsif ($elem eq "pl" || $elem eq "." || $elem eq "_") { + push(@temp, 0); + } elsif ($elem eq "pre" || $elem eq "rc") { + push(@temp, -1); + } elsif ($elem eq "beta") { + push(@temp, -2); + } elsif ($elem eq "alpha") { + push(@temp, -3); + } else { + push(@temp, 0); + push(@temp, ord($elem) - ord("a") + 1); + } + } + @temp; +} + +sub pkgversioncmp_extract($$) { + my ($match, $val) = @_; + my ($cmp, @matchlist, @vallist); + + @matchlist = convert_to_standard_pkgversion(split(/(\D+)/, lc($match))); + @vallist = convert_to_standard_pkgversion(split(/(\D+)/, lc($val))); + $cmp = 0; + while ($cmp == 0 && (@matchlist || @vallist)) { + $cmp = ((shift @matchlist || 0) <=> (shift @vallist || 0)); + } + $cmp; +} + +# 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); + + $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 = pkgversioncmp_extract($match, $val); + + if (!$cmp) { + # Iff otherwise identical, check nb suffix + $cmp = pkgversioncmp_extract($match_nb, $val_nb); + } + + debug("eval pkgversioncmp $cmp $test 0\n"); + eval "$cmp $test 0"; +} + +sub parse_expand_vars($$) { + 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($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, $varname) = ($1, $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; +} + +# 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); } - } - close(DISTINFO); + debug("$file: .if$type (! @if_false)\n"); + next; } - } - # distfiles downloaded on the current system - @tmpdistfiles = listdir("$pkgdistdir", undef); - foreach my $tmppkg (@tmpdistfiles) - { - if ($tmppkg ne "pkg-vulnerabilities") - { push (@dldistfiles, $tmppkg); } - } + 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; + } - # sort the two arrays to make searching a bit faster - @dldistfiles = sort { $a cmp $b } @dldistfiles; - @pkgdistfiles = sort { $a cmp $b } @pkgdistfiles; + 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 ($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"; + 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); + } + } + } } - $found = 0; + next; } - 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"; + 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"; + } } - $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); + } + + debug("$file: expand\n"); - @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} ); - } + # 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 canonicalize_pkgname($) { - my ($pkgname) = @_; +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)(pkgversion) + 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 (pkgversioncmp($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))) { - $pkgname =~ s,^py\d+(?:pth|)-,py-,; - $pkgname =~ s,^ruby\d+-,ruby-,; - $pkgname =~ s,^php\d+-,php-,; - return $pkgname; -} + # (large-glob) + foreach my $pkgver ($pkglist->pkgver) { + if ($pkgver->pkgname =~ /$regex/) { + $matchver = undef; + last; + } + } + } -# 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() { + } else { + ($matchpkgname, $matchver) = ($pkgmatch, 'missing'); + } - 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 ); - } - } - } + ($matchpkgname, $matchver); } -# Dewey decimal verson number matching - or thereabouts -# Also handles 'nb' suffix (checked iff values otherwise identical) +# Parse a pkgsrc package makefile and return the pkgname and set variables # -sub deweycmp($$$) { - my ( $match, $test, $val ) = @_; - my ( $cmp, $match_nb, $val_nb ); - - $match_nb = $val_nb = 0; - if ( $match =~ /(.*)nb(.*)/ ) { +sub parse_makefile_pkgsrc($) { + my ($file) = @_; + my ($pkgname, $vars); - # Handle nb suffix - $match = $1; - $match_nb = $2; - } + $vars = parse_makefile_vars($file, undef); - if ( $val =~ /(.*)nb(.*)/ ) { + if (!$vars) { - # Handle nb suffix - $val = $1; - $val_nb = $2; - } + # Missing Makefile + return undef; + } - $cmp = deweycmp_extract( $match, $val ); + if (defined $vars->{PKGNAME}) { + $pkgname = $vars->{PKGNAME}; + } elsif (defined $vars->{DISTNAME}) { + $pkgname = $vars->{DISTNAME}; + } - if ( !$cmp ) { + if (defined $vars->{PKGNAME}) { + debug("$file: PKGNAME=$vars->{PKGNAME}\n"); + } + if (defined $vars->{DISTNAME}) { + debug("$file: DISTNAME=$vars->{DISTNAME}\n"); + } - # Iff otherwise identical, check nb suffix - $cmp = deweycmp_extract( $match_nb, $val_nb ); - } + 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; + } + } + } - debug("eval deweycmp $cmp $test 0\n"); - eval "$cmp $test 0"; -} + if (defined $pkgname) { + if ($pkgname =~ /^pkg_install-(\d+)$/ && $1 < $pkg_installver) { + $pkgname = "pkg_install-$pkg_installver"; + } -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; -} + $pkgname = canonicalize_pkgname($pkgname); -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; -} + 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"; -sub fail($) { + } elsif ($vars->{PKGREVISION}) { + $pkgname .= "nb"; + $pkgname .= $vars->{PKGREVISION}; + } + } - print STDERR shift(), "\n"; - exit(3); -} + if ($pkgname =~ /\$/) { + print "\nBogus: $pkgname (from $file)\n"; -sub get_default_makefile_vars() { + } elsif ($pkgname =~ /(.*)-(\d.*)/) { + if ($pkglist) { + my ($pkgver) = $pkglist->add($1, $2); - 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'; -} + debug("add $1 $2\n"); -# 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; -} + foreach my $var (qw(DEPENDS RESTRICTED OSVERSION_SPECIFIC BROKEN)) { + $pkgver->var($var, $vars->{$var}); + } -# List (recursive) non directory contents of specified directory -# -#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; -} + if (defined $vars->{NO_BIN_ON_FTP}) { + $pkgver->var('RESTRICTED', 'NO_BIN_ON_FTP'); + } -# Use pkg_info to list installed packages -# -sub list_installed_packages() { - my (@pkgs); + if ($file =~ m:([^/]+/[^/]+)/Makefile$:) { + $pkgver->var('dir', $1); + } else { + $pkgver->var('dir', 'unknown'); + } + } + } else { + print "Cannot extract $pkgname version ($file)\n"; + } - 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); + return ($pkgname, $vars); - @pkgs; + } else { + return (undef); + } } -# 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 chdir_or_fail($) { + my ($dir) = @_; -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 . '$'; + debug("chdir: $dir"); + chdir($dir) or fail("Cannot chdir($dir): $!\n"); } -# 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*?{[].*)$/ ) { - - # (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 ); +sub load_pkgsrc_makefiles($) { + my ($fname) = @_; + + open(STORE, "<", $fname) + or die("Cannot read pkgsrc store from $fname: $!\n"); + my ($pkgver); + $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); } -# Parse a pkgsrc package makefile and return the pkgname and set variables +# Generate pkgname->category/pkg mapping, optionally check DEPENDS # -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); - } -} +sub scan_pkgsrc_makefiles($) { + my ($pkgsrcdir) = @_; + my (@categories); -# 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; -} + if ($pkglist) { -sub parse_expand_vars($$) { - my ( $line, $vars ) = @_; - - while ( $line =~ /\$\{([-\w.]+)\}/ ) { - if ( defined( ${$vars}{$1} ) ) { - $line = $` . ${$vars}{$1} . $'; - } - else { - $line = $` . $magic_undefined . $'; - } - } - $line; -} + # Already done + return; + } -sub parse_expand_vars_dumb($$) { - my ( $line, $vars ) = @_; - - while ( $line =~ /\$\{([-\w.]+)\}/ ) { - if ( defined( ${$vars}{$1} ) ) { - $line = $` . ${$vars}{$1} . $'; - } - else { - $line = $` . $magic_undefined . $'; - } - } - $line; -} + if ($opt{I}) { + load_pkgsrc_makefiles($opt{I}); + return; + } -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; -} + $pkglist = new PkgList; + @categories = list_pkgsrc_categories($pkgsrcdir); + verbose('Scan Makefiles: '); -# chdir() || fail() -# -sub safe_chdir($) { - my ($dir) = @_; + if (!$opt{L}) { + verbose('_' x @categories . "\b" x @categories); + } else { + verbose("\n"); + } - debug("chdir: $dir"); - if ( !chdir($dir) ) { - fail("Unable to chdir($dir): $!"); - } -} + foreach my $cat (sort @categories) { + foreach my $pkgdir (list_pkgsrc_pkgdirs($pkgsrcdir, $cat)) { + my ($pkg, $vars) = parse_makefile_pkgsrc("$pkgsrcdir/$cat/$pkgdir/Makefile"); + } -# 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" ); - } + 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); + } -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); + verbose("checksum mismatches\n"); + chdir_or_fail($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"; + } + chdir_or_fail('/'); # Do not want to stay in $pkgdistdir + } + (sort keys %bad_distfiles); } -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); +sub store_pkgsrc_makefiles($) { + 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 # 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,222 +1416,395 @@ () -D : Debug makefile and glob parsing -L : List each Makefile when scanned "; - exit; + exit; } -sub verbose(@) { +# 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 ( -t STDERR ) { - print STDERR @_; - } -} + if ($_ eq 'distfiles' || $_ eq 'pkgsrc') { + # Skip these subdirs if present + $File::Find::prune = 1; -sub debug(@) { + } elsif (/(.+)-(\d.*)\.t[bg]z$/) { + my ($pkg, $ver) = ($1, $2); - ( $opt{D} ) && print STDERR 'DEBUG: ', @_; -} + $pkg = canonicalize_pkgname($pkg); -# PkgList is the master list of all packages in pkgsrc. -# -package PkgList; + my ($pkgs); + if ($pkgs = $pkglist->pkgs($pkg)) { + my ($pkgver) = $pkgs->pkgver($ver); -sub add($@) { - my $self = shift; + if (!defined $pkgver) { + if ($opt{p}) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); + } - if ( !$self->pkgs( $_[0] ) ) { - $self->{_pkgs}{ $_[0] } = new Pkgs $_[0]; - } - $self->pkgs( $_[0] )->add(@_); -} + # Pick probably the last version + $pkgver = $pkgs->latestver; + } -sub new($) { - my $class = shift; - my $self = {}; - bless $self, $class; - return $self; -} + if ($opt{R} && $pkgver->var('RESTRICTED')) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); + } -sub numpkgver($) { - my $self = shift; - scalar( $self->pkgver ); -} + if ($opt{O} && $pkgver->var('OSVERSION_SPECIFIC')) { + print "$File::Find::dir/$_\n"; + push(@matched_prebuiltpackages, "$File::Find::dir/$_"); + } + } -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; -} + } elsif (-d $_) { + if ($prebuilt_pkgdir_cache{"$File::Find::dir/$_"}) { + $File::Find::prune = 1; + return; + } -sub pkgs($@) { - my $self = shift; - - if (@_) { - return $self->{_pkgs}{ $_[0] }; - } - else { - return ( sort { $a->pkg cmp $b->pkg } values %{ $self->{_pkgs} } ); - } - 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); + } + } + } } -sub store($) { - my $self = shift; - my @pkgs = keys %{ $self->{_pkgs} }; - my ( $cnt, $subcnt ) = $self->count; +sub debug_parse_makefiles(@) { - print("\$pkgcnt = $cnt;\n"); - print("\$subpkgcnt = $subcnt;\n"); - map( $self->{_pkgs}{$_}->store, keys %{ $self->{_pkgs} } ); -} + foreach my $file (@_) { + -d $file and $file .= "/Makefile"; + -f $file or fail("No such file: $file"); -sub count($) { - my $self = shift; - my ( $pkgcnt, $pkgsubcnt ); + 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"; + } - map { - $pkgcnt++; - $pkgsubcnt += $self->{_pkgs}{$_}->count; - } keys %{ $self->{_pkgs} }; - wantarray ? ( $pkgcnt, $pkgsubcnt ) : $pkgcnt; + #if ($opt{d}) { + # pkgsrc_check_depends(); + #} + } } -# Pkgs is all versions of a given package (eg: apache-1.x and apache-2.x) -# -package Pkgs; +sub check_distfiles($$) { + my ($pkgsrcdir, $pkgdistdir) = @_; -sub add($@) { - my $self = shift; + my @baddist = scan_pkgsrc_distfiles_vs_distinfo( + $pkgsrcdir, $pkgdistdir, $opt{o}, $opt{m}); - $self->{_pkgver}{ $_[1] } = new PkgVer @_; + return unless $opt{r}; + verbose("Unlinking 'bad' distfiles\n"); + foreach my $distfile (@baddist) { + unlink("$pkgdistdir/$distfile"); + } } -sub new($@) { - my $class = shift; - my $self = {}; +sub remove_distfiles($$) { + my ($pkgsrcdir, $pkgdistdir) = @_; - bless $self, $class; - $self->{_pkg} = $_[0]; - return $self; -} + my @pkgs = list_installed_packages(); + scan_pkgsrc_makefiles($pkgsrcdir); -sub versions($) { - my $self = shift; + # 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; + } + } + } - return sort { $b cmp $a } keys %{ $self->{_pkgver} }; -} + # 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); + } -sub pkg($) { - my $self = shift; - $self->{_pkg}; -} + # distfiles downloaded on the current system + my @tmpdistfiles = listdir("$pkgdistdir", undef); + my @dldistfiles = grep { $_ ne "pkg-vulnerabilities" } @tmpdistfiles; -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} }; -} + # sort the two arrays to make searching a bit faster + @dldistfiles = sort { $a cmp $b } @dldistfiles; + @pkgdistfiles = sort { $a cmp $b } @pkgdistfiles; -sub latestver($) { - my $self = shift; + 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; + } + } + if ($found != 1) { + push(@orphan, $dldf); + print "Orphaned file: $dldf\n"; + } + $found = 0; + } - ( $self->pkgver() )[0]; -} + if ($opt{r}) { + chdir_or_fail("$pkgdistdir"); + verbose("Unlinking 'orphaned' distfiles\n"); + foreach my $distfile (@orphan) { + unlink($distfile) + } + } + } -sub store($) { - my $self = shift; + 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) { + if ($pkgdf eq $dldf) { + $found = 1; + } + } + if ($found == 1) { + push(@parent, $pkgdf); + print "Parented file: $pkgdf\n"; + } + $found = 0; + } - print("\$pkgnum++;\n"); - map( $self->{_pkgver}{$_}->store, keys %{ $self->{_pkgver} } ); + if ($opt{r}) { + chdir_or_fail("$pkgdistdir"); + verbose("Unlinking 'parented' distfiles\n"); + foreach my $distfile (@parent) { + unlink($distfile); + } + } + } } -sub count($) { - my $self = shift; +sub list_broken_packages($) { + my ($pkgsrcdir) = @_; - scalar( keys %{ $self->{_pkgver} } ); + scan_pkgsrc_makefiles($pkgsrcdir); + foreach my $pkgver ($pkglist->pkgver) { + my $broken = $pkgver->var('BROKEN'); + next unless $broken; + print $pkgver->pkgname . ": $broken\n"; + } } -# PkgVer is a unique package+version +# List obsolete or NO_BIN_ON_FTP/RESTRICTED prebuilt packages # -package PkgVer; +sub list_prebuilt_packages($) { + my ($pkgsrcdir) = @_; -sub new($$$) { - my $class = shift; - my $self = {}; + scan_pkgsrc_makefiles($pkgsrcdir); - bless $self, $class; - $self->{_pkg} = $_[0]; - $self->{_ver} = $_[1]; - return $self; -} + @prebuilt_pkgdirs = ($default_vars->{PACKAGES}); + %prebuilt_pkgdir_cache = (); -sub pkgname($) { - my $self = shift; + while (@prebuilt_pkgdirs) { + find(\&check_prebuilt_packages, shift @prebuilt_pkgdirs); + } - $self->pkg . '-' . $self->ver; + if ($opt{r}) { + verbose("Unlinking listed prebuilt packages\n"); + foreach my $pkgfile (@matched_prebuiltpackages) { + unlink($pkgfile); + } + } } -sub pkg($) { - my $self = shift; +sub list_packages_not_in_SUBDIR($) { + my ($pkgsrcdir) = @_; - $self->{_pkg}; -} + my (%in_subdir); + foreach my $cat (list_pkgsrc_categories($pkgsrcdir)) { + my $vars = parse_makefile_vars("$pkgsrcdir/$cat/Makefile", undef); -sub var($$$) { - my $self = shift; - my ( $key, $val ) = @_; + if (!$vars->{SUBDIR}) { + print "Warning - no SUBDIR for $cat\n"; + next; + } + foreach my $pkgdir (split(/\s+/, $vars->{SUBDIR})) { + $in_subdir{"$cat/$pkgdir"} = 1; + } + } - ( defined $val ) - ? ( $self->{$key} = $val ) - : $self->{$key}; + 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"; + } + } } -sub ver($) { - my $self = shift; +sub generate_map_file($$) { + my ($pkgsrcdir, $fname) = @_; + + my $tmpfile = "$fname.tmp.$$"; - $self->{_ver}; + 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'): $!"); } -sub vars($) { - my $self = shift; +sub check_outdated_installed_packages($) { + my ($pkgsrcdir) = @_; - grep( !/^_(pkg|ver)$/, keys %{$self} ); -} + my @pkgs = list_installed_packages(); + scan_pkgsrc_makefiles($pkgsrcdir); -sub store($) { - my $self = shift; - my $data; + my @update; + foreach my $pkgname (sort @pkgs) { + next unless $_ = invalid_version($pkgname); - ( $data = $self->{_pkg} ) =~ s/([\\\$\@\%\"])/\\$1/g; - print("\$pkgver = \$pkglist->add(\"$data\", \""); + print $_; + next unless $pkgname =~ /^([^*?[]+)-([\d*?[].*)/; + + foreach my $pkgver ($pkglist->pkgver($1)) { + next if $pkgver->var('dir') =~ /-current/; + push(@update, $pkgver); + last; + } + } + + return unless $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"; + } - ( $data = $self->{_ver} ) =~ s/([\\\$\@\%\"])/\\$1/g; - print("$data\"); __pkgcount(1);\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'); - foreach ( $self->vars ) { - ( $data = $self->{$_} ) =~ s/([\\\$\@\%\"])/\\$1/g; - print("\$pkgver->var(\"$_\", \"$data\");\n"); - } + print "$pkgsrcdir/$pkgpath\n"; + chdir_or_fail("$pkgsrcdir/$pkgpath"); + system("$conf_make fetch-list | sh"); + } } -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} + || !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}) { + scan_pkgsrc_makefiles($pkgsrcdir); + store_pkgsrc_makefiles($opt{E}); + } +} -main(); +main() unless caller(); diff --git a/pkgtools/lintpkgsrc/files/t/packages.t b/pkgtools/lintpkgsrc/files/t/packages.t new file mode 100644 index 000000000000..ab9e9163486f --- /dev/null +++ b/pkgtools/lintpkgsrc/files/t/packages.t @@ -0,0 +1,61 @@ +# $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 => 8; } + +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); + + 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. +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(); diff --git a/pkgtools/lintpkgsrc/files/t/pkgversion.t b/pkgtools/lintpkgsrc/files/t/pkgversion.t new file mode 100644 index 000000000000..e83a703aaae9 --- /dev/null +++ b/pkgtools/lintpkgsrc/files/t/pkgversion.t @@ -0,0 +1,14 @@ +# $NetBSD: pkgversion.t,v 1.2 2022/07/30 17:06:29 rillig Exp $ +use strict; +use warnings; +use Test; + +BEGIN { plan tests => 5; } + +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'), ''); diff --git a/pkgtools/pkg_install/files/lib/dewey.c b/pkgtools/pkg_install/files/lib/dewey.c index 56c73b70dfee..51721f93e16b 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.13 2022/07/30 08:53:42 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 @@ -47,41 +47,41 @@ /* 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 } +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 } }; - 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) { @@ -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; @@ -281,11 +281,11 @@ 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) { + if ((n = dewey_mktest(&op, sep)) < 0) { return 0; - } + } /* skip operator */ sep += n; @@ -317,4 +317,3 @@ dewey_match(const char *pattern, const char *pkg) return 0; } - diff --git a/pkgtools/pkg_install/files/tkpkg b/pkgtools/pkg_install/files/tkpkg index 73f2f2907e32..baf9c12400b5 100644 --- a/pkgtools/pkg_install/files/tkpkg +++ b/pkgtools/pkg_install/files/tkpkg @@ -15,14 +15,14 @@ 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 # 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" 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 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 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