Add junie guidelines
This commit is contained in:
130
.junie/guidelines.md
Normal file
130
.junie/guidelines.md
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
# cl-cli — Project-specific development guidelines
|
||||||
|
|
||||||
|
This document captures project-specific knowledge to help advanced contributors work efficiently on this repository. It focuses on practical, non-obvious details (build, configuration, testing, and development tips) specific to this codebase.
|
||||||
|
|
||||||
|
## 1. Build and configuration
|
||||||
|
|
||||||
|
- Rust workspace/binaries
|
||||||
|
- Single crate with two binaries defined in `Cargo.toml`:
|
||||||
|
- `cl-cli` → `src/main.rs`: the CLI entrypoint.
|
||||||
|
- `webext` → `src/webext.rs`: a Native Messaging host used by the browser extension.
|
||||||
|
- Library module tree under `src/lib.rs` exposes common code to both binaries.
|
||||||
|
- Toolchain: stable Rust; CI uses dtolnay/rust-toolchain@stable.
|
||||||
|
- Dependencies and async runtime
|
||||||
|
- Async via `tokio` (features: `rt`, `rt-multi-thread`, `macros`). Both binaries use `#[tokio::main]`.
|
||||||
|
- HTTP via `reqwest`; serialization via `serde`/`serde_json`; configuration via `toml`.
|
||||||
|
- Build
|
||||||
|
- Standard build works without extra flags:
|
||||||
|
- `cargo build` (debug) or `cargo build --release` (optimized).
|
||||||
|
- Individual binaries:
|
||||||
|
- `cargo build --bin cl-cli`
|
||||||
|
- `cargo build --bin webext`
|
||||||
|
- The web extension host (`webext`) is a regular Rust binary; it is not bundled by NPM tooling.
|
||||||
|
- Configuration file
|
||||||
|
- Expected location by default: `$HOME/.config/cl-cli/config.toml`.
|
||||||
|
- The CLI allows overriding the path via `--config <PATH>`; the webext host always reads the default path.
|
||||||
|
- Template: `config.toml.dist`. Minimal fields:
|
||||||
|
- `[[gitlab]] { token, domain }`
|
||||||
|
- `[[gitea]] { token, domain }`
|
||||||
|
- `[openproject] { token, base_url }`
|
||||||
|
- Example of initial setup (copy the dist and edit):
|
||||||
|
```bash
|
||||||
|
mkdir -p "$HOME/.config/cl-cli"
|
||||||
|
cp config.toml.dist "$HOME/.config/cl-cli/config.toml"
|
||||||
|
$EDITOR "$HOME/.config/cl-cli/config.toml"
|
||||||
|
```
|
||||||
|
- Error surface: parsing and IO errors are surfaced as `GeneralError`; the CLI will print and exit non‑zero, the `webext` host will return an error payload.
|
||||||
|
- Local OpenProject for development
|
||||||
|
- `docker-compose.yaml` provides a local OpenProject (13.x) at `http://localhost:8080` with persisted volumes under `.docker-data/`.
|
||||||
|
|
||||||
|
## 2. Testing
|
||||||
|
|
||||||
|
- Test types present
|
||||||
|
- Unit tests live alongside code under `#[cfg(test)]` modules (e.g., `src/gitea/issue.rs`, `src/webext.rs`, `src/planning/utils.rs`).
|
||||||
|
- Integration tests can be placed under `tests/`. The crate exposes internal modules via `src/lib.rs` for integration testing.
|
||||||
|
- Running tests
|
||||||
|
- `cargo test` runs unit and integration tests. CI also runs `cargo test` on every push/PR.
|
||||||
|
- Tests are pure and do not require network or external services; avoid adding network‑bound tests.
|
||||||
|
- Adding new tests
|
||||||
|
- Prefer unit tests near the logic being tested. For integration coverage across modules, place files under `tests/` and use public items from `cl_cli`.
|
||||||
|
- Keep tests deterministic: no real HTTP calls; if needed, mock boundaries at the client layer.
|
||||||
|
- Example integration test (verified locally during preparation)
|
||||||
|
- Minimal example using a pure helper. Create `tests/example_gitea_url.rs`:
|
||||||
|
```rust
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn converts_gitea_issue_html_url_to_api_url() {
|
||||||
|
// Pure transformation; no network
|
||||||
|
let input = Url::parse("https://gitea.champs-libres.be/champs-libres/test/issues/1").unwrap();
|
||||||
|
let out = cl_cli::gitea::issue::issue_html_url_to_api(&input).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
out.as_str(),
|
||||||
|
"https://gitea.champs-libres.be/api/v1/repos/champs-libres/test/issues/1"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Run it with `cargo test`. Remove the file if it was only created as a demo.
|
||||||
|
|
||||||
|
## 3. CLI usage tips (project‑specific)
|
||||||
|
|
||||||
|
- `cl-cli planning i2work <gitlab_issue_url> <openproject_project_identifier>` creates an OpenProject work package from a GitLab issue.
|
||||||
|
- The OpenProject project identifier is the short slug in URLs, e.g. `chill` in `.../projects/chill/...`.
|
||||||
|
- The command uses tokens from the configuration file to authenticate to GitLab and OpenProject.
|
||||||
|
- Example:
|
||||||
|
```bash
|
||||||
|
cl-cli planning i2work \
|
||||||
|
https://gitlab.com/Chill-Projet/chill-bundles/-/issues/240 \
|
||||||
|
chill
|
||||||
|
```
|
||||||
|
- `cl-cli test` invokes a debug routine (see `src/debug.rs`) primarily for local diagnostics.
|
||||||
|
|
||||||
|
## 4. Web extension native host (`webext`)
|
||||||
|
|
||||||
|
- Purpose: acts as a Native Messaging host for a browser extension under `web-extension/`.
|
||||||
|
- Protocol: communicates via stdin/stdout using 4‑byte length‑prefixed JSON messages.
|
||||||
|
- Input `serde` enum is tagged with `type`; currently supports `{"type":"Issue2Work", ...}`.
|
||||||
|
- Output is tagged with `result` (`Ok` or `Error`) and contains `data` when successful.
|
||||||
|
- Business flow: the host reads config from `$HOME/.config/cl-cli/config.toml`, translates the input into `Issue2Work` CLI arguments, delegates to `planning::issue2work::handle_issue2work`, and returns the created work package URL.
|
||||||
|
- Testing the transport: see unit tests in `src/webext.rs` that exercise message framing and deserialization.
|
||||||
|
|
||||||
|
## 5. Code style and architectural notes
|
||||||
|
|
||||||
|
- Module layout
|
||||||
|
- Public library facade (`src/lib.rs`) re‑exports internal modules for reuse by both binaries and tests.
|
||||||
|
- Planning features under `src/planning/` with a trait (`Issue2WorkActionTrait`) and concrete actions per platform.
|
||||||
|
- Git providers (`src/gitlab`, `src/gitea`) and OpenProject client live in dedicated modules.
|
||||||
|
- Error handling
|
||||||
|
- Unified lightweight `GeneralError` encapsulates user‑facing messages; conversions from `reqwest::Error` and header errors are provided.
|
||||||
|
- Data parsing
|
||||||
|
- Input/Output types rely on `serde` with explicit tagging for clarity and forward compatibility.
|
||||||
|
- Concurrency
|
||||||
|
- All async entrypoints are `#[tokio::main]`; downstream async functions return `impl Future` to stay generic and testable.
|
||||||
|
- External calls
|
||||||
|
- Wrap external service interactions behind client modules; this eases mocking in tests and keeps pure helpers (like URL mappers) easily testable.
|
||||||
|
|
||||||
|
## 6. Continuous Integration
|
||||||
|
|
||||||
|
- `.gitea/workflows/release/check.yaml` performs:
|
||||||
|
- Checkout → install stable toolchain → `cargo build` → `cargo test`.
|
||||||
|
- Release job (see `.gitea/workflows/release/build-and-release.yaml`) builds release artifacts for distribution.
|
||||||
|
|
||||||
|
## 7. Troubleshooting / gotchas (project‑specific)
|
||||||
|
|
||||||
|
- Config path
|
||||||
|
- The CLI accepts `--config`, but the webext host reads the default path only. Ensure `$HOME/.config/cl-cli/config.toml` exists when using the browser integration.
|
||||||
|
- Tokens scope
|
||||||
|
- Ensure personal access tokens for GitLab and OpenProject have sufficient scopes for reading issues and creating work packages respectively.
|
||||||
|
- Locale/URLs
|
||||||
|
- `Issue2Work` requires the OpenProject project identifier (slug), not its display name.
|
||||||
|
- HTTP environment
|
||||||
|
- `reqwest` honors proxy vars (`HTTP_PROXY`, `HTTPS_PROXY`) if present; be aware for corporate environments.
|
||||||
|
|
||||||
|
## 8. Commands quick reference
|
||||||
|
|
||||||
|
- Build: `cargo build --release`
|
||||||
|
- Run CLI: `cargo run --bin cl-cli -- <args>`
|
||||||
|
- Run webext host directly for dev: `cargo run --bin webext`
|
||||||
|
- Tests: `cargo test`
|
||||||
|
- Linting: `cargo clippy` (not enforced in CI but recommended)
|
||||||
|
|
||||||
Reference in New Issue
Block a user