bud

Minimalistic Task Manager

Minimalistic Task Manager

build('dist.css', build.watch('**/*.css').ignore('dist.css'), function (b) {
  concat(b.files, 'dist.css', b.done)
})
 
task('clean', function (t) {
  rmrf('dist.*', t.done)
})

Examples:

$ npm install bud

The old version is completely gone, I've rewritten Bud during my last flight. Read the guide below for the new documentation, or jump to the old documentation.

Create a regular JavaScript (or Coffee, whatever) and require bud as "task" or "build":

var task = require('bud')

And create your first task;

var task = require('bud')
 
task('say hello', function (t) {
  t.exec('echo "hello!"').then(t.done)
})

The task above just says hello by spawning child process. To call this task in your command-line is pretty simple, all you do is calling the script you've created. In this example, I saved my tasks as do.js so I can simply call node do:

$ node do say-hello
say-hello  Running...
say-hello  (3951:echo "hello!")  "hello!"

Tasks can take parameters from command-line:

task('say hello', function (t) {
  t.exec('echo "hello {name}!"', t.params).then(t.done)
})

Passing parameters is similar to Makefiles:

$ node do say-hello name=azer
say-hello  Running...
say-hello  (3951:echo "hello!")  "hello azer!"

To watch files, pass extra options when you create a new task;

var task = require('bud')
 
task('say hello', task.files('*.js'), function (t) {
  t.files
  // => ['foo.js', 'bar.js' ...] 
 
  t.exec('echo "hello!"').then(t.done)
})

Pass -w or --watch parameter to enable file watching:

$ node do say-hello -w

This will restart the task by killing any actively running processes.

.watch method returns a chain with three more methods;

  • ignore
  • once
  • files

ignore: takes any filenames or glob patterns to specify the files to ignore. once: specifies the other tasks to be completed before running the defining task. files: alias for the watch method.

You can define tasks that requires to complete other tasks parelelly first using the .once method:

var task = require('bud')
 
task('foo', function (t) {
  t.end()
})
 
task('bar', function (t) {
  t.end()
})
 
task('qux', t.once('foo', 'bar'), function (t) {
  t.end()
})

Bud automatically resolves and prefers local binaries for you. For example, following task will be running './node_modules/browserify/bin/cmd' instead of global browserify:

var build = require('bud')
 
build('dist.js', function (b) {
  b.exec('browserify entry.js -o dist.js')
   .then(b.done);
})

You can define tasks that takes parameters from command-line. For example, let's say we wanna have a task that installs our app in remote machine with Docker:

var task = require('bud')
var setupDocker = require('setup-docker')
 
task('install', function (t) {
  setupDocker({ name: 'your-app', ssh: t.params.remote, dockerfile: './Dockerfile', port: '80:8080' }, t.done);
})

And here is how you can call this task from command-line:

$ node do install remote=azer@chessapp.com

To list available tasks in a file, pass -l or --list;

$ node [filename] -l

To see bud help:

$ node [filename] -h # or --help
var build = require('bud')
var concat = require('concat')
 
build('dist.css', build.watch('**/*.css').ignore('dist.css'), function (b) {
  concat(b.files, 'dist.css', b.done)
})

Using the library:

var browserify = require('browserify')
var build = require('bud')
 
build('dist.js', build.watch('**/*.js').ignore('node_modules', 'dist.js'), function (b) {
  browserify('entry.js').bundle().pipe(build.write('dist.js'))
})

Calling the command:

build('dist.js', build.watch('**/*.js').ignore('node_modules', 'dist.js'), function (b) {
  b.exec('browserify entry.js -o dist.js').then(b.done)
})

Using a library:

var task = require('bud')
var rmrf = require('rimraf-glob')
 
task('clean', function (t) {
  rmrf('dist.*', t.done)
})

Calling the rm command:

task('clean', function (t) {
  t.exec('rm -rf dist.*').then(t.done)
})
var remotely = require('remotely')
var task = require('bud')
 
task('update remote', function (t) {
   var r = remotely('azer@yourapp.com', 'cd repo && git pull')
   r.on('close', t.done)
   r.stdout.pipe(t.stdout)
   r.stderr.pipe(t.stderr)
})
task('publish', function (t) {
  t.exec('python -m SimpleHTTPServer').then(t.done)
})
var task = require('bud')
 
task('test', task.files('**/*.js'), function (t) {
  t.exec('node test').then(t.done)
})

Don't forget passing -w parameter:

$ node do test -w
var task = require('bud')
var concat = require('concat')
var build = task
 
task('send', task.once('dist.js', 'dist.css'), function (t) {
  t.exec('scp dist.* {0}:/src/.', t.params.remote).then(t.done)
})
 
build('dist.js', build.watch('**/*.js').ignore('dist.js'), function (b) {
  concat(b.files, 'dist.js', b.done)
})
 
build('dist.css', build.watch('**/*.css').ignore('dist.css'), function (b) {
  concat(b.files, 'dist.css', b.done)
})

You can run this task once, or on every change on the files:

$ node do send remote=azer@yourapp.com -w

You can define a default task that will run when no task name is given, as a dependent task:

task('default', task.once('dist.js', 'dist.css'))

File an issue, pull requests are always welcome!