Module-Starter-Smart-0.0.10/000755 000765 000024 00000000000 15135276114 016135 5ustar00rcchenstaff000000 000000 Module-Starter-Smart-0.0.10/Changes000644 000765 000024 00000001656 15135274160 017437 0ustar00rcchenstaff000000 000000 Revision history for Module-Starter-Smart 0.0.10 Jan 25, 2026 * Adjust tests to Module::Starter::Simple >= 1.790 (backport from Debian) 0.0.9 Nov 24, 2017 * Bug fixes 0.0.8 Jun 4, 2017 * Bug fixes for tests 0.0.7 Jun 1, 2017 * Fix inconsistencies with more recent releases of Module::Starter::Simple (Markus Böhme) * Some more bug fixes 0.0.6 Jan 30, 2015 * Some amendments to the code for clarity and a new test for basic function (Andrew Kirkpatrick) 0.0.5 Jan 18, 2014 * Fix typos and update CPAN metadata (David Steinbrunner) 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.10/MANIFEST000644 000765 000024 00000000450 15135276114 017265 0ustar00rcchenstaff000000 000000 Changes MANIFEST META.yml # Will be created by "make dist" Makefile.PL README lib/Module/Starter/Smart.pm t/00.load.t t/01.create_distro.t t/02.create_t.t t/03.create_distro_with_build.t t/pod-coverage.t t/pod.t META.json Module JSON meta-data (added by MakeMaker) Module-Starter-Smart-0.0.10/t/000755 000765 000024 00000000000 15135276114 016400 5ustar00rcchenstaff000000 000000 Module-Starter-Smart-0.0.10/README000644 000765 000024 00000001127 15135274240 017014 0ustar00rcchenstaff000000 000000 Module-Starter-Smart version 0.0.10 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 Test::More Test::TempDir::Tiny parent CONTRIBUTORS * Ruey-Cheng Chen * David Messina * David Steinbrunner * Andrew Kirkpatrick * Markus Böhme * Lisa Hare * Gregor Herrmann COPYRIGHT AND LICENCE Copyright (C) 2006, 2011, 2012, 2017, 2026 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.10/META.yml000644 000765 000024 00000001644 15135276114 017413 0ustar00rcchenstaff000000 000000 --- abstract: 'A Module::Starter plugin for adding new modules into an existing distribution' author: - 'Ruey-Cheng Chen ' build_requires: ExtUtils::MakeMaker: '6.48' File::Spec: '0' Module::Starter: '1.58' Test::More: '0' Test::TempDir::Tiny: '0' parent: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter version 2.150010' license: perl 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' Test::TempDir::Tiny: '0' parent: '0' perl: '5.006000' resources: repository: https://github.com/rueycheng/Module-Starter-Smart.git version: v0.0.10 x_serialization_backend: 'CPAN::Meta::YAML version 0.018' Module-Starter-Smart-0.0.10/lib/000755 000765 000024 00000000000 15135276114 016703 5ustar00rcchenstaff000000 000000 Module-Starter-Smart-0.0.10/Makefile.PL000644 000765 000024 00000002555 15135160555 020117 0ustar00rcchenstaff000000 000000 use 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', MIN_PERL_VERSION => 5.6.0, PL_FILES => {}, LICENSE => 'perl', BUILD_REQUIRES => { 'ExtUtils::MakeMaker' => 6.48, 'File::Spec' => 0, 'parent' => 0, 'Module::Starter' => 1.58, 'Test::More' => 0, 'Test::TempDir::Tiny' => 0, }, PREREQ_PM => { 'ExtUtils::Command' => 0, 'File::Spec' => 0, 'parent' => 0, 'Module::Starter' => 1.58, 'Test::More' => 0, 'Test::TempDir::Tiny' => 0, }, META_MERGE => { 'meta-spec' => { version => 2 }, resources => { repository => { type => 'git', url => 'https://github.com/rueycheng/Module-Starter-Smart.git', web => 'https://github.com/rueycheng/Module-Starter-Smart', }, }, }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'Module-Starter-Smart-*' }, ); Module-Starter-Smart-0.0.10/META.json000644 000765 000024 00000003107 15135276114 017557 0ustar00rcchenstaff000000 000000 { "abstract" : "A Module::Starter plugin for adding new modules into an existing distribution", "author" : [ "Ruey-Cheng Chen " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "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" : "6.48", "File::Spec" : "0", "Module::Starter" : "1.58", "Test::More" : "0", "Test::TempDir::Tiny" : "0", "parent" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "ExtUtils::Command" : "0", "File::Spec" : "0", "Module::Starter" : "1.58", "Test::More" : "0", "Test::TempDir::Tiny" : "0", "parent" : "0", "perl" : "5.006000" } } }, "release_status" : "stable", "resources" : { "repository" : { "type" : "git", "url" : "https://github.com/rueycheng/Module-Starter-Smart.git", "web" : "https://github.com/rueycheng/Module-Starter-Smart" } }, "version" : "v0.0.10", "x_serialization_backend" : "JSON::PP version 4.06" } Module-Starter-Smart-0.0.10/lib/Module/000755 000765 000024 00000000000 15135276114 020130 5ustar00rcchenstaff000000 000000 Module-Starter-Smart-0.0.10/lib/Module/Starter/000755 000765 000024 00000000000 15135276114 021554 5ustar00rcchenstaff000000 000000 Module-Starter-Smart-0.0.10/lib/Module/Starter/Smart.pm000644 000765 000024 00000025247 15135274365 023220 0ustar00rcchenstaff000000 000000 package Module::Starter::Smart; use warnings; use strict; =encoding utf8 =head1 NAME Module::Starter::Smart - A Module::Starter plugin for adding new modules into an existing distribution =head1 VERSION version 0.0.10 =cut our $VERSION = '0.0.10'; =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 implementation 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 $testdir = @_ == 2 ? 't' : shift; my $filename = shift; my $content = shift; my @dirparts = ( $self->{basedir}, $testdir ); 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 File::Spec->catfile( $testdir, $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 the following contributors: =over 4 =item * David Messina =item * David Steinbrunner =item * Andrew Kirkpatrick =item * Markus Böhme =item * Lisa Hare =item * Gregor Herrmann =back =head1 AUTHOR Ruey-Cheng Chen C<< >> =head1 LICENCE AND COPYRIGHT Copyright (c) 2006, 2012, 2017, 2026 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.10/t/pod.t000644 000765 000024 00000000214 15135160555 017345 0ustar00rcchenstaff000000 000000 #!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(); Module-Starter-Smart-0.0.10/t/02.create_t.t000644 000765 000024 00000003323 15135160555 020575 0ustar00rcchenstaff000000 000000 use strict; use warnings; use Test::More; use Test::TempDir::Tiny; use File::Spec::Functions qw(catdir catfile); use Module::Starter qw(Module::Starter::Smart); my $content = <<"EOF"; I think that I shall never see, a test as concise as this in ./t! EOF test_old_interface(); test_new_interface(); done_testing(); sub test_old_interface { my $tempdir = tempdir(); my $tdir = catdir($tempdir, 't'); my $testfile = '01.test_old_interface.t'; my $starter = Module::Starter::Smart->new(); $starter->{basedir} = $tempdir; Module::Starter::Smart::_create_t($starter, $testfile, $content); file_contains_ok(catfile($tdir, $testfile), $content); } sub test_new_interface { my $tempdir = tempdir(); my $tdir = catdir($tempdir, 't'); my $xtdir = catdir($tempdir, 'xt'); my $testfile1 = '01.test_new_interface.t'; my $testfile2 = '02.test_new_interface.t'; my $starter = Module::Starter::Smart->new(); $starter->{basedir} = $tempdir; Module::Starter::Smart::_create_t($starter, 't', $testfile1, $content); Module::Starter::Smart::_create_t($starter, 'xt', $testfile2, $content); file_contains_ok(catfile($tdir, $testfile1), $content); file_contains_ok(catfile($xtdir, $testfile2), $content); } sub file_contains_ok { my $file = shift; my $expected_content = shift; SKIP: { skip "File '$file' does not exist or is unreadable", 1 unless ok(-f -r $file, "File '$file' exists and is readable"); open my $fh, '<', $file or die "Cannot open $file: $!\n"; my $real_content = do { local $/; <$fh> }; close $fh; ok($expected_content eq $real_content, "File '$file' has correct content"); } } Module-Starter-Smart-0.0.10/t/01.create_distro.t000644 000765 000024 00000002267 15135273464 021647 0ustar00rcchenstaff000000 000000 use Test::More tests => 5; use Test::TempDir::Tiny; use Module::Starter qw/Module::Starter::Smart/; use File::Spec; my $tempdir = tempdir(); my $root = File::Spec->catdir($tempdir, 'Modern-Mo'); { local $SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /^Added to MANIFEST/; }; Module::Starter->create_distro( author => ['me '], builder => 'ExtUtils::MakeMaker', modules => ['Modern::Mo'], dir => $root, ); } ok(-d $root, 'Module root exists'); my $file = File::Spec->catfile($root, qw(lib Modern Mo.pm)); ok(-f $file, 'Module file exists'); push @INC, File::Spec->catdir($root, 'lib'); require_ok('Modern::Mo'); { local $SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /^Added to MANIFEST/; }; Module::Starter->create_distro( author => ['me '], builder => 'ExtUtils::MakeMaker', modules => ['Modern::Mumu'], dir => $root, ); } # ok(-d $root, 'Module root exists'); my $file = File::Spec->catfile($root, qw(lib Modern Mumu.pm)); ok(-f $file, 'Additional module file exists'); # push @INC, File::Spec->catdir($root, 'lib'); require_ok('Modern::Mumu'); Module-Starter-Smart-0.0.10/t/pod-coverage.t000644 000765 000024 00000000410 15135160555 021134 0ustar00rcchenstaff000000 000000 #!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.10/t/00.load.t000644 000765 000024 00000000232 15135160555 017720 0ustar00rcchenstaff000000 000000 use Test::More tests => 1; BEGIN { use_ok( 'Module::Starter::Smart' ); } diag( "Testing Module::Starter::Smart $Module::Starter::Smart::VERSION" ); Module-Starter-Smart-0.0.10/t/03.create_distro_with_build.t000644 000765 000024 00000001334 15135273464 024055 0ustar00rcchenstaff000000 000000 #!/usr/bin/env perl use strict; use warnings; use Test::More tests => 3; use Test::TempDir::Tiny; use Module::Starter qw/Module::Starter::Smart/; use File::Spec; my $tempdir = tempdir(); my $root = File::Spec->catdir($tempdir, 'Foo-Bar'); { local $SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /^Added to MANIFEST/; }; Module::Starter->create_distro( author => ['me '], builder => 'Module::Build', modules => ['Foo::Bar'], dir => $root, ); } ok(-d $root, 'Module root exists'); my $file = File::Spec->catfile($root, qw(lib Foo Bar.pm)); ok(-f $file, 'Module file exists'); push @INC, File::Spec->catdir($root, 'lib'); require_ok('Foo::Bar');