Module-Starter-Smart-0.0.4/0000755000175000017500000000000011734755524016227 5ustar rueychengrueychengModule-Starter-Smart-0.0.4/META.yml0000644000175000017500000000113511734755524017500 0ustar rueychengrueycheng--- abstract: 'A Module::Starter plugin for adding new modules into' author: - 'Ruey-Cheng Chen ' build_requires: ExtUtils::MakeMaker: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.112621' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Module-Starter-Smart no_index: directory: - t - inc requires: ExtUtils::Command: 0 File::Spec: 0 Module::Starter: 1.58 Test::More: 0 parent: 0 version: v0.0.4 Module-Starter-Smart-0.0.4/MANIFEST0000644000175000017500000000034311734755524017360 0ustar rueychengrueychengChanges MANIFEST META.yml # Will be created by "make dist" Makefile.PL README lib/Module/Starter/Smart.pm t/00.load.t t/pod-coverage.t t/pod.t META.json Module JSON meta-data (added by MakeMaker) Module-Starter-Smart-0.0.4/META.json0000644000175000017500000000202311734755524017645 0ustar rueychengrueycheng{ "abstract" : "A Module::Starter plugin for adding new modules into", "author" : [ "Ruey-Cheng Chen " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.112621", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Module-Starter-Smart", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : 0 } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : 0 } }, "runtime" : { "requires" : { "ExtUtils::Command" : 0, "File::Spec" : 0, "Module::Starter" : "1.58", "Test::More" : 0, "parent" : 0 } } }, "release_status" : "stable", "version" : "v0.0.4" } Module-Starter-Smart-0.0.4/README0000644000175000017500000000063311734552230017076 0ustar rueychengrueychengModule-Starter-Smart version 0.0.3 INSTALLATION To install this module, run the following commands: perl Makefile.PL make && make test && make install DEPENDENCIES ExtUtils::Command File::Spec Module::Starter::Simple COPYRIGHT AND LICENCE Copyright (C) 2006, 2011, 2012 Ruey-Cheng Chen This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Module-Starter-Smart-0.0.4/Changes0000644000175000017500000000063611734755454017531 0ustar rueychengrueychengRevision history for Module-Starter-Smart 0.0.4 Mar 29, 2012 * Fix broken dependency 0.0.3 Mar 28, 2012 * Fix RT 72565: Revise use cases * Rewrite create_distro() according to the latest version of Module::Starter::Simple (1.58) * Explicitly subclass Module::Starter::Simple, thanks to brian d foy's suggestion. 0.0.2 Apr 3, 2007 * Add use cases 0.0.1 May 7, 2006 * Initial release Module-Starter-Smart-0.0.4/Makefile.PL0000644000175000017500000000115411734755367020207 0ustar rueychengrueychenguse strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Module::Starter::Smart', AUTHOR => 'Ruey-Cheng Chen ', VERSION_FROM => 'lib/Module/Starter/Smart.pm', ABSTRACT_FROM => 'lib/Module/Starter/Smart.pm', PL_FILES => {}, PREREQ_PM => { 'Test::More' => 0, 'ExtUtils::Command' => 0, 'File::Spec' => 0, 'parent' => 0, 'Module::Starter' => 1.58, }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'Module-Starter-Smart-*' }, ); Module-Starter-Smart-0.0.4/lib/0000755000175000017500000000000011734755523016774 5ustar rueychengrueychengModule-Starter-Smart-0.0.4/lib/Module/0000755000175000017500000000000011734755523020221 5ustar rueychengrueychengModule-Starter-Smart-0.0.4/lib/Module/Starter/0000755000175000017500000000000011734755523021645 5ustar rueychengrueychengModule-Starter-Smart-0.0.4/lib/Module/Starter/Smart.pm0000644000175000017500000002434111734755325023275 0ustar rueychengrueychengpackage Module::Starter::Smart; use warnings; use strict; =head1 NAME Module::Starter::Smart - A Module::Starter plugin for adding new modules into an existing distribution =head1 VERSION version 0.0.4 =cut our $VERSION = '0.0.4'; =head1 SYNOPSIS use Module::Starter qw/Module::Starter::Smart/; Module::Starter->create_distro(%args); # or in ~/.module-starter/config plugin: Module::Starter::Smart # create a new distribution named 'Foo-Bar' $ module-starter --module=Foo::Bar # ... then add a new module $ module-starter --module=Foo::Bar::Me --distro=Foo-Bar =head1 DESCRIPTION Module::Starter::Smart is a simple helper plugin for L. It subclasses L and provides its own implementatoin for several file creation subroutines, such as C, C, C, and so on. These new implementations were designed to work with existing distributions. When invoked, the plugin checks if the distribution is already created. If so, the plugin would bypass C) and go ahead pull in all the existing modules and test files; these information would be used later in the corresponding file creation subroutines for skipping already-created files. B: This plugin only covers the simplest use cases. For advanced usage, check out L. =head2 Example Say you have an existing distro, Goof-Ball, and you want to add a new module, Goof::Troop. % ls -R Goof-Ball Build.PL Changes MANIFEST README lib/ t/ Goof-Ball/lib: Goof/ Goof-Ball/lib/Goof: Ball.pm Goof-Ball/t: 00.load.t perlcritic.t pod-coverage.t pod.t Go to the directory containing your existing distribution and run module-starter, giving it the names of the existing distribution and the new module: % module-starter --distro=Goof-Ball --module=Goof::Troop Created starter directories and files % ls -R Goof-Ball Build.PL Changes MANIFEST README lib/ t/ Goof-Ball/lib: Goof/ Goof-Ball/lib/Goof: Ball.pm Troop.pm Goof-Ball/t: 00.load.t perlcritic.t pod-coverage.t pod.t Troop.pm has been added to Goof-Ball/lib/Goof. =cut use parent qw(Module::Starter::Simple); use ExtUtils::Command qw/mkpath/; use File::Spec; # Module implementation here use subs qw/_unique_sort _pull_modules _list_modules _pull_t _list_t/; =head1 INTERFACE No public methods. The module works by subclassing Module::Starter::Simple and rewiring its internal behaviors. =cut sub create_distro { my $class = shift; my $self = ref $class? $class: $class->new(@_); my $basedir = $self->{dir} || $self->{distro} || do { (my $first = $self->{modules}[0]) =~ s/::/-/g; $first; }; $self->{modules} = [ _unique_sort _pull_modules($basedir), @{$self->{modules}} ]; $self->SUPER::create_distro; } sub create_basedir { my $self = shift; return $self->SUPER::create_basedir(@_) unless -e $self->{basedir} && !$self->{force}; $self->progress( "Found $self->{basedir}. Use --force if you want to stomp on it." ); } sub create_modules { my $self = shift; $self->SUPER::create_modules(@_); } sub _create_module { my $self = shift; my $module = shift; my $rtname = shift; my @parts = split( /::/, $module ); my $filepart = (pop @parts) . ".pm"; my @dirparts = ( $self->{basedir}, 'lib', @parts ); my $manifest_file = join( "/", "lib", @parts, $filepart ); if ( @dirparts ) { my $dir = File::Spec->catdir( @dirparts ); if ( not -d $dir ) { local @ARGV = $dir; mkpath @ARGV; $self->progress( "Created $dir" ); } } my $module_file = File::Spec->catfile( @dirparts, $filepart ); $self->{module_file}{$module} = File::Spec->catfile('lib', @parts, $filepart); if (-e $module_file) { $self->progress( "Skipped $module_file" ); } else { open( my $fh, ">", $module_file ) or die "Can't create $module_file: $!\n"; print $fh $self->module_guts( $module, $rtname ); close $fh; $self->progress( "Created $module_file" ); } return $manifest_file; } sub create_t { my $self = shift; _unique_sort $self->SUPER::create_t(@_), _pull_t $self->{basedir}; } sub _create_t { my $self = shift; my $filename = shift; my $content = shift; my @dirparts = ( $self->{basedir}, "t" ); my $tdir = File::Spec->catdir( @dirparts ); if ( not -d $tdir ) { local @ARGV = $tdir; mkpath(); $self->progress( "Created $tdir" ); } my $fname = File::Spec->catfile( @dirparts, $filename ); if (-e $fname) { $self->progress( "Skipped $fname" ); } else { open( my $fh, ">", $fname ) or die "Can't create $fname: $!\n"; print $fh $content; close $fh; $self->progress( "Created $fname" ); } return "t/$filename"; } sub create_Makefile_PL { my $self = shift; my $main_module = shift; my @parts = split( /::/, $main_module ); my $pm = pop @parts; my $main_pm_file = File::Spec->catfile( "lib", @parts, "${pm}.pm" ); $main_pm_file =~ s{\\}{/}g; # even on Win32, use forward slash my $fname = File::Spec->catfile( $self->{basedir}, "Makefile.PL" ); if (-e $fname) { $self->progress( "Skipped $fname" ); } else { open( my $fh, ">", $fname ) or die "Can't create $fname: $!\n"; print $fh $self->Makefile_PL_guts($main_module, $main_pm_file); close $fh; $self->progress( "Created $fname" ); } return "Makefile.PL"; } sub create_Build_PL { my $self = shift; my $main_module = shift; my @parts = split( /::/, $main_module ); my $pm = pop @parts; my $main_pm_file = File::Spec->catfile( "lib", @parts, "${pm}.pm" ); $main_pm_file =~ s{\\}{/}g; # even on Win32, use forward slash my $fname = File::Spec->catfile( $self->{basedir}, "Build.PL" ); if (-e $fname) { $self->progress( "Skipped $fname" ); } else { open( my $fh, ">", $fname ) or die "Can't create $fname: $!\n"; print $fh $self->Build_PL_guts($main_module, $main_pm_file); close $fh; $self->progress( "Created $fname" ); } return "Build.PL"; } sub create_Changes { my $self = shift; my $fname = File::Spec->catfile( $self->{basedir}, "Changes" ); if (-e $fname) { $self->progress( "Skipped $fname" ); } else { open( my $fh, ">", $fname ) or die "Can't create $fname: $!\n"; print $fh $self->Changes_guts(); close $fh; $self->progress( "Created $fname" ); } return "Changes"; } sub create_README { my $self = shift; my $build_instructions = shift; my $fname = File::Spec->catfile( $self->{basedir}, "README" ); if (-e $fname) { $self->progress( "Skipped $fname" ); } else { open( my $fh, ">", $fname ) or die "Can't create $fname: $!\n"; print $fh $self->README_guts($build_instructions); close $fh; $self->progress( "Created $fname" ); } return "README"; } # Utility functions sub _pull_modules { my $basedir = shift; return unless $basedir; my $libdir = File::Spec->catdir($basedir, "lib"); return unless $libdir && -d $libdir; return _list_modules($libdir); } sub _list_modules { my $dir = shift; my $prefix = shift || ''; opendir my $dh, $dir or die "Cannot opendir $dir: $!"; my @entries = grep { !/^\.{1,2}/ } readdir $dh; close $dh; my @modules = (); for (@entries) { my $name = File::Spec->catfile($dir, $_); push @modules, _list_modules($name, $prefix ? "$prefix\:\:$_": $_) and next if -d $name; $_ =~ s/\.pm$// and push @modules, $prefix ? "$prefix\:\:$_": $_ if $name =~ /\.pm$/; } return sort @modules; } sub _pull_t { my $basedir = shift; return unless $basedir; my $tdir = File::Spec->catdir($basedir, "t"); return unless $tdir && -d $tdir; return _list_t($tdir); } sub _list_t { my $dir = shift; opendir my $dh, $dir or die "Cannot opendir $dir: $!"; my @entries = grep { !/^\.{1,2}/ && /\.t$/ } readdir $dh; close $dh; map { "t/$_" } @entries; } # Remove duplicated entries sub _unique_sort { my %bag = map { $_ => 1 } @_; sort keys %bag; } # Magic true value required at end of module 1; __END__ =head1 DEPENDENCIES Module::Starter::Smart subclasses L. =head1 INCOMPATIBILITIES The plugin works perfectly with other template plugins, i.e. L (I started using it to develop this module) =head1 BUGS AND LIMITATIONS Please report any bugs or feature requests to C, or through the web interface at L. =head1 ACKNOWLEDGEMENT Special thanks to David Messina, who kindly contributes the example. =head1 AUTHOR Ruey-Cheng Chen C<< >> =head1 LICENCE AND COPYRIGHT Copyright (c) 2006, 2012 Ruey-Cheng Chen C<< >>. All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Module-Starter-Smart-0.0.4/t/0000755000175000017500000000000011734755523016471 5ustar rueychengrueychengModule-Starter-Smart-0.0.4/t/pod-coverage.t0000644000175000017500000000041010604403211021177 0ustar rueychengrueycheng#!perl -T use Test::More; eval "use Test::Pod::Coverage 1.04"; plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@; plan tests => 1; my $trustme = { trustme => [qr/^create_/] }; pod_coverage_ok('Module::Starter::Smart', $trustme); Module-Starter-Smart-0.0.4/t/00.load.t0000644000175000017500000000022610427352725020006 0ustar rueychengrueychenguse Test::More tests => 1; BEGIN { use_ok( 'Module::Starter::Smart' ); } diag( "Testing Module::Starter::Smart $Module::Starter::Smart::VERSION" ); Module-Starter-Smart-0.0.4/t/pod.t0000644000175000017500000000021410427352725017430 0ustar rueychengrueycheng#!perl -T use Test::More; eval "use Test::Pod 1.14"; plan skip_all => "Test::Pod 1.14 required for testing POD" if $@; all_pod_files_ok();