Repository navigation
spur 0.1.0
·
62 commits
to master
since this release
0.1.0 - 2026-09-22
First release. spur reads a Spurfile, lists the tasks and runs one per invocation in a single shell. The whole program is one file that depends on sh and awk: no build step and no runtime to install.
The scope is deliberate: spur runs tasks, it does not build software — no dependency graph, no timestamp rebuilds, no pattern rules. It needs a POSIX shell, so on Windows it runs under Git Bash, MSYS2, WSL or Cygwin. The trade-offs that follow are listed in the README under What it costs.
Added
- The
Spurfilelanguage: a line matching^[A-Za-z0-9_.-]+:opens a task,## textin the header documents it for--list, and the indented body is
dedented before it runs, soif,forand heredocs keep their relative shape. Everything before the first task is the preamble, injected at the top of every task that runs. - One shell for the whole body, with
set -eon:cdpersists, variables persist, and stdin stays free, so interactive tasks work. - A body that reaches the shell byte for byte. The runner expands nothing, so
$IMAGE,$(date),${x:-y}and$$arrive intact and there is no template layer to escape. - Positional passthrough:
spur test -k login -vvhands-k login -vvto the body as"$@". The first word that does not start with-is the task name; everything after it belongs to the task. - Spurfile discovery:
Spurfile, thenspurfile, in the current directory and then upwards to/. Every task runs in the directory that holds the file in use. - Chained calls: the assembled script injects a
spurfunction pointing at the runner itself. A recursion guard overSPUR_STACKexits 68, while repeated non-recursive calls are allowed. - Runner flags:
-f FILE,-C DIR,-l/--list,-n(print the assembled script instead of running it),-x(trace withPS4='$ ', after the preamble),-h/--helpand-v/--version. Short flags cannot be grouped. - Exit codes in the
sysexitsrange, so they never collide with a task's own, which is propagated unchanged: 64 usage, 65 malformed Spurfile, 66 Spurfile not found, 67 unknown task, 68 recursion. - Exported environment:
SPUR_BIN,SPUR_ROOT,SPUR_INVOCATION_DIR,SPUR_TASKandSPUR_STACK. - Shell diagnostics labelled
spur <task>: line N: ..., from$0on the singlesh -cthat runs the task. - Documentation:
README.mdas the user-facing contract (the language, the CLI, the exit codes, the make → spur mapping and the known limitations),CONTRIBUTING.mdfor the testing rules, and an MITLICENSE. - A behavior suite of 48 cases under
tests/, run by a dependency-free harness, plus CI runningshellcheck -s shand the suite undersh,dash,bashand busyboxash. Green on this tag.
Install
curl -fsSL https://raw.githubusercontent.com/esliph/spur/v0.1.0/spur \
-o ~/.local/bin/spur && chmod +x ~/.local/bin/spurOr download spur from the assets below and chmod +x it. Or vendor it: copy the file into your repository and commit it, and anyone who clones runs ./spur test with nothing installed.