Liking cljdoc? Tell your friends :D

hive-system.shell.binary

Binary identity: which names on PATH denote a program.

(bin :rg) => "rg" (names :fd) => ["fd" "fdfind"] (locate :fd) => (ok {:path "/usr/bin/fdfind" :bin "fdfind"})

What belongs here, and what does not

A binary identity answers exactly one question: what is this program called where it is installed. It says nothing about how to install it (that is shell.tools, which owns provisioning) and nothing about how a pattern enters its argv (that is shell.search, which owns grammar). Both of those registries reference an id here rather than restating the names.

Aliases

An id is registered under :binary/id AND under every :binary/aliases member, all pointing at the same map, so a lookup is a plain get and the value always names its own canonical id. shell.tools has keyed ripgrep as :ripgrep since before shell.search keyed it :rg; both resolve, and neither registry has to know what the other calls it.

Layout

Collect (registry reads) / Promote (pure derivation over a Binary VALUE) / Boundary (locate, the only form here that touches PATH). The probe is a port, so a caller — a test above all — supplies its own adapter instead of redefining somebody's var.

Binary identity: which names on PATH denote a program.

(bin :rg)     => "rg"
(names :fd)   => ["fd" "fdfind"]
(locate :fd)  => (ok {:path "/usr/bin/fdfind" :bin "fdfind"})

## What belongs here, and what does not

A binary identity answers exactly one question: what is this program called
where it is installed. It says nothing about how to install it (that is
`shell.tools`, which owns provisioning) and nothing about how a pattern
enters its argv (that is `shell.search`, which owns grammar). Both of those
registries reference an id here rather than restating the names.

## Aliases

An id is registered under `:binary/id` AND under every `:binary/aliases`
member, all pointing at the same map, so a lookup is a plain `get` and the
value always names its own canonical id. `shell.tools` has keyed ripgrep as
`:ripgrep` since before `shell.search` keyed it `:rg`; both resolve, and
neither registry has to know what the other calls it.

## Layout

Collect (registry reads) / Promote (pure derivation over a Binary VALUE) /
Boundary (`locate`, the only form here that touches PATH). The probe is a
port, so a caller — a test above all — supplies its own adapter instead of
redefining somebody's var.
raw docstring

hive-system.shell.core

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.
raw docstring

hive-system.shell.detect

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.
raw docstring

hive-system.shell.posix

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.
raw docstring

hive-system.shell.search

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.

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.
raw docstring

hive-system.shell.tools

Tool provisioning: descriptions and install hints per package manager.

(require-tool :ripgrep) => (ok {:path "/usr/bin/rg"}) or (err :tool/missing {:hints [...]})

What a tool is CALLED is not stated here — it is one fact, owned by shell.binary, which shell.search reads too. This namespace answers "is it here, and how do I install it"; that one answers "what is it called".

Tool provisioning: descriptions and install hints per package manager.

(require-tool :ripgrep) => (ok {:path "/usr/bin/rg"})
                         or (err :tool/missing {:hints [...]})

What a tool is CALLED is not stated here — it is one fact, owned by
`shell.binary`, which `shell.search` reads too. This namespace answers
"is it here, and how do I install it"; that one answers "what is it
called".
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close