diff options
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | Porting/README.pod | 4 | ||||
-rw-r--r-- | Porting/add-pod-file | 239 |
3 files changed, 244 insertions, 0 deletions
@@ -5346,6 +5346,7 @@ pod/splitpod Splits perlfunc into multiple pod pages Policy_sh.SH Hold site-wide preferences between Configure runs. Porting/acknowledgements.pl Generate perldelta acknowledgements text Porting/add-package.pl Add/Update CPAN modules that are part of Core +Porting/add-pod-file Utility to add new pod/*.pod file to core distribution Porting/bench.pl Run benchmarks against t/perf/benchmarks Porting/bisect.pl A tool to make bisecting easy Porting/bisect-example.sh Example script to use with git bisect run diff --git a/Porting/README.pod b/Porting/README.pod index aa268215a0..3e2fe7acaa 100644 --- a/Porting/README.pod +++ b/Porting/README.pod @@ -16,6 +16,10 @@ text. Program to prepare dual-life distributions for insertion into the Perl 5 F<lib/> and F<t/> directories. Now thought to be largely superseded. +=head2 F<add-pod-file> + +Program to facilitate addition of new F<.pod> files to F<pod/>. + =head2 F<bench.pl> Do performance analysis on the code snippets in F<t/perf/benchmarks>. diff --git a/Porting/add-pod-file b/Porting/add-pod-file new file mode 100644 index 0000000000..24b718544b --- /dev/null +++ b/Porting/add-pod-file @@ -0,0 +1,239 @@ +#!/usr/bin/perl +use 5.14.0; +use warnings; +use Carp; +use File::Spec; +use Getopt::Long; +require "./Porting/manifest_lib.pl"; + +=head1 NAME + +add-pod-file - Utility to add new F<pod/*.pod> file to core distribution + +=head1 USAGE + +After C<make test_prep> has been run, call from top level of Perl 5 core +distribution: + + perl Porting/add-pod-file \ + --stub=<XXX> --abstract=<YYY> --section=<Z> --verbose + +=head1 DESCRIPTION + +This is a program which I<may> be helpful when a committer has to add a new +F<*.pod> file in the F<pod/> directory. + +=head2 Prerequisites + +This program assumes that committer has taken the following steps (in the +order listed): + +=over 4 + +=item 1 You have run F<make test_prep>. + +This is to guarantee that all files are properly positioned. + +=item 2 You have placed a well-formatted F<.pod> file into the F<pod/> directory. + +In the C<NAME> section of this file there is a single non-blank line which +consists of a string in the format C<STUB - ABSTRACT>, where C<STUB> is the +basename of the file without the C<.pod> suffix and C<ABSTRACT> is the short +description of the file. For example, a new file whose path is +F<pod/perlphonypod.pod> must have a C<NAME> section like this: + + =head1 NAME + + perlphonypod - This is phony POD + +=back + +F<pod/*.pod> files need entries in multiple locations to keep F<make +test_porting> happy. This program automates the formulation of I<most> of +those entries, but will need some assistance from the committer to work +properly. The committer will have to make a reasonable choice as to which +section of F<pod/perl.pod> the new F<.pod> file should be listed under. +The eligible sections are shown in the following table: + + Command-Line Value Section in pod/perl.pod + + O => 'Overview', + T => 'Tutorials', + R => 'Reference Manual', + I => 'Internals and C Language Interface', + M => 'Miscellaneous', + L => 'Language-Specific', + P => 'Platform-Specific', + +For a first pass, we'll put the new entry at the end of the C<^=head2> section +specified by the committer with the single-initial provided for command-line +switch C<section>. + +=head2 Testing this program + +=over 4 + +=item 1 Create a well formatted F<.pod> file somewhere on your system. + +=item 2 Copy it into the source tree under F<pod>. + +=item 3 Call the program as in L</USAGE> above. + +=item 4 Call F<git diff> and examine results. + +=item 5 Run F<make test_porting>. + +=back + +=cut + +my @man_sections = ( + O => 'Overview', + T => 'Tutorials', + R => 'Reference Manual', + I => 'Internals and C Language Interface', + M => 'Miscellaneous', + L => 'Language-Specific', + P => 'Platform-Specific', +); + +my @man_section_abbrevs = (); +my $man_sections_str = ''; +for (my $i=0; $i<= $#man_sections; $i+=2) { + my $j = $i+1; + push @man_section_abbrevs, $man_sections[$i]; + $man_sections_str .= "\t$man_sections[$i] => $man_sections[$j]\n"; +} +my %man_sections_seen = map { $_ => 1 } @man_section_abbrevs; +my $man_sections = { @man_sections }; + +my ($stub, $abstract, $section, $verbose) = ('') x 4; +GetOptions( + "stub=s" => \$stub, + "abstract=s" => \$abstract, + "section=s" => \$section, + "verbose" => \$verbose, +) or croak("Error in command line arguments to add-pod-file.pl\n"); +croak "$0: Must provide value for command-line switch 'stub'" + unless length($stub); +croak "$0: Must provide value for command-line switch 'abstract'" + unless length($abstract); +croak "$0: Must provide value for command-line switch 'section'" + unless length($section); +my $section_croak = "$0: Value for command-line switch must be one of @man_section_abbrevs\n"; +$section_croak .= " Select one initial from:\n$man_sections_str"; +croak $section_croak unless $man_sections_seen{$section}; + +my $newpodfile = "$stub.pod"; +my $newpodpath = File::Spec->catfile('pod', $newpodfile); +croak "Unable to locate new file '$newpodpath'" unless -f $newpodpath; + +say "Step 1: Basic test of validity of POD in $newpodpath" if $verbose; + +my $rv; +system(qq|$^X cpan/Pod-Checker/podchecker $newpodpath|) + and croak "$newpodpath has POD errors"; +system(qq|git add $newpodpath|) and croak "Unable to 'git add'"; + +# Step 2: Insert entry for $newpodpath into MANIFEST + +say "Step 2: Insert entry for $newpodpath into MANIFEST" if $verbose; + +my $manifest = 'MANIFEST'; +open(my $IN, '<', $manifest) + or croak "Can't open $manifest for reading"; +my @manifest_orig = <$IN>; +close($IN) or croak "Can't close $manifest after reading"; +chomp(@manifest_orig); + +my (@before_pod, @pod, @after_pod); +my $seen_pod = 0; +while (my $l = shift(@manifest_orig)) { + if (! $seen_pod and $l !~ m{^pod\/}) { + push @before_pod, $l; + } + elsif ($l =~ m{^pod\/}) { + push @pod, $l; + $seen_pod++; + } + else { + push @after_pod, $l; + } +} + +say "Inserting entry for '$newpodpath' into MANIFEST; text will be '$abstract'" if $verbose; +my $new_manifest_entry = "$newpodpath\t\t$abstract"; +my @new_pod = sort_manifest(@pod, $new_manifest_entry); + +open(my $OUT, '>', $manifest) + or croak "Can't open $manifest for writing"; +binmode($OUT); +say $OUT join("\n", @before_pod, @new_pod, @after_pod); +close($OUT) or croak "Can't close $manifest after writing"; + +say "Step 3: Add entry to pod/perl.pod" if $verbose; + +# Read the existing pod/perl.pod into memory. +# Divide it into chunks before the selected section, the head2 of the selected +# section, the selected section, and what comes after the selected section. +# Add the stub and abstract for the new .pod file to the end of the selected +# section. (Manually reposition to taste.) + +my $perlpod = "./pod/perl.pod"; + +open(my $IN1, '<', $perlpod) + or croak "Can't open $perlpod for reading"; +my $perlpod_str; +{ + local $/; + $perlpod_str = <$IN1>; +} +close($IN1) or croak "Can't close $perlpod after reading"; + +my $section_head = "=head2 $man_sections->{$section}"; +my @chunks = split $section_head, $perlpod_str; +chomp $chunks[0]; # So we can use 'say' consistently later on + +my @balance = split /\n/, $chunks[1]; +shift @balance; # $chunks[1] begins with a newline which we won't need to output +my (@target_section, @after_section); + +my $this = 0; +for my $l (@balance) { + if ($l =~ m/^=(head2|for)/) { + push @after_section, $l; + $this++; + } + elsif (! $this) { + push @target_section, $l; + } + else { + push @after_section, $l; + } +} + +push @target_section, " $stub\t\t$abstract"; + +open(my $OUT1, '>', $perlpod) + or croak "Can't open $perlpod for writing"; +say $OUT1 $chunks[0]; +say $OUT1 $section_head; +say $OUT1 join("\n" => @target_section), "\n"; +say $OUT1 join("\n" => @after_section), "\n"; +close $OUT1 or croak "Can't close $perlpod after writing"; + +say "Step 4: Running './perl -Ilib Porting/pod_rules.pl --build-podmak' to update win32/pod.mak." + if $verbose; + +system(qq|./perl -Ilib Porting/pod_rules.pl --build-podmak|) + and croak "Porting/pod_rules.pl --build-podmak failed"; + +system(qq|git add MANIFEST pod/perl.pod win32/pod.mak|) + and croak "Unable to git-add three updated files"; + +if ($verbose) { + say "Call 'git diff --staged' and inspect modified files; correct as needed."; + say "Then run 'make test_porting'."; + say "Then say 'git commit'."; +} + |