diff --git a/Cargo.lock b/Cargo.lock index 9ee2059..987b486 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -593,7 +593,7 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "uphold" -version = "1.7.0" +version = "1.8.0" dependencies = [ "encoding_rs", "globset", diff --git a/Cargo.toml b/Cargo.toml index 625e830..6246b49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uphold" -version = "1.7.0" +version = "1.8.0" edition = "2021" # 1.88, not 1.85: the ripgrep stack this crate embeds -- globset 0.4.20 and # ignore 0.4.33 in Cargo.lock -- refuses anything older. The 1.85 that stood here diff --git a/README.md b/README.md index 1022ae5..036e8f7 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ bootstraps). default_install_hook_types: [pre-commit, commit-msg, pre-merge-commit, pre-push] repos: - repo: https://github.com/HackingGate/uphold - rev: v1.7.0 + rev: v1.8.0 hooks: - id: uphold-check # the claims still hold - id: uphold-scan # the content policy @@ -48,13 +48,13 @@ the binary must be on PATH. # lefthook.yml remotes: - git_url: https://github.com/HackingGate/uphold - ref: v1.7.0 + ref: v1.8.0 configs: - hooks/lefthook.yml ``` ```sh -cargo install --git https://github.com/HackingGate/uphold --tag v1.7.0 +cargo install --git https://github.com/HackingGate/uphold --tag v1.8.0 ``` That `ref:` is the one version a lefthook consumer pins, and **Dependabot does diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md index c7e90af..921da11 100644 --- a/docs/REFERENCE.md +++ b/docs/REFERENCE.md @@ -72,6 +72,53 @@ every git hook, and a repository whose own prose cites its issues would have every one of those citations refused — so the seam it belongs at is the command that publishes text to a forge, and only that one. +### One command, more than one flag vocabulary + +A `[[shim]]` names one `text_flags` for a whole command, and a command's flags do +not all mean one thing. On `gh`, `-c` is a **boolean** on `pr review` -- "Comment +on a pull request" -- and **takes a value** on `issue close` -- "Leave a closing +comment". Name it once for the table and one of the two is read wrong: + +* named -- `gh pr review -c -b "body"` reads `-c` as consuming `-b`, and the body + being published goes unread; +* not named -- `gh issue close --comment "text"` publishes with nothing in front + of it. + +Both are false negatives in the seam that exists to prevent one. A second +`[[shim]]` for the same command is not the answer either: it is refused at load, +because two vocabularies for one command have to be merged and merging is the +same guess in a different place. + +So a table may carry entries for the verbs whose grammar differs: + +```toml +[[shim]] +command = "gh" +match = ["pr:review", "issue:close"] +text_flags = ["-t", "--title", "-b", "--body"] + + [[shim.verbs]] + match = ["issue:close"] + text_flags = ["-c", "--comment"] +``` + +`match` takes the same `verb:noun` and `verb:*` spellings the table's own does, +and every entry must name a verb the table matches -- a vocabulary for an +invocation the shim does not stand in front of classifies nothing, and is refused +at load. + +**The entry's lists replace the table's** for the verbs it names, rather than +adding to them. Same rule as `allowed_scripts`, for the same reason: what is +declared beside the narrower thing is the whole truth for it. A union would mean +a vocabulary nobody wrote -- here `issue close --body`, a flag the real command +does not accept -- and reading a flag a command will not take is the shim +claiming to have checked a subject that was never published. + +`text_flags`, `file_flags`, `path_flags`, `skip_flags` and `web_flags` may be +overridden. `target_flags` may not: `-R`/`--repo` means the same thing on every +verb, and a per-verb answer to "which repository is this going to" would be a way +to publish somewhere the table did not expect. + ### A baseline entry may be asked to say who excused it and why `files.baseline` names a file of repository-relative paths a rule excuses, and diff --git a/hooks/lefthook.yml b/hooks/lefthook.yml index ad6de32..2f30025 100644 --- a/hooks/lefthook.yml +++ b/hooks/lefthook.yml @@ -10,7 +10,7 @@ # # lefthook.yml, in the consuming repository # remotes: # - git_url: https://github.com/HackingGate/uphold -# ref: v1.7.0 +# ref: v1.8.0 # configs: # - hooks/lefthook.yml # @@ -21,7 +21,7 @@ # their manifest contract; lefthook runs commands and has no such contract, so # `uphold` must be on PATH: # -# cargo install --git https://github.com/HackingGate/uphold --tag v1.7.0 +# cargo install --git https://github.com/HackingGate/uphold --tag v1.8.0 # # The names below are prefixed `uphold-` on purpose. A remote config is # merged into the consumer's own, and two commands sharing a name under one hook