Skip to content

feat: add bl pr commands (list/count/show/create/update/comment/attachment)#104

Merged
23prime merged 3 commits intomainfrom
feature/54-pr-commands
Mar 22, 2026
Merged

feat: add bl pr commands (list/count/show/create/update/comment/attachment)#104
23prime merged 3 commits intomainfrom
feature/54-pr-commands

Conversation

@23prime
Copy link
Owner

@23prime 23prime commented Mar 22, 2026

Checklist

  • Target branch is main
  • Status checks are passing
  • Documentation updated if user-visible behavior changed (website/docs/, website/i18n/ja/, README.md)

Summary

  • bl pr list <project> <repo> — list pull requests
  • bl pr count <project> <repo> — count pull requests
  • bl pr show <project> <repo> <number> — show pull request details
  • bl pr create <project> <repo> --summary --base --branch — create pull request
  • bl pr update <project> <repo> <number> — update pull request
  • bl pr comment list/count/add/update — manage PR comments
  • bl pr attachment list/get/delete — manage PR attachments

Reason for change

Implements #54.

Changes

  • src/api/pull_request.rsPullRequest, PullRequestComment, PullRequestAttachment structs + all BacklogClient methods
  • src/api/mod.rs — trait declarations + impl
  • src/cmd/pr/ — all command logic with tests
  • src/cmd/mod.rs — added pr module
  • src/main.rs — clap wiring for all bl pr subcommands
  • website/docs/commands.md, website/i18n/ja/.../commands.md — docs and coverage table updated

Notes

POST/PATCH/DELETE commands (create, update, comment add, comment update, attachment delete) are implemented but not tested against the real API (no PR environment available).

Closes #54

Copilot AI review requested due to automatic review settings March 22, 2026 00:46
@coderabbitai
Copy link

coderabbitai bot commented Mar 22, 2026

📝 Walkthrough

Walkthrough

Adds full pull-request support: new API models and BacklogClient methods, 12+ CLI subcommands for PR lifecycle, comments, and attachments, wiring into main CLI and docs; includes unit tests for API and command handlers.

Changes

Cohort / File(s) Summary
API: PR models & trait
src/api/pull_request.rs, src/api/mod.rs
New PR-related serde types and deserialization helper. Extended BacklogApi trait with 13 pull-request methods and added corresponding BacklogClient impl stubs that delegate to client methods.
CLI: PR core commands
src/cmd/pr/list.rs, src/cmd/pr/count.rs, src/cmd/pr/show.rs, src/cmd/pr/create.rs, src/cmd/pr/update.rs, src/cmd/pr/mod.rs
Added PR list/count/show/create/update command modules with arg structs, *_with testable entrypoints, output formatting (text/JSON) and unit tests.
CLI: PR comments
src/cmd/pr/comment/list.rs, src/cmd/pr/comment/count.rs, src/cmd/pr/comment/add.rs, src/cmd/pr/comment/update.rs, src/cmd/pr/comment/mod.rs
Implemented comment list/count/add/update subcommands following same API-delegate pattern; includes tests and JSON/text outputs.
CLI: PR attachments
src/cmd/pr/attachment/list.rs, src/cmd/pr/attachment/get.rs, src/cmd/pr/attachment/delete.rs, src/cmd/pr/attachment/mod.rs
Added attachment list/get/delete commands; get writes bytes to disk (path resolution), delete prints confirmation or JSON; unit tests exercise success and error paths.
CLI integration
src/cmd/mod.rs, src/main.rs
Exported pr module and wired new Pr subcommand enums and dispatch in run() with relevant imports.
Docs
website/docs/commands.md, website/i18n/ja/.../commands.md
Documentation added/updated for all PR subcommands and marked PR endpoints implemented.

Sequence Diagram(s)

sequenceDiagram
    participant CLI
    participant BacklogClient
    participant BacklogAPI
    participant Filesystem

    CLI->>BacklogClient: download_pull_request_attachment(project, repo, number, attachment_id)
    BacklogClient->>BacklogAPI: GET /.../pullRequests/{number}/attachments/{attachmentId}
    BacklogAPI-->>BacklogClient: 200 OK (bytes + Content-Disposition filename)
    BacklogClient-->>CLI: (bytes, filename)
    CLI->>Filesystem: write file (path, bytes)
    Filesystem-->>CLI: success
    CLI-->>User: "Saved attachment to <path> (<n> bytes)"
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add bl pr commands (list/count/show/create/update/comment/attachment)' clearly and concisely summarizes the main feature addition—implementing a comprehensive set of pull request CLI commands.
Description check ✅ Passed The description provides a detailed summary of the changes, including specific command examples, affected files, implementation details, and notes about testing limitations. It is clearly related to the changeset.
Linked Issues check ✅ Passed The pull request implements all 12 required command-to-API-endpoint mappings specified in issue #54, including PR list/count/show/create/update, comment operations (list/count/add/update), and attachment operations (list/get/delete).
Out of Scope Changes check ✅ Passed All changes directly support the 12 pull request command implementations required by issue #54. The API layer, CLI command logic, clap wiring, and documentation updates are all scoped to PR management functionality.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feature/54-pr-commands

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds bl pr functionality to the CLI by introducing pull request API models/endpoints, wiring new clap subcommands, and documenting the new commands.

Changes:

  • Added Backlog API v2 pull request structs + client/trait methods (PRs, comments, attachments).
  • Implemented bl pr CLI commands (list/count/show/create/update + comment/attachment subcommands) with unit tests.
  • Updated command documentation and the command coverage/status tables (EN/JA).

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
website/i18n/ja/docusaurus-plugin-content-docs/current/commands.md Adds Japanese docs for bl pr ... commands and marks them implemented in the coverage table.
website/docs/commands.md Adds English docs for bl pr ... commands and marks them implemented in the coverage table.
src/main.rs Adds clap subcommand wiring for bl pr and nested comment/attachment commands.
src/cmd/pr/mod.rs Introduces cmd::pr module exports.
src/cmd/pr/list.rs Implements bl pr list output + tests.
src/cmd/pr/count.rs Implements bl pr count output + tests.
src/cmd/pr/show.rs Implements bl pr show output + tests.
src/cmd/pr/create.rs Implements bl pr create + tests.
src/cmd/pr/update.rs Implements bl pr update (+ validation via try_new) + tests.
src/cmd/pr/comment/mod.rs Introduces cmd::pr::comment module exports.
src/cmd/pr/comment/list.rs Implements bl pr comment list + tests.
src/cmd/pr/comment/count.rs Implements bl pr comment count + tests.
src/cmd/pr/comment/add.rs Implements bl pr comment add + tests.
src/cmd/pr/comment/update.rs Implements bl pr comment update + tests.
src/cmd/pr/attachment/mod.rs Introduces cmd::pr::attachment module exports.
src/cmd/pr/attachment/list.rs Implements bl pr attachment list + tests.
src/cmd/pr/attachment/get.rs Implements bl pr attachment get (download + save) + tests.
src/cmd/pr/attachment/delete.rs Implements bl pr attachment delete + tests.
src/cmd/mod.rs Registers the new pr command module.
src/api/pull_request.rs Adds PR/comment/attachment API structs + BacklogClient endpoints (+ partial httpmock tests).
src/api/mod.rs Exposes pull_request module and extends BacklogApi trait + BacklogClient impl.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/cmd/pr/comment/count.rs (1)

57-69: Have the mock assert the forwarded PR coordinates.

These tests still pass if count_with swaps project_id_or_key, repo_id_or_name, or number, because MockApi::count_pull_request_comments ignores all three inputs. Asserting them here would make the cmd-layer test actually validate the new wiring.

🧪 Tighten the mock expectations
 impl crate::api::BacklogApi for MockApi {
     fn count_pull_request_comments(
         &self,
-        _project_id_or_key: &str,
-        _repo_id_or_name: &str,
-        _number: u64,
+        project_id_or_key: &str,
+        repo_id_or_name: &str,
+        number: u64,
     ) -> anyhow::Result<PullRequestCommentCount> {
+        assert_eq!(project_id_or_key, "TEST");
+        assert_eq!(repo_id_or_name, "main");
+        assert_eq!(number, 1);
         self.count.clone().ok_or_else(|| anyhow!("no count"))
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cmd/pr/comment/count.rs` around lines 57 - 69, The MockApi currently
ignores the incoming PR coordinates so tests won't catch swapped parameters;
modify the MockApi struct to store the expected values (e.g., expected_project:
String, expected_repo: String, expected_number: u64) and in its implementation
of count_pull_request_comments assert that the incoming _project_id_or_key,
_repo_id_or_name, and _number match those expected fields (use assert_eq! or
return an anyhow! mismatch error) before returning
self.count.clone().ok_or_else(|| anyhow!("no count")); this will ensure
count_with actually validates the forwarded PR coordinates.
src/cmd/pr/comment/update.rs (1)

1-118: Consider keeping pr/comment as a single sub-resource module.

This repo’s sub-resource command modules usually keep sibling operations together, so splitting PR comment commands into per-subcommand files makes pr/comment diverge from the local layout and harder to scan alongside similar modules.

Based on learnings, "In the 23prime/backlog-cli repository, sub-resource command files under src/cmd/<resource>/ (e.g., status.rs, admin.rs, user.rs, category.rs) consolidate all subcommands (add, update, delete, reorder, etc.) and their *_with variants into a single file rather than splitting each subcommand into its own file."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cmd/pr/comment/update.rs` around lines 1 - 118, Move the split PR comment
command back into a single pr/comment sub-resource module by consolidating the
sibling subcommand files into one file that exports the related functions (e.g.,
update, update_with, PrCommentUpdateArgs and its impl) and tests; ensure you
keep the public API surface the same and preserve helper imports (BacklogApi,
BacklogClient) and test utilities (sample_pr_comment) while removing duplicate
imports/defs from the other per-subcommand files so all add/update/delete
variants live together in the pr/comment module.
src/api/pull_request.rs (1)

175-310: Add httpmock coverage for the write/download PR endpoints.

The test module only exercises the GET variants right now, so create_pull_request, update_pull_request, add_pull_request_comment, update_pull_request_comment, download_pull_request_attachment, and delete_pull_request_attachment still have no automated check of their exact path and request shape. The higher-level command tests only assert returned values, so a typo here could slip through unnoticed.

As per coding guidelines, "For api/ layer tests, use httpmock to spin up a local HTTP server and construct BacklogClient::new_with(base_url, api_key) instead of calling BacklogClient::from_config()."

Also applies to: 314-478

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/api/pull_request.rs` around lines 175 - 310, Tests currently only cover
GET endpoints; add httpmock-based tests that exercise and assert the request
path, method, body/form and headers for the write/download PR endpoints
(create_pull_request, update_pull_request, add_pull_request_comment,
update_pull_request_comment, download_pull_request_attachment,
delete_pull_request_attachment and the same for items in the 314-478 range). Use
httpmock to spin up a server and construct BacklogClient::new_with(base_url,
api_key) (not from_config), register mocks that validate exact URL path, HTTP
verb, query/form payload shape and return representative JSON or binary
responses, then call the corresponding methods (create_pull_request,
update_pull_request, add_pull_request_comment, update_pull_request_comment,
download_pull_request_attachment, delete_pull_request_attachment) and assert
both the mock was hit and the returned values deserialize as expected.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@website/docs/commands.md`:
- Around line 1969-1985: Update the docs to list the missing --json flag
variants for the PR commands wired in src/main.rs: add `--json` to the usages
for `bl pr create`, `bl pr update`, and the PR comment commands (`bl pr comment
count`, `bl pr comment add`, `bl pr comment update`) so the examples reflect the
json: bool wiring; also mirror the same additions in the Japanese translations
under website/i18n/ja/ to keep user-visible command docs consistent across
locales.

In `@website/i18n/ja/docusaurus-plugin-content-docs/current/commands.md`:
- Around line 1946-2043: Update the Japanese PR CLI docs so examples and usage
show the --json output flag where the CLI supports it: add --json variants for
the commands named bl pr list, bl pr count, bl pr create, bl pr update, bl pr
comment list, bl pr comment count, bl pr comment add, bl pr comment update, and
bl pr attachment list/delete to match the behavior implemented in src/main.rs;
also ensure the attachment get example still shows --output usage only and
mirror the same changes in the website/docs/ (English) docs to keep both locales
in sync.

---

Nitpick comments:
In `@src/api/pull_request.rs`:
- Around line 175-310: Tests currently only cover GET endpoints; add
httpmock-based tests that exercise and assert the request path, method,
body/form and headers for the write/download PR endpoints (create_pull_request,
update_pull_request, add_pull_request_comment, update_pull_request_comment,
download_pull_request_attachment, delete_pull_request_attachment and the same
for items in the 314-478 range). Use httpmock to spin up a server and construct
BacklogClient::new_with(base_url, api_key) (not from_config), register mocks
that validate exact URL path, HTTP verb, query/form payload shape and return
representative JSON or binary responses, then call the corresponding methods
(create_pull_request, update_pull_request, add_pull_request_comment,
update_pull_request_comment, download_pull_request_attachment,
delete_pull_request_attachment) and assert both the mock was hit and the
returned values deserialize as expected.

In `@src/cmd/pr/comment/count.rs`:
- Around line 57-69: The MockApi currently ignores the incoming PR coordinates
so tests won't catch swapped parameters; modify the MockApi struct to store the
expected values (e.g., expected_project: String, expected_repo: String,
expected_number: u64) and in its implementation of count_pull_request_comments
assert that the incoming _project_id_or_key, _repo_id_or_name, and _number match
those expected fields (use assert_eq! or return an anyhow! mismatch error)
before returning self.count.clone().ok_or_else(|| anyhow!("no count")); this
will ensure count_with actually validates the forwarded PR coordinates.

In `@src/cmd/pr/comment/update.rs`:
- Around line 1-118: Move the split PR comment command back into a single
pr/comment sub-resource module by consolidating the sibling subcommand files
into one file that exports the related functions (e.g., update, update_with,
PrCommentUpdateArgs and its impl) and tests; ensure you keep the public API
surface the same and preserve helper imports (BacklogApi, BacklogClient) and
test utilities (sample_pr_comment) while removing duplicate imports/defs from
the other per-subcommand files so all add/update/delete variants live together
in the pr/comment module.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aaadc4d0-e446-475e-bd88-2cd1e8fd975c

📥 Commits

Reviewing files that changed from the base of the PR and between 27a3154 and 82af49f.

📒 Files selected for processing (21)
  • src/api/mod.rs
  • src/api/pull_request.rs
  • src/cmd/mod.rs
  • src/cmd/pr/attachment/delete.rs
  • src/cmd/pr/attachment/get.rs
  • src/cmd/pr/attachment/list.rs
  • src/cmd/pr/attachment/mod.rs
  • src/cmd/pr/comment/add.rs
  • src/cmd/pr/comment/count.rs
  • src/cmd/pr/comment/list.rs
  • src/cmd/pr/comment/mod.rs
  • src/cmd/pr/comment/update.rs
  • src/cmd/pr/count.rs
  • src/cmd/pr/create.rs
  • src/cmd/pr/list.rs
  • src/cmd/pr/mod.rs
  • src/cmd/pr/show.rs
  • src/cmd/pr/update.rs
  • src/main.rs
  • website/docs/commands.md
  • website/i18n/ja/docusaurus-plugin-content-docs/current/commands.md

23prime added 2 commits March 22, 2026 09:57
…ests for mutating endpoints

Addresses review comments: add --json usage examples to pr comment update,
attachment list, and attachment delete commands; add httpmock tests for
create/update/delete pull request, comment, and attachment API methods.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/api/pull_request.rs (1)

541-546: Harden download test by asserting API key query parameter.

This test currently doesn’t verify apiKey, unlike the rest of this module. Adding it improves regression detection for download auth/query wiring.

Proposed test assertion update
     server.mock(|when, then| {
         when.method(GET)
-            .path("/projects/TEST/git/repositories/main/pullRequests/1/attachments/1");
+            .path("/projects/TEST/git/repositories/main/pullRequests/1/attachments/1")
+            .query_param("apiKey", TEST_KEY);
         then.status(200)
             .header(
                 "Content-Disposition",
                 "attachment; filename=\"screenshot.png\"",
             )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/api/pull_request.rs` around lines 541 - 546, The test
download_pull_request_attachment_returns_bytes should assert the apiKey query
parameter on the mock like the other tests do; in the server.mock when clause
for the path "/projects/TEST/git/repositories/main/pullRequests/1/attachments/1"
add a query_param assertion (e.g., .query_param("apiKey", "TEST_API_KEY") or the
test constant used elsewhere) so the mock requires the apiKey query parameter
for the request to match.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/api/pull_request.rs`:
- Around line 541-546: The test download_pull_request_attachment_returns_bytes
should assert the apiKey query parameter on the mock like the other tests do; in
the server.mock when clause for the path
"/projects/TEST/git/repositories/main/pullRequests/1/attachments/1" add a
query_param assertion (e.g., .query_param("apiKey", "TEST_API_KEY") or the test
constant used elsewhere) so the mock requires the apiKey query parameter for the
request to match.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 809b26f1-2c25-4bc6-87aa-f4f52b118107

📥 Commits

Reviewing files that changed from the base of the PR and between 82af49f and 15314af.

📒 Files selected for processing (3)
  • src/api/pull_request.rs
  • website/docs/commands.md
  • website/i18n/ja/docusaurus-plugin-content-docs/current/commands.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • website/i18n/ja/docusaurus-plugin-content-docs/current/commands.md

@23prime 23prime merged commit 31f2881 into main Mar 22, 2026
8 checks passed
@23prime 23prime deleted the feature/54-pr-commands branch March 22, 2026 01:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: bl pr (list / count / show / create / update / comments / attachments)

2 participants