-F/--body-file for body input across issue/pr/release/milestone #140

Closed
opened 2026-06-11 00:58:06 +00:00 by stephen · 0 comments
Owner

Task

Add -F/--body-file <PATH> to every command that takes --body, resolved once in the shared editor::read_body / resolve_body helpers (src/cli/editor.rs:68-104) so it lands for all call sites: fj issue create/edit/comment, fj pr create/edit/comment, fj release create/edit, fj milestone create/edit.

  • Treat --body-file - as stdin (matching gh, which accepts -F -).
  • Keep --body and --body-file mutually exclusive via clap.
  • When --body-file <path> is given but the path is missing, error instead of falling through to $EDITOR, preserving the "never block in CI" property.

Source: rasterstate/fj#124.

Priority

p1. An agent that generates a multi-paragraph markdown body almost always writes it to a temp file, then references it; -F notes.md is the muscle-memory call and the gh-parity workhorse. The sharp edge is automation-specific: omitting --body to a command that defaults to launching $EDITOR silently hangs a non-interactive job, where -F path is an unambiguous, non-interactive read. The --body - < file fallback works but is strictly less ergonomic and breaks parity for ported scripts.

Reason

Every body-accepting command takes inline --body, --body - (stdin), or $EDITOR, but none accept -F/--body-file. The pattern is uniform: each body: Option<String> is documented identically and the shared resolvers (src/cli/editor.rs:68, :104) only understand Some("-") -> stdin, Some(s) -> literal, None -> editor; there is no "read this path" arm. Adding it to the shared helper closes the gap everywhere at once.

Acceptance

  • -F/--body-file <PATH> works on issue/pr create+edit+comment, release create+edit, and milestone create+edit.
  • --body-file - reads stdin; --body and --body-file are mutually exclusive (clap-enforced).
  • A missing --body-file path errors and never falls through to $EDITOR.
  • Resolution lives once in editor::read_body / resolve_body; no per-command duplication.
  • Wiremock/unit coverage for the file arm, the stdin arm, and the missing-path error.
  • cargo fmt --check, cargo clippy --all-targets --all-features -- -D warnings, and cargo test --all pass.

Dependencies

None. Sibling to rasterstate/fj#126, which adds file/stdin input to the raw fj api body; this issue covers human prose bodies on resource commands, that one covers raw HTTP request bodies on the api escape hatch. Different resolvers, kept separate deliberately.

Size

M

## Task Add `-F/--body-file <PATH>` to every command that takes `--body`, resolved once in the shared `editor::read_body` / `resolve_body` helpers (`src/cli/editor.rs:68-104`) so it lands for all call sites: `fj issue create`/`edit`/`comment`, `fj pr create`/`edit`/`comment`, `fj release create`/`edit`, `fj milestone create`/`edit`. - Treat `--body-file -` as stdin (matching `gh`, which accepts `-F -`). - Keep `--body` and `--body-file` mutually exclusive via clap. - When `--body-file <path>` is given but the path is missing, error instead of falling through to `$EDITOR`, preserving the "never block in CI" property. Source: rasterstate/fj#124. ## Priority p1. An agent that generates a multi-paragraph markdown body almost always writes it to a temp file, then references it; `-F notes.md` is the muscle-memory call and the gh-parity workhorse. The sharp edge is automation-specific: omitting `--body` to a command that defaults to launching `$EDITOR` silently hangs a non-interactive job, where `-F path` is an unambiguous, non-interactive read. The `--body - < file` fallback works but is strictly less ergonomic and breaks parity for ported scripts. ## Reason Every body-accepting command takes inline `--body`, `--body -` (stdin), or `$EDITOR`, but none accept `-F/--body-file`. The pattern is uniform: each `body: Option<String>` is documented identically and the shared resolvers (`src/cli/editor.rs:68`, `:104`) only understand `Some("-")` -> stdin, `Some(s)` -> literal, `None` -> editor; there is no "read this path" arm. Adding it to the shared helper closes the gap everywhere at once. ## Acceptance - [ ] `-F/--body-file <PATH>` works on issue/pr create+edit+comment, release create+edit, and milestone create+edit. - [ ] `--body-file -` reads stdin; `--body` and `--body-file` are mutually exclusive (clap-enforced). - [ ] A missing `--body-file` path errors and never falls through to `$EDITOR`. - [ ] Resolution lives once in `editor::read_body` / `resolve_body`; no per-command duplication. - [ ] Wiremock/unit coverage for the file arm, the stdin arm, and the missing-path error. - [ ] `cargo fmt --check`, `cargo clippy --all-targets --all-features -- -D warnings`, and `cargo test --all` pass. ## Dependencies None. Sibling to rasterstate/fj#126, which adds file/stdin input to the raw `fj api` body; this issue covers human prose bodies on resource commands, that one covers raw HTTP request bodies on the api escape hatch. Different resolvers, kept separate deliberately. ## Size M
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rasterstate/fj#140
No description provided.