SEE ALSO

This module is part of $distribution version $version, built on $today.$web

LICENSE

$contrib $lictext __PODTAIL

my $makefile_example = 'https://github.com/markov2/perl5-OODoc/blob/master/Makefile.PL'; my $rt_issue_queue = 'https://rt.cpan.org/Public/Dist/Display.html?Name=';

sub extract_manuals($$$); sub extract_distro($%); sub create_pod($$$); sub create_html($$); sub string_expand_values($$$); sub create_readme($$); sub create_meta($); sub run_tests($); sub prepare_release($); sub publish_release($); sub publish_raw($); sub create_export($$); sub read_makefile($); sub read_meta($);

sub convert2version3(); sub config3(); sub merge3(); sub introduce2oodoc();

### ### Command-line parsing ###

Getopt::Long::Configure 'bundling';

GetOptions 'all!' => \(my $make_all), 'exports!' => \(my $make_exports), 'release!' => \(my $make_release), 'export=s' => \(my $make_export), 'html!' => \(my $make_html), 'make|m=s' => \(my $make_config = 'oodist'), 'pod!' => \(my $make_pod), 'raw!' => \(my $make_raw), 'starter!' => \(my $starter), 'tests|t!' => \(my $run_tests), 'verbose|v+' => \(my $verbose = 0), 'workdir|w=s' => \(my $distdir),

'config3'       => \(my $config3),
'merge3'        => \(my $merge3),
or error __"stopped";

! @ARGV or error __x"No command-line arguments expected.";

my $any_requested = $make_release || $make_exports || $make_export || $make_html || $make_pod || $make_raw || $run_tests; if($make_all || ! $any_requested) { # explicit all, but not -no-* $_ //= 1 for $make_release, $make_exports, $make_html, $make_pod, $make_raw, $run_tests; }

dispatcher mode => $verbose, 'ALL'; my $silence = $verbose > 1 ? '' : ' >' . devnull;

my $ooversion = $OODoc::VERSION || 'devel';

### ### collect some project info ###

info "** Reading your project's configuration with Perl $]";

-f 'Makefile.PL' or error __x"This command must be run in the top directory of a Perl distribution.";

system "perl Makefile.PL$silence" and fault "cannot run Makefile.PL for basic information";

if($starter) { introduce2oodoc; exit 0; }

my $makefile = read_makefile 'Makefile'; my $meta = read_meta 'MYMETA.json';

### Help people convert from OODoc2 to OODoc3

if($config3) { config3; exit 0 } if($merge3) { merge3; exit 0 }

my $config = $meta->{'x_' . $make_config} || $meta->{$make_config}; unless($config) { if($makefile->{DISTDIR}) { convert2version3; exit 1; }

print <<'__INFO';

* INFO: you have not configured OODoc yet. Let me tell you how you can * bootstrap it by modifying your Makefile.PL (only).

__INFO

introduce2oodoc;
exit 1;
}

my $email = $meta->{email} || $1;

my $project = $meta->{name}; my $version = $meta->{version}; my $distvname = "$project-$version";

$distdir ||= "$tmpdir/$project"; -d $distdir || mkdir $distdir or fault __x"Cannot create workdir at {dir}", dir => $distdir;

info "* producing $project release $version";

### ### Start OODoc ###

my $doc = OODoc->new( distribution => $project, version => $version, # version of whole );

# Reading all the manual pages my $source = realpath '.'; my %distros = ($project => $meta); extract_manuals $source, $distdir, $config; # produces $distdir

# Generate various products foreach my $gen (@{$config->{generate} || []}) { if(my $format = $gen->{format}) { if($format =~ /^pod/) { create_pod $doc, $gen, $distdir if $make_pod; } elsif($format =~ /^html/) { create_html $doc, $gen if $make_html; } else { error __x"unknown format '{format}' to generate.", format => $format; } } elsif(my $export = $gen->{export}) { if($make_exports && (!$make_export || $export eq $make_export)) { create_export $doc, $gen; } } else { error __x"unknown generation type in configuration."; } }

# Produce release

if($run_tests || $make_release || $make_raw) { prepare_release $distdir;

run_tests $distdir
	if $run_tests;

publish_release $distdir
	if $make_release;

publish_raw $source
	if $make_raw;
}

info "** Ready"; exit 0;

### extract($release_dir, $publish_dir, $config) # Extract documentation from all manuals. When the manual is part of the # release to be made, it will produce a stripped pm's into $publish_dir # at the same time.

sub extract_manuals($$$) { my ($indir, $outdir, $config) = @_;

info "** Extracting manuals from distributions";
extract_distro $source, release_dir => $outdir, config => $config, recurse => 1;

info "** Merge the manuals into one documentation set";
my $pconfig = $config->{parser};
$doc->finalize(%$pconfig);  # for the auto* config

info $doc->stats;
}

my %included_dirs;

sub extract_distro($%) { my ($dir, %args) = @_; return if $included_dirs{$dir};

chdir $dir
	or fault __x"cannot go to {dir} to extract distribution";

my $lib       = "$dir/lib";
push @INC, $lib unless grep $_ eq $lib, @INC;

# Do not run Makefile.PL because the included distry may be in broken state.
my $outdir    = delete $args{release_dir};
my $is_root   = defined $outdir;
my $dist_meta = $is_root ? $meta : read_meta "$dir/MYMETA.json";
my $dist_name = $dist_meta->{name};
my $version   = $dist_meta->{version};

$included_dirs{$dir} = $dist_name;
$distros{$dist_name} = $dist_meta;

my $dist_config = delete $args{config} || $dist_meta->{x_oodist} || $dist_meta->{oodist};
unless($dist_config)
{	warning __x"distribution {name} is not yet converted to OODoc v3, hence ignored.", name => $dist_name;
	return;
}

if($args{recurse})
{
	foreach my $include (@{$dist_config->{include} || []})
	{	my $absdir = realpath (rel2abs $include, $dir);
		extract_distro $absdir, %args, recurse => 1;
	}

	foreach my $use (@{$dist_config->{use} || []})
	{	my $absdir = realpath (rel2abs $use, $dir);
		extract_distro $absdir, %args, recurse => 0;
	}
}

chdir $dir;

info "*  processing files of $dist_name $version from $dir";

# Every distribution may have different parser rules.
my $p_config = $dist_config->{parser} || { };
my $pmheadfn = rel2abs delete $p_config->{pmhead} || 'PMHEAD.txt', $dir;
my $select   = delete $p_config->{select} || qr[^ lib/ .*? \.(?:pod|pm) $ ]x;
my $parser   = OODoc::Parser->new(%$p_config);

if($is_root)
{	my $pmhead   = -f $pmheadfn ? read_text $pmheadfn : $default_pmhead;

	$doc->processFiles(
		version    => $version,
		workdir    => $outdir,
		parser     => $parser,
		select     => $select,
		notice     => string_expand_values($pmhead, $dir, $dist_meta),
	);
}
else
{	$doc->processFiles(
        distribution => $dist_name,
		version    => $version,
		parser     => $parser,
		select     => $select,
	);
}
}

# # Create pods # Only for the manuals in the source distribution. #

sub create_pod($$$) { my ($doc, $gen, $outdir) = @_;

my $format = $gen->{format};
info "** Creating POD files with $format";

my $podtailfn = rel2abs +($gen->{podtail} || 'PODTAIL.txt'), $source;
my $podtail   = -f $podtailfn ? read_text $podtailfn : $default_podtail;

$doc->formatter($format,
	workdir => $outdir,
)->createPages(
    select  => sub { my $manual = shift; $manual->distribution eq $project },
    append  => string_expand_values($podtail, $source, $meta),
);

# The POD output is not published separately, but as part of the release.
}

# # Create html #

sub create_html($$) { my ($doc, $gen) = @_;

my $format    = $gen->{format};
my $webpages  = $gen->{webpages}
	or error __x"html generation needs a location for the webpages.";

info "* Creating HTML with $format, files in $webpages";

chdir $source or panic;

my $templates = $gen->{templates} // 'html';

$doc->formatter($format,
	workdir         => $webpages,
 	html_root       => $gen->{docroot}    // '/',
	html_stylesheet => $gen->{stylesheet},
)->createPages(
	manual_format    => [],
	manual_templates => "$templates/manual",
	other_templates  => "$templates/other",
);

# Only continue when the combined HTML is to be packaged.
my $dest     = $gen->{publish} or return;
-d $dest || mkdir $dest
	or fault __x"cannot create {dir}", dir => $dest;

my $htmlfile = "$distvname-html.tar.gz";

info "*  building html package $htmlfile";
unlink $htmlfile;

local $" = ' ';
system "tar czf $htmlfile *"
	and fault __x"cannot produce {file} with tar", file => $htmlfile;

return if $dest eq $source;

info "*  publish HTML package to $dest/$htmlfile";

move $htmlfile, $dest
	or fault __x"cannot move {from} to {to}", from => $htmlfile, to=>$dest;
}

# # string_expand_values($$$) # The pmhead and podtail are flexible texts, which can have some values filled-in. # These names are have not changed in v3, but more information is provided.

sub _get_licenses($$) { my ($dist_meta, $config) = @_;

my $year  = strftime "%Y", localtime;
if(my $firstyear = $config->{first_year})
{	$year = $firstyear =~ m/$year$/ ? $firstyear
	      : $firstyear =~ m/\D$/    ? $firstyear.$year
	      : "$firstyear-$year";
}

my $liccodes = $dist_meta->{license}
	or error __x"The distribution does not specify a license (required)";

my $meta_spec = $dist_meta->{'meta-spec'}{version} || 1;

my @licenses;
foreach my $liccode (@$liccodes)
{	my ($class) = Software::LicenseUtils->guess_license_from_meta_key($liccode, $meta_spec)
		or error __x"cannot find license code '{code}'", code => $liccode;

	my $authors = $dist_meta->{author};
	push @licenses, $class->new({
		holder  => $dist_meta->{license_holder} || $authors->[0] =~ s/\s+\<(.*?)\>//r,
		year    => $year,
		program => $dist_meta->{name},
		Program => ucfirst($dist_meta->{name}),
	});
}

@licenses;
}

sub string_expand_values($$$) { my ($string, $dir, $dist_meta) = @_; my $config = $dist_meta->{x_oodist} || $dist_meta->{oodist};

my $website = $dist_meta->{resources}{homepage};
my $authors = $dist_meta->{author} or panic "no author";
my $email   = $authors->[0] =~ m! \<(.*?)\>! ? $1 : undef;
$email      = $config->{email} if exists $config->{email};
my $author  = join ', ', map s/ \<(.*?)\>$//r, @$authors;   # names only

my $log     = first { m/^(?:change|contrib)/i } bsd_glob '*';
my $contrib = $log ? "For contributors see file $log.\n" : "";

my ($license) = _get_licenses $dist_meta, $config;
my $year      = $license->year;

my %vars = (
	author    => " by $author",
    changelog => $log,
	contrib   => $contrib,
	email     => $email || '',
    lictext   => $license->notice,
	ooversion => $ooversion,  # OODoc's version which produces this docs
	project   => $project,    # overall project name
	spdx      => $license->spdx_expression,
	today     => (strftime "%B %d, %Y", localtime),
	version   => $dist_meta->{version},
 	web       => $website ? " Website: F<$website>" : '',
	website   => $website,
	year      => $license->year,       # license year range, backwards compatible name

	distribution  => $dist_meta->{name},
	license_years => $license->year,
);

$string =~ s/(?: \$(\w+) | \$\{(\w+)\} )/
	my $key = $+;
    exists $vars{$key} or error __x"unknown pmhead or podtail field '{name}'.", name => $key;
    $vars{$key};
 /grxe;
}

# # create_readme() # When the README file is missing, something useful gets added.

sub create_readme($$) { my ($release, $distdir) = @_; my @toplevel = bsd_glob "$distdir/*";

my $readme_basefn = 'README.txt';
my $take = $release->{readme};
if($take)
{	$readme_basefn = basename $take;
}
elsif(first { /\breadme(?:\..*)$/i } @toplevel)
{	# No readme added when there exists one
	return 1;
}

info "*  adding $readme_basefn";

my $manifn = first { /\bmanifest$/i } @toplevel;
open my $manifest, '>>', $manifn
	or fault __x"cannot append to {file}", file => $manifn;
$manifest->print("$readme_basefn\n");
$manifest->close;

my $readmefn = catfile $distdir, $readme_basefn;
if($take)
{	# user provided README
	info "* copying $take as README\n";

	copy $take, $readmefn
		or fault __x"cannot copy {from} to {to}", from => $take, to => $readmefn;

	return 1;
}

# Produce a README text

open my $readme, '>:encoding(utf8)', $readmefn
	or fault __x"cannot write to {file}", file => $readmefn;

my $date = localtime;

$readme->print(<<__README);
=== README for $project version $version
=   Generated on $date by OODoc $ooversion

There are various ways to install this module:

(1) if you have a command-line, you can do:
      cpan -i <any package from this distribution>'

(2) if you use Windows, have a look at https://strawberryperl.com

(3) if you have downloaded this module manually (as root/administrator)
      tar -xzf $project-$version.tar.gz
      cd $project-$version
      perl Makefile.PL
      make          # optional
      make test     # optional
      make install

References:

  * For usage, see the included manual-pages or https://metacpan.org/dist/$project
__README

	my $resources = $meta->{resources} || { repository => {} };
	if(my $homepage = $resources->{homepage}) { $readme->print(<<__HOMEPAGE) }
  * This project has a website at $homepage
__HOMEPAGE

	my $web = $resources->{repository}{web};
	if($web) { $readme->print(<<__REPO) }
  * The source repository can be found at $web
__REPO

	my $issues = $web =~ m/github.com/ ? "$web/issues" : "$rt_issue_queue$project";
	$readme->print(<<__ISSUES);
  * Please report issues via $issues
__ISSUES

	$readme->close;

	1;
}

# Since ExtUtils::MakeMaker, the META files only get updated when # they already exist. sub create_meta($) { my ($doc) = @_; my $manifest = first { /\bmanifest$/i } bsd_glob "*"; $manifest or panic "No manifest";

foreach my $fn ('META.yml', 'META.json')
{	next if -f $fn;
	info "adding $fn";
	open META, '>>', $fn and close META;

	open MANIFEST, '>>', $manifest
		or fault __x"cannot append to {file}", file => $manifest;

	print MANIFEST "$fn\n";
	close MANIFEST;
}
}

# # Run tests #

sub run_tests($) { my ($distdir) = @_;

 	info "** Running tests";

	my $tests = $config->{tests}   # no configuration params yet
		or (info "tests are not configured to be run."), return;

	chdir $distdir
		or fault __x"cannot chdir to run tests in {dir}", dir => $distdir;

	foreach my $testdir (qw/t tests xt/)
	{	-d $testdir or next;

		info "*  running tests in $distdir/$testdir";

		system "make test TEST_FILES=$testdir/*.t$silence"
			and fault __x"make test in {dir} failed", dir => $distdir;
	}
}

# # Create a distribution #

sub prepare_release($) { my ($distdir) = @_;

info "** Creating the release for $distvname";

info "*  prepare release in $distdir";

chdir $distdir
	or fault __x"cannot chdir to prepare release in {dir}", dir => $distdir;

system "perl Makefile.PL$silence"
	and fault __x"perl Makefile.PL failed";

system "make clean$silence"
	and fault __x"make clean failed";

move 'Makefile.old', 'Makefile'
	or fault __x"cannot reinstate Makefile";

system "make distdir$silence"
   and fault __x"make distdir failed";
}

sub publish_release($) { my ($distdir) = @_;

 	info "** Publish release";

	my $release = $config->{release}
		or (info "release output not configured."), return;

	chdir $distdir
		or fault __x"cannot chdir to publish release in {dir}", dir => $distdir;

	my $dest = rel2abs +($release->{publish} // '.'), $source;
	-d $dest || mkdir $dest
		or fault __x"cannot create release directory {dir}", dir => $dest;

	create_readme $release, $distdir;

	my $distfile = "$distvname.tar.gz";

	info "*  building distribution in $distfile";
	unlink $distfile;

	system "make dist >/dev/null"
		and fault __x"make dist in {dir} failed", dir => $distdir;

	return if $dest eq $distdir;

	info "*  publish release in $dest";

	-f $distfile
		or error __x"cannot find produced {file}", file => $distfile;

	-d $dest or mkdir $dest
		or fault __x"cannot create {dir}", dir => $dest;

	move $distfile, $dest
		or fault __x"cannot move {from} to {to}", from => $distfile, to=>$dest;
}

# # Publish RAW #

sub publish_raw($) { my ($distdir) = @_;

info "** Create package with raw distribution";

my $raw     = $config->{raw}
	or (info "raw output not configured."), return;

chdir $distdir
	or fault __x"cannot chdir to publish raw in {dir}", dir => $distdir;

my $rawname = "$distvname-raw";
my $rawfile = "$rawname.tar.gz";

info "*  building raw package $rawfile";
unlink $rawfile;

my %include;
foreach my $manifest (bsd_glob "MANIFEST*")
{	foreach (read_lines $manifest)
	{	s/\s{3,}.*$//;
	    next if m/^#/;
	    next unless length;
	    chomp;
	    $include{$_}++;
	}
}

my @include = map "$rawname/$_", sort keys %include;
symlink('.', $rawname) || readlink $rawname eq '.'
	or fault __x"cannot create temp symlink {name}", name => $rawname;

local $" = ' ';
system "tar czf $rawfile @include"
	and fault __x"cannot produce {file} with tar", file => $rawfile;

unlink $rawname;

my $dest = rel2abs +($raw->{publish} // '.'), $source;
-d $dest or mkdir $dest
	or fault __x"cannot create {dir}", dir => $dest;

info "*  publish raw package to $dest";

move $rawfile, $dest
	or fault __x"cannot move {from} to {to}", from => $rawfile, to => $dest;
}

# # Create EXPORT #

sub create_export($$) { my ($doc, $gen) = @_;

my $name   = $gen->{export};
my $markup = $gen->{markup}     //= 'html';
my $dest   = $gen->{publish}    //= '-';
my $serial = $gen->{serializer} //= 'json';

info "** Export data-set $name.";

my $filters = $gen->{include_manuals} || [];
my $manuals;
if(@$filters)
{	my %manuals;
	foreach my $filter (@$filters)
	{	my @found = grep /^ \Q$filter\E (?: \:\: | $) /ix, map $_->name, $doc->manuals;
		@found or warning __x"No manuals match filter '{filter}'.", filter => $filter;
		$manuals{$_}++ for @found;
	}
	$manuals = [ sort keys %manuals ];
}

info "*  creating export with markup $markup." ;

require OODoc::Export;
my $exporter = OODoc::Export->new(serializer => $serial, markup => $markup);

# my $tail = oodist_meta $makefile; # $tail->{license_year_range} = delete $tail->{year}; # naming improvement

my $tree = $exporter->tree($doc,
	manuals       => $manuals,
	distributions => \%distros,
#		meta     => $tail,      # only flat key-value, where value is a string
);

-d $dest || mkdir $dest
	or fault __x"cannot create export directory {dir}", dir => $dest;

my $exportfn = catfile $dest, "$distvname-$name.$serial";

info "** Publish export into $exportfn" ;
$exporter->write($exportfn, $tree, pretty_print => 1);

1;
}

# read_makefile($makefile) # Collect values of variable defined in the specified MAKEFILE, which was # produced by "perl Makefile.PL"

sub read_makefile($) { my $makefile = shift;

open MAKEFILE, '<', $makefile
   or fault __x"cannot open produced Makefile: {file}", file => $makefile;

my %makefile;
while( <MAKEFILE> )
{	$_ .= <MAKEFILE> while !eof MAKEFILE && s/\\$//; # continuations
	s/\n\t*/ /g;

	$makefile{$1} = $2 if m/^([A-Z_][A-Z\d_]+)\s*\=\s*(.*?)\s*$/;

	if(m/^#\s+([A-Z_][A-Z\d_]+)\s*\=>\s*(.*?)\s*$/)
	{	# important information which ended-up in comments ;(
	    my ($key, $v) = ($1, $2);
	    $v =~ s/q\[([^\]]*)\]/$1/g;  # remove q[]
	    $makefile{$key} = $v;
	}
}

close MAKEFILE;
\%makefile;
}

# read_meta($json_file) # Read a META.json or MYMETA.json file into a Perl structure.

sub read_meta($) { my $fn = shift; JSON->new->utf8(1)->decode(read_binary $fn); }

### ### convert2version3() # OODoc versions before 3.0 used fields in the Makefile.PL to configure # the documentation generation process. But it got too complex, with # growing needs. Help people convert (help myself to convert 70+ Perl # distributions ;-)

sub convert2version3() { print <<__EXPLAIN; *** Your configuration is based on an old OODoc version: you need to convert *** to a (more convenient) new structure. This only impacts the configuration: *** no need to change your documentation.

===> 1. Add the output of this to the top of your Makefile.PL:

    $0 --config3
    (hint:  vi Makefile.PL   :r! oodist --config3)

===> 2. Merge the following into your "WriteMakefile" call in Makefile.PL

    $0 --merge3
    (hint:  vi Makefile.PL   :r! oodist --merge3)

===> 3. Remove the "PREAMBLE" with OODoc values from the Makefile.PL

===> 4. Be warned that some command-line options to 'oodist' have changed

*** Merge the above with your Makefile.PL. Be smart with it. A documented *** example can be found in *** $makefile_example __EXPLAIN }

sub config3() { my $p = sub { my $x = $_[0]; my $y = ! defined $x ? "undef" : $x =~ m!^\d+$! ? $x # int : $x =~ m/^\["']/ ? $x # quoted string : ('"' . ($x =~ s/(["@])/\\$1/gr) . '"'); # do quote string \$y; };

my $dist         = $makefile->{DISTDIR};
my $distro       = $makefile->{NAME} =~ s/\:\:/-/gr;

my $html_output  = $makefile->{HTML_OUTPUT}  // '';
my $html_docroot = $makefile->{HTML_DOCROOT} // '/';
my $email        = $makefile->{EMAIL}
  || ($meta->{author} && $meta->{author} =~ m/ \<(.*?)\>/ ? $1 : undef);

print <<__HEAD;
# This is an attempt to automatically convert you configuration parameters.
# More docs: https://github.com/markov2/perl5-OODoc/wiki/oodist-config

# Use command 'oodist' to produce your whole software release. __HEAD

if($html_output) {
	my $webpages = $html_output =~ s/\Q$html_docroot\E$//r;
	print "my \$webpages = ${ $p->($webpages) }\n";
}

my $git          = qx(git config --get remote.origin.url 2>/dev/null);
if(defined $git && length $git)
{	chomp $git;
	$git =~ s/\.git$//;
	$git =~ s,^.*?:,https://github.com/, if $git =~ m!^git\@github.com!;
}
else
{	$git = 'https://github.com/XXX';
}

my $publish      = $dist ? (dirname $dist) : "../public_html/\L$distro";

print <<__CONFIG;
my \$git      = ${ $p->($git) };
my \$publish  = ${ $p->($publish) };
my \$homepage = ${ $p->($makefile->{WEBSITE} // 'https://XXX') };

my \%oodist = ( oodoc_version => $ooversion, first_year => ${ $p->($makefile->{FIRST_YEAR} || (strftime "%Y", localtime)) }, email => ${ $p->($email) }, __CONFIG

my @include = map "\t\t'$_',\n", sort split /[\: ]+/, $makefile->{EXTENDS} // '';
print <<__INCLUDE;

include  => [\n@include\t],

use      => [\n\t],
__INCLUDE

my @links   = map "\t\t'$_',\n", sort split /[\: ]+/, $makefile->{SKIP_LINKS} // '';
my $pmhead  = $makefile->{PMHEAD} // (-f 'PMHEAD.txt'  ? 'PMHEAD.txt'  : undef);

print <<__PARSER;

parser   => {
	syntax         => 'markov',
	skip_links     => [ @links],
	pmhead         => ${ $p->($pmhead) },
},
__PARSER

print <<__RELEASE;

tests    => {
},

release  => {
	publish        => "\$publish/${$dist ? \basename $dist : \'releases' }",
},
__RELEASE

# Raw output is not interesting since we have git.
if(my $r = $makefile->{RAWDIR}) { print <<__RAW }

raw      => {
	publish        => "\$publish/${ \basename $r }",
},
__RAW

my @generate;
my $podtail = $makefile->{PODTAIL} // (-f 'PODTAIL.txt' ? 'PODTAIL.txt' : undef);

push @generate, <<__POD;
  {	# Add real pod to the releases
	format         => 'pod3',
	podtail        => ${ $p->($podtail) },
  },
__POD

push @generate, $html_output ? <<__HTML : <<'__MAY_HTML';
  {	format         => 'html',
	webpages       => "\$webpages${ $html_docroot eq '/' ? \'' : \$html_docroot },
	publish        => "\$publish/${ \basename $makefile->{HTML_PACKAGE}}",
	docroot        => ${ $p->($html_docroot) },
	templates      => ${ $p->($makefile->{HTML_TEMPLATES}  // 'html') },
	stylesheet     => ${ $p->($makefile->{HTML_STYLESHEET} // '/oodoc.css') },
  },
__HTML
  # You may add HTML formatters here.
__MAY_HTML

push @generate, <<'__MAY_EXPORT';
  # You may add exporter configurations here.
__MAY_EXPORT

print <<__TAIL;

generate => [\n@generate\t],
);

__TAIL }

sub merge3() { print <<__MERGE;

WriteMakefile ... META_MERGE => { 'meta-spec' => { version => 2 }, resources => { repository => { type => 'git', url => "\$git.git", web => \$git, }, homepage => \$homepage, license => [ 'http//dev.perl.org/licenses/' ], }, prereqs => { develop => { requires => { 'OODoc' => $OODoc::VERSION, } }, test => { requires => { 'Test::More' => 1.00, 'Test::Pod' => 1.00, } }, },

	# You may use multiple set-ups, see "oodist --make"
	x_oodist => \\\%oodist,
};
__MERGE
}

### ### introduce2oodoc() # Help people configure OODoc

sub introduce2oodoc() { print <<__EXPLAIN; To start with OODoc, on an existing release which may already contain standard POD, do:

===> 1. Add the output of this to the top of your Makefile.PL:

    $0 --config3
    (hint:  vi Makefile.PL   :r! oodist --config3)

===> 2. Configure that template.  See the OODoc Wiki at
        https://github.com/markov2/perl5-OODoc/wiki/oodist-config

===> 2. Merge the following into your "WriteMakefile" call in Makefile.PL

    $0 --merge3
    (hint:  vi Makefile.PL   :r! oodist --merge3)

* Merge the above with your Makefile.PL. Be smart with it. A documented * example with more options can be found in * $makefile_example

__EXPLAIN }

__END__

NAME

oodist - create perl distributions with OODoc

SYNOPSIS

cd $yourmodule
oodist [OPTIONS]

  OPTION:                 DEFAULT:
  --all                     produce everything except '--no-'
  --dist    or --no-dist    package release
  --exports or --no-exports produce all exports
  --export <name>           produce a JSON dump of the parsed docs
  --html    or --no-html    produce html
  --pod     or --no-pod     produce pod in the release
  --raw     or --no-raw     produce package with raw files
  --tests   or --no-tests   run tests

 OPTIONS general:
  --make     | -m <tag>     select configuration in MYMETA.json
  --verbose  | -v  -vv      be verbose or even more verbose
  --workdir  | -w <dir>     /tmp/<distname>

 OPTIONS to help convert OODoc2 to OODoc3 style configuration
  --config3                 settings rewrite
  --merge3                  merge meta block
  --starter                 show instructions how to init OODoc use

DESCRIPTION

This script produces documentation from Perl sources, using the OODoc module. It can produce better POD, HTML via templates, and exports from parsed manuals. As source, it can use real POD or Markov pod with Object Orientation support extensions. You may also write your own documentation parsers, formatters, and exporters.

Configuring

Since version 3.0, OODoc requires the configuration to end-up in the MYMETA.json file, usually via META_MERGE in the Makefile.PL. You can best have a look at the Makefile.PL of the OODoc package for an example...

When you have used OODoc before 3.0, then a nice suggestion is produced on your first call to oodist.

Component enabling options

The process is controlled by four main options. All options are by default on.

--all Create all products, except when expliticly disable with --no-. This is the default, unless any product is enabled explicitly.
--dist or --no-dist Create a distribution, containing all files from the MANIFEST plus produced files. Even with nodist, you will end-up with these archives in the working directory (see --workdir).
--exports or --no-exports Produce all exports.
--export name Create a documentation tree (kind of AST) in a certain serialization type. At the moment, only json serialization is supported. You may multiple export definitions.
--html or --no-html Create html manual pages. The --html-templates options must point to an existing directory (defaults to the html/ sub-directory).
--pod or --no-pod or --nopod Produce pod files in the working directory and in the distribution.
--raw or --no-raw Create a package which contains the files which are needed to produce the distribution: the pm files still including the oodoc markup.
--tests or --no-tests Run the tests on the produced release, before packaging. =back

General options

The other options in detail

--make | -m <tag> By default, the MYMETA.json configuration at x_oodist or oodist is taken. But you may want different configurations, for instance a development version which is much simpler (hence easier to understand).
--starter Show instructions how to add OODoc to your existing module. This will also be shown when oodist is called where no configuration can be detected automatically.
--verbose | -v | -vv Shows what happens during the process. More v's will result in more output.
--workdir | -w <dir> The processing will take place in a seperate directory: the stripped pm's and produced pod files will end-up there.

If not provided, that directory will be named after the project, and located in $ENV{TMPDIR}, which defaults to /tmp. For instance /tmp/OODoc/