{"id":17791223,"url":"https://github.com/schell/steeloverseer","last_synced_at":"2025-05-16T06:06:35.229Z","repository":{"id":389512,"uuid":"9761583","full_name":"schell/steeloverseer","owner":"schell","description":"A file watcher and development tool.","archived":false,"fork":false,"pushed_at":"2024-11-11T20:48:46.000Z","size":499,"stargazers_count":130,"open_issues_count":19,"forks_count":15,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-05-12T06:30:38.153Z","etag":null,"topics":["capture-groups","file-watcher","haskell","pipeline","watches"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/schell.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":"2013-04-30T01:07:44.000Z","updated_at":"2025-04-25T11:55:32.000Z","dependencies_parsed_at":"2024-10-27T10:58:05.452Z","dependency_job_id":"8f2ccdab-4a62-43af-bc84-899a16bbee19","html_url":"https://github.com/schell/steeloverseer","commit_stats":{"total_commits":112,"total_committers":8,"mean_commits":14.0,"dds":0.4910714285714286,"last_synced_commit":"12f4e6d9fb17856d8b4d9b9b94ddc7e32f3f1985"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schell%2Fsteeloverseer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schell%2Fsteeloverseer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schell%2Fsteeloverseer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schell%2Fsteeloverseer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schell","download_url":"https://codeload.github.com/schell/steeloverseer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254478190,"owners_count":22077676,"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":["capture-groups","file-watcher","haskell","pipeline","watches"],"created_at":"2024-10-27T10:50:18.545Z","updated_at":"2025-05-16T06:06:30.177Z","avatar_url":"https://github.com/schell.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"Steel Overseer\n==============\n\nA file watcher and development tool, similar to Ruby's [Guard](https://github.com/guard/guard).\n\nThe main idea is that you have steeloverseer watch your files and then execute a series of shell \ncommands in response. The first command to fail short circuits the series. The watched files can \nbe selected using regular expressions and the commands may include capture groups.\n\n[![Build Status](https://travis-ci.org/steeloverseer/steeloverseer.png?branch=master)](https://travis-ci.org/steeloverseer/steeloverseer)\n[![Build status](https://github.com/schell/steeloverseer/actions/workflows/stack.yml/badge.svg)](https://github.com/schell/steeloverseer/actions/workflows/stack.yml)\n[![Build status](https://github.com/schell/steeloverseer/actions/workflows/haskell-ci.yml/badge.svg)](https://github.com/schell/steeloverseer/actions/workflows/haskell-ci.yml)\n\nAlso see [`feedback` and other tools](https://github.com/NorfairKing/feedback?tab=readme-ov-file#comparison-with-other-tools).\n\nInstallation\n============\n\nDownload and install the [stack](https://github.com/commercialhaskell/stack) build tool.\n\n    stack install steeloverseer\n\nThis will create a binary deep inside `~/.stack/`, and symlink to it at\n`~/.local/bin/sos`.\n\nUsage\n=====\n\nSee `sos --help` to get started:\n\n    Steel Overseer 2.0.2\n\n    Usage: sos [TARGET] [--rcfile ARG] [-c|--command COMMAND] [-p|--pattern PATTERN]\n               [-e|--exclude PATTERN]\n      A file watcher and development tool.\n\n    Available options:\n      -h,--help                Show this help text\n      TARGET                   Optional file or directory to watch for\n                               changes. (default: \".\")\n      --rcfile ARG             Optional rcfile to read patterns and commands\n                               from. (default: \".sosrc\")\n      -c,--command COMMAND     Add command to run on file event.\n      -p,--pattern PATTERN     Add pattern to match on file path. Only relevant if\n                               the target is a directory. (default: .*)\n      -e,--exclude PATTERN     Add pattern to exclude matches on file path. Only\n                               relevant if the target is a directory.\n\n\nPatterns and Commands\n-------------------\nCapture groups can be created with `(` `)` and captured variables can be\nreferred to with `\\1`, `\\2`, etc. (`\\0` contains the entire match).\n\nFor example, for each change to a `.c` file in `src/` (excluding files\ncontaining `\"_test\"`), we may want to compile the file and run its corresponding\nunit test:\n\n    sos src/ -c \"gcc -c \\0 -o obj/\\1.o\" -c \"make test --filter=test/\\1_test.c\" -p \"src/(.*)\\.c\" -e \"_test\"\n\nCommands are run left-to-right, and one failed command will halt the entire pipeline.\n\nThe RCFile\n----------\nAs a shortcut, we may want to write the above only once and save it in `.sosrc`,\nwhich is an alternative to the command-line interface (yaml syntax):\n\n```yaml\n- pattern: src/(.*)\\.c\n  exclude: _test\n  commands:\n  - gcc -c \\0 -o obj/\\1.o\n  - make test --filter=test/\\1_test.c\n```\n\nThen, we only need to run:\n\n    sos\n\nto start watching the current directory. If you'd like to use multiple rcfiles,\nor just don't like the name `.sosrc` you can specify the rcfile on the command\nline like so:\n\n    sos --rcfile my-rcfile\n\n### Grammar\n\n    sosrc            := [entry]\n    entry            := {\n                          pattern_entry,\n                          exclude_entry?, -- Note: optional!\n                          command_entry\n                        }\n    pattern_entry    := \"pattern\" | \"patterns\" : value | [value]\n    exclude_entry    := \"exclude\" | \"excludes\" | \"excluding\" : value | [value]\n    command_entry    := \"command\" | \"commands\" : value | [value]\n    value            := [segment]\n    segment          := text_segment | var_segment\n    text_segment     := string\n    var_segment      := '\\' integer\n\nThe .sosrc grammar is somewhat flexible with respect to the command\nspecifications. Both singular and plural keys are allowed, and both strings\nand lists of strings are allowed for values.\n\nPipelining Explaned\n-------------------\nPipelines of commands are immediately canceled and re-run if a subsequent\nfilesystem event triggers the *same* list of commands. Otherwise, commands are\nare enqueued and run sequentially to keep the terminal output clean and readable.\n\nFor example, we may wish to run `hlint` on any modified `.hs` file:\n\n```yaml\n- pattern: .*\\.hs\n  command: hlint \\0\n```\n\nWe can modify `foo.hs` and trigger `hlint foo.hs` to run. During its execution,\nmodifying `bar.hs` will *enqueue* `hlint bar.hs`, while modifying `foo.hs` again\nwill *re-run* `hlint foo.hs`.\n\nTransient Files\n---------------\nSometimes text editors and other programs create short lived files in the \ndirectories that `sos` is watching. These can trigger `sos` to run your \npipeline. This can often be avoided by using precise include syntax, ie \nadding explicit matchers like an end-line match:\n\n```\n- pattern: .*\\.tex$ \n```\n\nAlternatively you may use exclude syntax to exclude any transient editor files \n(eg here's an sosrc used for editing Haskell doctests and ignoring emac's flycheck files):\n\n```\n# This is for testing documentation\n- patterns:\n  - .*/[^_]*\\.l?hs$\n  excludes:\n  - \\#\n  - flycheck\n  commands:\n  - stack exec doctest -- \\0\n```\n\nFor more info, see https://github.com/schell/steeloverseer/issues/38\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschell%2Fsteeloverseer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschell%2Fsteeloverseer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschell%2Fsteeloverseer/lists"}