{"id":13484060,"url":"https://github.com/alexch/rerun","last_synced_at":"2025-05-14T11:13:34.339Z","repository":{"id":587714,"uuid":"221696","full_name":"alexch/rerun","owner":"alexch","description":"Restarts an app when the filesystem changes. Uses growl and FSEventStream if on OS X.","archived":false,"fork":false,"pushed_at":"2024-05-22T19:48:26.000Z","size":321,"stargazers_count":982,"open_issues_count":30,"forks_count":80,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-04-15T05:16:20.843Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexch.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,"zenodo":null}},"created_at":"2009-06-08T15:59:27.000Z","updated_at":"2025-04-03T12:17:28.000Z","dependencies_parsed_at":"2025-04-15T01:55:49.775Z","dependency_job_id":"16e143a1-53d5-4a72-9202-cf7487fc5d63","html_url":"https://github.com/alexch/rerun","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexch%2Frerun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexch%2Frerun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexch%2Frerun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexch%2Frerun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexch","download_url":"https://codeload.github.com/alexch/rerun/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254129530,"owners_count":22019629,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-07-31T17:01:18.829Z","updated_at":"2025-05-14T11:13:34.291Z","avatar_url":"https://github.com/alexch.png","language":"Ruby","funding_links":[],"categories":["Ruby","File System Listener"],"sub_categories":[],"readme":"# Rerun\n\n\u003chttp://github.com/alexch/rerun\u003e\n\nRerun launches your program, then watches the filesystem. If a relevant file\nchanges, then it restarts your program.\n\nRerun works for both long-running processes (e.g. apps) and short-running ones\n(e.g. tests). It's basically a no-frills command-line alternative to Guard,\nShotgun, Autotest, etc. that doesn't require config files and works on any\ncommand, not just Ruby programs.\n\nRerun's advantage is its simple design. Since it uses `exec` and the standard\nUnix `SIGINT` and `SIGKILL` signals, you're sure the restarted app is really\nacting just like it was when you ran it from the command line the first time.\n\nBy default it watches files ending in: `rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature,c,h`.\nUse the `--pattern` option if you want to change this.\n\nAs of version 0.7.0, we use the Listen gem, which tries to use your OS's\nbuilt-in facilities for monitoring the filesystem, so CPU use is very light.\n\n**UPDATE**: Now Rerun *does* work on Windows! Caveats:\n  * not well-tested\n  * you need to press Enter after keypress input\n  * you may need to install the `wdm` gem manually: `gem install wdm`\n  * You may see this persistent `INFO` error message; to remove it, use`--no-notify`:\n    * `INFO: Could not find files for the given pattern(s)`\n\n# Installation:\n\n        gem install rerun\n\n(\"sudo\" may be required on older systems, but try it without sudo first.)\n\nIf you are using RVM you might want to put this in your global gemset so it's\navailable to all your apps. (There really should be a better way to distinguish\ngems-as-libraries from gems-as-tools.)\n\n        rvm @global do gem install rerun\n\nThe Listen gem looks for certain platform-dependent gems, and will complain if\nthey're not available. Unfortunately, Rubygems doesn't understand optional\ndependencies very well, so you may have to install extra gems (and/or put them\nin your Gemfile) to make Rerun work more smoothly on your system.\n(Learn more at \u003chttps://github.com/guard/listen#listen-adapters\u003e.)\n\nOn Mac OS X, use\n\n        gem install rb-fsevent\n\nOn Windows, use\n\n        gem install wdm\n\nOn *BSD, use\n\n        gem install rb-kqueue\n\n## Installation via Gemfile / Bundler\n\nIf you are using rerun inside an existing Ruby application (like a Rails or Sinatra app), you can add it to your Gemfile:\n\n``` ruby\ngroup :development, :test do\n  gem \"rerun\"\nend\n```\n\nUsing a Gemfile is also an easy way to use the pre-release branch, which may have bugfixes or features you want:\n\n``` ruby\ngroup :development, :test do\n  gem \"rerun\", git: \"https://github.com/alexch/rerun.git\"\nend\n```\n\nWhen using a Gemfile, install with `bundle install` or `bundle update`, and run using `bundle exec rerun`, to guarantee you are using the rerun version specified in the Gemfile, and not a different version in a system-wide gemset.\n\n# Usage:\n\n        rerun [options] [--] cmd\n\nFor example, if you're running a Sinatra app whose main file is `app.rb`:\n\n        rerun ruby app.rb\n\nIf the first part of the command is a `.rb` filename, then `ruby` is\noptional, so the above can also be accomplished like this:\n\n        rerun app.rb\n\nRails doesn't automatically notice all config file changes, so you can force it\nto restart when you change a config file like this:\n\n        rerun --dir config rails s\n\nOr if you're using Thin to run a Rack app that's configured in config.ru\nbut you want it on port 4000 and in debug mode, and only want to watch\nthe `app` and `web` subdirectories:\n\n        rerun --dir app,web -- thin start --debug --port=4000 -R config.ru\n\nThe `--` is to separate rerun options from cmd options. You can also\nuse a quoted string for the command, e.g.\n\n        rerun --dir app \"thin start --debug --port=4000 -R config.ru\"\n\nRackup can also be used to launch a Rack server, so let's try that:\n\n        rerun -- rackup --port 4000 config.ru\n\nWant to mimic [autotest](https://github.com/grosser/autotest)? Try\n\n        rerun -x rake\n\nor\n\n        rerun -cx rspec\n\nAnd if you're using [Spork](https://github.com/sporkrb/spork) with Rails, you\nneed to [restart your spork server](https://github.com/sporkrb/spork/issues/201)\nwhenever certain Rails environment files change, so why not put this in your\nRakefile...\n\n    desc \"run spork (via rerun)\"\n    task :spork do\n      sh \"rerun --pattern '{Gemfile,Gemfile.lock,spec/spec_helper.rb,.rspec,spec/factories/**,config/environment.rb,config/environments/test.rb,config/initializers/*.rb,lib/**/*.rb}' -- spork\"\n    end\n\nand start using `rake spork` to launch your spork server?\n\n(If you're using Guard instead of Rerun, check out\n[guard-spork](https://github.com/guard/guard-spork)\nfor a similar solution.)\n\nHow about regenerating your HTML files after every change to your\n[Erector](http://erector.rubyforge.org) widgets?\n\n        rerun -x erector --to-html my_site.rb\n\nUse Heroku Cedar? `rerun` is now compatible with `foreman`. Run all your\nProcfile processes locally and restart them all when necessary.\n\n        rerun foreman start\n\n# Options:\n\nThese options can be specified on the command line and/or inside a `.rerun` config file (see below).\n\n`--dir` directory (or directories) to watch (default = \".\"). Separate multiple paths with ',' and/or use multiple `-d` options.\n\n`--pattern` glob to match inside directory. This uses the Ruby Dir glob style -- see \u003chttp://www.ruby-doc.org/core/classes/Dir.html#M002322\u003e for details.\nBy default it watches files ending in: `rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature,c,h`.\nOn top of this, it also ignores dotfiles, `.tmp` files, and some other files and directories (like `.git` and `log`).\nRun `rerun --help` to see the actual list.\n\n`--ignore pattern` file glob to ignore (can be set many times). To ignore a directory, you must append `'/*'` e.g.\n  `--ignore 'coverage/*'`.\n\n`--[no-]ignore-dotfiles` By default, on top of --pattern and --ignore, we ignore any changes to files and dirs starting with a dot. Setting `--no-ignore-dotfiles` allows you to monitor a relevant file like .env, but you may also have to explicitly --ignore more dotfiles and dotdirs. \n\n`--signal` (or `-s`) use specified signal(s) (instead of the default `TERM,INT,KILL`) to terminate the previous process. You can use a comma-delimited list if you want to try a signal, wait up to 5 seconds for the process to die, then try again with a different signal, and so on. \nThis may be useful for forcing the respective process to terminate as quickly as possible.\n(`--signal KILL` is the equivalent of `kill -9`)\n\n`--wait sec` (or `-w`)           after asking the process to terminate, wait this long (in seconds) before either aborting, or trying the next signal in series. Default: 2 sec\n\n`--restart` (or `-r`) expect process to restart itself, using signal HUP by default\n(e.g. `-r -s INT` will send a INT and then resume watching for changes)\n\n`--exit` (or -x) expect the program to exit. With this option, rerun checks the return value; without it, rerun checks that the launched process is still running.\n\n`--clear` (or -c) clear the screen before each run\n\n`--background` (or -b) disable on-the-fly commands, allowing the process to be backgrounded\n\n`--notify NOTIFIER` use `growl` or `osx` or `notify-send` for notifications (see below)\n\n`--no-notify` disable notifications\n\n`--name` set the app name (for display)\n\n`--force-polling` use polling instead of a native filesystem scan (useful for Vagrant)\n\n`--quiet` silences most messages\n\n`--verbose` enables even more messages (unless you also specified `--quiet`, which overrides `--verbose`)\n\nAlso `--version` and `--help`, naturally.\n\n## Config file\n\nIf the current directory contains a file named `.rerun`, it will be parsed with the same rules as command-line arguments. Newlines are the same as any other whitespace, so you can stack options vertically, like this:\n\n```\n--quiet\n--pattern **/*.{rb,js,scss,sass,html,md}\n```\n\nOptions specified on the command line will override those in the config file. You can negate boolean options with `--no-`, so for example, with the above config file, to re-enable logging, you could say:\n\n```sh\nrerun --no-quiet rackup\n```\n\nIf you're not sure what options are being overwritten, use `--verbose` and rerun will show you the final result of the parsing.\n\n# Notifications\n\nIf you have `growlnotify` available on the `PATH`, it sends notifications to\ngrowl in addition to the console.\n\nIf you have `terminal-notifier`, it sends notifications to\nthe OS X notification center in addition to the console.\n\nIf you have `notify-send`, it sends notifications to Freedesktop-compatible\ndesktops in addition to the console.\n\nIf you have more than one available notification program, Rerun will pick one, or you can choose between them using `--notify growl`, `--notify osx`, `--notify notify-send`, etc.\n\nIf you have a notifier installed but don't want rerun to use it,\nset the `--no-notify` option.\n\nDownload [growlnotify here](http://growl.info/downloads.php#generaldownloads)\nnow that Growl has moved to the App Store.\n\nInstall [terminal-notifier](https://github.com/julienXX/terminal-notifier) using `gem install terminal-notifier`. (You may have to put it in your system gemset and/or use `sudo` too.) Using Homebrew to install terminal-notifier is not recommended.\n\nOn Debian/Ubuntu, `notify-send` is available in the `libnotify-bin` package. On other GNU/Linux systems, it might be in a package with a different name.\n\n# On-The-Fly Commands\n\nWhile the app is (re)running, you can make things happen by pressing keys:\n\n* **r** -- restart (as if a file had changed)\n* **f** -- force restart (stop and start)\n* **c** -- clear the screen\n* **x** or **q** -- exit (just like control-C)\n* **p** -- pause/unpause filesystem watching\n\nIf you're backgrounding or using Pry or a debugger, you might not want these\nkeys to be trapped, so use the `--background` option.\n\n# Signals\n\nThe current algorithm for killing the process is:\n\n* send [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) (or the value of the `--signal` option)\n* if that doesn't work after 2 seconds, send SIGINT (aka control-C)\n* if that doesn't work after 2 more seconds, send SIGKILL (aka kill -9)\n\nThis seems like the most gentle and unixy way of doing things, but it does\nmean that if your program ignores SIGTERM, it takes an extra 2 to 4 seconds to\nrestart.\n\nIf you want to use your own series of signals, use the `--signal` option. If you want to change the delay before attempting the next signal, use the `--wait` option.\n\n# Vagrant and VirtualBox\n\nIf running inside a shared directory using Vagrant and VirtualBox, you must pass the `--force-polling` option. You may also have to pass some extra `--ignore` options too; otherwise each scan can take 10 or more seconds on directories with a large number of files or subdirectories underneath it.\n\n# Troubleshooting\n\n## zsh ##\n\nIf you are using `zsh` as your shell, and you are specifying your `--pattern` as `**/*.rb`, you may face this error\n```\nErrno::EACCES: Permission denied - \u003cfilename\u003e\n```\nThis is because `**/*.rb` gets expanded into the command by `zsh` instead of passing it through to rerun. The solution is to simply quote ('' or \"\") the pattern.\ni.e\n```\nrerun -p **/*.rb rake test\n```\nbecomes\n```\nrerun -p \"**/*.rb\" rake test\n```\n\n# To Do:\n\n## Must have for v1.0\n* Make sure to pass through quoted options correctly to target process [bug]\n* Optionally do \"bundle install\" before and \"bundle exec\" during launch\n\n## Nice to have\n* \".rerun\" file in $HOME\n* If the last element of the command is a `.ru` file and there's no other command then use `rackup`\n* Figure out an algorithm so \"-x\" is not needed (if possible) -- maybe by accepting a \"--port\" option or reading `config.ru`\n* Specify (or deduce) port to listen for to determine success of a web server launch\n* see also [todo.md](todo.md)\n\n## Wacky Ideas\n\n* On OS X:\n    * use a C library using growl's developer API \u003chttp://growl.info/developer/\u003e\n    * Use growl's AppleScript or SDK instead of relying on growlnotify\n    * \"Failed\" icon for notifications\n\n# Other projects that do similar things\n\n* Guard: \u003chttp://github.com/guard/guard\u003e\n* Restartomatic: \u003chttp://github.com/adammck/restartomatic\u003e\n* Shotgun: \u003chttp://github.com/rtomayko/shotgun\u003e\n* Rack::Reloader middleware: \u003chttp://github.com/rack/rack/blob/5ca8f82fb59f0bf0e8fd438e8e91c5acf3d98e44/lib/rack/reloader.rb\u003e\n* The Sinatra FAQ has a discussion at \u003chttp://www.sinatrarb.com/faq.html#reloading\u003e\n* Kicker: \u003chttp://github.com/alloy/kicker/\u003e\n* Watchr: \u003chttps://github.com/mynyml/watchr\u003e\n* Autotest: \u003chttps://github.com/grosser/autotest\u003e\n\n# Why would I use this instead of Shotgun?\n\nShotgun does a \"fork\" after the web framework has loaded but before\nyour application is loaded. It then loads your app, processes a\nsingle request in the child process, then exits the child process.\n\nRerun launches the whole app, then when it's time to restart, uses\n\"kill\" to shut it down and starts the whole thing up again from\nscratch.\n\nSo rerun takes somewhat longer than Shotgun to restart the app, but\ndoes it much less frequently. And once it's running it behaves more\nnormally and consistently with your production app.\n\nAlso, Shotgun reloads the app on every request, even if it doesn't\nneed to. This is fine if you're loading a single file, but if your web\npages all load other files (CSS, JS, media) then that adds up quickly.\n(I can only assume that the developers of shotgun are using caching or a\nfront web server so this isn't a pain point for them.)\n\nAnd hey, does Shotgun reload your Worker processes if you're using Foreman and\na Procfile? I'm pretty sure it doesn't.\n\nYMMV!\n\n# Why would I use this instead of Rack::Reloader?\n\nRack::Reloader is certifiably beautiful code, and is a very elegant use\nof Rack's middleware architecture. But because it relies on the\nLOADED_FEATURES variable, it only reloads .rb files that were 'require'd,\nnot 'load'ed. That leaves out (non-Erector) template files, and also,\nat least the way I was doing it, sub-actions (see\n[this thread](http://groups.google.com/group/sinatrarb/browse_thread/thread/7329727a9296e96a#\n)).\n\nRack::Reloader also doesn't reload configuration changes or redo other\nthings that happen during app startup. Rerun takes the attitude that if\nyou want to restart an app, you should just restart the whole app. You know?\n\n# Why would I use this instead of Guard?\n\nGuard is very powerful but requires some up-front configuration.\nRerun is meant as a no-frills command-line alternative requiring no knowledge\nof Ruby nor config file syntax.\n\n# Why did you write this?\n\nI've been using [Sinatra](http://sinatrarb.com) and loving it. In order\nto simplify their system, the Rat Pack removed auto-reloading from\nSinatra proper. I approve of this: a web application framework should be\nfocused on serving requests, not on munging Ruby ObjectSpace for\ndev-time convenience. But I still wanted automatic reloading during\ndevelopment. Shotgun wasn't working for me (see above) so I spliced\nRerun together out of code from Rspactor, FileSystemWatcher, and Shotgun\n-- with a heavy amount of refactoring and rewriting. In late 2012 I\nmigrated the backend to the Listen gem, which was extracted from Guard,\nso it should be more reliable and performant on multiple platforms.\n\n# Credits\n\nRerun: [Alex Chaffee](http://alexchaffee.com), \u003cmailto:alex@stinky.com\u003e, \u003chttp://github.com/alexch/\u003e\n\nBased upon and/or inspired by:\n\n* Shotgun: \u003chttp://github.com/rtomayko/shotgun\u003e\n* Rspactor: \u003chttp://github.com/mislav/rspactor\u003e\n  * (In turn based on http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/ )\n* FileSystemWatcher: \u003chttp://paulhorman.com/filesystemwatcher/\u003e\n\n## Patches by:\n\n* David Billskog \u003cbillskog@gmail.com\u003e\n* Jens B \u003chttps://github.com/dpree\u003e\n* Andrés Botero \u003chttps://github.com/anbotero\u003e\n* Dreamcat4\n* \u003chttps://github.com/FND\u003e\n* Barry Sia \u003chttps://github.com/bsia\u003e\n* Paul Rangel \u003chttps://github.com/ismell\u003e\n* James Edward Gray II \u003chttps://github.com/JEG2\u003e\n* Raul E Rangel \u003chttps://github.com/ismell\u003e and Antonio Terceiro \u003chttps://github.com/terceiro\u003e\n* Mike Pastore \u003chttps://github.com/mwpastore\u003e\n* Andy Duncan \u003chttps://github.com/ajduncan\u003e\n* Brent Van Minnen\n* Matthew O'Riordan \u003chttps://github.com/mattheworiordan\u003e\n* Antonio Terceiro \u003chttps://github.com/terceiro\u003e\n* \u003chttps://github.com/mattbrictson\u003e\n* \u003chttps://github.com/krissi\u003e\n\n# Version History\n\n* v0.14.0  4 January 2023\n  * Ruby 3.2 compatibility fix: .exists? no longer exists\n\n* v0.13.1   9 December 2020\n  * --no-ignore-dotfiles option\n\n* v0.13.0   26 January 2018\n  * bugfix: pause/unpause works again (thanks Barry!)\n  * `.rerun` config file\n\n* v0.12.0   23 January 2018\n  * smarter `--signal` option, allowing you to specify a series of signals to try in order; also `--wait` to change how long between tries\n  * `--force-polling` option (thanks ajduncan)\n  * `f` key to force stop and start (thanks mwpastore)\n  * add `.c` and `.h` files to default ignore list\n  * support for Windows\n     * use `Kernel.spawn` instead of `fork`\n     * use `wdm` gem for Windows Directory Monitor\n  * support for notifications on GNU/Linux using [notify-send](http://www.linuxjournal.com/content/tech-tip-get-notifications-your-scripts-notify-send) (thanks terceiro)\n  * fix `Gem::LoadError - terminal-notifier is not part of the bundle` [bug](https://github.com/alexch/rerun/issues/108) (thanks \tmattheworiordan)\n\n* 0.11.0    7 October 2015\n  * better 'changed' message\n  * `--notify osx` option\n  * `--restart` option (with bugfix by Mike Pastore)\n  * use Listen 3 gem\n  * add `.feature` files to default watchlist (thanks @jmuheim)\n\n* v0.10.0   4 May 2014\n  * add '.coffee,.slim,.md' to default pattern (thanks @xylinq)\n  * --ignore option\n\n* v0.9.0    6 March 2014\n  * --dir (or -d) can be specified more than once, for multiple directories (thanks again Barry!)\n  * --name option\n  * press 'p' to pause/unpause filesystem watching (Barry is the man!)\n  * works with Listen 2 (note: needs 2.3 or higher)\n  * cooldown works, thanks to patches to underlying Listen gem\n  * ignore all dotfiles, and add actual list of ignored dirs and files\n\n* v0.8.2\n  * bugfix, forcing Rerun to use Listen v1.0.3 while we work out the troubles we're having with Listen 1.3 and 2.1\n\n* v0.8.1\n  * bugfix release (#30 and #34)\n\n* v0.8.0\n  * --background option (thanks FND!) to disable the keyboard listener\n  * --signal option (thanks FND!)\n  * --no-growl option\n  * --dir supports multiple directories (thanks Barry!)\n\n* v0.7.1\n  * bugfix: make rails icon work again\n\n* v0.7.0\n  * uses Listen gem (which uses rb-fsevent for lightweight filesystem snooping)\n\n# License\n\nOpen Source MIT License. See \"LICENSE\" file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexch%2Frerun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexch%2Frerun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexch%2Frerun/lists"}