pkgwatch/src/config.rs

55 lines
1.7 KiB
Rust
Raw Normal View History

use anyhow::{Context, Result};
use serde::Deserialize;
use std::collections::HashMap;
use std::path::Path;
#[derive(Debug, Deserialize)]
struct PackageFile {
package: HashMap<String, Package>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct Package {
pub repo: String,
pub asset_pattern: String,
pub verification: Verification,
}
#[derive(Debug, Deserialize, Clone)]
#[serde(tag = "method", rename_all = "kebab-case")]
pub enum Verification {
/// Tier 4: proves transport integrity only, not authorship. See
/// SPEC.md > Verification trust tiers.
SameOriginSha256 { checksum_asset_pattern: String },
/// Tier 2: GitHub build-provenance attestation, verified via `gh
/// attestation verify` rather than reimplementing sigstore in Rust.
GithubAttestation,
}
impl Verification {
pub fn tier(&self) -> u8 {
match self {
Verification::SameOriginSha256 { .. } => 4,
Verification::GithubAttestation => 2,
}
}
}
/// Loads every `*.toml` file in `dir` (the `packages.d/` layout from
/// SPEC.md > Scaling to many packages), keyed by package name.
pub fn load_packages_dir(dir: &Path) -> Result<Vec<(String, Package)>> {
let mut out = Vec::new();
for entry in std::fs::read_dir(dir).with_context(|| format!("reading {}", dir.display()))? {
let path = entry?.path();
if path.extension().and_then(|e| e.to_str()) != Some("toml") {
continue;
}
let text = std::fs::read_to_string(&path)
.with_context(|| format!("reading {}", path.display()))?;
Set up project tooling to match the rest of ~/dev's Rust fleet Surveyed sporah/doubleo7/feedsignal/uy-immigration-watcher/notif-picker for conventions and replicated the current dominant pattern rather than inventing a new one: - Forgejo CI (.forgejo/workflows/ci.yml): build/test/audit jobs on the rust-ci runner label, cargo+sccache caching, cargo fmt --check, cargo clippy --all-targets -- -D warnings, cargo audit. Matches sporah/doubleo7/feedsignal/uy-immigration-watcher; notif-picker's docker-label/manual-toolchain-install variant looks like an earlier iteration superseded by this one. - Makefile.toml with format/format-check/lint/test/audit/build tasks and a `ci` task chaining them — copied from notif-picker's clean version, the only project that had this pattern. `cargo make ci` now runs the same checks locally that CI runs. - Explicit empty [workspace] in Cargo.toml (doubleo7's pattern) so a nested git-worktree checkout can't accidentally inherit an ancestor directory's workspace manifest. - rustfmt: no rustfmt.toml, matching every sibling project — default style is the established convention here, not an oversight. New for this fleet, since nothing else in ~/dev has it: a git-native pre-commit hook (.githooks/pre-commit, activated via `cargo make install-hooks` / `git config core.hooksPath .githooks`) that runs `cargo fmt` and re-stages whatever it reformats. Chose git's native hooksPath over the pre-commit(.com) framework or cargo-husky — no extra runtime dependency, hook is tracked and shareable, and nothing else here needs Python. Kept to formatting only; clippy/audit stay in CI, which already covers them and can run heavier checks than a commit hook should. Fixed one clippy finding (useless format! in checker.rs) and reformatted the existing code to match the now-enforced default rustfmt style. `cargo make ci` passes clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A2FEut5tVMNjeVjqhgVZbr
2026-09-11 08:13:29 +00:00
let file: PackageFile =
toml::from_str(&text).with_context(|| format!("parsing {}", path.display()))?;
out.extend(file.package);
}
Ok(out)
}