App::GitGot, tmux and Lotsa Laziness

March 3rd, 2013

App::GitGot, tmux and Lotsa Laziness

In the last couple of days, I’ve been working on a new Dancer application. Because it’s using Dancer2 and my brand-new, shiny and, err, fairly buggy Template::Caribou, I’ve found myself bouncing back and forth between projects. So today I decided to take a few minutes to streamline my the yak shaving process.

Got to have the right tools

First tool that I was already using (but nowhere often enough): App::GitGot, which herd your local Git repositories for you. Amongst other nifty commands, it has chdir, which opens a subshell to any of those projects.

    $ got list
    1) Catalyst-Plugin-VersionedURI    git
    2) Dancer                          git
    3) Dancer-Plugin-Cache-CHI         git (Not checked out)
    4) Dancer-Plugin-Cache-CHI         git
    5) Dancer-Template-Declare         git   git://
    6) Dancer2                         git
    7) Dist-Zilla-PluginBundle-YANICK  git
    8) GitStore                        git
    9) GnuPG                           git
    10) Template-Caribou                git
    11) Term-Caca                       git
    12) app-gitgot                      git
    13) environment                     git
    14) template-declare                git

    $ got chdir Dancer

    $ pwd

Neat, isn’t? But, really, typing a whole distribution name to get there? This is sooo exhausting. No, that simply won’t do, so I hacked a quick got-complete utility script for my autocomplete pleasure.

Move away chdir, tmux is in the house

I’ve heard of tmux before, but it’s only yesterday that the dam suddenly broke inside and the love began to pour in.

You see, got chdir is nice, but it’s shells within shells. When I’m hacking on my application, I typically hack on, realize that a library has a booboo, jump on that library and do terrible things, return to the application, then probably return to the library, and then patch a third set of modules just because I had a crazy idea, and so on and so forth ad absurdum. The whole process is more like an ever-widening madness gyre than a depth-first touch’n’go. What I need is parallel shells, and tmux might be the answer.

Hence the hacking of a new got subcommand: mux (yes, I’m amused by calling it got mux, but I was sane enough to provide a got tmux. There’s still hope for me). Instead of opening a subshell, it opens a new tmux window or, if the window for that project is already opened, jump to it.

Yeeees, this is beginning to take shape. But… got mux, that’s awfully long. Let’s reduce that to a four-letter word, shall we?

    complete -C got-complete -o nospace -o default hack
    alias hack='got mux'

There. Now I want to hack on Dancer? Then I do

$ hack Dancer

Using Your Local Monsters

Of course, once you begin to mock with dependencies while you develop, you have to begin to add them to your perl invocation, or stash them in PERL5LIB. In my case, the project that began with

    $ perl ./bin/

soon found itself requiring an amended Template::Caribou

    $ perl -I ../perl-modules/Template-Caribou/lib ./bin/

then some shared modules with another project

    $ perl -I ../perl-modules/Template-Caribou/lib  -I ../perl-modules/Galuga/lib ./bin/

Urgh. There should be a way to stash local paths for a project by doing something like

    $ devinc ../perl-modules/Template-Caribou/lib
    $ devinc Dancer-Plugin-Cache-CHI

and have them automatically stored in a file ready to be used to populate PERL5LIB, like so

    $ cat devlibs 
    export PERL5LIB=

    $ . devlibs 

    $ echo $PERL5LIB

If you also think that could be handy, rejoice.

And a last cherry on the sundae…

We already have hack, how about also having a tweak to jump to a module that need to be fixed, and automatically add it to the originator’s devlibs?

    # in your .bashrc
    complete -C got-complete -o nospace -o default tweak
    function tweak { devinc $1; hack $1; }

The result? Here, let me show you: