feat: implement issue inspect and issue sprint show (PR 3/5) #14

Merged
David merged 1 commit from feat/issue-inspect-and-sprint-show into main 2026-05-14 00:10:30 +02:00
Owner

Summary

PR 3 of 5. Ports the two read-only single-issue commands.

  • issue inspect <id>: primary GET /api/issues/<id> plus four sub-fetches (comments, work items, sprints, links). Sub-fetch failures are non-fatal and collected into warnings, matching Go. Output sections: ID: summary, Fields:, Sprints:, Recent comments: (last 5), Recent work items: (last 5), Links:, Warnings: (only when non-empty). Work-item duration falls back to humanized minutes when YouTrack returns an empty presentation. --json emits the full IssueInspect struct.
  • issue sprint show <id>: marker-list (* <name> [current]) of every sprint the issue belongs to, with --json for the raw array.

New shared infrastructure

  • yt::duration::humanize_duration: 1d = 6h convention, identical to Go's HumanizeDuration. Returns "1h 15m" style strings; zero -> "0m".
  • yt::output::{format_millis, compact_text, author_name, tail}: timestamp formatting (UTC YYYY-MM-DD HH:MM), whitespace-collapsing truncation with ellipsis, author display ladder (fullName -> login -> unknown), and slice tail helper.
  • New models: Author, IssueComment, WorkItem/WorkDuration, IssueLink/IssueLinkType, aggregate IssueInspect.
  • New api helpers: inspect_issue (composes the five fetches and surfaces warnings) and list_issue_sprints.

Verification

  • cargo fmt --check clean.
  • cargo clippy --all-targets -- -D warnings clean.
  • cargo test --all-targets: 85 tests pass (27 new on this branch).

Coverage on this PR: full happy-path wiremock test for inspect, all-subfetches-failed (asserts 4 warnings in fixed order, every section empty), primary 404 propagation, missing-credentials guard, empty/non-empty/JSON paths for sprint show, link-label fallback ladder, humanize_duration zero / day-rollover / day+hours-no-minutes, plus existing helper coverage.

Test plan

  • Run youtrack-cli issue inspect <ID> against a real instance. Confirm: fields render, last 5 comments / work items shown, links labeled with localized name where present.
  • Force a partial failure (e.g. revoke read access to comments) and confirm the command still prints the rest with a Warnings: - comments: ... block at the bottom.
  • youtrack-cli issue inspect <ID> --json | jq produces a parseable object.
  • youtrack-cli issue sprint show <ID> prints * <name> [current] for the active sprint and <name> for inactive ones, or (none) for an issue with no sprints.
## Summary PR 3 of 5. Ports the two read-only single-issue commands. - `issue inspect <id>`: primary `GET /api/issues/<id>` plus four sub-fetches (comments, work items, sprints, links). Sub-fetch failures are non-fatal and collected into `warnings`, matching Go. Output sections: `ID: summary`, `Fields:`, `Sprints:`, `Recent comments:` (last 5), `Recent work items:` (last 5), `Links:`, `Warnings:` (only when non-empty). Work-item duration falls back to humanized minutes when YouTrack returns an empty `presentation`. `--json` emits the full `IssueInspect` struct. - `issue sprint show <id>`: marker-list (`* <name> [current]`) of every sprint the issue belongs to, with `--json` for the raw array. ## New shared infrastructure - `yt::duration::humanize_duration`: 1d = 6h convention, identical to Go's `HumanizeDuration`. Returns `"1h 15m"` style strings; zero -> `"0m"`. - `yt::output::{format_millis, compact_text, author_name, tail}`: timestamp formatting (UTC `YYYY-MM-DD HH:MM`), whitespace-collapsing truncation with ellipsis, author display ladder (`fullName` -> `login` -> `unknown`), and slice tail helper. - New models: `Author`, `IssueComment`, `WorkItem`/`WorkDuration`, `IssueLink`/`IssueLinkType`, aggregate `IssueInspect`. - New api helpers: `inspect_issue` (composes the five fetches and surfaces warnings) and `list_issue_sprints`. ## Verification - `cargo fmt --check` clean. - `cargo clippy --all-targets -- -D warnings` clean. - `cargo test --all-targets`: 85 tests pass (27 new on this branch). Coverage on this PR: full happy-path wiremock test for inspect, all-subfetches-failed (asserts 4 warnings in fixed order, every section empty), primary 404 propagation, missing-credentials guard, empty/non-empty/JSON paths for sprint show, link-label fallback ladder, `humanize_duration` zero / day-rollover / day+hours-no-minutes, plus existing helper coverage. ## Test plan - [ ] Run `youtrack-cli issue inspect <ID>` against a real instance. Confirm: fields render, last 5 comments / work items shown, links labeled with localized name where present. - [ ] Force a partial failure (e.g. revoke read access to comments) and confirm the command still prints the rest with a `Warnings: - comments: ...` block at the bottom. - [ ] `youtrack-cli issue inspect <ID> --json | jq` produces a parseable object. - [ ] `youtrack-cli issue sprint show <ID>` prints `* <name> [current]` for the active sprint and ` <name>` for inactive ones, or ` (none)` for an issue with no sprints.
feat: implement issue inspect and issue sprint show
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 8s
Create release / Create release from merged PR (pull_request) Has been skipped
62505c1cea
PR 3 of 5. Ports the two read-only single-issue commands. `issue inspect` makes the primary GET on the issue plus four sub-fetches (comments, work items, sprints, links). Sub-fetch failures are non-fatal and collected as warnings, matching the Go CLI; only the primary issue request causes the command to abort. The output mirrors Go's sections (ID:Summary, Fields, Sprints, Recent comments (last 5), Recent work items (last 5), Links, Warnings), with `--json` falling back to a pretty-printed `IssueInspect` struct. Work-item duration falls back to humanized minutes when the YouTrack response leaves `presentation` empty, again matching Go. `issue sprint show` prints the marker list `* <name> [current]` for a single issue, with `--json` for the raw sprint array. New shared infrastructure: `yt::duration::humanize_duration` (1d = 6h convention, identical to Go's `HumanizeDuration`); `yt::output::{format_millis, compact_text, author_name, tail}` for the inspect rendering; `Author`, `IssueComment`, `WorkItem`/`WorkDuration`, `IssueLink`/`IssueLinkType`, and `IssueInspect` models. New api helpers `inspect_issue` and `list_issue_sprints`. Tests cover both end-to-end paths via wiremock (full happy path, all-subfetches-failed warnings collection, primary 404 propagation, missing-credentials guard, empty sprint list, JSON mode), pure-function tests for the new output helpers (format_millis edge cases, compact_text truncation, author_name fallback ladder, tail), pure unit tests for the link-label selector, plus the new humanize_duration cases (zero, day-rollover, day+hours-no-minutes). 85 tests pass; clippy clean; fmt clean.
David merged commit 2d88ddeb83 into main 2026-05-14 00:10:30 +02:00
David deleted branch feat/issue-inspect-and-sprint-show 2026-05-14 00:10:30 +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!14
No description provided.