Make pod generation more palatable to the existing toolchain
Peter Rabbitson [Thu, 13 Dec 2012 10:37:37 +0000 (11:37 +0100)]
While the installation toolchain seems to understand the concept of
PMLIBDIRS/PMLIBPARENTDIRS rather well, it turns out that both s.c.o.
and metacpan hav great troubles displaying the results. While there
is work underway to fix metacpan, the intermittency of the failures
prompted a rethink of how to handle all of this.

So instead we turn (ab)use of ExtUtils::MakeMaker to 11. The generation
scripts still dump their contents into .generated_pod/ as before.
However afterwards we hook the create_distdir EUMM target and split it
into several targets:

create_distdir : clonedir_generate_files clonedir_post_generate_files fresh_manifest create_distdir_copy_manifested clonedir_cleanup_generated_files

Then we use the pre-existing EUMM install facility to copy the generated
POD directly to lib/, create a manifest and a distdir, and then delete
everything we just copied from lib/, leaving the clone-dir as pristine
as it was before we started.

.gitignore
MANIFEST.SKIP
Makefile.PL
lib/DBIx/Class/Manual/ResultClass.pod.proto [moved from lib/DBIx/Class/Manual/ResultClass.pod with 92% similarity]
maint/Makefile.PL.inc/50_redefine_makefile_flow.pl [new file with mode: 0644]
maint/Makefile.PL.inc/51_autohandle_MANIFEST.pl [new file with mode: 0644]
maint/Makefile.PL.inc/52_autogen_README.pl [moved from maint/Makefile.PL.inc/51_autogen_README.pl with 76% similarity]
maint/Makefile.PL.inc/53_autogen_pod.pl
maint/Makefile.PL.inc/59_autogen_MANIFEST.pl [deleted file]
maint/Makefile.PL.inc/61_inject_dbicadmin_pod.pl [moved from maint/Makefile.PL.inc/52_inject_dbicadmin_pod.pl with 71% similarity]
maint/gen_pod_inherit

index fb5c204..94a2aec 100644 (file)
@@ -17,4 +17,4 @@ t/var/
 *#
 .#*
 *~
-.generated_pod/*
+.generated_pod/DBIx
index 207b17d..aeae5c6 100644 (file)
@@ -1,4 +1,4 @@
-^(?!script/|examples/|lib/|inc/|t/|xt/|Makefile\.PL$|maint/|.generated_pod/|README$|MANIFEST$|Changes$|META\.(?:yml|json)$)
+^(?!script/|examples/|lib/|inc/|t/|xt/|Makefile\.PL$|maint/|README$|MANIFEST$|Changes$|META\.(?:yml|json)$)
 
 # Avoid version control files.
 \bRCS\b
@@ -26,3 +26,4 @@
 \.orig$
 \.rej$
 
+lib/DBIx/Class/Manual/ResultClass.pod.proto
index 89f64f5..8162234 100644 (file)
@@ -34,11 +34,6 @@ install_script (qw|
     script/dbicadmin
 |);
 
-makemaker_args(
-  PMLIBDIRS => [qw(lib .generated_pod)],
-  PMLIBPARENTDIRS => [qw(lib .generated_pod)],
-);
-
 ###
 ### DO NOT ADD OPTIONAL DEPENDENCIES HERE, EVEN AS recommends()
 ### All of them *MUST* go to DBIx::Class::Optional::Dependencies
@@ -161,7 +156,6 @@ else {
   # make sure this Makefile can not be used to make a dist
   # (without the author includes there are no meta cleanup, no sanity checks, etc)
   postamble <<EOP;
-.PHONY: nonauthor_stop_distdir_creation
 create_distdir: nonauthor_stop_distdir_creation
 nonauthor_stop_distdir_creation:
 \t\$(NOECHO) \$(ECHO) Creation of dists in non-author mode is not allowed
similarity index 92%
rename from lib/DBIx/Class/Manual/ResultClass.pod
rename to lib/DBIx/Class/Manual/ResultClass.pod.proto
index 7699a81..29ff9e9 100644 (file)
@@ -1,3 +1,7 @@
+#
+# This is what eventually becomes lib/DBIx/Class/Manual/ResultClass.pod
+# Courtesy of maint/gen_pod_inherit and Pod::Inherit
+#
 
 =head1 NAME
 
diff --git a/maint/Makefile.PL.inc/50_redefine_makefile_flow.pl b/maint/Makefile.PL.inc/50_redefine_makefile_flow.pl
new file mode 100644 (file)
index 0000000..3813e80
--- /dev/null
@@ -0,0 +1,63 @@
+# Split create_distdir into several subtargets, allowing us to generate
+# stuff, inject it into lib/, manifest it, and then clean all of it up
+{
+  package MY;
+  sub distdir {
+    (my $snippet = shift->SUPER::distdir(@_)) =~ s/^create_distdir :/create_distdir_copy_manifested :/;
+    return <<"EOM";
+$snippet
+
+create_distdir : clonedir_generate_files clonedir_post_generate_files fresh_manifest create_distdir_copy_manifested clonedir_cleanup_generated_files
+\t\$(NOECHO) \$(NOOP)
+
+clonedir_generate_files :
+\t\$(NOECHO) \$(NOOP)
+
+clonedir_post_generate_files :
+\t\$(NOECHO) \$(NOOP)
+
+clonedir_cleanup_generated_files :
+\t\$(NOECHO) \$(NOOP)
+
+EOM
+  }
+}
+
+# EU::MM BUG - workaround
+# somehow the init_PM of EUMM (in MM_Unix) interprets ResultClass.pod.proto
+# as a valid ResultClass.pod. While this has no effect on dist-building
+# it royally screws up the local Makefile.PL $TO_INST_PM and friends,
+# making it impossible to make/make test from a checkout
+# just rip it out here (remember - this is only executed under author mode)
+{
+  package MY;
+  sub init_PM {
+    my $self = shift;
+    my $rv = $self->SUPER::init_PM(@_);
+    delete @{$self->{PM}}{qw(lib/DBIx/Class/Manual/ResultClass.pod lib/DBIx/Class/Manual/ResultClass.pod.proto)};
+    $rv
+  }
+}
+
+# make the install (and friends) target a noop - instead of
+# doing a perl Makefile.PL && make && make install (which will leave pod
+# behind), one ought to assemble a distdir first
+
+{
+  package MY;
+  sub install {
+    (my $snippet = shift->SUPER::install(@_))
+      =~ s/^( (?: install [^\:]+ | \w+_install \s) \:+ )/$1 block_install_from_checkout/mxg;
+    return <<"EOM";
+$snippet
+
+block_install_from_checkout :
+\t\$(NOECHO) \$(ECHO) Installation directly from a checkout is not possible. You need to prepare a distdir, enter it, and run the installation from within.
+\t\$(NOECHO) \$(FALSE)
+
+EOM
+  }
+}
+
+# keep the Makefile.PL eval happy
+1;
diff --git a/maint/Makefile.PL.inc/51_autohandle_MANIFEST.pl b/maint/Makefile.PL.inc/51_autohandle_MANIFEST.pl
new file mode 100644 (file)
index 0000000..217b3b1
--- /dev/null
@@ -0,0 +1,16 @@
+# make sure manifest is deleted and generated anew on distdir
+# preparation, and is deleted on realclean
+
+postamble <<"EOM";
+
+fresh_manifest : remove_manifest manifest
+
+remove_manifest :
+\t\$(RM) MANIFEST
+
+realclean :: remove_manifest
+
+EOM
+
+# keep the Makefile.PL eval happy
+1;
similarity index 76%
rename from maint/Makefile.PL.inc/51_autogen_README.pl
rename to maint/Makefile.PL.inc/52_autogen_README.pl
index 39a2ba6..8914211 100644 (file)
@@ -7,11 +7,9 @@ unlink 'README' if -f 'README';
 
 postamble <<"EOP";
 
-.PHONY: dbic_clonedir_cleanup_readme dbic_clonedir_gen_readme
+clonedir_generate_files : dbic_clonedir_gen_readme
 
-distdir : dbic_clonedir_cleanup_readme
-
-create_distdir : dbic_clonedir_gen_readme
+clonedir_cleanup_generated_files : dbic_clonedir_cleanup_readme
 
 dbic_clonedir_gen_readme :
 \tpod2text lib/DBIx/Class.pm > README
@@ -19,6 +17,8 @@ dbic_clonedir_gen_readme :
 dbic_clonedir_cleanup_readme :
 \t\$(RM_F) README
 
+realclean :: dbic_clonedir_cleanup_readme
+
 EOP
 
 # keep the Makefile.PL eval happy
index 0c69623..c085a51 100644 (file)
@@ -8,7 +8,8 @@ my $ver = Meta->version;
 # cleanup the generated pod dir (again - kill leftovers from old checkouts)
 require File::Path;
 require File::Glob;
-File::Path::rmtree( [File::Glob::bsd_glob "$pod_dir/*"], { verbose => 0 } );
+File::Path::rmtree( File::Glob::bsd_glob("$pod_dir/*"), { verbose => 0 } );
+
 
 # generate the OptDeps pod both in the clone-dir and during the makefile distdir
 {
@@ -18,16 +19,15 @@ File::Path::rmtree( [File::Glob::bsd_glob "$pod_dir/*"], { verbose => 0 } );
 
   postamble <<"EOP";
 
-.PHONY: dbic_clonedir_gen_optdeps_pod
-
-create_distdir : dbic_clonedir_gen_optdeps_pod
+clonedir_generate_files : dbic_clonedir_gen_optdeps_pod
 
 dbic_clonedir_gen_optdeps_pod :
-\t\$(ABSPERL) -Ilib -MDBIx::Class::Optional::Dependencies -e "DBIx::Class::Optional::Dependencies->_gen_pod(qw($ver $pod_dir))"
+\t\$(ABSPERLRUN) -Ilib -MDBIx::Class::Optional::Dependencies -e "DBIx::Class::Optional::Dependencies->_gen_pod(qw($ver $pod_dir))"
 
 EOP
 }
 
+
 # generate the inherit pods both in the clone-dir and during the makefile distdir
 {
   print "Regenerating project documentation to include inherited methods\n";
@@ -37,12 +37,38 @@ EOP
 
   postamble <<"EOP";
 
-.PHONY: dbic_clonedir_gen_inherit_pods
-
-create_distdir : dbic_clonedir_gen_inherit_pods
+clonedir_generate_files : dbic_clonedir_gen_inherit_pods
 
 dbic_clonedir_gen_inherit_pods :
-\t\$(ABSPERL) -Ilib maint/gen_pod_inherit
+\t\$(ABSPERLRUN) -Ilib maint/gen_pod_inherit
+
+EOP
+}
+
+
+# copy the contents of .generated_pod over to lib/
+# (yes, overwriting is fine, though nothing should reside there)
+{
+  postamble <<"EOP";
+
+clonedir_post_generate_files : dbic_clonedir_copy_generated_pod
+
+dbic_clonedir_copy_generated_pod :
+\t\$(RM_F) .generated_pod/.packlist
+\t\$(ABSPERLRUN) -MExtUtils::Install -e 'install([ from_to => {qw(.generated_pod/DBIx lib/DBIx write .generated_pod/.packlist)}, verbose => 0, uninstall_shadows => 0, skip => [] ]);'
+
+EOP
+}
+
+
+# everything that came from .generated_pod, needs to be removed from our lib/
+{
+  postamble <<"EOP";
+
+clonedir_cleanup_generated_files : dbic_clonedir_cleanup_generated_pod_copies
+
+dbic_clonedir_cleanup_generated_pod_copies :
+\t\$(ABSPERLRUN) -MExtUtils::Install -e 'uninstall(qw(.generated_pod/.packlist))'
 
 EOP
 }
diff --git a/maint/Makefile.PL.inc/59_autogen_MANIFEST.pl b/maint/Makefile.PL.inc/59_autogen_MANIFEST.pl
deleted file mode 100644 (file)
index 1dbd861..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# Makefile syntax allows adding extra dep-specs for already-existing targets,
-# and simply appends them on *LAST*-come *FIRST*-serve basis.
-# This allows us to inject extra depenencies for standard EUMM targets
-
-print "Removing MANIFEST, will regenerate on next `make dist(dir)`\n";
-unlink 'MANIFEST';
-
-# preamble. so that the manifest target is first, hence executes last
-preamble <<"EOP";
-
-create_distdir : manifest
-
-EOP
-
-# keep the Makefile.PL eval happy
-1;
@@ -4,14 +4,12 @@
 
 postamble <<"EOP";
 
-.PHONY: dbic_distdir_dbicadmin_pod_inject
-
-distdir : dbic_distdir_dbicadmin_pod_inject
+create_distdir : dbic_distdir_dbicadmin_pod_inject
 
 # The pod self-injection code is in fact a hidden option in
 # dbicadmin itself, we execute the one in the distdir
 dbic_distdir_dbicadmin_pod_inject :
-\t\$(ABSPERL) -I\$(DISTVNAME)/lib \$(DISTVNAME)/script/dbicadmin --selfinject-pod
+\t\$(ABSPERLRUN) -I\$(DISTVNAME)/lib \$(DISTVNAME)/script/dbicadmin --selfinject-pod
 
 EOP
 
index b7adc14..f5532a8 100755 (executable)
@@ -6,9 +6,23 @@ use strict;
 my $lib_dir = 'lib';
 my $pod_dir = '.generated_pod';
 
+my $result_metapod_fn = "$lib_dir/DBIx/Class/Manual/ResultClass.pod";
+
 die "POD generator must be executed from the dist root\n"
   unless -d $lib_dir and -d $pod_dir;
 
+require File::Copy;
+File::Copy::copy(
+  "$result_metapod_fn.proto",
+  "$result_metapod_fn",
+) or die "Copying ResultClass proto pod ($result_metapod_fn.pod) failed: $!";
+
+# cleanup
+END {
+  local ($@, $!, $?);
+  unlink $result_metapod_fn;
+}
+
 require Pod::Inherit;
 
 Pod::Inherit->new({