<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Irreverential Interventions</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/sebastian_willert/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/sebastian_willert/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/sebastian_willert//680</id>
    <updated>2011-11-22T09:30:21Z</updated>
    <subtitle>Brute-forcing perl and emacs to do my biddings</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.38</generator>

<entry>
    <title>Using Dist::Zilla to extract parts of your distribution</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/sebastian_willert/2011/11/using-distzilla-to-extract-parts-of-your-distribution.html" />
    <id>tag:blogs.perl.org,2011:/users/sebastian_willert//680.2478</id>

    <published>2011-11-22T08:04:09Z</published>
    <updated>2011-11-22T09:30:21Z</updated>

    <summary> Imagine you are working on a smallish Catalyst project with an DBIx::Class model. You have been a good citizen and adhered to the principal of separation of concerns. Now you would like to extract the schema to use it...</summary>
    <author>
        <name>Sebastian Willert</name>
        
    </author>
    
    <category term="distzilla" label="dist-zilla" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/sebastian_willert/">
        <![CDATA[<a name='___top' class='dummyTopAnchor' ></a>

<p>Imagine you are working on a smallish <a href="http://search.cpan.org/perldoc?Catalyst" class="podlinkpod"
>Catalyst</a> project with an <a href="http://search.cpan.org/perldoc?DBIx%3A%3AClass" class="podlinkpod"
>DBIx::Class</a> model.
You have been a good citizen and adhered to the principal of separation of concerns.
Now you would like to extract the schema to use it anywhere else (in my case a monitoring interface that is in place and allows simple plugins).
Creating a whole distribution with the related infrastructure out of the schema classes is just to much work for this one-off task.
<a href="http://search.cpan.org/perldoc?Dist%3A%3AZilla" class="podlinkpod"
>Dist::Zilla</a> to the rescue.</p>
]]>
        <![CDATA[<a name='___top' class='dummyTopAnchor' ></a>

<p><a href="http://search.cpan.org/perldoc?Dist%3A%3AZilla" class="podlinkpod"
>Dist::Zilla</a> can&#39;t handle multiple dists in one directory,
so you have to create an empty subdir in the project.
I&#39;ll go with <code>contrib/schema</code> for now.
Put the following</p>

<div style="border: 0.25ex dashed rgb(0, 94, 145);
color: rgb(187, 187, 187); background-color: rgb(0, 42, 62);
margin: -1em 0 1em 0; padding: 0.1ex 1ex;overflow: auto;">
    <pre>
<span style="color: #eedd82;">name</span>    = MyApp-Schema
<span style="color: #eedd82;">author</span>  = You &lt;<a href="mailto:you&#64;example.com">you&#64;example.com</a>&gt;
<span style="color: #eedd82;">license</span> = None
<span style="color: #eedd82;">copyright_holder</span> = You
<span style="color: #eedd82;">copyright_year</span>   = 2011
<span style="color: #eedd82;">version</span> = 0.01
<span style="color: #eedd82;">main_module</span> = lib/MyApp/Schema.pm

[<span style="color: #98fb98;">Manifest</span>]
[<span style="color: #98fb98;">MakeMaker</span>]
[<span style="color: #98fb98;">TestRelease</span>]

[<span style="color: #98fb98;">Prereqs</span>]
<span style="color: #eedd82;">DBIx::Class</span> = 0
<span style="color: #eedd82;">DBD::SQLite</span> = 0
<span style="color: #eedd82;">Test::DBIx::Class</span> = 0


[<span style="color: #98fb98;">GatherDir</span>]
<span style="color: #eedd82;">root</span>   = ../../lib/MyApp/Schema
<span style="color: #eedd82;">prefix</span> = lib/MyApp/Schema


<span style="color: #ff7f24;">; </span><span style="color: #ff7f24;">this is a hack to additionally gather the schema class
</span><span style="color: #ff7f24;">; </span><span style="color: #ff7f24;">maybe there is a better way, but I was not able to
</span><span style="color: #ff7f24;">; </span><span style="color: #ff7f24;">find a plugin that can gather files and also support
</span><span style="color: #ff7f24;">; </span><span style="color: #ff7f24;">a GatherDir-like prefix option
</span>[<span style="color: #98fb98;">GatherDir / Schema</span>]
<span style="color: #eedd82;">root</span>   = ../../lib/MyApp/
<span style="color: #eedd82;">prefix</span> = lib/MyApp/
<span style="color: #eedd82;">exclude_match</span> = (?&lt;!Schema.pm)$


[<span style="color: #98fb98;">GatherDir / Tests</span>]
<span style="color: #eedd82;">root</span>   = ../../t/schema
<span style="color: #eedd82;">prefix</span> = t/schema
</pre>
  </div><div style="text-align: right;
font-size: x-small; color: #aaa; height:1em; line-height: 1em;
margin: -2ex 1ex 1em;">
  Rendered by <em>emacs</em>, <em>blooper.el</em> and <em>htmlize.el</em>
</div>


<p>Now change to the directory and run</p>

<div style="border: 0.25ex dashed rgb(0, 94, 145);
color: rgb(187, 187, 187); background-color: rgb(0, 42, 62);
margin: -1em 0 1em 0; padding: 0.1ex 1ex;overflow: auto;">
    <pre>
dzil build
</pre>
  </div><div style="text-align: right;
font-size: x-small; color: #aaa; height:1em; line-height: 1em;
margin: -2ex 1ex 1em;">
  Rendered by <em>emacs</em>, <em>blooper.el</em> and <em>htmlize.el</em>
</div>


<p>and you should have a shiny <code>MyApp-Schema-0.01.tar.gz</code> at your (not really best practice) disposal.</p>


<!-- blooper pod source
# POST&ndash;ID: 2478
# TITLE: Using Dist::Zilla to extract parts of your distribution
# TAGS: dist&ndash;zilla

=head1 DESCRIPTION

Imagine you are working on a smallish L&lt;Catalyst&gt; project with an
L&lt;DBIx::Class&gt; model. You have
been a good citizen and adhered to the principal of separation of
concerns. Now you would like to extract the schema to use it anywhere
else (in my case a monitoring interface that is in place and allows
simple plugins). Creating a whole distribution with the related
infrastructure out of the schema classes is just to much work for this
one&ndash;off task. L&lt;Dist::Zilla&gt; to the rescue.

=head1 BODY

L&lt;Dist::Zilla&gt; can't handle multiple dists in one directory, so you
have to create an empty subdir in the project. I'll go with
C&lt;contrib/schema&gt; for now. Put the following 

=begin conf

name    = MyApp&ndash;Schema
author  = You &lt;you@example.com&gt;
license = None
copyright_holder = You
copyright_year   = 2011
version = 0.01
main_module = lib/MyApp/Schema.pm

[Prereqs]
DBIx::Class = 0
DBD::SQLite = 0
Test::DBIx::Class = 0

[GatherDir]
root   = ../../lib/MyApp/Schema
prefix = lib/MyApp/Schema

; this is a hack to additionally gather the schema class
; maybe there is a better way, but I was not able to
; find a plugin that can gather files and also support
; a GatherDir&ndash;like prefix option
[GatherDir / Schema]
root   = ../../lib/MyApp/
prefix = lib/MyApp/
exclude_match = (?&lt;!Schema.pm)$

[GatherDir / Tests]
root   = ../../t/schema
prefix = t/schema

=end conf

Now change to the directory and run

=begin sh

dzil build

=end sh

and you should have a shiny C&lt;MyApp&ndash;Schema&ndash;0.01.tar.gz&gt; at your
(not really best practice) disposal.

-->]]>
    </content>
</entry>

<entry>
    <title>First steps with App::Mist</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/sebastian_willert/2011/04/first-steps-with-appmist.html" />
    <id>tag:blogs.perl.org,2011:/users/sebastian_willert//680.1629</id>

    <published>2011-04-04T22:22:24Z</published>
    <updated>2011-04-04T23:23:16Z</updated>

    <summary> My last posting seems to have whet the appetite of a few people, or at least interested one or two enough to follow this project on GitHub. Today I&#39;d like to delve deeper into how you can use App::Mist...</summary>
    <author>
        <name>Sebastian Willert</name>
        
    </author>
    
    <category term="deployment" label="deployment" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="distribution" label="distribution" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mist" label="mist" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/sebastian_willert/">
        <![CDATA[<a name='___top' class='dummyTopAnchor' ></a>

<p>My last posting seems to have whet the appetite of a few people,
or at least interested one or two enough to follow this project on GitHub.
Today I&#39;d like to delve deeper into how you can use <a href="https://github.com/willert/mist" class="podlinkurl"
>App::Mist</a> to deploy or distribute an application.</p>
]]>
        <![CDATA[<a name='___top' class='dummyTopAnchor' ></a>

<p>I will use <a href="https://github.com/willert/mist" class="podlinkurl"
>App::Mist</a> itself as example for this mini-tutorial on how to use it.
<a href="https://github.com/willert/mist" class="podlinkurl"
>App::Mist</a> is self-hosting and has few dependencies on its own,
but you have to make sure that <a href="http://search.cpan.org/perldoc?Dist%3A%3AZilla" class="podlinkpod"
>Dist::Zilla</a> and <a href="http://search.cpan.org/perldoc?App%3A%3Acpanminus" class="podlinkpod"
>App::cpanminus</a> are present on your build system,
otherwise everything will fail miserably.</p>

<p>In an ideal world,
every package you depend on lives on <a href="http://search.cpan.org" class="podlinkurl"
>CPAN</a>,
correctly lists its dependencies and passes its many tests with flying colors.
The real world definitively is no such place,
especially when viewed from the trenches,
but for this post and for the installation of <a href="https://github.com/willert/mist" class="podlinkurl"
>App::Mist</a> we can make this assumption.
How to deal with the inevitable hiccups in the dependency chain will be a topic for another two (or ten) blog posts down the road.</p>

<h2 style="font-size:larger;margin-bottom:1em;">
<a style="text-decoration: none;color:inherit;" class='u' href='#___top' title='click to go to top of document'
>Installing mist from github.com</a></h2>

<p>The <a href="https://github.com/willert/mist" class="podlinkurl"
>App::Mist</a> repository itself contains a <code>mist</code> environment and is self-hosting.
The script to run <a href="https://github.com/willert/mist/raw/master/contrib/run_mist_as_mist_package.sh" class="podlinkurl"
>mist as a mist package</a> is included.
For the rest of this post it is assumed that this script is available as <code>mist</code> in your path (e.g.
<code>~/bin/mist</code>) and you have adjusted the <code>CHECKOUT</code> variable according to your local conditions.</p>

<p>First clone <a href="https://github.com/willert/mist" class="podlinkurl"
>App::Mist</a>,
e.g.
via</p>

<div style="border: 0.25ex dashed rgb(0, 94, 145);
color: rgb(187, 187, 187); background-color: rgb(0, 42, 62);
margin: -1em 0 1em 0; padding: 0.1ex 1ex;overflow: auto;">
    <pre>
  git clone git://github.com/willert/mist.git
</pre>
  </div><div style="text-align: right;
font-size: x-small; color: #aaa; height:1em; line-height: 1em;
margin: -2ex 1ex 1em;">
  Rendered by <em>emacs</em>, <em>blooper.el</em> and <em>htmlize.el</em>
</div>


<p>You will notice the unusual entries <code>mpan-dist</code> and <code>mpan-install</code>.
The directory <code>mpan-dist</code> contains a stable copy of all distributions needed to run the application,
and the script <code>mpan-install</code> is a fat-packed script directly derived from your (or mine in this case) <code>cpanm</code> that can install those distributions without any external dependencies.
Go ahead,
try it:</p>

<div style="border: 0.25ex dashed rgb(0, 94, 145);
color: rgb(187, 187, 187); background-color: rgb(0, 42, 62);
margin: -1em 0 1em 0; padding: 0.1ex 1ex;overflow: auto;">
    <pre>
  <span style="color: #b0c4de; font-weight: bold;">cd</span> mist
  ./mpan-install
</pre>
  </div><div style="text-align: right;
font-size: x-small; color: #aaa; height:1em; line-height: 1em;
margin: -2ex 1ex 1em;">
  Rendered by <em>emacs</em>, <em>blooper.el</em> and <em>htmlize.el</em>
</div>


<p>Run that command as normal user,
because <a href="https://github.com/willert/mist" class="podlinkurl"
>App::Mist</a> will refuse to run with root privileges to protect you from accidentally modifying your system-wide perl installation.</p>

<p>This will install all dependencies from <code>mpan-dist</code> into the local lib (named <code>perl5</code> by default as that seems to be the emerging naming convention) for this project.
If you created a <code>mist</code> script as mentioned above,
your copy of <a href="https://github.com/willert/mist" class="podlinkurl"
>App::Mist</a> is now ready to run.
Hopefully at least,
this is still alpha quality software.</p>

<p>You can check if everything is configured correctly with running</p>

<div style="border: 0.25ex dashed rgb(0, 94, 145);
color: rgb(187, 187, 187); background-color: rgb(0, 42, 62);
margin: -1em 0 1em 0; padding: 0.1ex 1ex;overflow: auto;">
    <pre>
  mist
</pre>
  </div><div style="text-align: right;
font-size: x-small; color: #aaa; height:1em; line-height: 1em;
margin: -2ex 1ex 1em;">
  Rendered by <em>emacs</em>, <em>blooper.el</em> and <em>htmlize.el</em>
</div>


<p>without any parameters and be wow&#39;ed by my skills at writing useful help messages!</p>

<h2 style="font-size:larger;margin-bottom:1em;">
<a style="text-decoration: none;color:inherit;" class='u' href='#___top' title='click to go to top of document'
>Using mist to rebuild the distribution package</a></h2>

<p>I promised that <a href="https://github.com/willert/mist" class="podlinkurl"
>App::Mist</a> is self hosting,
so now its time to show you how to use your freshly installed <code>mist</code> to create its own distribution package.</p>

<p>First of all,
delete <code>mpan-dist</code> and <code>mpan-install</code>,
they are not needed at run-time.
Leave <code>perl5</code> untouched for now,
or your <code>mist</code> script won&#39;t run anymore because of missing libraries:</p>

<div style="border: 0.25ex dashed rgb(0, 94, 145);
color: rgb(187, 187, 187); background-color: rgb(0, 42, 62);
margin: -1em 0 1em 0; padding: 0.1ex 1ex;overflow: auto;">
    <pre>
  rm -Rf mpan-dist
  rm mpan-install
</pre>
  </div><div style="text-align: right;
font-size: x-small; color: #aaa; height:1em; line-height: 1em;
margin: -2ex 1ex 1em;">
  Rendered by <em>emacs</em>, <em>blooper.el</em> and <em>htmlize.el</em>
</div>


<p>To recreate the distribution run the following commands:</p>

<div style="border: 0.25ex dashed rgb(0, 94, 145);
color: rgb(187, 187, 187); background-color: rgb(0, 42, 62);
margin: -1em 0 1em 0; padding: 0.1ex 1ex;overflow: auto;">
    <pre>
  mist init    <span style="color: #ff7f24;"># </span><span style="color: #ff7f24;">scan dist.ini and pick up all deps from cpan.org
</span>  mist index   <span style="color: #ff7f24;"># </span><span style="color: #ff7f24;">reindex the local mpan directory
</span>  mist compile <span style="color: #ff7f24;"># </span><span style="color: #ff7f24;">build the ./mpan-install script
</span></pre>
  </div><div style="text-align: right;
font-size: x-small; color: #aaa; height:1em; line-height: 1em;
margin: -2ex 1ex 1em;">
  Rendered by <em>emacs</em>, <em>blooper.el</em> and <em>htmlize.el</em>
</div>


<p>If everything works as expected,
you should have created your first full-fledged mist environment!
And if you ignore my long-winded ramblings,
it was surprisingly fast and straight-forward,
wasn&#39;t it ;)</p>

<p>To verify the distribution you can now throw away your local lib and created it anew:</p>

<div style="border: 0.25ex dashed rgb(0, 94, 145);
color: rgb(187, 187, 187); background-color: rgb(0, 42, 62);
margin: -1em 0 1em 0; padding: 0.1ex 1ex;overflow: auto;">
    <pre>
  rm -Rf perl5
  <span style="color: #ff7f24;"># </span><span style="color: #ff7f24;">'mist' is unlikely to work between those two steps
</span>  ./mpan-install
</pre>
  </div><div style="text-align: right;
font-size: x-small; color: #aaa; height:1em; line-height: 1em;
margin: -2ex 1ex 1em;">
  Rendered by <em>emacs</em>, <em>blooper.el</em> and <em>htmlize.el</em>
</div>


<p>Good luck,
and please submit a bug report in the <a href="https://github.com/willert/mist/issues" class="podlinkurl"
>github issue tracker</a> if anything went amiss.</p>


<!-- blooper pod source
# POST&ndash;ID: 1629
# TITLE: First steps with App::Mist
# TAGS: mist, deployment, distribution

=head1 DESCRIPTION

My last posting seems to have whet the appetite of a few people, 
or at least interested one or two enough to follow this project
on GitHub. Today I'd like to delve deeper into how you can use
L&lt;App::Mist|https://github.com/willert/mist&gt;
to deploy or distribute an application. 

=head1 BODY

I will use L&lt;App::Mist|https://github.com/willert/mist&gt; itself as
example for this mini&ndash;tutorial on how to use it.
L&lt;App::Mist|https://github.com/willert/mist&gt; is self&ndash;hosting and has
few dependencies on its own, but you have to make sure that
L&lt;Dist::Zilla&gt; and L&lt;App::cpanminus&gt; are present on your build system,
otherwise everything will fail miserably.

In an ideal world, every package you depend on lives on
L&lt;CPAN|http://search.cpan.org&gt;, correctly lists its dependencies and
passes its many tests with flying colors. The real world definitively
is no such place, especially when viewed from the trenches, but
for this post and for the installation of
L&lt;App::Mist|https://github.com/willert/mist&gt; we can make this
assumption. How to deal with the inevitable hiccups in the
dependency chain will be a topic for another two (or ten) blog posts
down the road.

=head2 Installing mist from github.com

The L&lt;App::Mist|https://github.com/willert/mist&gt; repository itself
contains a C&lt;mist&gt; environment and is self&ndash;hosting. The script to run
L&lt;mist as a mist package|https://github.com/willert/mist/raw/master/contrib/run_mist_as_mist_package.sh&gt;
is included. For the rest of this post it is assumed that this script
is available as C&lt;mist&gt; in your path (e.g. C&lt;~/bin/mist&gt;) and you have
adjusted the C&lt;CHECKOUT&gt; variable according to your local conditions.

First clone L&lt;App::Mist|https://github.com/willert/mist&gt;,
e.g. via

=begin sh

  git clone git://github.com/willert/mist.git

=end sh

You will notice the unusual entries C&lt;mpan&ndash;dist&gt; and C&lt;mpan&ndash;install&gt;.
The directory C&lt;mpan&ndash;dist&gt; contains a stable copy of all distributions
needed to run the application, and the script C&lt;mpan&ndash;install&gt; is a
fat&ndash;packed script directly derived from your (or mine in this case)
C&lt;cpanm&gt; that can install those distributions without any external
dependencies. Go ahead, try it: 

=begin sh

  cd mist
  ./mpan&ndash;install

=end sh

Run that command as normal user, because
L&lt;App::Mist|https://github.com/willert/mist&gt; will refuse to run with
root privileges to protect you from accidentally modifying your
system&ndash;wide perl installation.

This will install all dependencies from C&lt;mpan&ndash;dist&gt; into the local lib
(named C&lt;perl5&gt; by default as that seems to be the emerging naming 
convention) for this project. If you created a C&lt;mist&gt; script
as mentioned above, your copy of
L&lt;App::Mist|https://github.com/willert/mist&gt; is now ready to run.
Hopefully at least, this is still alpha quality software.

You can check if
everything is configured correctly with running

=begin sh

  mist

=end sh

without any parameters and be wow'ed by my skills at writing useful
help messages!

=head2 Using mist to rebuild the distribution package

I promised that L&lt;App::Mist|https://github.com/willert/mist&gt;
is self hosting, so now its time to show you how to use your
freshly installed C&lt;mist&gt; to create its own distribution package.

First of all, delete C&lt;mpan&ndash;dist&gt; and C&lt;mpan&ndash;install&gt;, they are
not needed at run&ndash;time. Leave C&lt;perl5&gt; untouched for now, or
your C&lt;mist&gt; script won't run anymore because of missing libraries:

=begin sh

  rm &ndash;Rf mpan&ndash;dist
  rm mpan&ndash;install

=end sh

To recreate the distribution run the following commands:

=begin sh

  mist init    # scan dist.ini and pick up all deps from cpan.org
  mist index   # reindex the local mpan directory
  mist compile # build the ./mpan&ndash;install script

=end sh

If everything works as expected, you should have created your first
full&ndash;fledged mist environment! And if you ignore my long&ndash;winded
ramblings, it was surprisingly fast and straight&ndash;forward, wasn't it ;)

To verify the distribution you can now throw away your local lib and
created it anew:

=begin sh

  rm &ndash;Rf perl5
  # 'mist' is unlikely to work between those two steps
  ./mpan&ndash;install

=end sh

Good luck, and please submit a bug report in the 
L&lt;github issue tracker|https://github.com/willert/mist/issues&gt;
if anything went amiss.


-->]]>
    </content>
</entry>

<entry>
    <title>How I manage the distribution of Perl5 projects</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/sebastian_willert/2011/03/how-i-distribute-my-projects.html" />
    <id>tag:blogs.perl.org,2099:/users/sebastian_willert//680.1609</id>

    <published>2011-03-31T00:00:00Z</published>
    <updated>2011-03-30T23:58:14Z</updated>

    <summary> If you are working like me (which is unlikely) distributing and deploying your Perl5 projects poses a significant challenge. Managing self-contained projects has become vastly easier since the advent of local::lib, Dist::Zilla and App::cpanminus but the ever changing (and...</summary>
    <author>
        <name>Sebastian Willert</name>
        
    </author>
    
    <category term="mistdeploymentdistribution" label="mist deployment distribution" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/sebastian_willert/">
        <![CDATA[<a name='___top' class='dummyTopAnchor' ></a>

<p>If you are working like me (which is unlikely) distributing and deploying your Perl5 projects poses a significant challenge.
Managing self-contained projects has become vastly easier since the advent of <a href="http://search.cpan.org/perldoc?local%3A%3Alib" class="podlinkpod"
>local::lib</a>,
<a href="http://search.cpan.org/perldoc?Dist%3A%3AZilla" class="podlinkpod"
>Dist::Zilla</a> and <a href="http://search.cpan.org/perldoc?App%3A%3Acpanminus" class="podlinkpod"
>App::cpanminus</a> but the ever changing (and sometimes incompatible) nature of CPAN has bitten me more than once in my life as a coder.
Here is how I try to solve this,
judge for yourself if this approach has any merit and encourage me to go further down this path if you think it does.</p>
]]>
        <![CDATA[<a name='___top' class='dummyTopAnchor' ></a>

<p><a href="http://search.cpan.org/perldoc?App%3A%3Acpanminus" class="podlinkpod"
>App::cpanminus</a> included the <code>--save-dists</code> option for the first time in version 1.4 that was released this month.
It might not seem like a big deal at first,
but it got me thinking.
I was always looking for a nice and hassle-free way to manage a mini-cpan that is localized to a project and could easily be managed by source control.
Using a full mini-cpan for this simply couldn&#39;t be done due to size constraints.
A gig here and a gig there amounts to real space requirements when needed in dozens of projects.
Not to mention the pain of uploading and syncing this stuff.</p>

<p>Why would I want to do this?
Its simple: most of my work is done for a smallish web-shop with a grown infrastructure and tons of freelancers.
Every <code>Ubuntu</code> version from 8.04 to 11.04 beta can be found on our development machines and servers,
you can never be sure which packages are installed (especially on the dev machines) and if you are working with a 32-bit or a 64-bit variant of the OS,
nor which <code>perl</code> version is installed (although I would kick any of our freelancers that couldn&#39;t manage to get hold of at least 5.10.1).
<a href="http://search.cpan.org/perldoc?Dist%3A%3AZilla" class="podlinkpod"
>Dist::Zilla</a> and <a href="http://search.cpan.org/perldoc?local%3A%3Alib" class="podlinkpod"
>local::lib</a> brought some improvements to this non-existing process,
but you are still at the whims of CPAN when installing from scratch.
Not to mention that local libs are not portable between different versions of <code>perl</code> and different host environments.</p>

<p>Don&#39;t get me wrong,
I don&#39;t want to lay any blame here.
In fact In am more than impressed how stable and glitch-free the installation of modules like <a href="http://search.cpan.org/perldoc?Catalyst" class="podlinkpod"
>Catalyst</a> and <a href="http://search.cpan.org/perldoc?DBIx%3A%3AClass" class="podlinkpod"
>DBIx::Class</a> is,
given that they have zillions of dependencies they don&#39;t control.
But being on the road,
having only your netbook available and getting a call to urgently fix something in a project you haven&#39;t touched for months (and thus no dev environment ready to dive into) sucks.
The last thing you need right then is the fun of working around a temporarily broken toolchain or framework of choice that makes installing from CPAN a nightmare.</p>

<p>Even more fun,
if the bug you are hunting is caused by a bug in a dependency that has since be fixed and the version of this library you are using in production has vanished from CPAN (you know,
some people clean up their authors directory) ...</p>

<p>Maybe I am trying to solve problems no one but me has.
Or there is any solution to this that I have missed that is not as complicated as <a href="http://search.cpan.org/perldoc?Shipwright" class="podlinkpod"
>Shipwright</a> seems to be.
The usual recommendations (fixed dev environment with company wide mini-cpan,
custom apt-repositories,
you name it) just don&#39;t cut it for me.</p>

<p>...</p>

<p>I&#39;ve exhausted my blogging tuits (and probably your patience) for today,
but the good news is that I&#39;ve managed to weave <a href="http://search.cpan.org/perldoc?local%3A%3Alib" class="podlinkpod"
>local::lib</a>,
<a href="http://search.cpan.org/perldoc?Dist%3A%3AZilla" class="podlinkpod"
>Dist::Zilla</a>,
<a href="http://search.cpan.org/perldoc?App%3A%3Acpanminus" class="podlinkpod"
>App::cpanminus</a> and some fragments of mini-cpan style repository management into a nice small package that allows for easy tarball or VCS distribution of projects with no more requirements than a working perl and the theoretical ability to install from CPAN (<code>cpanm</code> is fat-packed into the deployment script) on the target machine.</p>

<p>Without further ado,
if you are interested in a distribution management package that can do this for you,
without requiring more than writing the usual <code>dist.ini</code> for <a href="http://search.cpan.org/perldoc?Dist%3A%3AZilla" class="podlinkpod"
>Dist::Zilla</a>,
check out <a href="https://github.com/willert/mist" class="podlinkurl"
>the github repository for App::Mist</a> and especially the <a href="https://github.com/willert/mist/blob/master/docs/workflow.txt" class="podlinkurl"
>workflow document</a> and tell me what you think.</p>

<p>Cheers &#38; have fun,</p>

<pre>  Sebastian</pre>

<p>P.S. Prepending distributions needed by others that fail to list those dependencies (I&#39;m looking at you, <a href="http://search.cpan.org/perldoc?DBD%3A%3Amysql" class="podlinkpod"
>DBD::mysql</a>) or simply fail some unimportant tests (<a href="http://search.cpan.org/perldoc?Test%3A%3AWWW%3A%3AMechanize" class="podlinkpod"
>Test::WWW::Mechanize</a>, anyone?) is fully supported. Writing some checks to ensure the environment confirms to your expectations (pkg-config, C compiler, whatever ..) also is.</p>


<!-- blooper pod source
# POST&ndash;ID: 1609
# TITLE: How I manage the distribution of Perl5 projects
# TAGS: mist deployment distribution

=head1 DESCRIPTION

If you are working like me (which is unlikely) distributing and
deploying your Perl5 projects poses a significant challenge. Managing
self&ndash;contained projects has become vastly easier since the advent of
L&lt;local::lib&gt;, L&lt;Dist::Zilla&gt; and L&lt;App::cpanminus&gt; but the ever
changing (and sometimes incompatible) nature of CPAN has bitten
me more than once in my life as a coder. Here is how I try to solve
this, judge for yourself if this approach has any merit and encourage
me to go further down this path if you think it does.

=head1 BODY

L&lt;App::cpanminus&gt; included the C&lt;&ndash;&ndash;save&ndash;dists&gt; option for the first
time in version 1.4 that was released this month. It might not seem
like a big deal at first, but it got me thinking. I was always looking
for a nice and hassle&ndash;free way to manage a mini&ndash;cpan that is localized
to a project and could easily be managed by source control. Using a
full mini&ndash;cpan for this simply couldn't be done due to size
constraints. A gig here and a gig there amounts to real space
requirements when needed in dozens of projects. Not to mention the
pain of uploading and syncing this stuff. 

Why would I want to do this? Its simple: most of my work is done for a
smallish web&ndash;shop with a grown infrastructure and tons of
freelancers. Every C&lt;Ubuntu&gt; version from 8.04 to 11.04 beta can be
found on our development machines and servers, you can never be sure
which packages are installed (especially on the dev machines) and if
you are working with a 32&ndash;bit or a 64&ndash;bit variant of the OS, nor which
C&lt;perl&gt; version is installed (although I would kick any of our
freelancers that couldn't manage to get hold of at least
5.10.1). L&lt;Dist::Zilla&gt; and L&lt;local::lib&gt; brought some improvements to
this non&ndash;existing process, but you are still at the whims of CPAN when
installing from scratch. Not to mention that local libs are not
portable between different versions of C&lt;perl&gt; and different host
environments.

Don't get me wrong, I don't want to lay any blame here. In fact In am
more than impressed how stable and glitch&ndash;free the installation of
modules like L&lt;Catalyst&gt; and L&lt;DBIx::Class&gt; is, given that they have
zillions of dependencies they don't control. But being on the road,
having only your netbook available and getting a call to urgently fix
something in a project you haven't touched for months (and thus no dev
environment ready to dive into) sucks. The last thing you need right
then is the fun of working around a temporarily broken toolchain
or framework of choice that makes installing from CPAN a nightmare. 

Even more fun, if the bug you are hunting is caused by a bug in a
dependency that has since be fixed and the version of this library you
are using in production has vanished from CPAN (you know, some people
clean up their authors directory) ...

Maybe I am trying to solve problems no one but me has. Or there is any
solution to this that I have missed that is not as complicated as
L&lt;Shipwright&gt; seems to be. The usual recommendations (fixed dev
environment with company wide mini&ndash;cpan, custom apt&ndash;repositories, you
name it) just don't cut it for me.

...

I've exhausted my blogging tuits (and probably your patience) for today,
but the good news is that I've managed to weave L&lt;local::lib&gt;,
L&lt;Dist::Zilla&gt;, L&lt;App::cpanminus&gt; and some fragments of mini&ndash;cpan
style repository management into a nice small package that allows for
easy tarball or VCS distribution of projects with no more requirements
than a working perl and the theoretical ability to install from CPAN
(C&lt;cpanm&gt; is fat&ndash;packed into the deployment script) on the target
machine. 

Without further ado, if you are interested in a distribution
management package that can do this for you, without requiring more
than writing the usual C&lt;dist.ini&gt; for L&lt;Dist::Zilla&gt;, check out 
L&lt;the github repository for App::Mist|https://github.com/willert/mist&gt;
and especially the
L&lt;workflow document|https://github.com/willert/mist/blob/master/docs/workflow.txt&gt;
and tell me what you think. 

Cheers &amp; have fun,

  Sebastian

P.S. Prepending distributions needed by others that fail to list those
dependencies (I'm looking at you, L&lt;DBD::mysql&gt;) or simply fail some
unimportant tests (L&lt;Test::WWW::Mechanize&gt;, anyone?) is fully
supported. Writing some checks to ensure the environment confirms to
your expectations (pkg&ndash;config, C compiler, whatever ..) also is.



-->]]>
    </content>
</entry>

<entry>
    <title>Converting Module::Install prereqs to Dist::Zilla with elisp</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/sebastian_willert/2011/01/converting-moduleinstall-prereqs-to-distzilla-syntax-with-elisp.html" />
    <id>tag:blogs.perl.org,2011:/users/sebastian_willert//680.1347</id>

    <published>2011-01-11T15:02:25Z</published>
    <updated>2011-01-11T18:20:46Z</updated>

    <summary>After half a day of yak-shaving that started with having to port yet another Makefile.PL to the dist.ini format, I am now finally able to post this small snippet of elisp code to blogs.perl.org from within emacs (more on that...</summary>
    <author>
        <name>Sebastian Willert</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/sebastian_willert/">
        <![CDATA[After half a day of yak-shaving that started with having to port yet another Makefile.PL to the dist.ini format, I am now finally able to post this small snippet of elisp code to blogs.perl.org from within emacs (more on that later):
<div style="margin-bottom: 1em;height: 0px;"></div>]]>
        <![CDATA[
<div style="border: 2px dashed rgb(0, 94, 145); color: rgb(187, 187, 187); background-color: rgb(0, 42, 62); margin: 12px 0pt; padding: 9px 10px;">
    <pre>
(<span style="color: #00ffff;">defun</span> <span style="color: #87cefa;">sbw/prereqs-to-dist-zilla</span> ()
  (interactive)
  (<span style="color: #00ffff;">save-excursion</span>
   (<span style="color: #00ffff;">while</span>
       (re-search-forward
        (concat
         <span style="color: #ffa07a;">"^</span><span style="color: #ffa07a; font-weight: bold;">\\</span><span style="color: #ffa07a; font-weight: bold;">(</span><span style="color: #ffa07a;">build_</span><span style="color: #ffa07a; font-weight: bold;">\\</span><span style="color: #ffa07a; font-weight: bold;">)</span><span style="color: #ffa07a;">?requires *['\"]</span><span style="color: #ffa07a; font-weight: bold;">\\</span><span style="color: #ffa07a; font-weight: bold;">(</span><span style="color: #ffa07a;">[</span><span style="color: #ffa07a;">^</span><span style="color: #ffa07a;">'\"]*</span><span style="color: #ffa07a; font-weight: bold;">\\</span><span style="color: #ffa07a; font-weight: bold;">)</span><span style="color: #ffa07a;">['\"]"</span>
         <span style="color: #ffa07a;">" *</span><span style="color: #ffa07a; font-weight: bold;">\\</span><span style="color: #ffa07a; font-weight: bold;">(</span><span style="color: #ffa07a;">=&gt;</span><span style="color: #ffa07a; font-weight: bold;">\\</span><span style="color: #ffa07a; font-weight: bold;">|</span><span style="color: #ffa07a;">,</span><span style="color: #ffa07a; font-weight: bold;">\\</span><span style="color: #ffa07a; font-weight: bold;">)</span><span style="color: #ffa07a;">? *['\"]?</span><span style="color: #ffa07a; font-weight: bold;">\\</span><span style="color: #ffa07a; font-weight: bold;">(</span><span style="color: #ffa07a;">[0-9_.]*</span><span style="color: #ffa07a; font-weight: bold;">\\</span><span style="color: #ffa07a; font-weight: bold;">)</span><span style="color: #ffa07a;">?['\"]? *[;,]"</span>)
        nil t)
     (replace-match
      (<span style="color: #00ffff;">let</span>
          ((module (match-substitute-replacement <span style="color: #ffa07a;">"\\2"</span>))
           (version (match-substitute-replacement <span style="color: #ffa07a;">"\\4"</span>)))
        (concat module <span style="color: #ffa07a;">" = "</span> (<span style="color: #00ffff;">if</span> (string= version <span style="color: #ffa07a;">""</span>) <span style="color: #ffa07a;">"0"</span> version)))
      t nil)
     ))
)
</pre>
  </div>

Hope someone finds this useful... oh, and, yeah: first post!
<div style="white-space:pre;">
Cheers,
    Sebastian

</div>]]>
    </content>
</entry>

</feed>
