The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

#!/usr/bin/perl
use 5.026;
use strict;
use Cwd;
use File::ShareDir qw(dist_dir);
use File::Spec::Functions qw(abs2rel canonpath catfile updir);
use FindBin;
our $VERSION = $Dist::Setup::VERSION; ## no critic (ProhibitComplexVersion, RequireConstantVersion)
my $data_dir = catfile($FindBin::Bin, updir(), 'data');
if (!-d $data_dir) {
# If the directory does not exist next to the binary, we’re assuming that
# the tool was `make install`-ed.
$data_dir = dist_dir('Dist-Setup');
}
# We're using a relative path here because this works better across OSes
# (e.g. on Cygwin when talking to some Windows binaries).
$data_dir = abs2rel(canonpath($data_dir));
my $target_dir = abs2rel(canonpath(getcwd()));
Dist::Setup::setup($data_dir, $target_dir);
__END__
=pod
=encoding utf8
=head1 NAME
perl_dist_setup – Simple, opinionated tool to set up a Perl distribution directory.
=head1 SYNOPSIS
mkdir project_name
cd project_name
git init
perl_dist_setup
$(EDITOR) dist_setup.conf
perl_dist_setup
=head1 DESCRIPTION
=head2 Overview
This tool has no command line options as of now. You should run it from the root
of your project directory, which should be a Git repository. The first time the
tool is run (or if the F<dist_setup.conf> file does not exist) the tool will
create a template configuration file.
You should then edit this file, following the explanatory comments that it
contains. Once the config file is edited, you can run C<perl_dist_setup> again
and it will set up the distribution.
Most of the files created by C<perl_dist_setup> have guard comments at the top
and bottom of the file. You can customize these files by adding more content
after the bottom comment. That content will be kept when the tool is run again
to update the files (for example after you update to a newer version of
C<perl_dist_setup>).
Some files don’t have these comments (because they are in a format that don’t
support them), these files can’t be modified.
You can find below in the L</"FILES"> section a description of all the generated
files and how they can be customized.
=head2 Features
=head3 Make targets
The F<Makefile> generated by the tool has the following custom targets:
=over 4
=item - alltest
Runs all the tests of the distribution, including the extended tests. This works
by setting the C<EXTENDED_TESTING> environment variable, as specified by the
=item - cover
Generate a code coverage report from your test suite.
=item - critic
Run the code through Perl Critic using the L<Test2::Tools::PerlCritic> module
and display the policy violations.
=item - distupload
Test and then upload the distribution to CPAN. You will be queried on the
command line for your PAUSE username and password, unless a F<~/.pause> file
exists following the syntax documented in the
manual provides these values.
=item - exe
Converts each of the scripts specified by C<exe_files> in the F<dist_setup.conf>
file into a self-extracting executable using C<pp> from L<PAR::Packer>. This is
quite experimental and lack many configuration options that might be needed for
advanced usages. In particular this will not work if the programs relies on a
shared folder (as specified by the C<data_dir> option). The programs are written
in the F<build> directory.
=item - pod2html
Converts the POD documentation embedded in all the F<.pm> files under F<lib/>
as well as in all the scripts specified by C<exe_files> in the
F<dist_setup.conf> file into HTML. The output files are written in the
F<pod2html> directory in the project folder.
=item - rawcritic
Execute your code through C<perlcritic> directly, without the violation grouping
done by the L<Test2::Tools::PerlCritic> module as when running C<make critic>.
=item - spelling
Run C<aspell> interactively to spell-check the distribution. For each misspelled
word, you can either fix their spelling, or add them to a local F<.aspelldict>
dictionary file, which should be stored in your source version control system.
=item - tidy
Run the code through L<perltidy>. It is recommended to commit your code to your
source version control system first, if you want to be able to use it to show
you the diff of the formatting.
=back
=head1 FILES
Below is a description of the files created by the tool and how they can be
customized.
=head2 Changes
The F<Changes> file is special because it is generated only once by the program
(if it does not yet exist) and is never touched after that. So you can modify it
however you want.
The L<CPAN::Changes::Spec> page has the description of the required format for
this file.
=head2 cpanfile
This file list all the dependencies of the project. The template file has the
dependencies required due to the setup created by C<perl_dist_setup> but you can
add any other required dependencies at the end of the file.
The L<cpanfile> page has the description of the required format for this file.
Note that the F<001-cpanfile.t> test, created by C<perl_dist_setup>, tries to
catch missing dependencies from the F<cpanfile> file.
=head2 LICENSE
For now the license file is not modifiable and uses an MIT License. If you need
support for other licenses, please file a feature-request to the project.
=head2 Makefile.PL
This file uses C<ExtUtils::MakeMaker> to create the F<Makefile> for the
distribution. The main way to extend it is to add more content to put in the
output F<Makefile>. This can be achieved by writing a C<postamble> method at the
end of the file, like so:
sub postamble {
return <<"MAKE_FRAGMENT";
my_target: dependencies
\trecipe
MAKE_FRAGMENT
}
=head2 MANIFEST.SKIP
This file lists regex matching files that should not be embedded in the
distribution tarball that is uploaded to CPAN. You can add more regex at the
end.
=head2 .gitignore
This file lists regex matching files that should not be stored under the Git
version control. You can add more regex at the end.
=head2 .perlcriticrc
This file contains the default rules that will be applied by L<perlcritic>. You
can override these rules at the end of the file (adding or removing policies and
overriding the configuration of other policies).
The default policy is pretty strict. An easy way to make it be less strict is
to increase the minimum severity above its default value of 2. For example by
adding the following line at the end of the file:
severity = 2
=head2 .perltidyrc
This file has the default formatting rules for L<perltidy>. You can override
them at the end of the file.
In the future, there might be different I<theme> supported by C<perl_dist_setup>
to provide other styles. If you already have a C<.perltidyrc> file with
significantly different style from ours, feel free to send a feature request for
this distribution, for inclusion of your style file.
=head2 t/
This directory contains various standard tests for the distribution. While it
is technically possible to add more content at the end of the file, this is not
supported for now. Instead you should just add your own test files.
=over 4
=item - 000-load.t
A test that the main module of the distribution can be loaded and correctly
returns a C<true> value.
=item - 001-cpanfile.t
A test that the syntax of the F<cpanfile> is valid and that it contains all the
modules that are used by the distribution (not that some of them may be missed).
This is based on the L<Test::CPANfile> module.
=item - 001-perlcritic.t
Checks that all the files validate the Perl Critic policies listed in the
F<.perlcriticrc> file. In particular, one of these policies also tests that the
files format are coherent with the F<.perltidyrc> Perl Tidy configuration.
You can run C<make critic> to execute this test manually and C<make tidy> to
automatically format the code.
=item - 001-podsyntax.t
Checks that the syntax of the POD embedded in all the Perl sources is correct.
=item - 001-spelling.t
Spellcheck your code. You can run C<aspell> interactively over your code with
C<make spelling> to either fix your spelling and/or build a F<.aspelldict> file
containing the words that are not otherwise known to the aspell dictionary.
=back
=head2 .devcontainer/
This directory contains the necessary setup to use a GitHub Dev Container
development environment (also known as codespace). This directory is created
only if the C<github.use_devcontainer> option is set in the F<dist_setup.conf>
file.
It contains the following 3 files:
=over 4
=item - devcontainer.json
This file can’t be modified and point to the other two files.
=item - Dockerfile
This file create the initial setup of the container. You can customize it by
adding more commands at the end of the file, typically more C<RUN> commands to
execute actions at the creation of the container.
By default, the file install some binaries needed by the distribution (like
C<aspell>, C<cpanm>, and C<cpan-upload>) as well as some tools commonly needed
development tools (C<perlbrew>).
Note that, when this file is run, the environment does not yet have access to
the content of your distribution.
=item - update_content.sh
This script is run after the content of the container is modified (that is, once
your code is available). It installs all the dependencies of your distribution.
If the C<PAUSE_USERNAME> and C<PAUSE_PASSWORD> environment variables exist,
t also creates a F<~/.pause> file that can be used by the
to automatically upload your distribution to CPAN. These environment variables
are typically created by setting the username and password as GitHub I<secrets>
shared with your repository.
This file can be customized by adding more command lines at the bottom.
=back
=head2 .github/
This directory is only created if the C<github.use_ci> option is set in the
F<dist_setup.conf> file. It contains a GitHub workflow that will run CI tests
for the distribution.
While technically the workflow file can be customized by adding more content at
its end, there is probably no scenario to do that.