Replaces the Endpoints enum and checker's per-host dispatch: checker.rs now holds only the ReleaseSource trait (latest release + API root), each host implements it in its own module (github.rs, forgejo.rs), and source.rs is a factory returning a Box<dyn ReleaseSource> per package. Adding a host no longer touches existing ones, and the pipeline only sees the trait. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
48 lines
1.9 KiB
Rust
48 lines
1.9 KiB
Rust
//! The check stage's contract: a `ReleaseSource` says what a package's
|
|
//! latest release is and where its releases API lives, and
|
|
//! `version_from_tag` turns the resulting tag into a version string. Each
|
|
//! hosting service implements the trait in its own module (`github`,
|
|
//! `forgejo`) so per-host logic doesn't accumulate here;
|
|
//! `source::for_package` picks the implementation for a package.
|
|
|
|
use anyhow::Result;
|
|
|
|
/// A hosting service a package's releases are published on. `Debug` so a
|
|
/// `Box<dyn ReleaseSource>` can sit in a `Result` that tests unwrap.
|
|
pub trait ReleaseSource: std::fmt::Debug {
|
|
/// The latest release tag for `repo`.
|
|
fn latest_release(&self, client: &reqwest::blocking::Client, repo: &str) -> Result<String>;
|
|
|
|
/// The releases API root, which `fetcher` and `verifier` build their
|
|
/// own paths under. GitHub and Forgejo both serve
|
|
/// `/repos/{owner}/{repo}/releases/tags/{tag}` there with the same
|
|
/// `assets[].{name, browser_download_url}` shape, which is why those
|
|
/// stages need only this and not the source itself.
|
|
fn api(&self) -> &str;
|
|
}
|
|
|
|
/// Strips a leading `v` from a release tag, e.g. `v2.62.0` -> `2.62.0`.
|
|
///
|
|
/// Some projects (uv) tag releases with the bare version and use it
|
|
/// verbatim in asset filenames; others (scaleway-cli) tag `vX.Y.Z` but
|
|
/// still use the bare version in filenames. This is the version string
|
|
/// substituted into `{version}` placeholders in `asset_pattern` /
|
|
/// `checksum_asset_pattern`, not the tag used for API/attestation calls.
|
|
pub fn version_from_tag(tag: &str) -> &str {
|
|
tag.strip_prefix('v').unwrap_or(tag)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn version_from_tag_strips_leading_v() {
|
|
assert_eq!(version_from_tag("v2.62.0"), "2.62.0");
|
|
}
|
|
|
|
#[test]
|
|
fn version_from_tag_leaves_bare_version_unchanged() {
|
|
assert_eq!(version_from_tag("0.12.15"), "0.12.15");
|
|
}
|
|
}
|