The Perl Toolchain Summit 2025 Needs You: You can help 🙏 Learn more

#! perl ## no critic (PerlMinimumVersion)
use strict;
use 5.010;
use IO::Handle qw( );
use List::Util qw( first );
use List::MoreUtils qw( indexes uniq );
use File::Slurp qw( read_file );
use File::ShareDir 1.00 qw( module_file dist_file );
use Getopt::Long qw( GetOptions );
use Pod::Usage qw( pod2usage );
use English qw( -no_match_vars );
use CPAN::Mini::Devel 0.03 qw( );
use LWP::UserAgent qw( );
use File::Spec::Functions qw( catdir );
our $VERSION = '1.110';
$VERSION = eval $VERSION;
sub filters;
sub usage;
sub version;
STDOUT->autoflush(1);
STDERR->autoflush(1);
my (@dists, @modules, @files, @add_files);
my $verbose = 1;
my $force = 0;
my $minicpan = 'C:\minicpan';
my $result = GetOptions(
"cpan=s" => \$cpan,
"minicpan=s" => \$minicpan,
"dist=s" => \@dists,
"module=s" => \@modules,
"file=s" => \@files,
"add_file=s" => \@add_files,
"verbose!" => \$verbose,
"force!" => \$force,
"help|?" => sub { pod2usage(-exitstatus => 1, -verbose => 0); },
"man" => sub { pod2usage(-exitstatus => 1, -verbose => 2); },
"usage" => sub { usage(); },
"version" => sub { version(); }
);
$result or usage();
my @input;
foreach my $dist (@dists) {
my @regex_file = read_file( dist_file( $dist, 'minicpan_filters.txt' ) );
push @input, @regex_file;
}
foreach my $module (@modules) {
my @regex_file = read_file( module_file( $module, 'minicpan_filters.txt' ) );
push @input, @regex_file;
}
foreach my $file (@files) {
my @regex_file = read_file( $file );
push @input, @regex_file;
}
# Delete comments
chomp @input;
my @regex_list = uniq grep { $_ !~ m{\A\s*\z|\A\s*#} } @input;
if ($#regex_list < 0) {
usage(<<'EOF');
No files to download.
One or more of --file, --dist, or --module must be used.
EOF
}
say 'Updated: ', scalar localtime;
CPAN::Mini::Devel->update_mirror(
remote => $cpan,
local => $minicpan,
trace => $verbose,
force => $force,
path_filters => [ sub { filters( $_[0] ); } ] );
my $ua;
foreach my $file_to_add (@add_files) {
$ua //= LWP::UserAgent->new(env_proxy => 1, agent => "minicpan_pdwix/$VERSION ");
my $l1 = substr $file_to_add, 0, 1;
my $l2 = substr $file_to_add, 0, 2;
my $url = "${cpan}author/id/$l1/$l2/$file_to_add";
my $target = catfile( $minicpan, qw( author id ), $l1, $l2, $file_to_add );
print "Downloading URL $url to $target\n";
$ua->mirror( $url, $target );
}
say 'Finished: ', scalar localtime;
exit 0;
sub filters {
my $dist = shift;
my $result = first { $dist =~ m{$_} } @regex_list;
return ( defined $result ? 0 : 1 );
}
sub version {
my $version = $VERSION->stringify();
print <<"EOF";
This is $PROGRAM_NAME, version $VERSION, a minicpan script
for Perl::Dist::WiX and subclasses.
Copyright 2009 Curtis Jewell.
This script may be copied only under the terms of either the Artistic License
or the GNU General Public License, which may be found in the Perl 5
distribution or the distribution containing this script.
EOF
exit(1);
}
sub usage {
my $error = shift;
print "Error: $error\n\n" if (defined $error);
print <<"EOF";
This is $PROGRAM_NAME, version $VERSION, a minicpan script
for Perl::Dist::WiX and subclasses.
Usage: $PROGRAM_NAME [ --dist <distribution> ] [ --module <module> ]
[ --file <file> ] [ --cpan <URL> ] [ --[no]force ]
[ --minicpan <filespec> ] [ --[no]verbose ]
[ --help ] [ --usage ] [ --man ] [ --version ] [ -? ]
For more assistance, run $PROGRAM_NAME --help.
EOF
exit(1);
}
__END__
=head1 NAME
minicpan_pdwix - a minicpan script for Perl::Dist::WiX and subclasses.
=head1 VERSION
This document describes minicpan_pdwix version 1.000.
=head1 DESCRIPTION
This creates a minicpan for L<Perl::Dist::WiX> and subclasses to
use that contains the minimum files required to make a perl
distribution.
=head1 SYNOPSIS
minicpan_pdwix [ --dist <distribution> ] [ --module <module> ]
[ --file <file> ] [ --cpan <URL> ] [ --[no]force ]
[ --minicpan <dir> ] [ --[no]verbose ]
[ --help ] [ --usage ] [ --man ] [ --version ] [ -?]
Options:
--dist <dist> Loads a list to download from the named distribution.
--module <module> Loads a list to download from the named module.
--file <file> Loads a list to download from the named file.
--cpan <URL> Specifies the CPAN mirror to download to.
--minicpan <dir> Specifies the directory to download to.
Defaults to C:\minicpan\.
--verbose Lists the files as they are downloaded. (default)
--noverbose Does not list the files as they are downloaded.
--force Forces rescanning even if index files are not updated.
--noforce Does not force rescanning of minicpan. (default)
--usage Gives a minimum amount of aid and comfort.
--help Gives aid and comfort.
-? Gives aid and comfort.
--man Gives maximum aid and comfort.
--version Gives the name, version and copyright of the script.
=head1 OPTIONS
=over
=item B<--dist>
Loads a list of regular expressions that specify which files to download
from the file minicpan_filters.txt in the directory File::ShareDir uses
for the named distribution.
=item B<--module>
Loads a list of regular expressions that specify which files to download
from the file minicpan_filters.txt in the directory File::ShareDir uses
for the named module.
=item B<--file>
Loads a list of regular expressions that specify which files to download
from the named file.
=item B<--cpan>
Specifies the CPAN mirror to use.
Defaults to L<http://cpan.hexten.net/>.
=item B<--minicpan>
Specifies the location to download the minicpan.
Defaults to C<C:\minicpan\>.
=item B<--verbose>/B<--noverbose>
Specifies whether the list of files downloaded should be printed or not.
Defaults to B<--verbose>.
=item B<--force>/B<--noforce>
Specifies whether the index files should be rescanned even if they were not
updated. This is useful when the list of files to download has been changed.
Defaults to B<--noforce>.
=item B<--usage>
Print a brief usage message and exits.
=item B<--help> or B<-?>
Print a short help message and exits.
=item B<--man>
Prints the POD documentation contained in the script and exits.
=item B<--version>
Prints the script name, version, and copyright and exits.
=back
=head1 CONFIGURATION
No environment variables are used during the execution of this script
that the modules used do not already use.
The --dist and --module options use File::ShareDir to get a file named
minicpan_filters.txt from the root directory of the named options.
The --file option names a file to load.
The files loaded by the options mentioned above contain a list of regular
expressions that define files to download, as shown in the example file
below:
# Downloads 4 files.
/MBARBON/Wx-\d
/MDOOTSON/Wx-Perl-ProcessStream-
/(?:GARU|SZABGAB)/Padre-\d
/AZAWAWI/Padre-Plugin-Perl6-
There are no options given by default, and lines containing only whitespace,
or that are empty, or whose first non-whitespace character is a C<#> are
disregarded.
=head1 DEPENDENCIES
Perl 5.10.0 is the mimimum version of perl that this script will run on.
Other modules that this script depends on are L<IO::Handle>, L<List::Util>,
L<List::MoreUtils>, L<File::ShareDir> 1.00, L<File::Slurp>, L<Getopt::Long>,
L<Pod::Usage>, L<English>, L<CPAN::Mini> 0.576, and L<CPAN::Mini::Devel>
0.03.
=head1 SUPPORT
No support is provided for this script.
=head1 AUTHOR
Curtis Jewell, E<lt>csjewell@cpan.orgE<gt>
=head1 COPYRIGHT & LICENSE
Copyright 2009 Curtis Jewell.
This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the
LICENSE file included with this distribution.
=cut