A tool to watch files for changes and continuously react by running commands.
- Compatible with tooling for any technology;
baconsimply executes shell commands - Control files to watch using extended globs
- Command status summary line
- Command status system notifications
- Store bacon configuration in a yaml Baconfile
Checkout releases and download the appropriate binary for your system.
Put the binary in a convenient place, such as /usr/local/bin/bacon.
Or, run the handy dandy install script: (Note: go read the script and understand what you're running before trusting it)
export PREFIX=~ # install into ~/bin
wget -q -O - https://raw.githubusercontent.com/troykinsella/bacon/master/install.sh | bashOr, run these commands to download and install:
VERSION=1.0.0
OS=darwin # or linux, or windows
curl -SL -o /usr/local/bin/bacon https://github.com/troykinsella/bacon/releases/download/v${VERSION}/bacon_${OS}_amd64
chmod +x /usr/local/bin/baconOr, for Go lang projects, from your GOPATH:
go get github.com/troykinsella/baconLastly, test the installation:
bacon -hRunning bacon will watch your files, run commands when they've changed. As
soon as you run bacon, it will immediately execute your commands, without
waiting for a watched file to change.
Here.
# Load a Baconfile and run the default target.
bacon run
# Load a Baconfile and run a specific target.
bacon run other-files
# Generate a Baconfile by asking you questions.
bacon init
# Watch files matching **/* in the CWD, except for files in **/.*,
# and run a script when any of them change.
bacon -c ./run-me.sh
# Watch Go lang project source files and run "go test" when any change.
bacon -w 'src/github.com/you/project/**/*.go' \
-c 'go test github.com/you/project/...'
# Watch Node.js project source files and run mocha tests when any change.
bacon -w '**/*.js' \
-w '**/*.json' \
-e node_modules \
-c 'mocha test/unit/*.js'
# Watch a mixed set of files by including some then excluding from those.
bacon -w '**/*.sh' \
-e '**/third-party' \
-c ./test.sh
# Run commands only when pass or fail.
bacon -c check-syntax.sh \
-c find-bugs.sh \
-p notfiy-tom-vogel-of-great-success.sh \
-f notify-tom-vogel-of-terrible-failure.sh
# Use long options for readability.
bacon --watch '**/*.sh' \
--exclude '**/third-party' \
--cmd ./test.sh
# Print the effective list of files for the given inclusions and exclusions.
bacon list -w '**/*.rb' \
-e '**/.git' \
-e '**/naughty'
# Execute the given commands once, as bacon would after a watched file change,
# then exit. Useful for troubleshooting bacon configuration.
bacon command -c ./unit-tests.sh \
-c ./int-tests.sh \
-p ./celebrate.shbacon provides several different ways to run it by passing (or omitting) a command name.
"Command" in this context is not to be confused with the shell commands that are given to
bacon to execute with the -c option (see Shell Commands).
Commands:
| Command | Description |
|---|---|
<omitted> |
Watch a set of files, and run the given shell commands when they change. |
command |
Execute the given shell commands as bacon would when watching files, and exit. |
init |
Generate a Baconfile by asking you questions. |
list |
Print a list of files matched by the given inclusion and exclusion glob expressions, and exit. |
run |
Load a Baconfile and run a target, which specifies a set of files to watch, and commands to run when they change. |
Run bacon -h for comprehensive usage.
When files change, bacon runs the shell commands that you pass with the -c, --cmd option:
bacon -c "go test github.com/you/project/..." \
-c "./find-bugs.sh"Commands are executed in the order supplied, and against the same working directory
in which you ran bacon. When running several commands, bacon will only consider the
execution as "passing" if all commands exit with code 0. The first command that
fails (exits with non-0), will abort the execution of subsequent commands, and
mark the entire execution as "failing".
Commands supplied with the -p, --pass option are executed only when all -c commands pass.
bacon -c "go test github.com/you/project/..." \
-p "./notify-the-pentagon.sh"These "pass" commands do not influence the final pass/fail result.
Commands passed with the -f, --fail option are executed when a -c command fails.
bacon -c "go test github.com/you/project/..." \
-f ./send-email-to-microsoft.shThese "fail" commands do not influence the final pass/fail result.
All commands are provided a $BACON_CHANGED environment variable containing the absolute path
of the file that changed to trigger the command execution, if any.
bash -c "go test github.com/you/project/..." \
-p 'go fmt $BACON_CHANGED'Here, bacon is running go fmt against the file that was just changed, if tests pass.
Note: Be sure to pass $BACON_CHANGED in single quotes so that your shell doesn't interpret it
prior to being passed into bacon.
When commands are executed not as a result of a file change, such as immediately after
running bacon or when using bacon command, $BACON_CHANGED is substituted with an empty string ("").
Files can be watched for changes. "Change", specifically, means: When a file is written to. Creation and deletion changes are ignored.
Files are selected for watching using extended glob syntax (having support for **).
See the bmatcuk/doublestar documentation for glob syntax.
bacon does not follow symlinks in resolving matches. Globs that do not start with / are
considered relative to the CWD.
A list of include globs and a list of exclude globs can be passed into bacon to tell it what to watch.
First, the list of includes is expanded, then the result is passed through the excludes list to arrive
at the effective list of files to watch.
Use the bacon list command to print the effective watch list, and exit.
Without telling bacon otherwise, it includes **/*, which translates into
"every file below the CWD". Supply one or more alternate include globs with the
-w, --watch option:
bacon -w "src/github.com/you/project/**" \
-c "go test github.com/you/project/..."bacon excludes **/.* by default, which omits any .* (dot) file or directory.
Pass one ore more alternate exclude globs with the -e, --exclude option:
bacon -w "src/github.com/you/project/**" \
-e "src/github.com/you/project/no-watchee/**" \
-c "go test github.com/you/project/..."If you supply an exclusion, be sure to also supply the overridden **/.* default,
if that's desirable.
bacon -e "exclude-me/**" \
-e "**/.*" \
-c ./test-my-stuff.shA Baconfile is a YAML file that defines configuration for which files to watch
and which commands to execute when files change. It contains targets which are
configuration profiles. Using targets, you can capture multiple configurations
in one Baconfile and select the desired configuration when you run bacon.
Run bacon init to generate a Baconfile by asking you questions.
The bacon run command loads a Baconfile to find configuration
rather than requiring you to pass arguments, such as -w and -c.
If a Baconfile is not specified with the -b option, bacon
searches for one in the current working directory in this order:
BaconfileBaconfile.ymlBaconfile.yaml.Baconfile.Baconfile.yml.Baconfile.yaml
The "default" target is special in that it is loaded when a target name is not
supplied to the bacon run [target] command, otherwise the specified
target is loaded.
A Baconfile has two fields at its root:
version: Optional. The version of theBaconfilespecification used. Currently only1.0is supported.targets: Required. A list of target objects.
A target object defines a single configuration for how bacon should
watch files and run things for you. It allows these fields:
dir: Optional. The working directory on whichwatchandexcludepatterns are rooted, and on whichcommand,pass, andfailcommands are executed. Defaults to the working directory in which you runbacon. Can be a relative or absolute path.watch: At least one entry required. A list of glob patterns to watch for changes. Equivalent to the-wargument.exclude: Optional. A list of glob patterns to exclude from thewatchmatches. Equivalent to the-eargument.command: At least one entry required. A list of commands to execute whenever files change. Equivalent to the-cargument.pass: Optional. A list of commands to execute only if thecommandlist succeeds. Equivalent to the-pargument.fail: Optional. A list of commands to execute only if any of thecommandlist fails. Equivalent to the-fargument.
---
version: "1.0"
target:
target_name:
dir: "some/cwd"
watch: [ "some/files/**" ]
exclude: [ "some/files/*.not_me" ]
command: [ "make test", "make something-else" ]
pass: [ "celebrate.sh" ]
fail: [ "eat-a-bucket-of-ice-cream.sh" ]By default, bacon only prints status lines, clearing the screen in between command executions
to hide clutter. But, if you pass it -o, --show-output, it will print all command output continuously.
Regardless of this option, if an execution fails, the output and error streams of the failing
command are printed to bacon's standard error.
Since it takes more than a single glance to figure out from the command output if
commands have passed or failed, bacon prints an ansii-coloured status line after
executions.
When commands start executing, bacon prints this:
[19:31:40] → Running
After commands complete successfully, a passing status looks like this:
[19:31:42] ✓ Passed
Or, if any command fails:
[19:37:13] ✗ Failed
Sometimes you don't want to watch a terminal to see bacon output, you just
want to know when things break, and when they're fixed. That's where
status system notifications come in. Notifications look like this:
In order to not spam you with notifications for every watched file change,
bacon will only notify you when:
- Commands pass or fail for the first time
- Commands were failing, but are now passing
- Commands were passing, but are now failing
If you don't want notifications, pass the --no-notify option.
Are your inclusion/exclusion globs correct? See what bacon is effectively watching
with the bacon list command.
Are you watching more files than your operating system can support?
Adjust your include (-w), and/or exclude (-e) options as necessary to reduce the match count.
System notifications are supported by 0xAX/notificator. Refer to this documentation to see if notifications are supported on your operating system.
The commands you're running are potentially modifying files, causing and endless execution loop.
Stop it. In the future bacon will detect endless build loops.
- Detect endless build loops
If bacon doesn't suit your need, maybe the excellent Tonkpils/snag will.
MIT © Troy Kinsella

