feat(issue): read description/comment from file or stdin (YT-13) #57

Merged
David merged 1 commit from feat/issue-file-input-YT-13 into main 2026-05-25 04:22:07 +02:00
Owner

Resolves YT-13.

What

Adds file-input flags so issue descriptions and comments can come from a file or stdin instead of only an inline argument:

  • yt issue create --description-file <PATH> (mutually exclusive with --description)
  • yt issue update <id> --description-file <PATH> (mutually exclusive with --description)
  • yt issue comment <id> --comment-file <PATH> (mutually exclusive with the positional text)

Each *-file flag accepts - to read from stdin. The file is read as UTF-8 and used verbatim. A missing, unreadable, or non-UTF-8 file produces a clear error and performs no API mutation. --dry-run resolves the body before the POST, so it works with every variant.

How

A shared read_text_arg(inline, file) helper in src/commands/issue/mod.rs centralizes the file/stdin/conflict resolution and returns Option<String>. That preserves update's "field not provided means do not touch it" semantics while create/comment fall back to empty-or-required-body handling. The clap conflicts_with attribute enforces mutual exclusivity, producing a clear error when both inline and file inputs are supplied.

Acceptance criteria

  • yt issue create --description-file <path> creates an issue whose description is the file contents.
  • yt issue update <id> --description-file <path> sets the description from the file.
  • yt issue comment <id> --comment-file <path> posts a comment with the file contents.
  • Each *-file flag accepts - to read the body from stdin.
  • --description-file conflicts with --description, and --comment-file conflicts with the positional text, with a clear clap error when both are supplied.
  • A missing, unreadable, or non-UTF-8 file produces a clear error and performs no API mutation.
  • --dry-run works with each *-file variant.
  • Help text documents the new flags.

Testing

cargo fmt --all -- --check, cargo clippy --all-targets -- -D warnings, cargo build --release, and cargo test --all-targets (306 passed). New tests cover the helper (file read, missing file, non-UTF-8, inline passthrough, None), plus end-to-end --description-file (create) and --comment-file (comment). Manually verified stdin (-) and --dry-run for both create and comment, and the two clap conflict errors.

Resolves YT-13. ## What Adds file-input flags so issue descriptions and comments can come from a file or stdin instead of only an inline argument: - `yt issue create --description-file <PATH>` (mutually exclusive with `--description`) - `yt issue update <id> --description-file <PATH>` (mutually exclusive with `--description`) - `yt issue comment <id> --comment-file <PATH>` (mutually exclusive with the positional text) Each `*-file` flag accepts `-` to read from stdin. The file is read as UTF-8 and used verbatim. A missing, unreadable, or non-UTF-8 file produces a clear error and performs no API mutation. `--dry-run` resolves the body before the POST, so it works with every variant. ## How A shared `read_text_arg(inline, file)` helper in `src/commands/issue/mod.rs` centralizes the file/stdin/conflict resolution and returns `Option<String>`. That preserves `update`'s "field not provided means do not touch it" semantics while `create`/`comment` fall back to empty-or-required-body handling. The clap `conflicts_with` attribute enforces mutual exclusivity, producing a clear error when both inline and file inputs are supplied. ## Acceptance criteria - [x] `yt issue create --description-file <path>` creates an issue whose description is the file contents. - [x] `yt issue update <id> --description-file <path>` sets the description from the file. - [x] `yt issue comment <id> --comment-file <path>` posts a comment with the file contents. - [x] Each `*-file` flag accepts `-` to read the body from stdin. - [x] `--description-file` conflicts with `--description`, and `--comment-file` conflicts with the positional `text`, with a clear clap error when both are supplied. - [x] A missing, unreadable, or non-UTF-8 file produces a clear error and performs no API mutation. - [x] `--dry-run` works with each `*-file` variant. - [x] Help text documents the new flags. ## Testing `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, `cargo build --release`, and `cargo test --all-targets` (306 passed). New tests cover the helper (file read, missing file, non-UTF-8, inline passthrough, None), plus end-to-end `--description-file` (create) and `--comment-file` (comment). Manually verified stdin (`-`) and `--dry-run` for both create and comment, and the two clap conflict errors.
feat(issue): read description/comment from file or stdin (YT-13)
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 14s
Create release / Create release from merged PR (pull_request) Has been skipped
6cfe7974c7
Authoring long Markdown bodies for `yt issue create`/`update`/`comment` previously required passing the whole body as an inline argument (`--description "$(cat body.md)"` or positional comment text). That hits `Argument list too long` (ARG_MAX) on large bodies, is at the mercy of shell quoting, and has no way to pipe from stdin.

Add file-input flags that pair with each command's existing text input: `--description-file` on `issue create` and `issue update`, and `--comment-file` on `issue comment`. Each flag is mutually exclusive with its inline counterpart (clap `conflicts_with`), so supplying both yields a clear clap error. A path of `-` reads from stdin; otherwise the file is read as UTF-8 and used verbatim. A missing, unreadable, or non-UTF-8 file produces a clear error before any API mutation, and `--dry-run` still works because the body is resolved before the POST.

A shared `read_text_arg(inline, file)` helper in the issue module centralizes the file/stdin resolution and returns `Option<String>` so `update` keeps its "field not provided means do not touch it" semantics while `create`/`comment` fall back to an empty/required-body check.

#YT-13 State Done
David merged commit f2a0d87343 into main 2026-05-25 04:22:07 +02:00
David deleted branch feat/issue-file-input-YT-13 2026-05-25 04:22:08 +02:00
Sign in to join this conversation.
No reviewers
No labels
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
pandoras-box/youtrack-cli!57
No description provided.