hawkeye

Monitors files for changes and fires commands straight at them when they do.

hawkeye - track files and fire commands at them (like a boss).

This functionality was inspired by tools like grunt and fsniper (to name a couple). The reason why I decided to take a whack at it was because I thought they are either too complex for the job at hand or too difficult to configure. Hawkeye uses a very simple configuration syntax to get you going. Plus it has a method called "deploy(warhead)" that actually works, which is just plain awesome.

You can use any valid glob-style pattern to target files. If you already know you way around the command line, you probably already know how to glob files:

  • A single asterisk (*) selects everything
  • Specific extensions are specified with an asterisk followed by the extension (*.txt)
  • A literal file name can be specified by just naming it (i.e. example.txt)
  • More complex patterns can be found in the minimatch readme

The moment a tracked file is modified on disk, the related command is executed and the results are logged by stdout/stderr (for now, although I will add support for standard log files soon). Real time tracking is provided by the most excellent [node-]inotify.

Create a JSON file on the current path which serves as a config file:

$ hawkeye -C watch.json

A file with contents similar to this one is created:

{
  "/your/path" : {
    "*" : "echo the file %% was just modified!"
  }
}

Specify the path that you want to track by changing /your/path with... well, your path. Then simply provide a pattern to track file(s) and the command to execute once a modification is detected. The two percentage signs get replaced with the absolute path of the file being tracked at runtime. For example, if you create a file called /your/path/example.txt, you will get the following command:

$ echo file /your/path/example was just modified!

Which in this case will simply (you guessed it) echo that command on screen.

A slightly more complicated example:

{
  "/etc" : {
    "*.conf" : "logger someone just changed %%"
  },
  "/mnt/downloads/" : {
    "*.pdf" : "mupdf %%",
    "*.zip" : "unzip %%"
  }
}

Both abosulte and relative paths work, so you can simply use a single dot to specify the current working directory:

{
  "." : {
    "*.txt" : "echo the text file %% was just detected."
  }
}

The tracking is NOT made recursively, so you will need to specify both the parent and child paths if you want to track them both:

{
  "downloads/" : {
    "*.pdf" : "logger 'new download: %%'"
  },
  "downloads/ebooks" : {
    "*.pdf" : "mupdf %%"
  }
}

Once the config file is saved, point to it using the -c switch:

$ hawkeye -c example.json

Add -v if you want verbose output:

$ hawkeye -vc example.json
hawkeye info version 0.0.1 deployed
hawkeye info opened watch file './example.json'
hawkeye info tracking target '/any/absolute/path'
hawkeye info tracking target 'relative/paths/too'
$ hawkeye -h

Usage: hawkeye [options]

  Options:

    -h, --help           output usage information
    -V, --version        output the version number
    -c, --config <path>  set config file path
    -C, --create <path>  create a boilerplate config file in the specified path
    -v, --verbose        output events to stdout

Hawkeye uses the following excellent libraries:

If you happen to be running this under Linux with systemd, you can use this service file to run hawkeye in the background.

Feel free to fork away and/or submit a pull request. If you want to contact me directly, you can email me (hawkeye at bkuri.com) or send me a tweet (@bkuri). I read and try to reply to everything.