vcs-gitea 0.1.0

Automate the Gitea CLI (tea) from Rust through process execution.
Documentation
# vcs-gitea

Automate **Gitea** (and Forgejo) from Rust through the `tea` CLI and process
execution. Part of the [vcs-toolkit-rs](https://github.com/ZelAnton/vcs-toolkit-rs)
workspace.

Typed, **async** commands over the Gitea CLI (`tea`) that deserialize
`tea … --output json` (tea's print-table for lists, a typed object for the issue
detail view — **not** the Gitea REST shape) into structs, behind a **mockable
interface**. Commands run inside an OS job (via [`processkit`]) so no
`tea` subprocess is ever orphaned, return the structured `Error`, and honour an
optional timeout. The [`vcs-forge`](https://crates.io/crates/vcs-forge) facade
unifies this with `vcs-github` and `vcs-gitlab`.

[`processkit`]: https://crates.io/crates/processkit

> 📖 **Full guide:** [on docs.rs]https://docs.rs/vcs-gitea/latest/vcs_gitea/guide/

`tea`'s surface is narrower than `gh`/`glab`: it has **no** single-PR view (this
crate synthesizes `pr_view` by listing and filtering), **no** current-repo view,
**no** draft toggle, and **no** PR-checks command — so those operations are absent
here (the facade reports them as `Unsupported` for the Gitea backend).

Inside an async context (every method is `async`):

```rust
use std::path::Path;
use vcs_gitea::{Gitea, GiteaApi};

let tea = Gitea::new();
let prs = tea.pr_list(Path::new(".")).await?; // Vec<PullRequest>
let authed = tea.auth_status().await?; // bool — true when a login is configured
```

### Open and merge a pull request

```rust
use std::path::Path;
use vcs_gitea::{Gitea, GiteaApi, MergeStrategy, PrCreate};

# async fn demo(repo: &Path) -> Result<(), processkit::Error> {
    let tea = Gitea::new();

    for pr in tea.pr_list(repo).await? {
        println!("#{} [{}] {} — {}", pr.number, pr.state, pr.title, pr.url);
    }

    let out = tea
        .pr_create(
            repo,
            PrCreate::new("Add streaming", "Implements …")
                .head("feat/streaming")
                .base("main"),
        )
        .await?;
    println!("{out}");

    tea.pr_merge(repo, 7, MergeStrategy::Squash).await?;
# Ok(()) }
```

Consumers depend on the `GiteaApi` trait and substitute a fake in tests — enable
the `mock` feature for a `mockall`-generated `MockGiteaApi`, or inject a fake
process runner with `Gitea::with_runner(processkit::ScriptedRunner::new()…)`:

```rust
use processkit::{Reply, ScriptedRunner};
use std::path::Path;
use vcs_gitea::{Gitea, GiteaApi};

# async fn demo() {
    let json = r#"[{"number":7,"title":"Add X","state":"open"}]"#;
    let tea = Gitea::with_runner(ScriptedRunner::new().on(["pr", "list"], Reply::ok(json)));
    assert_eq!(tea.pr_list(Path::new(".")).await.unwrap()[0].number, 7);
# }
```

Requires the `tea` binary on `PATH` (configured via `tea login add`).

## License

MIT