Babushka: test-driven sysadmin.

Running Deps

Running deps with babushka is simple. The form of the dep names varies depending on where the deps are located, but the way they’re run is always the same.

Referencing Deps & Sources

If the dep you’re running is within one of babushka’s standard load paths (read about them here), then you can just reference the dep directly.

$ babushka homebrew

There are many more deps out there, though, which you might like to use (when you trust them!). You can run a dep from any source that’s published using babushka’s convention automatically:

$ babushka benhoskings:TextMate.app

That runs the dep called ‘TextMate.app’ in my source.

A runtime example

Here’s what babushka does when you run ‘Cucumber.tmbundle’ from my source, to install the Cucumber TextMate bundle. Each step of the way, it’s checking what should be done, and only doing the bits that aren’t done already. (In babushka parlance, it’s only meeting deps that aren’t already met.)

If you already have TextMate installed, babushka notices and just installs the bundle.

$ babushka benhoskings:Cucumber.tmbundle
Cucumber.tmbundle {
  TextMate.app {
    Found TextMate.app in /Applications.
  } ✓ TextMate.app
  meet {
    Cloning git://github.com/bmabey/cucumber-tmbundle.git... at bb89925, done.
    Telling TextMate to reload bundles... done.
  }
} ✓ Cucumber.tmbundle

But if you don’t have TextMate, that’s an unmet dependency, so it gets pulled in too.

$ babushka benhoskings:Cucumber.tmbundle
Cucumber.tmbundle {
  TextMate.app {
    Couldn't find TextMate.app.
    meet {
      ✓ Already downloaded TextMate_1.5.10.zip.
      Extracting TextMate_1.5.10.zip... done.
      Found TextMate.app, copying to /Applications... done.
      Cleaning up... done.
    }
    Found TextMate.app in /Applications.
  } ✓ TextMate.app
  meet {
    Cloning git://github.com/bmabey/cucumber-tmbundle.git... at bb89925, done.
    Telling TextMate to reload bundles... done.
  }
} ✓ Cucumber.tmbundle

Options

There are several useful options to use when running deps. One to try out now is --dry-run, which will just check whether the dep in question (and its requirements) are met, without changing your system; babushka won’t attempt to meet unmet deps.

Suppose the Cucumber bundle isn’t installed. If we kick off a dry run of the same dep as above, then we’ll see this:

$ babushka benhoskings:Cucumber.tmbundle --dry-run
Cucumber.tmbundle {
  TextMate.app {
    Found TextMate.app in /Applications.
  } ✓ TextMate.app
} ~ Cucumber.tmbundle

Babushka has found that the bundle’s requirement, TextMate, is met, but the bundle itself is unmet. But rather than attempt to meet the dep, it’s just printed the state (indicated by ‘~’) and exited (if any dep in the tree is unmet, babushka exits with a non-zero status). See the argument section below for another --dry-run example.

When writing deps, the option you’ll be after most regularly is --debug, which makes babushka much more verbose. In particular, output from long-running shell commands will be printed in realtime.

$ babushka rubygems --debug

A third useful option is --defaults, which causes babushka to run non-interactively so it doesn’t prompt for input at runtime.

Passing arguments to deps

Deps are, in some ways, like a method call - the outer block of the dep is run at the point the dep is defined, which happens lazily as it is invoked from its parent, or from the commandline if it’s the top-level dep.

Like methods, deps can have parameters, and when you call the dep, you can pass values for those parameters, just like supplying arguments to a method call.

There are more details on dep parameters in the section on writing deps. For now, the important part is that deps can always accept arguments, whether they’re run directly from the commandline, or required from another dep.

To pass arguments on the commandline, use name=value pairs:

$ babushka benhoskings:push! ref=HEAD remote=production

Here’s a runtime example, passing the ‘version’ argument to babushka’s builtin ‘git’ dep (we’re also using --dry-run again here). If we pass a version that matches the installed version, then the dep is met:

$ babushka git version=1.8.0 --dry-run
git {
  'git' runs from /usr/local/bin.
  ✓ git is 1.8.3.1, which is >= 1.8.0.
} ✓ git

But if we pass a version newer than the one we have installed, the dep is unmet.

$ babushka git version=1.8.5 --dry-run
git {
  'git' runs from /usr/local/bin.
  git is 1.8.3.1, which isn't >= 1.8.5.
} ~ git
dep 'custom nginx config' do
  requires 'benhoskings:nginx.src'.with(version: '1.0.8')
  # ...
end

You don’t have to supply values for a dep’s parameters when you call it; dep parameters can be unset, and will lazily prompt for values as required (i.e. at the point babushka attempts to use an unset parameter’s value). You can find more details about dep parameters in the writing deps section.