Watchful

A shell script for busy web developers

What?

Watchful is a lightweight tool that runs command line tools on updated files. It was built by a web developer who got seriously tired of managing a whole range of CLI minification, translation, and compression tools on his CSS, Javascript, PNGs, etc.

You can think of Watchful as kind of recursive, constantly-running Rake: you tell it which tools to run on which files, then fire it off in your current project directory and go back to your text editor. When you save a change to a relevant file under that directory, Watchful will run the proper tool on it. If you have Growl installed, you’ll get a notification. If you’re on OS X Leopard and have the FSEvents gem installed, you’ll get a rather nice performance to boot.

Where?

Watchful is available as a Gem:

sudo gem install watchful

The development git repo is currently hosted on GitHub:

http://github.com/kemitchell/watchful

Please feel free to fork me!

To install the latest from GitHub:

cd /tmp
git clone git://github.com/kemitchell/watchful.git
cd watchful
rake build
sudo rake install

How?

All configuration is done in pure Ruby. Configurations are created by subclassing Watchful::Configuration in watchful files. Configurations contain action lines which describe CLI commands, the extension of the files they should be run on, and the extension that should be used for the resulting output. An example follows:

require 'rubygems'
require 'watchful/configuration'

class MyConfiguration < Watchful::Configuration

    description 'LESS CSS and YUI Compressor'

    # actions are applied in order, hence Less is defined before YUI

    action  :name => "Less CSS",        # Used for command line and Growl notifications
            :in => ".less",             # The extension of files to use as input
            :out => ".css",             # Extension to replace the above for output files
            :command => "lessc %s %s",  # The command to create output files from input files
                                        # In the future all of the above will also take blocks.
                                        # Currently the command is built using sprintf.
                                        # The first %s is the full input path.
                                        # The second %s is the full output path.
            :dependencies => ['less']   # If “less” isn’t found in PATH, this action will be disabled.

    action  :name => 'YUI Compressor',
            :in => '.css',
            :out => '.min.css',         # Notice that Watchful computes extensions differently than basename
                                        # Namely, the extension is anything in the file name from the
                                        # first period onward, hence this.big.ext.name => '.big.ext.name'
            :command => 'java -jar /usr/local/utils/yuicompressor-2.4.2.jar --type css --charset utf-8 %s -o %s',
            :dependencies => ['java', '/usr/local/utils/yuicompressor-2.4.2.jar']
                                        # Dependencies can be programs (e.g. “java”), or full file paths.

end

When Watchful is started, it searches in the following locations (in the following order) for files called watchful and loads them:

  1. In the directory Watchful is told to monitor
  2. In the current user’s home directory

If no such files are found, Watchful will use the default configuration, which searches your PATH for tools it recognizes. If your tool isn't listed in http://github.com/kemitchell/watchful/blob/master/lib/watchful/defaultconfiguration.rb and you would like it to be, please fork the project or send me a patch. I would be happy to include any web development tools with current stable or Beta releases.