chore: extract fj-client (keys, client, URL/SSH resolution) (FJ-6) #6

Merged
David merged 1 commit from chore/extract-fj-client-fj-6 into main 2026-05-25 14:22:39 +02:00
Owner

Implements FJ-6 (FJ-3 Phase 2 of 5): extract the connection and credential layer into crates/fj-client and have the fj binary consume it. Depends on Phase 1 (the workspace skeleton from FJ-5).

What moved into fj-client

  • KeyInfo / LoginInfo, keys.json load/save, and forgejo_api::Forgejo client construction (get_api, api_for) - crates/fj/src/keys.rs to crates/fj-client/src/keys.rs via git rename (4-line delta: the internal crate::auth::get_client_info_for call became crate::get_client_info_for).
  • Host / SSH / URL resolution (ssh_url_parse, host_name, repo_url_host_name, get_ssh_config, the SSH_CONFIG static) and the USER_AGENT constant - from crates/fj/src/main.rs into crates/fj-client/src/url_resolve.rs and lib.rs.
  • Non-interactive OAuth client-id lookup (get_client_info_for, parse_client_info_file) - from crates/fj/src/auth.rs into crates/fj-client/src/client_info.rs.

What stayed in crates/fj

The interactive add-key / login flow in auth.rs (prompts, the OAuth browser dance, ssh-alias discovery) stays in the binary and delegates persistence, client construction, and client-id lookup to fj-client. The binary re-exports fj-client under the historical crate::keys / crate::* paths, so the rest of the source compiles unchanged.

fj-client dependencies: forgejo-api, serde, serde_json, url, ssh2-config, directories, eyre, tokio (fs + io-util), and time (serde feature, required by LoginInfo::OAuth { expires_at }). No clap / crossterm / comrak / fluent-*.

Behavior change to review

USER_AGENT expands CARGO_PKG_NAME from whichever package owns the const. Now that it lives in fj-client, the agent string sent to Forgejo is fj-client/0.5.0 (https://codeberg.org/forgejo-contrib/forgejo-cli/) rather than forgejo-cli/0.5.0 (...). Version and repository URL are unchanged. This is the natural consequence of relocating the const per the issue scope. If you would rather keep the forgejo-cli name in the agent string, say so and I will hardcode it in fj-client.

Verification (all from the issue's AC)

  • cargo build --locked (workspace) and cargo build -p fj-client (standalone) both succeed.
  • cargo tree -p fj-client -e normal | grep -E 'clap|crossterm|comrak|fluent' prints nothing.
  • cargo fmt --check clean; clippy on fj-client clean; cargo test passes.
  • fj version / fj version --verbose and fj auth --help work.

The ~108 pre-existing clippy lints in the crates/fj binary are byte-identical to origin/main and surfaced only by the newer local clippy (as documented on FJ-5). They are out of scope for this PR.

🤖 Generated with Claude Code

Implements **FJ-6** (FJ-3 Phase 2 of 5): extract the connection and credential layer into `crates/fj-client` and have the `fj` binary consume it. Depends on Phase 1 (the workspace skeleton from FJ-5). ## What moved into `fj-client` - `KeyInfo` / `LoginInfo`, `keys.json` load/save, and `forgejo_api::Forgejo` client construction (`get_api`, `api_for`) - `crates/fj/src/keys.rs` to `crates/fj-client/src/keys.rs` via git rename (4-line delta: the internal `crate::auth::get_client_info_for` call became `crate::get_client_info_for`). - Host / SSH / URL resolution (`ssh_url_parse`, `host_name`, `repo_url_host_name`, `get_ssh_config`, the `SSH_CONFIG` static) and the `USER_AGENT` constant - from `crates/fj/src/main.rs` into `crates/fj-client/src/url_resolve.rs` and `lib.rs`. - Non-interactive OAuth client-id lookup (`get_client_info_for`, `parse_client_info_file`) - from `crates/fj/src/auth.rs` into `crates/fj-client/src/client_info.rs`. ## What stayed in `crates/fj` The interactive add-key / login flow in `auth.rs` (prompts, the OAuth browser dance, ssh-alias discovery) stays in the binary and delegates persistence, client construction, and client-id lookup to `fj-client`. The binary re-exports `fj-client` under the historical `crate::keys` / `crate::*` paths, so the rest of the source compiles unchanged. `fj-client` dependencies: `forgejo-api`, `serde`, `serde_json`, `url`, `ssh2-config`, `directories`, `eyre`, `tokio` (`fs` + `io-util`), and `time` (`serde` feature, required by `LoginInfo::OAuth { expires_at }`). No `clap` / `crossterm` / `comrak` / `fluent-*`. ## Behavior change to review `USER_AGENT` expands `CARGO_PKG_NAME` from whichever package owns the const. Now that it lives in `fj-client`, the agent string sent to Forgejo is `fj-client/0.5.0 (https://codeberg.org/forgejo-contrib/forgejo-cli/)` rather than `forgejo-cli/0.5.0 (...)`. Version and repository URL are unchanged. This is the natural consequence of relocating the const per the issue scope. If you would rather keep the `forgejo-cli` name in the agent string, say so and I will hardcode it in `fj-client`. ## Verification (all from the issue's AC) - `cargo build --locked` (workspace) and `cargo build -p fj-client` (standalone) both succeed. - `cargo tree -p fj-client -e normal | grep -E 'clap|crossterm|comrak|fluent'` prints nothing. - `cargo fmt --check` clean; clippy on `fj-client` clean; `cargo test` passes. - `fj version` / `fj version --verbose` and `fj auth --help` work. The ~108 pre-existing clippy lints in the `crates/fj` binary are byte-identical to `origin/main` and surfaced only by the newer local clippy (as documented on FJ-5). They are out of scope for this PR. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chore: extract fj-client (keys, client, URL/SSH resolution) (FJ-6)
Some checks failed
Check / fmt + clippy + build + tests (pull_request) Failing after 18s
Create release / Create release from merged PR (pull_request) Has been skipped
7887a71d19
FJ-3 Phase 2 of 5: move the connection and credential layer into crates/fj-client and have the binary consume it. No CLI dependency leaks into fj-client; its tree contains no clap, crossterm, comrak, or fluent-* crate.

Moved into fj-client: KeyInfo / LoginInfo and keys.json load/save plus the forgejo_api::Forgejo client construction (get_api, api_for) from crates/fj/src/keys.rs (now crates/fj-client/src/keys.rs via git rename); the host / SSH / URL resolution (ssh_url_parse, host_name, repo_url_host_name, get_ssh_config, the SSH_CONFIG static) and the USER_AGENT constant from crates/fj/src/main.rs, now in crates/fj-client/src/url_resolve.rs and lib.rs; and the non-interactive OAuth client-id lookup (get_client_info_for, parse_client_info_file) from crates/fj/src/auth.rs, now in crates/fj-client/src/client_info.rs.

Kept in crates/fj: the interactive add-key / login flow in auth.rs (prompts, OAuth browser dance, ssh-alias discovery), which delegates persistence, client construction, and client-id lookup to fj-client. The binary re-exports fj-client under the historical crate::keys / crate::* paths so the rest of the source compiles unchanged.

fj-client dependencies: forgejo-api, serde, serde_json, url, ssh2-config, directories, eyre, tokio (fs + io-util), and time (serde feature, required by LoginInfo::OAuth expires_at).

Behavior change to flag: USER_AGENT now expands CARGO_PKG_NAME from the fj-client package, so the agent string sent to Forgejo is fj-client/0.5.0 (https://codeberg.org/forgejo-contrib/forgejo-cli/) rather than forgejo-cli/0.5.0 (...). Version and repository URL are unchanged. This is the natural consequence of relocating the const per the issue scope; preserve the old name in review if the maintainer prefers.

Verified: cargo build --locked (workspace) and cargo build -p fj-client (standalone) both succeed; cargo tree -p fj-client -e normal | grep -E 'clap|crossterm|comrak|fluent' prints nothing; cargo fmt --check is clean; clippy on fj-client is clean; cargo test passes; fj version (--verbose) and fj auth --help work. The ~108 pre-existing clippy lints in the crates/fj binary are unchanged from origin/main and surfaced only by the newer local clippy, as noted on FJ-5; they are out of scope here.

#FJ-6 State Done

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
David merged commit 4083f603ed into main 2026-05-25 14:22:39 +02:00
David deleted branch chore/extract-fj-client-fj-6 2026-05-25 14:22:39 +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/forgejo-cli!6
No description provided.