IShell implementation via ProcessBuilder. All operations return hive-dsl Results.
Stream draining and process-tree teardown are shared with the IProcess implementation — see hive-system.process.streams / .tree. Both faced the same hazard (a descendant holding an inherited pipe), and one copy of the answer is the point.
IShell implementation via ProcessBuilder. All operations return hive-dsl Results. Stream draining and process-tree teardown are shared with the IProcess implementation — see hive-system.process.streams / .tree. Both faced the same hazard (a descendant holding an inherited pipe), and one copy of the answer is the point.
Detect available package managers and system capabilities. Delegates to babashka.fs for path resolution.
Detect available package managers and system capabilities. Delegates to babashka.fs for path resolution.
Pure POSIX shell-quoting helpers.
Two functions:
shell-quote — single-quote a string for safe embedding in a
sh -c command, escaping embedded single-quotes and quoting the
empty string as '' so it survives tokenization.join-as-cmd — join an argv into one shell-command string by
quoting each element with shell-quote.Re-quoting an already-quoted string nests correctly — each sh -c
peel removes exactly one quoting layer.
Pure POSIX shell-quoting helpers.
Two functions:
- `shell-quote` — single-quote a string for safe embedding in a
`sh -c` command, escaping embedded single-quotes and quoting the
empty string as `''` so it survives tokenization.
- `join-as-cmd` — join an argv into one shell-command string by
quoting each element with `shell-quote`.
Re-quoting an already-quoted string nests correctly — each `sh -c`
peel removes exactly one quoting layer.Building an argv for a pattern-taking CLI from a Construct.
Callers used to hand-assemble a pattern string and hand it to rg. A
lookahead in that string reaches rg, which rejects it at runtime with
regex parse error: look-around, including look-ahead and look-behind, is not supported
— a failure the caller can only discover by spawning a process and then parsing English out of stderr. The dialect gate already knows the answer from the shape of the construct, so the refusal belongs here, before the fork, naming the missing capability as data.
With grep the argument is stronger still. GNU grep does not reject what it
cannot do: grep -E '\d+' matches a literal d, exit 0, no warning. There
the gate is not saving the caller a stderr parse, it is saving them a wrong
answer they had no way to notice.
A tool is a Tool map: which dialect it speaks, what it needs in order to
speak it, and how a pattern enters its argv. Adding ugrep is a register!
call, not an edit to argv — the open set gets a registry, not a case.
An argv is a claim about a program's parser, and only that program can
settle it. rg, sd and grep are driven for real by the suite, and the
separator rule argv applies is what those runs established.
fd is measured too, as of fd 9.0.0: sd's positional shape holds for it,
including the negative control — strip the -- and fd reads -dash-[0-9]+
as --max-depth ash-[0-9]+ and exits 2. What that run also established is
that the argv was not the whole claim. Debian installs the binary as
fdfind, so the shape was right, the program was present, and the command
was still unrunnable. Hence executable and spawn-argv: argv states the
grammar, and resolving argv[0] against PATH is a separate question with its
own refusal.
A PATH grep is frequently ugrep or another superset, which would accept
constructs POSIX ERE cannot express. That only ever widens what runs, never
narrows it, so emitting strict ERE stays correct whichever binary answers.
Building an argv for a pattern-taking CLI from a Construct. ## What this is for Callers used to hand-assemble a pattern string and hand it to `rg`. A lookahead in that string reaches rg, which rejects it at runtime with regex parse error: look-around, including look-ahead and look-behind, is not supported — a failure the caller can only discover by spawning a process and then parsing English out of stderr. The dialect gate already knows the answer from the shape of the construct, so the refusal belongs here, before the fork, naming the missing capability as data. With `grep` the argument is stronger still. GNU grep does not reject what it cannot do: `grep -E '\d+'` matches a literal `d`, exit 0, no warning. There the gate is not saving the caller a stderr parse, it is saving them a wrong answer they had no way to notice. ## Tools are data, not code A tool is a `Tool` map: which dialect it speaks, what it needs in order to speak it, and how a pattern enters its argv. Adding `ugrep` is a `register!` call, not an edit to `argv` — the open set gets a registry, not a `case`. ## What is measured An argv is a claim about a program's parser, and only that program can settle it. `rg`, `sd` and `grep` are driven for real by the suite, and the separator rule `argv` applies is what those runs established. `fd` is measured too, as of fd 9.0.0: sd's positional shape holds for it, including the negative control — strip the `--` and fd reads `-dash-[0-9]+` as `--max-depth ash-[0-9]+` and exits 2. What that run also established is that the argv was not the whole claim. Debian installs the binary as `fdfind`, so the shape was right, the program was present, and the command was still unrunnable. Hence `executable` and `spawn-argv`: `argv` states the grammar, and resolving argv[0] against PATH is a separate question with its own refusal. A PATH `grep` is frequently ugrep or another superset, which would accept constructs POSIX ERE cannot express. That only ever widens what runs, never narrows it, so emitting strict ERE stays correct whichever binary answers.
Tool registry: maps tool names to their binaries, descriptions, and install hints per package manager.
(require-tool :ripgrep) => (ok {:path "/usr/bin/rg"}) or (err :tool/missing {:hints [...]})
Tool registry: maps tool names to their binaries, descriptions,
and install hints per package manager.
(require-tool :ripgrep) => (ok {:path "/usr/bin/rg"})
or (err :tool/missing {:hints [...]})cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |