fix: comprehensive bakery package manager audit and repair
Critical fixes: - gen-index.sh: emit services, config, optional_system_deps from bakery.toml; parse product list from registry TOML instead of hardcoded array; fail loudly when bakery.toml is missing (was silently producing empty metadata in prod) - install.rs: download service units and example configs from dl server at install time (were never fetched); check systemctl exit codes (were swallowed); save state before file cleanup in remove_package (was inconsistent on error) - doctor.rs: rewrite dep detection to use `pacman -Q` as primary (no more dependency on `which` or pkg-config name mismatches); add optional_system_deps support returning (missing, warnings) — warnings print but never block install - get.sh: fix GitHub fallback URL (was 404 for both latest and versioned releases); add SHA-256 checksum verification using published .sha256 file High priority fixes: - bakery doctor <unknown-pkg>: exit non-zero (was silently passing) - bakery update: add --all flag (documented in README but missing from CLI); add doctor gate before update (was bypassing dep check) - bread_deps: now resolved recursively with cycle detection (was ignored) - manifest.rs: add artifact_urls() helper and optional_system_deps field - state.rs: atomic save via tmp+rename; cmd_info shows optional_system_deps Tests: 17 new unit tests across doctor, download, install, state modules; scripts/test-gen-index.sh fixture test for full pipeline
This commit is contained in:
parent
0b38e8cce3
commit
694829c50f
13 changed files with 971 additions and 148 deletions
|
|
@ -23,7 +23,7 @@ pub struct Service {
|
|||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct ConfigScaffold {
|
||||
pub dir: String,
|
||||
/// relative to the product repo root; copied as-is if absent at install time
|
||||
/// Example config filename, relative to the release artifact directory.
|
||||
pub example: Option<String>,
|
||||
}
|
||||
|
||||
|
|
@ -36,6 +36,8 @@ pub struct Package {
|
|||
#[serde(default)]
|
||||
pub system_deps: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub optional_system_deps: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub bread_deps: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub services: Vec<Service>,
|
||||
|
|
@ -44,6 +46,21 @@ pub struct Package {
|
|||
pub post_install: Vec<String>,
|
||||
}
|
||||
|
||||
impl Package {
|
||||
/// Returns `(primary_url, github_url)` for any artifact filename in this
|
||||
/// package's release directory. Derived by stripping the filename from the
|
||||
/// first binary's URLs.
|
||||
pub fn artifact_urls(&self, filename: &str) -> Option<(String, String)> {
|
||||
let first = self.binaries.first()?;
|
||||
let dl_base = first.dl_url.rsplit_once('/')?.0;
|
||||
let gh_base = first.github_url.rsplit_once('/')?.0;
|
||||
Some((
|
||||
format!("{dl_base}/{filename}"),
|
||||
format!("{gh_base}/{filename}"),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct Index {
|
||||
pub version: String,
|
||||
|
|
@ -67,8 +84,7 @@ pub fn load(force_refresh: bool) -> Result<Index> {
|
|||
let cache_path = cache_path();
|
||||
|
||||
if !force_refresh && cache_is_fresh(&cache_path) {
|
||||
let text = std::fs::read_to_string(&cache_path)
|
||||
.context("reading cached index")?;
|
||||
let text = std::fs::read_to_string(&cache_path).context("reading cached index")?;
|
||||
return serde_json::from_str(&text).context("parsing cached index");
|
||||
}
|
||||
|
||||
|
|
@ -132,6 +148,6 @@ fn fetch_bytes(url: &str) -> Result<Vec<u8>> {
|
|||
let mut buf = Vec::new();
|
||||
resp.into_reader()
|
||||
.read_to_end(&mut buf)
|
||||
.context("reading binary")?;
|
||||
.context("reading response")?;
|
||||
Ok(buf)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue