Minilla(3pm)

πŸ“¦
version 3.1.29 Β· 5 versions
, in ubuntu resolute, ubuntu stonking

πŸ’– Minilla β€” the manual page, but make it a group chat πŸ’–

Manual name: Minilla(3pm) β€” User Contributed Perl Documentation. Yeah bestie, this is the one.


✨ NAME ✨

Minilla β€” a CPAN module authoring tool. That's the whole name section, short and slay. πŸ’…


πŸŽ€ SYNOPSIS πŸŽ€

Here's the whole vibe in one code block, no cap:

minil new     - Create a new dist
minil test    - Run test cases
minil dist    - Make your dist tarball
minil install - Install your dist
minil release - Release your dist to CPAN
minil run     - Run arbitrary commands against build dir

Six commands. That's the whole tool. Iconic behavior honestly. πŸ’œ


🌸 DESCRIPTION 🌸

Okay so Minilla is a CPAN module authoring tool, fr fr. What it actually does is hand you the minil command so you can go author a whole CPAN distribution with it. Like, that's the job. That's the assignment.

And here's the whole concept, mathematically:

(M::I - inc) + shipit + (dzil - plugins)

It's giving "take the good parts of everything and yeet the annoying parts." Periodt. πŸ‘‘


πŸ¦‹ CONVENTION πŸ¦‹

So, like I said above β€” Minilla is opinionated. It has a bold assumption and convention going on, and here's the list. These are almost compatible with its sister project Dist::Milla, iykyk.

  • Your modules are written in Pure Perl and are located in lib/.
  • Your executable files are in script/ directory, if any.
  • Your module is maintained with Git, git ls-files matches with what you will release and your remote is named origin.
  • Your module has a static list of prerequisites that can be described in cpanfile.
  • Your module has a Changes file.
  • Your module requires at least perl 5.6.

That's the whole contract bestie, learn it and you're golden. ⭐


🌈 GETTING STARTED 🌈

Okay okay okay, here's the entire lifecycle, and I mean entire:

# First time only
% cpanm --with-recommends Minilla
# Minilla has only a few deps. It should be very quick

# Make a new distribution
% minil new Dist-Name
% cd Dist-Name/

# Git commit
% git commit -m "initial commit"

# Hack your code!
% $EDITOR lib/Dist/Name.pm t/dist-name.t cpanfile

# Done? Test and release it!
% minil release

It's that easy. Literally that easy. πŸ˜­πŸ’–

And listen β€” you already have distributions built with Module::Install, Module::Build, Dist::Zilla or ShipIt? Migrating is also trivial, no stress. See "MIGRATING" in Minilla::Tutorial for more details. 🫢


πŸ‘‘ WHY MINILLA? πŸ‘‘

πŸ”₯ Repository managed by Minilla is git install ready.

The repository created and managed by Minilla is git install ready. You can install the library by cpanm git://.... Yes really.

And of course, you can install Minilla from cpanm git://github.com/tokuhirom/Minilla.git. Self-hosting queen. πŸ’…

🧚 Minilla is built on small libraries.

Minilla is built on only few small libraries. You can install Minilla without a huge list of dependencies to heavy modules. No dependency avalanche, we don't do that here. ✨

πŸ’€ And, what is Minilla?

Okay this is the fun part:

Minilla is a Kaiju (Japanese giant monster) from the Godzilla series of films and is the first of several young Godzillas.
https://en.wikipedia.org/wiki/Minilla

It's named after a baby Godzilla. Main character energy from day one. πŸ¦–


⭐ Minilla's release process ⭐

Here's the whole pipeline, step by step, in order. Minilla's release process is the following:

πŸŽ€ CheckUntrackedFiles

Checking git's untracked files. If there's untracked files, minilla will abort. Clean your room first bestie, no stray files allowed. πŸ™ˆ

πŸŽ€ CheckOrigin

This step will run the git remote. If there's no remote, minilla will abort. You need somewhere to push to, obviously. 🌸

πŸŽ€ CheckReleaseBranch

Checking git's current branch is release.branch key in minil.toml. If no match, minilla will abort. Wrong branch? Abort. Sorry babe. πŸ’…

πŸŽ€ BumpVersion

Minilla will show 'Next Release?' prompt. You can input next version number.

After that, minilla rewrites version numbers in **/*.pm, **/*.pl, and a script file contains perl-ish shebang. It's going through your whole codebase and updating numbers, that's the vibe. ✨

πŸŽ€ CheckChanges

You need to write Changes file. Your module's users need to know the difference between versions. Like, that's just being a considerate author.

Minilla's Changes file includes {{$NEXT}} next version indicator. You should put update informations after that. Yes, "informations". That's what it says. We keep it. 😌

πŸŽ€ RegenerateFiles

In this step, minilla will regenerate META.json, README.md and (Makefile.PL|Build.PL). Fresh files, regenerated, slay. 🧚

πŸŽ€ RunHooks

This step runs commands listed on release.hooks key in minil.toml. Your hooks, your rules.

πŸŽ€ DistTest

This script runs test cases in clean working directory with "$ENV{RELEASE_TESTING} = 1". Clean directory, real testing conditions, no shortcuts. πŸ”₯

πŸŽ€ MakeDist

Make distribution tar ball. That's it, that's the step. πŸ“¦

πŸŽ€ UploadToCPAN

Upload your module to CPAN. The moment. The main event. The whole reason we're here. πŸ‘‘

πŸŽ€ RewriteChanges

Rewrite Changes file. Minilla replaces "{{$NEXT}}" with released version number and current date & time. And put "{{$NEXT}}" on the first line. So it's always ready for the next next version. Iconic. πŸ’œ

πŸŽ€ Commit

Commit current directory with automatically generated commit message from Changes file. And push it to origin. Auto-generated message, no thinking required. 🫢

πŸŽ€ Tag

Create new git tag and push it to origin. And that's the end of the pipeline... for this part, anyway. 🌈


to be continued, bestie... πŸ’–

✨ CONFIGURATION ✨

okay so bestie, Minilla is fully committed to the Convention over Configuration lifestyle. it just knows what you want most of the time, no cap. πŸ’…

but obviously you can still write your own configs into a minil.toml file, in TOML format (yes that TOML, the one at https://github.com/toml-lang/toml). Minilla reads the minil.toml file in the root directory of your project. πŸ“‚

here's every single key you can put in there, no skips:


  • name β€” you can write 'name' instead of letting Minilla auto-detect the project name out of the directory name. very much a glow-up move. ✨
  • module_maker β€” Minilla supports three module building mechanisms. Module::Build::Tiny is the default one, and Module::Build or ExtUtils::MakeMaker are the alternatives. (see also the FAQ section in this document, bestie, iykyk.)
module_maker="ModuleBuild"
  • readme_from β€” you can specify the file to generate the README.md from. it's a main module path by default.
readme_from="lib/My/Foo.pod"
  • tag_format β€” the format of the tag to apply. Defaults to %v. and %v will replace with the distribution version.
tag_format="perl/%v"
  • abstract_from β€” grab the abstract information from the file that contains pod.
abstract_from="lib/My/Foo.pod"
  • authors_from β€” grab the authors information from the file that contains pod.
authors_from="lib/My/Foo.pod"
  • authority β€” sets the x_authority attribute on META. see https://jawnsy.wordpress.com/2011/02/20/what-is-x_authority/ for more details. Note that now PAUSE itself copies the permissions from the "main module" to any new modules entering the index for the first time, so you don't need to set this attribute anymore. periodt.
authority = "cpan:TOKUHIROM"
  • allow_pureperl β€” a boolean indicating the module is still functional without its XS parts. when an XS module is built with --pureperl_only, it will otherwise fail. it affects Module::Build 0.4005+ only.
allow_pureperl=1
  • no_github_issues β€” Minilla sets the bugtracker to github/GitLab's issue tracker by default. but if you wanna use RT instead, you set this variable. πŸŽ€
no_github_issues=true
  • no_index β€” Minilla sets META.json's no_index as "directory => ['t', 'xt', 'inc', 'share', 'eg', 'examples', 'author', 'builder']" by default. but if you want to change them, you can set this section variable. and heads up: if this section is set, the specified variables are only used β€” the default settings are not merged, fr fr.
[no_index]
directory=['t', 'xt', 'tools']
  • c_source β€” a directory which contains C source files that the rest of the build may depend on. any ".c" files in the directory will be compiled to object files. the directory will be added to the search path during the compilation and linking phases of any C or XS files. πŸ”₯
c_source = ['src']
  • script_files β€” Minilla sets the install script files as ['script/*', 'bin/*'] by default.
script_files = ['bin/foo', 'script/*']
Note. this option doesn't affect anything if you are using ModuleBuildTiny or ExtUtilsMakeMaker, for now. and if you are using ModuleBuildTiny, you MUST put scripts in the script/ directory. non-negotiable bestie.
  • tap_harness_args (EXPERIMENTAL) β€” these parameters get passed to TAP::Harness when running tests. see the TAP::Harness documentation for details.
[tap_harness_args]
jobs=19
  • license β€” you can specify your favorite license in minil.toml. the license key is the same as the CPAN Meta spec 2.0. see CPAN::Meta::Spec. πŸ’œ
license="artistic_2"
  • badges β€” embed badge images (e.g. Travis-CI) into README.md. it ought to be an array and each element must be a service name. right now, the supported services are 'travis-ci.com', 'travis-ci.org', 'circleci', 'appveyor', 'coveralls', 'codecov', 'gitter', 'metacpan', 'kritika' 'github-actions', 'gitlab-pipeline' and 'gitlab-coverage'.
badges = ['travis-ci.com', 'travis-ci.org', 'circleci', 'appveyor', 'coveralls', 'codecov', 'gitter', 'metacpan', 'kritika', 'github-actions/$workflow_file', 'gitlab-pipeline', 'gitlab-coverage']

you can send additional parameters as required by your CI provider by including a query string along with your service name: e.g. "travis?token=[YOUR_TOKEN_GOES_HERE]&branch=dev"

  • PL_files β€” specify the PL files.
[PL_files]
lib/Foo/Bar.pm.PL="lib/Foo/Bar.pm"

this option is not supported by Minilla::ModuleMaker::ModuleBuildTiny.

Note. MBTiny executes *.PL files by default.
  • build.build_class β€” specify a custom Module::Build subclass.
[build]
build_class = "builder::MyBuilder"
  • XSUtil.needs_compiler_c99 β€” you can specify the "needs_compiler_c99" parameter of Module::Build::XSUtil.
[XSUtil]
needs_compiler_c99 = 1
  • XSUtil.needs_compiler_cpp β€” you can specify the "needs_compiler_cpp" parameter of Module::Build::XSUtil.
[XSUtil]
needs_compiler_cpp = 1
  • XSUtil.generate_ppport_h β€” you can specify the "generate_ppport_h" parameter of Module::Build::XSUtil.
[XSUtil]
generate_ppport_h = 1
  • XSUtil.generate_xshelper_h β€” you can specify the "generate_xshelper_h" parameter of Module::Build::XSUtil.
[XSUtil]
generate_xshelper_h = 1
  • XSUtil.cc_warnings β€” you can specify the "cc_warnings" parameter of Module::Build::XSUtil.
[XSUtil]
cc_warnings = 1
  • FileGatherer.exclude_match β€” nothing by default. to exclude certain files from being gathered into the dist, use the "exclude_match" option. files matching the patterns are not gathered. πŸ¦‹
[FileGatherer]
exclude_match = ['^author_tools/.*']
  • FileGatherer.include_dotfiles β€” by default, files will not be included in the dist if they begin with a dot. this goes both for files and for directories. in almost all cases, the default value (false) is correct.
[FileGatherer]
include_dotfiles = false
  • release.pause_config β€” by setting this value to another PAUSE configuration file (see "CONFIGURATION" in cpan-upload for the details), it's possible to use another PAUSE server (or anything good enough to mimic its upload process) for the release step.
[release]
pause_config = "/path/to/some/.pause"

to do so, simply add an "upload_uri" entry in your file pointing to the alternate PAUSE server, i.e:

upload_uri http://127.0.0.1:5000/pause/authenquery

if you instantly launch your origin upload server as DarkPAN, see OrePAN2::Server. πŸ‘‘

  • release.do_not_upload_to_cpan β€” this variable disables the CPAN upload feature.
[release]
do_not_upload_to_cpan=true
  • release.hooks β€” commands that are specified by this option will be executed when releasing. if the result of the commands is not successful, it will abort. 😭
[release]
hooks = [
    "COMMAND1",
    "COMMAND2"
]
  • release.branch β€” if this value does not match the current branch, it will abort.
[release]
branch = "main"
  • unsupported.os β€” by setting this value, you add unsupported OS checks for (Build.PL|Makefile.PL).
[unsupported]
os = [
    "MSWin32",
    "darwin"
]
  • ReleaseTest.MinimumVersion β€” if you set this key to false, Minilla will not generate 'xt/minilla/minimum_version.t'.
[ReleaseTest]
MinimumVersion = false
  • requires_external_bin β€” the "requires_external_bin" command takes the name of a system command or program. the build fails if the command does not exist.
requires_external_bin=['tar']
  • markdown_maker β€” use a different module to generate "README.md" from your pod. this module must subclass Pod::Markdown.
markdown_maker = "Pod::Markdown::Github"
  • markdown_maker_opts β€” specify arguments to pass to "markdown_maker"'s new() constructor.
[markdown_maker_opts]
local_module_re = "^MyApp::"
local_module_url_prefix = "https://example.org/perl/pod/"
  • Metadata β€” add arbitrary keys to "META.json"/"META.yml".
[Metadata]
x_deprecated = 1
  • static_install β€” if static_install = "auto" (or nothing is specified at all), then minil tries to detect whether distributions are ready for static install or not, and sets "x_static_install" in the META files accordingly. you can also set static_install = 0/1 explicitly, and then minil will respect it.
static_install = "auto"

for static install itself, please refer to https://github.com/Perl-Toolchain-Gang/cpan-static. 🌈

πŸ’– FAQ πŸ’–

✨ How can I manage contributors section?

okay so Minilla just aggregates your contributors list by running this, fr fr:

git log --format="%aN <%aE>" | sort | uniq

And if the same gorgeous human shows up under like five different names/emails, you merge the accounts with a .mailmap file πŸ’…. The deets live over at https://www.kernel.org/pub/software/scm/git/docs/git-shortlog.html β€” go read it, it's giving documentation.

✨ Why don't you provide plug-in support?

bestie, if you want a pluggable tool... it already exists. It's called Dist::Zilla :P

But lowkey if you love how Minilla behaves and you really want something pluggable, you can use Dist::Milla β€” Minilla's sister project πŸ‘―. Dist::Milla's behavior is almost identical to Minilla's. Almost. Iconic sibling energy.

✨ Why does minil only support git?

ngl, the take here is: git is the best VC for CPAN modules, for now. That's the whole vibe.

If you wanna use another version control system, you can probably use Dist::Milla. πŸ¦‹

✨ And why...

Yes. You can use Dist::Milla. 😭 periodt.

✨ Should I add (META.json|Build.PL) to repository?

Yes. You literally need to add it to make your git repo installable via cpanm. No cap, it's required.

✨ How do I manage ppport.h?

Honestly? Is there a reason to remove ppport.h from repo? πŸ€” that's the whole question, bestie.

✨ How can I install script files?

Your executables must be in the script/ directory. That's it, that's the rule. πŸ“βœ¨

✨ How to switch from Module::Install/Module::Build/Dist::Zilla?

There's an experimental minil migrate sub-command for exactly this 🧚. See Minilla::CLI::Migrate for more details.

✨ How should I manage the files you do not want to upload to CPAN?

Please use FileGatherer.exclude_match to ignore files when building the upload tar ball πŸŽ€.

You can also use a MANIFEST.SKIP file for ignoring files β€” ref. ExtUtils::Manifest.

✨ How do I use Module::Build::Tiny with Minilla?

Minilla supports Module::Build::Tiny and uses it as the default installer since v1.0.0 πŸ‘‘.

If you want to migrate an existing project that was created before Minilla v1.0, you need to rewrite your minil.toml file. Add this line:

module_maker="ModuleBuildTiny"

✨ How do I use Module::Build with Minilla?

If you wanna create a new project with Module::Build, run the command like this:

% minil new -p ModuleBuild My::Awesome::Module

✨ How do I use ExtUtils::MakeMaker with Minilla?

Minilla v2.1.0+ supports EUMM β€” and yes it's EXPERIMENTAL 🫣.

You need to rewrite your minil.toml file and add this line:

module_maker="ExtUtilsMakeMaker"

(There is no profile, yet. Patches welcome. 🫢)

I don't suggest to use this module... But you can use this option for maintaining primitive modules like Test::TCP.

✨ Ho do I support Perl 5.6?

EUMM can run on Perl 5.6. Write the following statement in your minil.toml file:

module_maker="ExtUtilsMakeMaker"

🌈 bash/zsh completion 🌈

Minilla provides bash and zsh completion files under the contrib/ directory. Tab-tab-tab your way to glory, bestie ✨.


πŸ‘‘ AUTHORS πŸ‘‘

  • Tokuhiro Matsuno < tokuhirom@gmail.com >
  • Tatsuhiko Miyagawa

🫢 THANKS TO 🫢

RJBS, the author of Dist::Zilla. Dist::Zilla points CPAN authorizing tool. Absolute legend behavior πŸ’œ.


πŸ”₯ SEE ALSO πŸ”₯

(this section is literally empty in the original β€” no entries, nothing, nada. leaving it here so you know it's not just me being lazy πŸ’€)


πŸ“œ LICENSE πŸ“œ

Copyright (C) Tokuhiro Matsuno

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


okay bestie that's the whole page, we made it to the end πŸŽ‰ this lil beauty ships as Minilla(3pm), perl v5.40.1, dated 2025-12-21 β€” go forth and release your modules, you absolute main character πŸŒΈπŸ’–βœ¨

πŸ“¦ where this page comes from