Skip to content

Instantly share code, notes, and snippets.

@netsensei
Last active September 1, 2017 09:06
Show Gist options
  • Save netsensei/e019fdbc413e4525e2120359e140526d to your computer and use it in GitHub Desktop.
Save netsensei/e019fdbc413e4525e2120359e140526d to your computer and use it in GitHub Desktop.
Bootstrap a Catmandu module

Catmandu development

Okay. So you want to build your own Catmandu module? This is a bit of documentation that should help you bootstrap your development environment.

Prerequisites

PERL

Catmandu depends on Perl. You can start out working with system Perl that came with your OS. But since you want to do active development, it's recommended to go with an alternate installation and leave the default alone. This is especially true if you work on OSX or Windows!

Plenv will do that for you. This tool will allow you to install and manage different versions of Perl in your home folder seemingly. So, install that and switch to a suitable perl version.

# Install plenv from https://github.com/tokuhirom/plenv
git clone https://github.com/tokuhirom/plenv.git ~/.plenv
echo 'export PATH="$HOME/.plenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(plenv init -)"' >> ~/.bash_profile
exec $SHELL -l
git clone https://github.com/tokuhirom/Perl-Build.git ~/.plenv/plugins/perl-build/
# Install a modern Perl
plenv install 5.22.0
plenv rehash
cpan App::cpanminus
# Install catmandu
cpanm Catmandu Catmandu::MARC
plenv rehash

OSX remarks

The installation might complain about not being able to install the XML::LibXML module due to a missing libxml2. Here are a few pointers:

  • Make sure to install libxml2 and it's dependencies using homebrew: brew install libxml2 libxslt libiconv
  • In XCode 8, a linker file went AWOL which could cause issues when compiling. I had to downgrade XCode to a previous version (for the time being).
  • However, you do need the developer tools. Especially on El Capitan, since /usr/include was removed. So do a xcode-select --install after installing XCode. This will also give you the libxml header files you'll need to compile the Perl module.
  • Make sure you've added the /usr/include path to the @inc variable. Do this with export PERL5LIB=/usr/include/ (optionally: add this to your .bash_profile file). This will include the libxml header files location in the Perl include path. Execute perl -V to verify that the directory is scanned by Perl.

Another dependency that might give you issues is Code::TidyAll. On OSX 10.11, installation fails because several tests fail. Several temporary folders are created in /private/var/folders while the test expect them to be in /var/folders. This shouldn't be an issue. Force installing the module separately with cpanm Code::TidyAll --force solves the issue.

Carton

Carton is a dependency manager. Think of it as Bundler for Perl. Instead of manually cat herding modules in a gazillion include paths (and trying to track different versions), Carton will create a local include folder with all the dependencies in your active project.

Dependencies are managed in a cpanfile which is added to the root of your project. Running carton install will download and setup all the entire dependency tree in a local folder under your active project. With carton exec you'll run your project code including the stuff in the local folder instead of the systemwide includes.

Installation is easy: cpanm Carton

Dist::Milla

Catmandu modules are plain old Perl modules. There isn't really anything special about them (except that the code in the *.pm files integrates with the Catmandu framework). As such, they are published to CPAN which allows Catmandu users to easily download and install modules using cpanm.

Publishing a module isn't that trivial though. You'll need to write a lot of boilerplate code that needs to adhere to various standards. There's also versioning and release management to be considered. Instead of doing that manually, Dist::Milla will generate a lot of stuff for you.

So, when we develop a Catmandu module, we'll use Dist:Milla to roll a new release, or create new build.

Installing is easy: cpanm Dist::Milla

Make sure you watch this screencast to understand how this tool works, and how it integrates with Github.

Developing for Catmandu

If you have everything installed, let's start a new project:

$ milla new Catmandu-Hello

This will create a new folder with all the boilerplate ready for you to use. If you did a milla setup, it should take your presets into account.

Now, let's configure the cpanfile and set up the local development environment specific to Catmandu. Add these lines to the end of the file:

requires 'Catmandu', '>=1.0201';
requires 'Moo', '1.0';

This will retrieve Moo and Catmandu with all their dependencies and put them in a local folder inside your Catmandu-Hello project. You want your module to depend on another Catmandu module? Can do! Just add them to like this: requires 'Catmandu::XML', '>=1.0';

When you're done editing, run carton install to download everything you specified in the cpanfile.

Now, suppose you already have a stable, global Catmandu installation, you'd normally run it like this:

$ catmandu 

However, if we want to run the local version we just installed via Carton, we'll need to run it like this:

$ carton exec catmandu

Now, create a lib\Catmandu folder in your project and follow the fixer tutorial to create an example fixer in your new module. Check out the MARC module to see how you should structure/layout your code files.

Ready? Let's build it and test it:

$ milla build
$ carton exec catmandu info

The first command will build your code (see: build.PL) and create a new folder Catmandu-hello-* with your bundled code inside your project. Don't worry, the default .gitignore file will prevent you from adding that duplicate code to your git repo. You can remove those bundled folders afterwards with milla clean.

The second command will run the local version of Catmandu and include your bundled code. The info command should give you a list of all the included modules. You should see your custom fixer module mentioned in the list.

When ready to create a new release (change version number): run the milla release command to roll a new release. This command integrates well with Github and can also announce your release with cpan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment