All about MANIFEST.SKIP

The MANIFEST.SKIP file lets you specify what shouldn’t be in a distribution instead of what should be (the MANIFEST). Inside MANIFEST.SKIP, you list one Perl pattern per line to specify what to exclude, and then use that file to generate MANIFEST.

For example, you can exclude backup files and the Git directory:

\.bak$
\.git$

You update MANIFEST with the manifest target, which runs the the mkmanifest subroutine from ExtUtils::Manifest:

% perl Makefile.PL

% make manifest
/usr/bin/perl "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
Added to MANIFEST: Changes
Added to MANIFEST: examples/README
Added to MANIFEST: lib/Module.pm
Added to MANIFEST: LICENSE
Added to MANIFEST: Makefile.PL
Added to MANIFEST: MANIFEST
Added to MANIFEST: MANIFEST.SKIP
Added to MANIFEST: README
Added to MANIFEST: t/load.t
Added to MANIFEST: t/pod.t
Added to MANIFEST: t/pod_coverage.t

This goes through all the files in the distribution (the current directory and all subdirectories, recursively), filters out the ones matched by the patterns in MANIFEST.SKIP, and adds the rest to MANIFEST.

If it finds lines in MANIFEST that match a pattern in MANIFEST.SKIP (perhaps because you edited the file by hand), the t

% make manifest
/usr/bin/perl "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
Removed from MANIFEST: .git

There is a slight problem that it doesn’t remove from MANIFEST any files that have disappeared, such as renamed tests or data files.

The trick, however, is to get the right patterns in MANIFEST.SKIP. You could do that through trial and error, but ExtUtils::Manifest provides a way to include a default set with a special directive:

#!include_default

Right next to the ExtUtils::Manifest there’s the default MANIFEST.SKIP. Find where you have that module then look in that directory:

% perl -l ExtUtils::Manifest
/System/Library/Perl/5.16/ExtUtils/Manifest.pm

% more /System/Library/Perl/5.16/ExtUtils/MANIFEST.SKIP
# Avoid version control files.
\bRCS\b
\bCVS\b
\bSCCS\b
,v$
\B\.svn\b
\B\.git\b
\B\.gitignore\b
\b_darcs\b
\B\.cvsignore$
...

Those are just the defaults, which don’t know anything about your local setup and the special files that you might want to exclude. You can load another file. Perhaps you want to exclude the same things across all of our projects:

#!include /path/to/some/file

When you run the manifest target again, ExtUtils::Manifest replaces these directives with the contents of their files. The start and stop of the imported patterns are marked:

#!start included /System/Library/Perl/5.16/ExtUtils/MANIFEST.SKIP
# Avoid version control files.
\bRCS\b
\bCVS\b
...
# Avoid MYMETA files
^MYMETA\.
#!end included /System/Library/Perl/5.16/ExtUtils/MANIFEST.SKIP

Once included, however, these sections aren’t updated if the those files change.

When you run the dist target, all of the files listed in MANIFEST are archived in the distribution file. The output shows the Perl one-liner that does the work to copy those:

% make dist
...
perl "-MExtUtils::Manifest=manicopy,maniread" \
    -e "manicopy(maniread(),'Some-Module-1.23', 'best');"
...

Before you release that file though, you should also run the disttest target. That creates a new directory with just the files from MANIFEST, changes to that directory, and runs the tests. This ferrets out missing files that you might not miss as you work in your repository.

Leave a Reply

Your email address will not be published. Required fields are marked *