commit c7d27dd8695d8e9c1f26087d3be7283188231002 Author: chris Date: Thu May 14 15:25:40 2026 -0400 v.1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db86b20 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +blib/ +Makefile +Makefile.old +pm_to_blib +*.tar.gz +MYMETA.* +_build/ diff --git a/App-SortCopies-0.01/Changes b/App-SortCopies-0.01/Changes new file mode 100644 index 0000000..59f6752 --- /dev/null +++ b/App-SortCopies-0.01/Changes @@ -0,0 +1,5 @@ +Revision history for App-SortCopies + +0.01 Date/time + First version, released on an unsuspecting world. + diff --git a/App-SortCopies-0.01/MANIFEST b/App-SortCopies-0.01/MANIFEST new file mode 100644 index 0000000..289e11c --- /dev/null +++ b/App-SortCopies-0.01/MANIFEST @@ -0,0 +1,12 @@ +Changes +bin/sortcopies +lib/App/SortCopies.pm +Makefile.PL +MANIFEST This list of files +README +t/00-load.t +t/manifest.t +t/pod-coverage.t +t/pod.t +META.yml Module YAML meta-data (added by MakeMaker) +META.json Module JSON meta-data (added by MakeMaker) diff --git a/App-SortCopies-0.01/META.json b/App-SortCopies-0.01/META.json new file mode 100644 index 0000000..9ce622f --- /dev/null +++ b/App-SortCopies-0.01/META.json @@ -0,0 +1,47 @@ +{ + "abstract" : "The copy sorter! (What did you expect?)", + "author" : [ + "Semandi " + ], + "dynamic_config" : 1, + "generated_by" : "ExtUtils::MakeMaker version 7.76, CPAN::Meta::Converter version 2.150010", + "license" : [ + "artistic_2" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : 2 + }, + "name" : "App-SortCopies", + "no_index" : { + "directory" : [ + "t", + "inc" + ] + }, + "prereqs" : { + "build" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "runtime" : { + "requires" : { + "perl" : "5.008003" + } + }, + "test" : { + "requires" : { + "Test::More" : "0" + } + } + }, + "release_status" : "stable", + "version" : "0.01", + "x_serialization_backend" : "JSON::PP version 4.16" +} diff --git a/App-SortCopies-0.01/META.yml b/App-SortCopies-0.01/META.yml new file mode 100644 index 0000000..0e44905 --- /dev/null +++ b/App-SortCopies-0.01/META.yml @@ -0,0 +1,24 @@ +--- +abstract: 'The copy sorter! (What did you expect?)' +author: + - 'Semandi ' +build_requires: + ExtUtils::MakeMaker: '0' + Test::More: '0' +configure_requires: + ExtUtils::MakeMaker: '0' +dynamic_config: 1 +generated_by: 'ExtUtils::MakeMaker version 7.76, CPAN::Meta::Converter version 2.150010' +license: artistic_2 +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: '1.4' +name: App-SortCopies +no_index: + directory: + - t + - inc +requires: + perl: '5.008003' +version: '0.01' +x_serialization_backend: 'CPAN::Meta::YAML version 0.020' diff --git a/App-SortCopies-0.01/Makefile.PL b/App-SortCopies-0.01/Makefile.PL new file mode 100644 index 0000000..f6fcc35 --- /dev/null +++ b/App-SortCopies-0.01/Makefile.PL @@ -0,0 +1,46 @@ +use 5.008003; +use strict; +use warnings; +use ExtUtils::MakeMaker; + +my %WriteMakefileArgs = ( + NAME => 'App::SortCopies', + AUTHOR => ['Semandi '], + VERSION_FROM => 'lib/App/SortCopies.pm', + ABSTRACT_FROM => 'lib/App/SortCopies.pm', + EXE_FILES => ['bin/sortcopies'], + LICENSE => 'artistic_2', + MIN_PERL_VERSION => '5.008003', + CONFIGURE_REQUIRES => { + 'ExtUtils::MakeMaker' => '0', + }, + TEST_REQUIRES => { + 'Test::More' => '0', + }, + PREREQ_PM => { + #'ABC' => '1.6', + #'Foo::Bar::Module' => '5.0401', + }, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'App-SortCopies-*' }, +); + +# Compatibility with old versions of ExtUtils::MakeMaker +unless (eval { ExtUtils::MakeMaker->VERSION('6.64'); 1 }) { + my $test_requires = delete $WriteMakefileArgs{TEST_REQUIRES} || {}; + @{$WriteMakefileArgs{PREREQ_PM}}{keys %$test_requires} = values %$test_requires; +} + +unless (eval { ExtUtils::MakeMaker->VERSION('6.55_03'); 1 }) { + my $build_requires = delete $WriteMakefileArgs{BUILD_REQUIRES} || {}; + @{$WriteMakefileArgs{PREREQ_PM}}{keys %$build_requires} = values %$build_requires; +} + +delete $WriteMakefileArgs{CONFIGURE_REQUIRES} + unless eval { ExtUtils::MakeMaker->VERSION('6.52'); 1 }; +delete $WriteMakefileArgs{MIN_PERL_VERSION} + unless eval { ExtUtils::MakeMaker->VERSION('6.48'); 1 }; +delete $WriteMakefileArgs{LICENSE} + unless eval { ExtUtils::MakeMaker->VERSION('6.31'); 1 }; + +WriteMakefile(%WriteMakefileArgs); diff --git a/App-SortCopies-0.01/README b/App-SortCopies-0.01/README new file mode 100644 index 0000000..fee9bb3 --- /dev/null +++ b/App-SortCopies-0.01/README @@ -0,0 +1,49 @@ +App-SortCopies + +The README is used to introduce the module and provide instructions on +how to install the module, any machine dependencies it may have (for +example C compilers and installed libraries) and any other information +that should be provided before the module is installed. + +A README file is required for CPAN modules since CPAN extracts the README +file from a module distribution so that people browsing the archive +can use it to get an idea of the module's uses. It is usually a good idea +to provide version information here so that people can decide whether +fixes for the module are worth downloading. + + +INSTALLATION + +To install this module, run the following commands: + + perl Makefile.PL + make + make test + make install + +SUPPORT AND DOCUMENTATION + +usage: sortcopies /somedirectory + +After installing, you can find documentation for this module with the +perldoc command. + + perldoc App::SortCopies + +You can also look for information at: + + RT, CPAN's request tracker (report bugs here) + https://rt.cpan.org/NoAuth/Bugs.html?Dist=App-SortCopies + + Search CPAN + https://metacpan.org/release/App-SortCopies + + +LICENSE AND COPYRIGHT + +This software is Copyright (c) 2026 by Semandi . + +This is free software, licensed under: + + The Artistic License 2.0 (GPL Compatible) + diff --git a/App-SortCopies-0.01/bin/sortcopies b/App-SortCopies-0.01/bin/sortcopies new file mode 100755 index 0000000..bd57a88 --- /dev/null +++ b/App-SortCopies-0.01/bin/sortcopies @@ -0,0 +1,7 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use App::SortCopies; + +App::SortCopies::run(@ARGV); diff --git a/App-SortCopies-0.01/lib/App/SortCopies.pm b/App-SortCopies-0.01/lib/App/SortCopies.pm new file mode 100644 index 0000000..3cb3231 --- /dev/null +++ b/App-SortCopies-0.01/lib/App/SortCopies.pm @@ -0,0 +1,130 @@ +package App::SortCopies; + +use 5.008003; +use strict; +use warnings; +use File::Spec; +use File::Path qw(make_path); +use Digest::MD5; +use File::Copy qw(move); +use File::Basename; +use feature 'say'; + +=head1 NAME + +App::SortCopies - The copy sorter! (What did you expect?) + +=head1 VERSION + +Version 0.01 + +=cut + +our $VERSION = '0.01'; + +sub run { + my $src = shift @ARGV or die "Usage: sortcopies dir\n"; + die "'$src' is not readable" unless -d $src and -r $src; + + my $dup_dir = File::Spec->catdir($src, "copies"); + make_path($dup_dir) unless -d $dup_dir; + + opendir(my $d, $src) or die $!; + my @unsorted_stuff = grep { + -f File::Spec->catfile($src, $_) + } readdir($d); + closedir($d); + + my %fried; + + for my $file (@unsorted_stuff) { + my $path = File::Spec->catfile($src, $file); + + open(my $potato, '<', $path) or do { + warn "I couldn't open '$file'\n"; + next; + }; + + binmode($potato); + my $hash = Digest::MD5->new->addfile($potato)->hexdigest; + close($potato); + + if ($fried{$hash}) { + my $dest = File::Spec->catfile($dup_dir, $file); + my $i = 1; + + my ($name, undef, $ext) = fileparse($file, qr/\.[^.]*/); + + $dest = File::Spec->catfile( + $dup_dir, + "${name}_$i$ext" + ) while -e $dest and $i++; + + move($path, $dest) or warn $!; + say "Duplicate $file is moved to $dest"; + } + else { + $fried{$hash} = 1; + } + } + + say "All copies in $src have been moved to $dup_dir!"; +} + +1; +=head1 SYNOPSIS + +This sorts a directory, in a non-recursive way. + +Copies of files are moved to a ./copies folder created in the directory being sorted + + sortcopies ~/path/to/dir_with_dupes + +=head1 EXPORT +Just run, for use by bin/sortcopies + +=head1 AUTHOR + +Semandi + +=head1 BUGS + +Please report any bugs or feature requests to C, or through +the web interface at L. I will be notified, and then you'll +automatically be notified of progress on your bug as I make changes. + + +=head1 SUPPORT + +You can find documentation for this module with the perldoc command. + + perldoc App::SortCopies + +You can also look for information at: + +=over 4 + +=item * RT: CPAN's request tracker (report bugs here) + +L + +=item * Search CPAN + +L + +=back + +=head1 ACKNOWLEDGEMENTS +To all the foxes of the world... + +=head1 LICENSE AND COPYRIGHT + +This software is Copyright (c) 2026 by Semandi . + +This is free software, licensed under: + + The Artistic License 2.0 (GPL Compatible) + +=cut + +1; # End of App::SortCopies diff --git a/App-SortCopies-0.01/t/00-load.t b/App-SortCopies-0.01/t/00-load.t new file mode 100644 index 0000000..e1df277 --- /dev/null +++ b/App-SortCopies-0.01/t/00-load.t @@ -0,0 +1,13 @@ +#!perl +use 5.008003; +use strict; +use warnings; +use Test::More; + +plan tests => 1; + +BEGIN { + use_ok( 'App::SortCopies' ) || print "Bail out!\n"; +} + +diag( "Testing App::SortCopies $App::SortCopies::VERSION, Perl $], $^X" ); diff --git a/App-SortCopies-0.01/t/manifest.t b/App-SortCopies-0.01/t/manifest.t new file mode 100644 index 0000000..b1b021f --- /dev/null +++ b/App-SortCopies-0.01/t/manifest.t @@ -0,0 +1,15 @@ +#!perl +use 5.008003; +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +my $min_tcm = 0.9; +eval "use Test::CheckManifest $min_tcm"; +plan skip_all => "Test::CheckManifest $min_tcm required" if $@; + +ok_manifest(); diff --git a/App-SortCopies-0.01/t/pod-coverage.t b/App-SortCopies-0.01/t/pod-coverage.t new file mode 100644 index 0000000..f1e26ce --- /dev/null +++ b/App-SortCopies-0.01/t/pod-coverage.t @@ -0,0 +1,24 @@ +#!perl +use 5.008003; +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +# Ensure a recent version of Test::Pod::Coverage +my $min_tpc = 1.08; +eval "use Test::Pod::Coverage $min_tpc"; +plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" + if $@; + +# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, +# but older versions don't recognize some common documentation styles +my $min_pc = 0.18; +eval "use Pod::Coverage $min_pc"; +plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" + if $@; + +all_pod_coverage_ok(); diff --git a/App-SortCopies-0.01/t/pod.t b/App-SortCopies-0.01/t/pod.t new file mode 100644 index 0000000..72bb38c --- /dev/null +++ b/App-SortCopies-0.01/t/pod.t @@ -0,0 +1,16 @@ +#!perl +use 5.008003; +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +# Ensure a recent version of Test::Pod +my $min_tp = 1.22; +eval "use Test::Pod $min_tp"; +plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; + +all_pod_files_ok(); diff --git a/Changes b/Changes new file mode 100644 index 0000000..59f6752 --- /dev/null +++ b/Changes @@ -0,0 +1,5 @@ +Revision history for App-SortCopies + +0.01 Date/time + First version, released on an unsuspecting world. + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..e9eda55 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,10 @@ +Changes +bin/sortcopies +lib/App/SortCopies.pm +Makefile.PL +MANIFEST This list of files +README +t/00-load.t +t/manifest.t +t/pod-coverage.t +t/pod.t diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..f6fcc35 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,46 @@ +use 5.008003; +use strict; +use warnings; +use ExtUtils::MakeMaker; + +my %WriteMakefileArgs = ( + NAME => 'App::SortCopies', + AUTHOR => ['Semandi '], + VERSION_FROM => 'lib/App/SortCopies.pm', + ABSTRACT_FROM => 'lib/App/SortCopies.pm', + EXE_FILES => ['bin/sortcopies'], + LICENSE => 'artistic_2', + MIN_PERL_VERSION => '5.008003', + CONFIGURE_REQUIRES => { + 'ExtUtils::MakeMaker' => '0', + }, + TEST_REQUIRES => { + 'Test::More' => '0', + }, + PREREQ_PM => { + #'ABC' => '1.6', + #'Foo::Bar::Module' => '5.0401', + }, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'App-SortCopies-*' }, +); + +# Compatibility with old versions of ExtUtils::MakeMaker +unless (eval { ExtUtils::MakeMaker->VERSION('6.64'); 1 }) { + my $test_requires = delete $WriteMakefileArgs{TEST_REQUIRES} || {}; + @{$WriteMakefileArgs{PREREQ_PM}}{keys %$test_requires} = values %$test_requires; +} + +unless (eval { ExtUtils::MakeMaker->VERSION('6.55_03'); 1 }) { + my $build_requires = delete $WriteMakefileArgs{BUILD_REQUIRES} || {}; + @{$WriteMakefileArgs{PREREQ_PM}}{keys %$build_requires} = values %$build_requires; +} + +delete $WriteMakefileArgs{CONFIGURE_REQUIRES} + unless eval { ExtUtils::MakeMaker->VERSION('6.52'); 1 }; +delete $WriteMakefileArgs{MIN_PERL_VERSION} + unless eval { ExtUtils::MakeMaker->VERSION('6.48'); 1 }; +delete $WriteMakefileArgs{LICENSE} + unless eval { ExtUtils::MakeMaker->VERSION('6.31'); 1 }; + +WriteMakefile(%WriteMakefileArgs); diff --git a/README b/README new file mode 100644 index 0000000..fee9bb3 --- /dev/null +++ b/README @@ -0,0 +1,49 @@ +App-SortCopies + +The README is used to introduce the module and provide instructions on +how to install the module, any machine dependencies it may have (for +example C compilers and installed libraries) and any other information +that should be provided before the module is installed. + +A README file is required for CPAN modules since CPAN extracts the README +file from a module distribution so that people browsing the archive +can use it to get an idea of the module's uses. It is usually a good idea +to provide version information here so that people can decide whether +fixes for the module are worth downloading. + + +INSTALLATION + +To install this module, run the following commands: + + perl Makefile.PL + make + make test + make install + +SUPPORT AND DOCUMENTATION + +usage: sortcopies /somedirectory + +After installing, you can find documentation for this module with the +perldoc command. + + perldoc App::SortCopies + +You can also look for information at: + + RT, CPAN's request tracker (report bugs here) + https://rt.cpan.org/NoAuth/Bugs.html?Dist=App-SortCopies + + Search CPAN + https://metacpan.org/release/App-SortCopies + + +LICENSE AND COPYRIGHT + +This software is Copyright (c) 2026 by Semandi . + +This is free software, licensed under: + + The Artistic License 2.0 (GPL Compatible) + diff --git a/bin/sortcopies b/bin/sortcopies new file mode 100755 index 0000000..bd57a88 --- /dev/null +++ b/bin/sortcopies @@ -0,0 +1,7 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use App::SortCopies; + +App::SortCopies::run(@ARGV); diff --git a/ignore.txt b/ignore.txt new file mode 100644 index 0000000..acf7af2 --- /dev/null +++ b/ignore.txt @@ -0,0 +1,18 @@ +Makefile +Makefile.old +Build +Build.bat +META.* +MYMETA.* +.build/ +_build/ +cover_db/ +blib/ +inc/ +.lwpcookies +.last_cover_stats +nytprof.out +pod2htm*.tmp +pm_to_blib +App-SortCopies-* +App-SortCopies-*.tar.gz diff --git a/lib/App/SortCopies.pm b/lib/App/SortCopies.pm new file mode 100644 index 0000000..3cb3231 --- /dev/null +++ b/lib/App/SortCopies.pm @@ -0,0 +1,130 @@ +package App::SortCopies; + +use 5.008003; +use strict; +use warnings; +use File::Spec; +use File::Path qw(make_path); +use Digest::MD5; +use File::Copy qw(move); +use File::Basename; +use feature 'say'; + +=head1 NAME + +App::SortCopies - The copy sorter! (What did you expect?) + +=head1 VERSION + +Version 0.01 + +=cut + +our $VERSION = '0.01'; + +sub run { + my $src = shift @ARGV or die "Usage: sortcopies dir\n"; + die "'$src' is not readable" unless -d $src and -r $src; + + my $dup_dir = File::Spec->catdir($src, "copies"); + make_path($dup_dir) unless -d $dup_dir; + + opendir(my $d, $src) or die $!; + my @unsorted_stuff = grep { + -f File::Spec->catfile($src, $_) + } readdir($d); + closedir($d); + + my %fried; + + for my $file (@unsorted_stuff) { + my $path = File::Spec->catfile($src, $file); + + open(my $potato, '<', $path) or do { + warn "I couldn't open '$file'\n"; + next; + }; + + binmode($potato); + my $hash = Digest::MD5->new->addfile($potato)->hexdigest; + close($potato); + + if ($fried{$hash}) { + my $dest = File::Spec->catfile($dup_dir, $file); + my $i = 1; + + my ($name, undef, $ext) = fileparse($file, qr/\.[^.]*/); + + $dest = File::Spec->catfile( + $dup_dir, + "${name}_$i$ext" + ) while -e $dest and $i++; + + move($path, $dest) or warn $!; + say "Duplicate $file is moved to $dest"; + } + else { + $fried{$hash} = 1; + } + } + + say "All copies in $src have been moved to $dup_dir!"; +} + +1; +=head1 SYNOPSIS + +This sorts a directory, in a non-recursive way. + +Copies of files are moved to a ./copies folder created in the directory being sorted + + sortcopies ~/path/to/dir_with_dupes + +=head1 EXPORT +Just run, for use by bin/sortcopies + +=head1 AUTHOR + +Semandi + +=head1 BUGS + +Please report any bugs or feature requests to C, or through +the web interface at L. I will be notified, and then you'll +automatically be notified of progress on your bug as I make changes. + + +=head1 SUPPORT + +You can find documentation for this module with the perldoc command. + + perldoc App::SortCopies + +You can also look for information at: + +=over 4 + +=item * RT: CPAN's request tracker (report bugs here) + +L + +=item * Search CPAN + +L + +=back + +=head1 ACKNOWLEDGEMENTS +To all the foxes of the world... + +=head1 LICENSE AND COPYRIGHT + +This software is Copyright (c) 2026 by Semandi . + +This is free software, licensed under: + + The Artistic License 2.0 (GPL Compatible) + +=cut + +1; # End of App::SortCopies diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..e1df277 --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,13 @@ +#!perl +use 5.008003; +use strict; +use warnings; +use Test::More; + +plan tests => 1; + +BEGIN { + use_ok( 'App::SortCopies' ) || print "Bail out!\n"; +} + +diag( "Testing App::SortCopies $App::SortCopies::VERSION, Perl $], $^X" ); diff --git a/t/manifest.t b/t/manifest.t new file mode 100644 index 0000000..b1b021f --- /dev/null +++ b/t/manifest.t @@ -0,0 +1,15 @@ +#!perl +use 5.008003; +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +my $min_tcm = 0.9; +eval "use Test::CheckManifest $min_tcm"; +plan skip_all => "Test::CheckManifest $min_tcm required" if $@; + +ok_manifest(); diff --git a/t/pod-coverage.t b/t/pod-coverage.t new file mode 100644 index 0000000..f1e26ce --- /dev/null +++ b/t/pod-coverage.t @@ -0,0 +1,24 @@ +#!perl +use 5.008003; +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +# Ensure a recent version of Test::Pod::Coverage +my $min_tpc = 1.08; +eval "use Test::Pod::Coverage $min_tpc"; +plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" + if $@; + +# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, +# but older versions don't recognize some common documentation styles +my $min_pc = 0.18; +eval "use Pod::Coverage $min_pc"; +plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" + if $@; + +all_pod_coverage_ok(); diff --git a/t/pod.t b/t/pod.t new file mode 100644 index 0000000..72bb38c --- /dev/null +++ b/t/pod.t @@ -0,0 +1,16 @@ +#!perl +use 5.008003; +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +# Ensure a recent version of Test::Pod +my $min_tp = 1.22; +eval "use Test::Pod $min_tp"; +plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; + +all_pod_files_ok(); diff --git a/xt/boilerplate.t b/xt/boilerplate.t new file mode 100644 index 0000000..ed8b855 --- /dev/null +++ b/xt/boilerplate.t @@ -0,0 +1,57 @@ +#!perl +use 5.008003; +use strict; +use warnings; +use Test::More; + +plan tests => 3; + +sub not_in_file_ok { + my ($filename, %regex) = @_; + open( my $fh, '<', $filename ) + or die "couldn't open $filename for reading: $!"; + + my %violated; + + while (my $line = <$fh>) { + while (my ($desc, $regex) = each %regex) { + if ($line =~ $regex) { + push @{$violated{$desc}||=[]}, $.; + } + } + } + + if (%violated) { + fail("$filename contains boilerplate text"); + diag "$_ appears on lines @{$violated{$_}}" for keys %violated; + } else { + pass("$filename contains no boilerplate text"); + } +} + +sub module_boilerplate_ok { + my ($module) = @_; + not_in_file_ok($module => + 'the great new $MODULENAME' => qr/ - The great new /, + 'boilerplate description' => qr/Quick summary of what the module/, + 'stub function definition' => qr/function[12]/, + ); +} + +TODO: { + local $TODO = "Need to replace the boilerplate text"; + + not_in_file_ok(README => + "The README is used..." => qr/The README is used/, + "'version information here'" => qr/to provide version information/, + ); + + not_in_file_ok(Changes => + "placeholder date/time" => qr(Date/time) + ); + + module_boilerplate_ok('lib/App/SortCopies.pm'); + + +} +