refactor command flow and add signed package/hook safety

- split CLI definitions and command execution out of main.rs into new cli.rs and commands.rs modules\n- add transaction hook support via /etc/depot.d/hooks/*.toml with pre/post phases, operation/package/path filters, wildcard negation, and optional affected-path stdin\n- execute transaction hooks around install/update/remove operations and add package-action prompts for install/build/remove flows\n- require and verify detached minisign signatures for binary package archives when allow_unsigned=false, including cache handling and tests\n- persist optional dependencies from package metadata into repo index data and include optional deps in produced metadata\n- update dependency/planner logic to ignore dependencies provided by local split outputs and stop pulling test deps into install planning\n- auto-disable tests when required test dependencies are missing instead of hard-failing build/install paths\n- improve autotools defaults by injecting standard install directory flags when supported and preserving user overrides\n- remove static .a archives during staging by default with new build.flags.no_delete_static escape hatch\n- preserve symlinks and file metadata (permissions/timestamps) in extractor fallback copy path and add regression tests\n- refresh README docs for detached package signatures, optional dependencies, and transaction hooks\n- adjust dependency set: add filetime, disable reqwest default features, and simplify git2/OpenSSL linkage
This commit is contained in:
2026-02-28 00:54:08 -06:00
parent e045ae78fd
commit ce5fefa833
19 changed files with 3863 additions and 2923 deletions
+54 -6
View File
@@ -5,7 +5,7 @@ use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde::Serializer;
use std::collections::BTreeMap;
use std::collections::{BTreeMap, HashSet};
use std::fmt;
use std::fs;
use std::path::Path;
@@ -192,6 +192,22 @@ impl PackageSpec {
.unwrap_or_else(|| self.dependencies.clone())
}
/// Return all package names/provided features produced by this spec.
///
/// This includes all output package names and per-output `provides` entries.
pub fn local_dependency_provides(&self) -> HashSet<String> {
let mut names = HashSet::new();
for output in self.outputs() {
let output_name = output.name.clone();
names.insert(output_name.clone());
let alternatives = self.alternatives_for_output(&output_name);
for provided in alternatives.provides {
names.insert(provided);
}
}
names
}
/// Return alternatives/provides for a specific output package name.
///
/// If no per-output override exists, returns the top-level alternatives.
@@ -481,6 +497,11 @@ impl PackageSpec {
self.build.flags.no_strip = b;
}
}
"no_delete_static" | "no-delete-static" => {
if let Some(b) = v.as_bool() {
self.build.flags.no_delete_static = b;
}
}
"no_compress_man"
| "no-compress-man"
| "no_compress_manpages"
@@ -997,6 +1018,11 @@ impl PackageSpec {
self.build.flags.no_strip = b;
}
}
"no_delete_static" | "no-delete-static" => {
if let Some(b) = values.last().and_then(|v| v.as_bool()) {
self.build.flags.no_delete_static = b;
}
}
"no_compress_man"
| "no-compress-man"
| "no_compress_manpages"
@@ -1535,6 +1561,7 @@ make_test_dirs = ["tests"]
make_install_dirs = ["lib"]
no_flags = true
no_strip = true
no_delete_static = true
no_compress_man = true
skip_tests = true
keep = ["etc/locale.gen"]
@@ -1572,6 +1599,10 @@ post_configure = ["echo configured"]
"build.flags.no_compress_man".to_string(),
vec![toml::Value::Boolean(false)],
);
config.appends.insert(
"build.flags.no_delete_static".to_string(),
vec![toml::Value::Boolean(false)],
);
config.appends.insert(
"build.flags.passthrough_env".to_string(),
vec![toml::Value::String("CARGO_HOME".to_string())],
@@ -1627,6 +1658,7 @@ post_configure = ["echo configured"]
);
assert!(spec.build.flags.no_flags);
assert!(!spec.build.flags.no_strip);
assert!(!spec.build.flags.no_delete_static);
assert!(!spec.build.flags.no_compress_man);
assert!(
spec.build
@@ -1735,7 +1767,7 @@ no_flags = true
}
#[test]
fn parse_no_strip_and_no_compress_man_from_spec() {
fn parse_no_strip_no_delete_static_and_no_compress_man_from_spec() {
let tmp = tempfile::tempdir().unwrap();
let path = tmp.path().join("pkg.toml");
@@ -1759,6 +1791,7 @@ type = "custom"
[build.flags]
no_strip = true
"no-delete-static" = true
no-compress-man = true
"#,
)
@@ -1766,6 +1799,7 @@ no-compress-man = true
let spec = PackageSpec::from_file(&path).unwrap();
assert!(spec.build.flags.no_strip);
assert!(spec.build.flags.no_delete_static);
assert!(spec.build.flags.no_compress_man);
}
@@ -2128,10 +2162,11 @@ extract_dir = "foo"
[build]
type = "autotools"
[dependencies]
build = ["make"]
test = ["python", "bats"]
"#,
[dependencies]
build = ["make"]
test = ["python", "bats"]
optional = ["gtk-doc"]
"#,
)
.unwrap();
@@ -2140,6 +2175,7 @@ test = ["python", "bats"]
spec.dependencies.test,
vec!["python".to_string(), "bats".to_string()]
);
assert_eq!(spec.dependencies.optional, vec!["gtk-doc".to_string()]);
}
#[test]
@@ -2576,6 +2612,14 @@ pub struct BuildFlags {
/// Disable automatic stripping of ELF files during staging.
#[serde(default, alias = "no-strip")]
pub no_strip: bool,
/// Disable automatic deletion of static libraries (`*.a`) during staging.
#[serde(
default,
alias = "no-delete-static",
alias = "no_remove_static",
alias = "no-remove-static"
)]
pub no_delete_static: bool,
/// Disable automatic zstd compression of man pages during staging.
#[serde(
default,
@@ -2814,6 +2858,7 @@ impl Default for BuildFlags {
keep: Vec::new(),
no_flags: false,
no_strip: false,
no_delete_static: false,
no_compress_man: false,
skip_tests: false,
build_32: false,
@@ -2981,4 +3026,7 @@ pub struct Dependencies {
/// Dependencies required to run package test suites.
#[serde(default)]
pub test: Vec<String>,
/// Optional runtime integrations that enhance functionality when installed.
#[serde(default)]
pub optional: Vec<String>,
}