{"id":37164095,"url":"https://github.com/troykinsella/bacon","last_synced_at":"2026-01-14T19:30:09.143Z","repository":{"id":43614140,"uuid":"71522265","full_name":"troykinsella/bacon","owner":"troykinsella","description":"Watch for file changes and continuously trigger commands","archived":false,"fork":false,"pushed_at":"2025-08-01T17:57:39.000Z","size":153,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-01T19:34:54.599Z","etag":null,"topics":["command-line","development","go","golang","sweet-bacon","watch-files"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/troykinsella.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-21T02:28:22.000Z","updated_at":"2025-08-01T17:57:23.000Z","dependencies_parsed_at":"2024-06-19T22:52:58.035Z","dependency_job_id":"216a8a92-a93a-4e04-b742-32e8eb58f80d","html_url":"https://github.com/troykinsella/bacon","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/troykinsella/bacon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troykinsella%2Fbacon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troykinsella%2Fbacon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troykinsella%2Fbacon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troykinsella%2Fbacon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/troykinsella","download_url":"https://codeload.github.com/troykinsella/bacon/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troykinsella%2Fbacon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28432618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T18:57:19.464Z","status":"ssl_error","status_checked_at":"2026-01-14T18:52:48.501Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command-line","development","go","golang","sweet-bacon","watch-files"],"created_at":"2026-01-14T19:30:08.335Z","updated_at":"2026-01-14T19:30:09.033Z","avatar_url":"https://github.com/troykinsella.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Bacon](https://troykinsella.github.io/bacon/bacon.png)\n---\n\n[![Version](https://badge.fury.io/gh/troykinsella%2Fbacon.svg)](https://badge.fury.io/gh/troykinsella%2Fbacon)\n[![License](https://img.shields.io/github/license/troykinsella/bacon.svg)](https://github.com/troykinsella/bacon/blob/master/LICENSE)\n[![Build Status](https://github.com/troykinsella/bacon/actions/workflows/ci.yml/badge.svg)](https://github.com/troykinsella/bacon/actions/workflows/ci.yml)\n\nA tool to watch files for changes and continuously react by running commands.\n\n## Contents\n\n1. [Features](#features)\n1. [Installation](#installation)\n1. [Usage](#usage)\n    1. [TL;DR](#tldr)\n    1. [Program Commands](#program-commands)\n    1. [Shell Commands](#shell-commands)\n    1. [On-Success Commands](#on-success-commands)\n    1. [On-Failure Commands](#on-failure-commands)\n    1. [Command Arguments](#command-arguments)\n    1. [Watch Files](#watch-files)\n    1. [Baconfile](#baconfile)\n1. [Output](#output)\n    1. [Command Status Line](#command-status-line)\n    1. [Status Notifications](#status-notifications)\n1. [Troubleshooting](#troubleshooting)\n1. [Road Map](#road-map)\n1. [Similar Tools](#similar-tools)\n1. [License](#license)\n\n## Features\n\n* Compatible with tooling for any technology; `bacon` simply executes shell commands\n* Control files to watch using extended globs\n* Command status summary line\n* Command status system notifications\n* Store bacon configuration in a yaml Baconfile\n\n## Installation\n\nCheckout [releases](https://github.com/troykinsella/bacon/releases) and download the appropriate binary for your system.\nPut the binary in a convenient place, such as `/usr/local/bin/bacon`.\n\nOr, run the handy dandy install script:\n(Note: go read the script and understand what you're running before trusting it)\n```bash\nexport PREFIX=~ # install into ~/bin\nwget -q -O - https://raw.githubusercontent.com/troykinsella/bacon/master/install.sh | bash\n```\n\nOr, run these commands to download and install:\n```bash\nVERSION=1.0.0\nOS=darwin # or linux, or windows\ncurl -SL -o /usr/local/bin/bacon https://github.com/troykinsella/bacon/releases/download/v${VERSION}/bacon_${OS}_amd64\nchmod +x /usr/local/bin/bacon\n```\n\nOr, for [Go lang](https://golang.org/doc/code.html) projects, from your `GOPATH`:\n```bash\ngo get github.com/troykinsella/bacon\n```\n\nLastly, test the installation:\n```bash\nbacon -h\n```\n\n## Usage\n\nRunning `bacon` will watch your files, run commands when they've changed. As\nsoon as you run `bacon`, it will immediately execute your commands, without\nwaiting for a watched file to change.\n\n### TL;DR\n\nHere.\n```bash\n# Load a Baconfile and run the default target.\nbacon run\n\n# Load a Baconfile and run a specific target.\nbacon run other-files\n\n# Generate a Baconfile by asking you questions.\nbacon init\n\n# Watch files matching **/* in the CWD, except for files in **/.*,\n# and run a script when any of them change.\nbacon -c ./run-me.sh\n\n# Watch Go lang project source files and run \"go test\" when any change.\nbacon -w 'src/github.com/you/project/**/*.go' \\\n      -c 'go test github.com/you/project/...'\n\n# Watch Node.js project source files and run mocha tests when any change.\nbacon -w '**/*.js' \\\n      -w '**/*.json' \\\n      -e node_modules \\\n      -c 'mocha test/unit/*.js'\n\n# Watch a mixed set of files by including some then excluding from those.\nbacon -w '**/*.sh' \\\n      -e '**/third-party' \\\n      -c ./test.sh\n\n# Run commands only when pass or fail.\nbacon -c check-syntax.sh \\\n      -c find-bugs.sh \\\n      -p notfiy-tom-vogel-of-great-success.sh \\\n      -f notify-tom-vogel-of-terrible-failure.sh\n\n# Use long options for readability.\nbacon --watch '**/*.sh' \\\n      --exclude '**/third-party' \\\n      --cmd ./test.sh\n\n# Print the effective list of files for the given inclusions and exclusions.\nbacon list -w '**/*.rb' \\\n           -e '**/.git' \\\n           -e '**/naughty'\n\n# Execute the given commands once, as bacon would after a watched file change,\n# then exit. Useful for troubleshooting bacon configuration.\nbacon command -c ./unit-tests.sh \\\n              -c ./int-tests.sh \\\n              -p ./celebrate.sh\n```\n\n### Program Commands\n\n`bacon` provides several different ways to run it by passing (or omitting) a command name.\n\"Command\" in this context is not to be confused with the shell commands that are given to\n`bacon` to execute with the `-c` option (see [Shell Commands](#shell-commands)).\n\nCommands:\n\nCommand     | Description\n----------- | -----------\n`\u003comitted\u003e` | Watch a set of files, and run the given shell commands when they change.\n`command`   | Execute the given shell commands as `bacon` would when watching files, and exit.\n`init`      | Generate a `Baconfile` by asking you questions.\n`list`      | Print a list of files matched by the given inclusion and exclusion glob expressions, and exit.\n`run`       | Load a `Baconfile` and run a target, which specifies a set of files to watch, and commands to run when they change.\n\nRun `bacon -h` for comprehensive usage.\n\n### Shell Commands\n\nWhen files change, `bacon` runs the shell commands that you pass with the `-c, --cmd` option:\n```bash\nbacon -c \"go test github.com/you/project/...\" \\\n      -c \"./find-bugs.sh\"\n```\n\nCommands are executed in the order supplied, and against the same working directory\nin which you ran `bacon`. When running several commands, `bacon` will only consider the\nexecution as \"passing\" if all commands exit with code `0`. The first command that\nfails (exits with non-`0`), will abort the execution of subsequent commands, and\nmark the entire execution as \"failing\".\n\n### On-Success Commands\n\nCommands supplied with the `-p, --pass` option are executed only when all `-c` commands pass.\n```bash\nbacon -c \"go test github.com/you/project/...\" \\\n      -p \"./notify-the-pentagon.sh\"\n```\nThese \"pass\" commands do not influence the final pass/fail result.\n\n### On-Failure Commands\n\nCommands passed with the `-f, --fail` option are executed when a `-c` command fails.\n```bash\nbacon -c \"go test github.com/you/project/...\" \\\n      -f ./send-email-to-microsoft.sh\n```\nThese \"fail\" commands do not influence the final pass/fail result.\n\n### Command Arguments\n\nAll commands are provided a `$BACON_CHANGED` environment variable containing the absolute path\nof the file that changed to trigger the command execution, if any.\n\n```bash\nbash -c \"go test github.com/you/project/...\" \\\n     -p 'go fmt $BACON_CHANGED'\n```\n\nHere, `bacon` is running `go fmt` against the file that was just changed, if tests pass.\nNote: Be sure to pass `$BACON_CHANGED` in single quotes so that your shell doesn't interpret it\nprior to being passed into `bacon`.\n\nWhen commands are executed not as a result of a file change, such as immediately after\nrunning `bacon` or when using `bacon command`, `$BACON_CHANGED` is substituted with an empty string (\"\").\n\n### Watch Files\n\nFiles can be watched for changes. \"Change\", specifically,\nmeans: When a file is written to. Creation and deletion changes are ignored.\n\nFiles are selected for watching using extended glob syntax (having support for `**`).\nSee the [bmatcuk/doublestar](https://github.com/bmatcuk/doublestar) documentation for glob syntax.\n`bacon` does not follow symlinks in resolving matches. Globs that do not start with `/` are\nconsidered relative to the CWD.\n\nA list of include globs and a list of exclude globs can be passed into `bacon` to tell it what to watch.\nFirst, the list of includes is expanded, then the result is passed through the excludes list to arrive\nat the effective list of files to watch.\n\nUse the `bacon list` command to print the effective watch list, and exit.\n\n#### Includes\n\nWithout telling `bacon` otherwise, it includes `**/*`, which translates into\n\"every file below the CWD\". Supply one or more alternate include globs with the\n`-w, --watch` option:\n```bash\nbacon -w \"src/github.com/you/project/**\" \\\n      -c \"go test github.com/you/project/...\"\n```\n\n#### Excludes\n\n`bacon` excludes `**/.*` by default, which omits any `.*` (dot) file or directory.\nPass one ore more alternate exclude globs with the `-e, --exclude` option:\n\n```bash\nbacon -w \"src/github.com/you/project/**\" \\\n      -e \"src/github.com/you/project/no-watchee/**\" \\\n      -c \"go test github.com/you/project/...\"\n```\n\nIf you supply an exclusion, be sure to also supply the overridden `**/.*` default,\nif that's desirable.\n\n```bash\nbacon -e \"exclude-me/**\" \\\n      -e \"**/.*\" \\\n      -c ./test-my-stuff.sh\n```\n\n### Baconfile\n\nA `Baconfile` is a YAML file that defines configuration for which files to watch\nand which commands to execute when files change. It contains `targets` which are \nconfiguration profiles. Using `targets`, you can capture multiple configurations \nin one `Baconfile` and select the desired configuration when you run `bacon`.\n\nRun `bacon init` to generate a `Baconfile` by asking you questions.\n\n#### Running `bacon` with a `Baconfile`\n\nThe `bacon run` command loads a `Baconfile` to find configuration\nrather than requiring you to pass arguments, such as `-w` and `-c`.\nIf a `Baconfile` is not specified with the `-b` option, `bacon` \nsearches for one in the current working directory in this order:\n\n* `Baconfile`\n* `Baconfile.yml`\n* `Baconfile.yaml`\n* `.Baconfile`\n* `.Baconfile.yml`\n* `.Baconfile.yaml`\n\nThe \"default\" `target` is special in that it is loaded when a target name is not\nsupplied to the `bacon run [target]` command, otherwise the specified\n`target` is loaded.\n\n#### Baconfile Fields\n\nA `Baconfile` has two fields at its root:\n\n* `version`: Optional. The version of the `Baconfile` specification used. \n  Currently only `1.0` is supported.\n* `targets`: Required. A list of target objects.\n\nA `target` object defines a single configuration for how `bacon` should\nwatch files and run things for you. It allows these fields:\n\n* `dir`: Optional. The working directory on which `watch` and `exclude` patterns are \n  rooted, and on which `command`, `pass`, and `fail` commands are executed. Defaults\n  to the working directory in which you run `bacon`. Can be a relative or absolute path.\n* `watch`: At least one entry required. A list of glob patterns to watch for changes. \n  Equivalent to the `-w` argument.\n* `exclude`: Optional. A list of glob patterns to exclude from the `watch` matches.\n  Equivalent to the `-e` argument.\n* `command`: At least one entry required. A list of commands to execute whenever files change.\n  Equivalent to the `-c` argument.\n* `pass`: Optional. A list of commands to execute only if the `command` list succeeds.\n  Equivalent to the `-p` argument.\n* `fail`: Optional. A list of commands to execute only if any of the `command` list fails.\n  Equivalent to the `-f` argument.\n\n#### Baconfile Example\n\n```yaml\n---\nversion: \"1.0\"\ntarget:\n  target_name:\n    dir: \"some/cwd\"\n    watch: [ \"some/files/**\" ]\n    exclude: [ \"some/files/*.not_me\" ]\n    command: [ \"make test\", \"make something-else\" ]\n    pass: [ \"celebrate.sh\" ]\n    fail: [ \"eat-a-bucket-of-ice-cream.sh\" ]\n```\n\n## Output\n\nBy default, `bacon` only prints status lines, clearing the screen in between command executions\nto hide clutter. But, if you pass it `-o, --show-output`, it will print all command output continuously.\nRegardless of this option, if an execution fails, the output and error streams of the failing\ncommand are printed to `bacon`'s standard error.\n\n### Command Status Line\n\nSince it takes more than a single glance to figure out from the command output if \ncommands have passed or failed, `bacon` prints an ansii-coloured status line after\nexecutions.\n\nWhen commands start executing, `bacon` prints this:\n```\n[19:31:40] → Running\n```\n\nAfter commands complete successfully, a passing status looks like this:\n```\n[19:31:42] ✓ Passed\n```\n\nOr, if any command fails:\n```\n[19:37:13] ✗ Failed\n```\n\n### Status Notifications\n\nSometimes you don't want to watch a terminal to see `bacon` output, you just\nwant to know when things break, and when they're fixed. That's where\nstatus system notifications come in. Notifications look like this:\n\n![Commands Recovered](https://troykinsella.github.io/bacon/notify_recover.png)\n\nIn order to not spam you with notifications for every watched file change,\n`bacon` will only notify you when:\n\n* Commands pass or fail for the first time\n* Commands were failing, but are now passing\n* Commands were passing, but are now failing\n\nIf you don't want notifications, pass the `--no-notify` option.\n\n## Troubleshooting\n\n### My file changes aren't being noticed\n\nAre your inclusion/exclusion globs correct? See what `bacon` is effectively watching\nwith the `bacon list` command.\n\nAre you watching more files than your operating system can support? \nAdjust your include (`-w`), and/or exclude (`-e`) options as necessary to reduce the match count.\n\n### System notifications aren't working\n\nSystem notifications are supported by [0xAX/notificator](https://github.com/0xAX/notificator).\nRefer to this documentation to see if notifications are supported on your operating system.\n\n### My commands are executing endlessly\n\nThe commands you're running are potentially modifying files, causing and endless execution loop.\nStop it. In the future `bacon` will detect endless build loops.\n\n## Road Map\n\n* Detect endless build loops\n\n## Similar Tools\n\nIf `bacon` doesn't suit your need, maybe the excellent [Tonkpils/snag](https://github.com/Tonkpils/snag) will.\n\n## License\n\nMIT © Troy Kinsella\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroykinsella%2Fbacon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftroykinsella%2Fbacon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroykinsella%2Fbacon/lists"}