5 use CPANPLUS::Internals::Constants;
10 use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
12 use constant PREREQ_SKIP_CLASS => 'CPANPLUS::To::Dist::PREREQ_SKIP';
13 use constant ALARM_CLASS => 'CPANPLUS::To::Dist::ALARM';
15 ### print when you can
18 my $cb = CPANPLUS::Backend->new
19 or die loc("Could not create new CPANPLUS::Backend object");
20 my $conf = $cb->configure_object;
22 my %formats = map { $_ => $_ } CPANPLUS::Dist->dist_types;
26 'format=s', 'archive',
28 'skiptest!', 'keepsource!',
29 'makefile!', 'buildprereq!',
31 'ban=s@', 'banlist=s@',
32 'ignore=s@', 'ignorelist=s@',
33 'defaults', 'modulelist=s@',
34 'logfile=s', 'timeout=s',
37 'default-ignorelist!',
40 die usage() if exists $opts->{'help'};
43 my $tarball = $opts->{'archive'} || 0;
44 my $keep = $opts->{'keepsource'} ? 1 : 0;
45 my $prereqbuild = exists $opts->{'buildprereq'}
46 ? $opts->{'buildprereq'}
48 my $timeout = exists $opts->{'timeout'}
52 ### use default answers?
53 $ENV{'PERL_MM_USE_DEFAULT'} = $opts->{'defaults'} ? 1 : 0;
56 ### if provided, we go with the command line option, fall back to conf setting
57 { $format = $opts->{'format'} || $conf->get_conf('dist_type');
58 $conf->set_conf( dist_type => $format );
60 ### is this a valid format??
61 die loc("Invalid format: " . ($format || "[NONE]") ) . usage()
62 unless $formats{$format};
64 my %map = ( verbose => 'verbose',
66 skiptest => 'skiptest',
67 makefile => 'prefer_makefile'
70 ### set config options from arguments
71 while (my($key,$val) = each %map) {
72 my $bool = exists $opts->{$key} ? $opts->{$key} : $conf->get_conf($val);
73 $conf->set_conf( $val => $bool );
78 if( exists $opts->{'modulelist'} ) {
79 push @modules, map { parse_file( $_ ) } @{ $opts->{'modulelist'} };
82 die usage() unless @modules;
87 if( my $file = $opts->{logfile} ) {
88 open $fh, ">$file" or (
89 warn loc("Could not open '%1' for writing: %2", $file,$!),
93 warn "Logging to '$file'\n";
100 ### reload indices if so desired
101 $cb->reload_indices() if $opts->{'flushcache'};
103 { my @ban = exists $opts->{'ban'}
104 ? map { qr/$_/ } @{ $opts->{'ban'} }
108 if( exists $opts->{'banlist'} ) {
109 push @ban, map { parse_file( $_, 1 ) } @{ $opts->{'banlist'} };
112 push @ban, map { s/\s+//; $_ }
113 map { [split /\s*#\s*/]->[0] }
115 map { split /\n/ } _default_ban_list()
116 if $opts->{'default-banlist'};
118 ### use our prereq install callback
119 $conf->set_conf( prereqs => PREREQ_ASK );
121 ### register install callback ###
122 $cb->_register_callback(
123 name => 'install_prerequisite',
124 code => \&__ask_about_install,
128 ### check for ban patterns when handling prereqs
129 sub __ask_about_install {
131 my $mod = shift or return;
132 my $prereq = shift or return;
135 ### die with an error object, so we can verify that
136 ### the die came from this location, and that it's an
137 ### 'acceptable' death
138 my $pat = ban_me( $prereq );
139 die bless \(loc("Module '%1' requires '%2' to be installed " .
140 "but found in your ban list (%3) -- skipping",
141 $mod->module, $prereq->module, $pat )),
142 PREREQ_SKIP_CLASS if $pat;
146 ### should we skip this module?
150 for my $pat ( @ban ) {
151 return $pat if $mod->module =~ /$pat/;
157 ### patterns to strip from prereq lists
158 { my @ignore = exists $opts->{'ignore'}
159 ? map { qr/$_/ } @{ $opts->{'ignore'} }
162 if( exists $opts->{'ignorelist'} ) {
163 push @ignore, map { parse_file( $_, 1 ) } @{ $opts->{'ignorelist'} };
166 push @ignore, map { s/\s+//; $_ }
167 map { [split /\s*#\s*/]->[0] }
169 map { split /\n/ } _default_ignore_list()
170 if $opts->{'default-ignorelist'};
173 ### register install callback ###
174 $cb->_register_callback(
175 name => 'filter_prereqs',
176 code => \&__filter_prereqs,
179 sub __filter_prereqs {
183 for my $name ( keys %$href ) {
184 my $obj = $cb->parse_module( module => $name ) or (
185 warn "Cannot make a module object out of ".
186 "'$name' -- skipping\n",
189 if( my $pat = ignore_me( $obj ) ) {
190 warn loc("'%1' found in your ignore list (%2) ".
191 "-- filtering it out\n", $name, $pat);
193 delete $href->{ $name };
200 ### should we skip this module?
204 for my $pat ( @ignore ) {
205 return $pat if $mod->module =~ /$pat/;
206 return $pat if $mod->package_name =~ /$pat/;
214 for my $name (@modules) {
218 ### is it a tarball? then we get it locally and transform it
219 ### and it's dependencies into .debs
221 ### make sure we use an absolute path, so chdirs() dont
223 $name = File::Spec->rel2abs( $name );
227 warn loc("Archive '$name' does not exist");
231 $obj = CPANPLUS::Module::Fake->new(
232 module => basename($name),
233 path => dirname($name),
234 package => basename($name),
237 ### if it's a traditional CPAN package, we can tidy
238 ### up the module name some
239 $obj->module( $obj->package_name ) if $obj->package_name;
241 ### get the version from the package name
242 $obj->version( $obj->package_version || 0 );
244 ### set the location of the tarball
245 $obj->status->fetch($name);
247 ### plain old cpan module?
250 ### find the corresponding module object ###
251 $obj = $cb->parse_module( module => $name ) or (
252 warn "Cannot make a module object out of ".
253 "'$name' -- skipping\n",
258 if( my $pat = ban_me( $obj ) ) {
259 warn loc("'%1' found in your ban list (%2) -- skipping\n",
260 $obj->module, $pat );
264 ### or just ignored it?
265 if( my $pat = ignore_me( $obj ) ) {
266 warn loc("'%1' found in your ignore list (%2) -- skipping\n",
267 $obj->module, $pat );
273 local $SIG{ALRM} = sub { die bless {}, ALARM_CLASS }
278 my $dist_opts = $opts->{'dist-opts'} || {};
280 my $rv = $obj->install(
281 prereq_target => 'create',
283 keep_source => $keep,
284 prereq_build => $prereqbuild,
286 ### any passed arbitrary options
295 ### set here again, in case the install dies
298 ### install failed due to a 'die' in our prereq skipper?
299 if( $@ and ref $@ and $@->isa( PREREQ_SKIP_CLASS ) ) {
300 warn loc("Dist creation of '%1' skipped: '%2'",
301 $obj->module, ${$@} );
304 } elsif ( $@ and ref $@ and $@->isa( ALARM_CLASS ) ) {
305 warn loc("\nDist creation of '%1' skipped, build time exceeded: ".
306 "%2 seconds\n", $obj->module, $timeout );
309 ### died for some other reason? just report and skip
311 warn loc("Dist creation of '%1' failed: '%2'",
316 ### we didn't get a dist object back?
317 unless ($dist and $obj->status->dist) {
318 warn loc("Unable to create '%1' dist of '%2'", $format, $obj->module);
322 print "Created '$format' distribution for ", $obj->module,
323 " to:\n\t", $obj->status->dist->status->dist, "\n";
328 my $file = shift or return;
329 my $qr = shift() ? 1 : 0;
331 my $fh = OPEN_FILE->( $file ) or return;
336 next if /^#/; # skip comments
337 next unless /\S/; # skip empty lines
338 s/^(\S+).*/$1/; # skip extra info
339 push @rv, $qr ? qr/$_/ : $_; # add pattern to the list
347 cpan2dist - The CPANPLUS distribution creator
351 This script will create distributions of C<CPAN> modules of the format
352 you specify, including its prerequisites. These packages can then be
353 installed using the corresponding package manager for the format.
355 Note, you can also do this interactively from the default shell,
356 C<CPANPLUS::Shell::Default>. See the C<CPANPLUS::Dist> documentation,
357 as well as the documentation of your format of choice for any format
358 specific documentation.
365 my $me = basename($0);
366 my $formats = join "\n", map { "\t\t$_" } sort keys %formats;
368 my $usage = << '=cut';
371 Usage: cpan2dist [--format FMT] [OPTS] Mod::Name [Mod::Name, ...]
372 cpan2dist [--format FMT] [OPTS] --modulelist /tmp/mods.list
373 cpan2dist [--format FMT] [OPTS] --archive /tmp/dist [/tmp/dist2]
375 Will create a distribution of type FMT of the modules
376 specified on the command line, and all their prerequisites.
378 Can also create a distribution of type FMT from a local
379 archive and all it's prerequisites
384 Possible formats are:
387 You can install more formats from CPAN!
395 ### take no argument:
396 --help Show this help message
397 --skiptest Skip tests. Can be negated using --noskiptest
398 --force Force operation. Can be negated using --noforce
399 --verbose Be verbose. Can be negated using --noverbose
400 --keepsource Keep sources after building distribution. Can be
401 negated by --nokeepsource. May not be supported
403 --makefile Prefer Makefile.PL over Build.PL. Can be negated
404 using --nomakefile. Defaults to your config setting
405 --buildprereq Build packages of any prerequisites, even if they are
406 already uptodate on the local system. Can be negated
407 using --nobuildprereq. Defaults to false.
408 --archive Indicate that all modules listed are actually archives
409 --flushcache Update CPANPLUS' cache before commencing any operation
410 --defaults Instruct ExtUtils::MakeMaker and Module::Build to use
411 default answers during 'perl Makefile.PL' or 'perl
412 Build.PL' calls where possible
415 --format Installer format to use (defaults to config setting)
416 --ban Patterns of module names to skip during installation
417 (affects prerequisites too) May be given multiple times
418 --banlist File containing patterns that could be given to --ban
419 Are appended to the ban list built up by --ban
420 May be given multiple times.
421 --ignore Patterns of modules to exclude from prereq list. Useful
422 for when a prereq listed by a CPAN module is resolved
423 in another way than from its corresponding CPAN package
424 (Match is done on both module name, and package name of
425 the package the module is in)
426 --ignorelist File containing patterns that may be given to --ignore.
427 Are appended to the ban list build up by --ignore.
428 May be given multiple times.
429 --modulelist File containing a list of modules that should be built.
430 Are appended to the list of command line modules.
431 May be given multiple times.
432 --logfile File to log all output to. By default, all output goes
434 --timeout The allowed time for buliding a distribution before
435 aborting. This is useful to terminate any build that
436 hang or happen to be interactive despite being told not
437 to be. Defaults to 300 seconds. To turn off, you can
439 --dist-opts Arbitrary options passed along to the chosen installer
440 format's prepare()/create() routine.
443 --default-banlist Use our builtin banlist. Works just like --ban
444 and --banlist, but with pre-set lists. See the
445 "Builtin Lists" section for details.
446 --default-ignorelist Use our builtin ignorelist. Works just like
447 --ignore and --ignorelist but with pre-set lists.
448 See the "Builtin Lists" section for details.
452 ### build a debian package of DBI and it's prerequisites,
453 ### don't bother running tests
454 cpan2dist --format CPANPLUS::Dist::Deb --buildprereq --skiptest DBI
456 ### Build a package, whose format is determined by your config of
457 ### the local tarball, reloading cpanplus' indices first and using
458 ### the tarballs Makefile.PL if it has one.
459 cpan2dist --makefile --flushcache --archive /path/to/Cwd-1.0.tgz
461 ### build a package from Net::FTP, but dont build any packages or
462 ### dependencies whose name match 'Foo', 'Bar' or any of the
463 ### patterns mentioned in /tmp/ban
464 cpan2dist --ban Foo --ban Bar --banlist /tmp/ban Net::FTP
466 ### build a package from Net::FTP, but ignore it's listed dependency
467 ### on IO::Socket, as it's shipped per default with the OS we're on
468 cpan2dist --ignore IO::Socket Net::FTP
470 ### building all modules listed, plus their prerequisites
471 cpan2dist --ignorelist /tmp/modules.ignore --banlist /tmp/modules.ban
472 --modulelist /tmp/modules.list --buildprereq --flushcache
473 --makefile --defaults
475 ### pass arbitrary options to the format's prepare()/create() routine
476 cpan2dist --dist-opts deb_version=3 --dist-opts prefix=corp
483 Ignore list:] . _default_ignore_list() . qq[
484 Ban list:] . _default_ban_list();
486 ### strip the pod directives
487 $usage =~ s/=pod\n//g;
494 =head1 Built-In Filter Lists
496 Some modules you'd rather not package. Some because they
497 are part of core-perl and you dont want a new package.
498 Some because they won't build on your system. Some because
499 your package manager of choice already packages them for you.
501 There may be a myriad of reasons. You can use the C<--ignore>
502 and C<--ban> options for this, but we provide some built-in
503 lists that catch common cases. You can use these built-in lists
504 if you like, or supply your own if need be.
506 =head2 Built-In Ignore List
510 You can use this list of regexes to ignore modules matching
511 to be listed as prerequisites of a package. Particulaly useful
512 if they are bundled with core-perl anyway and they have known
515 Toggle it by supplying the C<--default-ignorelist> option.
519 sub _default_ignore_list {
521 my $list = << '=cut';
524 ^IO$ # Provided with core anyway
525 ^Cwd$ # Provided with core anyway
526 ^File::Spec # Provided with core anyway
527 ^Config$ # Perl's own config, not shipped separately
528 ^ExtUtils::MakeMaker$ # Shipped with perl, recent versions
529 # have bug 14721 (see rt.cpan.org)
530 ^ExtUtils::Install$ # Part of of EU::MM, same reason
537 =head2 Built-In Ban list
539 You can use this list of regexes to disable building of these
542 Toggle it by supplying the C<--default-banlist> option.
546 sub _default_ban_list {
548 my $list = << '=cut';
551 ^GD$ # Needs c libaries
552 ^Berk.*DB # DB packages require specific options & linking
553 ^DBD:: # DBD drives require database files/headers
554 ^XML:: # XML modules usually require expat libraries
555 Apache # These usually require apache libraries
556 SSL # These usually require SSL certificates & libs
557 Image::Magick # Needs ImageMagick C libraries
558 Mail::ClamAV # Needs ClamAV C Libraries
559 ^Verilog # Needs Verilog C Libraries
560 ^Authen::PAM$ # Needs PAM C libraries & Headers
571 L<CPANPLUS::Dist>, L<CPANPLUS::Module>, L<CPANPLUS::Shell::Default>,
576 Please report bugs or other issues to E<lt>bug-cpanplus@rt.cpan.org<gt>.
580 This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
584 The CPAN++ interface (of which this module is a part of) is copyright (c)
585 2001 - 2007, Jos Boumans E<lt>kane@cpan.orgE<gt>. All rights reserved.
587 This library is free software; you may redistribute and/or modify it
588 under the same terms as Perl itself.
593 # c-indentation-style: bsd
595 # indent-tabs-mode: nil
597 # vim: expandtab shiftwidth=4: