5 use CPANPLUS::Internals::Constants;
10 use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
12 local $Data::Dumper::Indent = 1;
14 use constant PREREQ_SKIP_CLASS => 'CPANPLUS::To::Dist::PREREQ_SKIP';
15 use constant ALARM_CLASS => 'CPANPLUS::To::Dist::ALARM';
17 ### print when you can
20 my $cb = CPANPLUS::Backend->new
21 or die loc("Could not create new CPANPLUS::Backend object");
22 my $conf = $cb->configure_object;
24 my %formats = map { $_ => $_ } CPANPLUS::Dist->dist_types;
28 'format=s', 'archive',
30 'skiptest!', 'keepsource!',
31 'makefile!', 'buildprereq!',
33 'ban=s@', 'banlist=s@',
34 'ignore=s@', 'ignorelist=s@',
35 'defaults', 'modulelist=s@',
36 'logfile=s', 'timeout=s',
37 'dist-opts=s%', 'set-config=s%',
38 'default-banlist!', 'set-program=s%',
39 'default-ignorelist!',
42 die usage() if exists $opts->{'help'};
45 my $tarball = $opts->{'archive'} || 0;
46 my $keep = $opts->{'keepsource'} ? 1 : 0;
47 my $prereqbuild = exists $opts->{'buildprereq'}
48 ? $opts->{'buildprereq'}
50 my $timeout = exists $opts->{'timeout'}
54 ### use default answers?
55 $ENV{'PERL_MM_USE_DEFAULT'} = $opts->{'defaults'} ? 1 : 0;
58 ### if provided, we go with the command line option, fall back to conf setting
59 { $format = $opts->{'format'} || $conf->get_conf('dist_type');
60 $conf->set_conf( dist_type => $format );
62 ### is this a valid format??
63 die loc("Invalid format: " . ($format || "[NONE]") ) . usage()
64 unless $formats{$format};
66 ### any options to fix config entries
67 { my $set_conf = $opts->{'set-config'} || {};
68 while( my($key,$val) = each %$set_conf ) {
69 $conf->set_conf( $key => $val );
73 ### any options to fix program entries
74 { my $set_prog = $opts->{'set-program'} || {};
75 while( my($key,$val) = each %$set_prog ) {
76 $conf->set_program( $key => $val );
80 ### any other options passed
81 { my %map = ( verbose => 'verbose',
83 skiptest => 'skiptest',
84 makefile => 'prefer_makefile'
87 ### set config options from arguments
88 while (my($key,$val) = each %map) {
89 my $bool = exists $opts->{$key}
91 : $conf->get_conf($val);
92 $conf->set_conf( $val => $bool );
98 if( exists $opts->{'modulelist'} ) {
99 push @modules, map { parse_file( $_ ) } @{ $opts->{'modulelist'} };
102 die usage() unless @modules;
107 if( my $file = $opts->{logfile} ) {
108 open $fh, ">$file" or (
109 warn loc("Could not open '%1' for writing: %2", $file,$!),
113 warn "Logging to '$file'\n";
120 ### reload indices if so desired
121 $cb->reload_indices() if $opts->{'flushcache'};
123 { my @ban = exists $opts->{'ban'}
124 ? map { qr/$_/ } @{ $opts->{'ban'} }
128 if( exists $opts->{'banlist'} ) {
129 push @ban, map { parse_file( $_, 1 ) } @{ $opts->{'banlist'} };
132 push @ban, map { s/\s+//; $_ }
133 map { [split /\s*#\s*/]->[0] }
135 map { split /\n/ } _default_ban_list()
136 if $opts->{'default-banlist'};
138 ### use our prereq install callback
139 $conf->set_conf( prereqs => PREREQ_ASK );
141 ### register install callback ###
142 $cb->_register_callback(
143 name => 'install_prerequisite',
144 code => \&__ask_about_install,
148 ### check for ban patterns when handling prereqs
149 sub __ask_about_install {
151 my $mod = shift or return;
152 my $prereq = shift or return;
155 ### die with an error object, so we can verify that
156 ### the die came from this location, and that it's an
157 ### 'acceptable' death
158 my $pat = ban_me( $prereq );
159 die bless sub { loc("Module '%1' requires '%2' to be installed " .
160 "but found in your ban list (%3) -- skipping",
161 $mod->module, $prereq->module, $pat )
162 }, PREREQ_SKIP_CLASS if $pat;
166 ### should we skip this module?
170 for my $pat ( @ban ) {
171 return $pat if $mod->module =~ /$pat/i;
177 ### patterns to strip from prereq lists
178 { my @ignore = exists $opts->{'ignore'}
179 ? map { qr/$_/ } @{ $opts->{'ignore'} }
182 if( exists $opts->{'ignorelist'} ) {
183 push @ignore, map { parse_file( $_, 1 ) } @{ $opts->{'ignorelist'} };
186 push @ignore, map { s/\s+//; $_ }
187 map { [split /\s*#\s*/]->[0] }
189 map { split /\n/ } _default_ignore_list()
190 if $opts->{'default-ignorelist'};
193 ### register install callback ###
194 $cb->_register_callback(
195 name => 'filter_prereqs',
196 code => \&__filter_prereqs,
199 sub __filter_prereqs {
203 for my $name ( keys %$href ) {
204 my $obj = $cb->parse_module( module => $name ) or (
205 warn "Cannot make a module object out of ".
206 "'$name' -- skipping\n",
209 if( my $pat = ignore_me( $obj ) ) {
210 warn loc("'%1' found in your ignore list (%2) ".
211 "-- filtering it out\n", $name, $pat);
213 delete $href->{ $name };
220 ### should we skip this module?
224 for my $pat ( @ignore ) {
225 return $pat if $mod->module =~ /$pat/i;
226 return $pat if $mod->package_name =~ /$pat/i;
234 for my $name (@modules) {
238 ### is it a tarball? then we get it locally and transform it
239 ### and it's dependencies into .debs
241 ### make sure we use an absolute path, so chdirs() dont
243 $name = File::Spec->rel2abs( $name );
247 warn loc("Archive '$name' does not exist");
251 $obj = CPANPLUS::Module::Fake->new(
252 module => basename($name),
253 path => dirname($name),
254 package => basename($name),
257 ### if it's a traditional CPAN package, we can tidy
258 ### up the module name some
259 $obj->module( $obj->package_name ) if $obj->package_name;
261 ### get the version from the package name
262 $obj->version( $obj->package_version || 0 );
264 ### set the location of the tarball
265 $obj->status->fetch($name);
267 ### plain old cpan module?
270 ### find the corresponding module object ###
271 $obj = $cb->parse_module( module => $name ) or (
272 warn "Cannot make a module object out of ".
273 "'$name' -- skipping\n",
278 if( my $pat = ban_me( $obj ) ) {
279 warn loc("'%1' found in your ban list (%2) -- skipping\n",
280 $obj->module, $pat );
284 ### or just ignored it?
285 if( my $pat = ignore_me( $obj ) ) {
286 warn loc("'%1' found in your ignore list (%2) -- skipping\n",
287 $obj->module, $pat );
293 local $SIG{ALRM} = sub { die bless {}, ALARM_CLASS }
298 my $dist_opts = $opts->{'dist-opts'} || {};
300 my $rv = $obj->install(
301 prereq_target => 'create',
303 keep_source => $keep,
304 prereq_build => $prereqbuild,
306 ### any passed arbitrary options
315 ### set here again, in case the install dies
318 ### install failed due to a 'die' in our prereq skipper?
319 if( $@ and ref $@ and $@->isa( PREREQ_SKIP_CLASS ) ) {
320 warn loc("Dist creation of '%1' skipped: '%2'",
321 $obj->module, $@->() );
324 } elsif ( $@ and ref $@ and $@->isa( ALARM_CLASS ) ) {
325 warn loc("\nDist creation of '%1' skipped, build time exceeded: ".
326 "%2 seconds\n", $obj->module, $timeout );
329 ### died for some other reason? just report and skip
331 warn loc("Dist creation of '%1' failed: '%2'",
336 ### we didn't get a dist object back?
337 unless ($dist and $obj->status->dist) {
338 warn loc("Unable to create '%1' dist of '%2'", $format, $obj->module);
342 print "Created '$format' distribution for ", $obj->module,
343 " to:\n\t", $obj->status->dist->status->dist, "\n";
348 my $file = shift or return;
349 my $qr = shift() ? 1 : 0;
351 my $fh = OPEN_FILE->( $file ) or return;
356 next if /^#/; # skip comments
357 next unless /\S/; # skip empty lines
358 s/^(\S+).*/$1/; # skip extra info
359 push @rv, $qr ? qr/$_/ : $_; # add pattern to the list
367 cpan2dist - The CPANPLUS distribution creator
371 This script will create distributions of C<CPAN> modules of the format
372 you specify, including its prerequisites. These packages can then be
373 installed using the corresponding package manager for the format.
375 Note, you can also do this interactively from the default shell,
376 C<CPANPLUS::Shell::Default>. See the C<CPANPLUS::Dist> documentation,
377 as well as the documentation of your format of choice for any format
378 specific documentation.
385 my $me = basename($0);
386 my $formats = join "\n", map { "\t\t$_" } sort keys %formats;
388 my $usage = << '=cut';
391 Usage: cpan2dist [--format FMT] [OPTS] Mod::Name [Mod::Name, ...]
392 cpan2dist [--format FMT] [OPTS] --modulelist /tmp/mods.list
393 cpan2dist [--format FMT] [OPTS] --archive /tmp/dist [/tmp/dist2]
395 Will create a distribution of type FMT of the modules
396 specified on the command line, and all their prerequisites.
398 Can also create a distribution of type FMT from a local
399 archive and all it's prerequisites
404 Possible formats are:
407 You can install more formats from CPAN!
415 ### take no argument:
416 --help Show this help message
417 --skiptest Skip tests. Can be negated using --noskiptest
418 --force Force operation. Can be negated using --noforce
419 --verbose Be verbose. Can be negated using --noverbose
420 --keepsource Keep sources after building distribution. Can be
421 negated by --nokeepsource. May not be supported
423 --makefile Prefer Makefile.PL over Build.PL. Can be negated
424 using --nomakefile. Defaults to your config setting
425 --buildprereq Build packages of any prerequisites, even if they are
426 already uptodate on the local system. Can be negated
427 using --nobuildprereq. Defaults to false.
428 --archive Indicate that all modules listed are actually archives
429 --flushcache Update CPANPLUS' cache before commencing any operation
430 --defaults Instruct ExtUtils::MakeMaker and Module::Build to use
431 default answers during 'perl Makefile.PL' or 'perl
432 Build.PL' calls where possible
435 --format Installer format to use (defaults to config setting)
436 --ban Patterns of module names to skip during installation,
437 case-insensitive (affects prerequisites too)
438 May be given multiple times
439 --banlist File containing patterns that could be given to --ban
440 Are appended to the ban list built up by --ban
441 May be given multiple times.
442 --ignore Patterns of modules to exclude from prereq list. Useful
443 for when a prereq listed by a CPAN module is resolved
444 in another way than from its corresponding CPAN package
445 (Match is done on both module name, and package name of
446 the package the module is in, case-insensitive)
447 --ignorelist File containing patterns that may be given to --ignore.
448 Are appended to the ban list built up by --ignore.
449 May be given multiple times.
450 --modulelist File containing a list of modules that should be built.
451 Are appended to the list of command line modules.
452 May be given multiple times.
453 --logfile File to log all output to. By default, all output goes
455 --timeout The allowed time for buliding a distribution before
456 aborting. This is useful to terminate any build that
457 hang or happen to be interactive despite being told not
458 to be. Defaults to 300 seconds. To turn off, you can
460 --set-config Change any options as specified in your config for this
461 invocation only. See CPANPLUS::Config for a list of
463 --set-program Change any programs as specified in your config for this
464 invocation only. See CPANPLUS::Config for a list of
466 --dist-opts Arbitrary options passed along to the chosen installer
467 format's prepare()/create() routine. Please see the
468 documentation of the installer of your choice for
472 --default-banlist Use our builtin banlist. Works just like --ban
473 and --banlist, but with pre-set lists. See the
474 "Builtin Lists" section for details.
475 --default-ignorelist Use our builtin ignorelist. Works just like
476 --ignore and --ignorelist but with pre-set lists.
477 See the "Builtin Lists" section for details.
481 ### build a debian package of DBI and it's prerequisites,
482 ### don't bother running tests
483 cpan2dist --format CPANPLUS::Dist::Deb --buildprereq --skiptest DBI
485 ### Build a package, whose format is determined by your config, of
486 ### the local tarball, reloading cpanplus' indices first and using
487 ### the tarballs Makefile.PL if it has one.
488 cpan2dist --makefile --flushcache --archive /path/to/Cwd-1.0.tgz
490 ### build a package from Net::FTP, but dont build any packages or
491 ### dependencies whose name match 'Foo', 'Bar' or any of the
492 ### patterns mentioned in /tmp/ban
493 cpan2dist --ban Foo --ban Bar --banlist /tmp/ban Net::FTP
495 ### build a package from Net::FTP, but ignore it's listed dependency
496 ### on IO::Socket, as it's shipped per default with the OS we're on
497 cpan2dist --ignore IO::Socket Net::FTP
499 ### building all modules listed, plus their prerequisites
500 cpan2dist --ignorelist /tmp/modules.ignore --banlist /tmp/modules.ban
501 --modulelist /tmp/modules.list --buildprereq --flushcache
502 --makefile --defaults
504 ### pass arbitrary options to the format's prepare()/create() routine
505 cpan2dist --dist-opts deb_version=3 --dist-opts prefix=corp
512 Ignore list:] . _default_ignore_list() . qq[
513 Ban list:] . _default_ban_list();
515 ### strip the pod directives
516 $usage =~ s/=pod\n//g;
523 =head1 Built-In Filter Lists
525 Some modules you'd rather not package. Some because they
526 are part of core-perl and you dont want a new package.
527 Some because they won't build on your system. Some because
528 your package manager of choice already packages them for you.
530 There may be a myriad of reasons. You can use the C<--ignore>
531 and C<--ban> options for this, but we provide some built-in
532 lists that catch common cases. You can use these built-in lists
533 if you like, or supply your own if need be.
535 =head2 Built-In Ignore List
539 You can use this list of regexes to ignore modules matching
540 to be listed as prerequisites of a package. Particulaly useful
541 if they are bundled with core-perl anyway and they have known
544 Toggle it by supplying the C<--default-ignorelist> option.
548 sub _default_ignore_list {
550 my $list = << '=cut';
553 ^IO$ # Provided with core anyway
554 ^Cwd$ # Provided with core anyway
555 ^File::Spec # Provided with core anyway
556 ^Config$ # Perl's own config, not shipped separately
557 ^ExtUtils::MakeMaker$ # Shipped with perl, recent versions
558 # have bug 14721 (see rt.cpan.org)
559 ^ExtUtils::Install$ # Part of of EU::MM, same reason
566 =head2 Built-In Ban list
568 You can use this list of regexes to disable building of these
571 Toggle it by supplying the C<--default-banlist> option.
575 sub _default_ban_list {
577 my $list = << '=cut';
580 ^GD$ # Needs c libaries
581 ^Berk.*DB # DB packages require specific options & linking
582 ^DBD:: # DBD drives require database files/headers
583 ^XML:: # XML modules usually require expat libraries
584 Apache # These usually require apache libraries
585 SSL # These usually require SSL certificates & libs
586 Image::Magick # Needs ImageMagick C libraries
587 Mail::ClamAV # Needs ClamAV C Libraries
588 ^Verilog # Needs Verilog C Libraries
589 ^Authen::PAM$ # Needs PAM C libraries & Headers
600 L<CPANPLUS::Dist>, L<CPANPLUS::Module>, L<CPANPLUS::Shell::Default>,
605 Please report bugs or other issues to E<lt>bug-cpanplus@rt.cpan.org<gt>.
609 This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
613 The CPAN++ interface (of which this module is a part of) is copyright (c)
614 2001 - 2007, Jos Boumans E<lt>kane@cpan.orgE<gt>. All rights reserved.
616 This library is free software; you may redistribute and/or modify it
617 under the same terms as Perl itself.
622 # c-indentation-style: bsd
624 # indent-tabs-mode: nil
626 # vim: expandtab shiftwidth=4: