diff --git a/Cargo.lock b/Cargo.lock index 2540604..30bd5e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -347,7 +347,7 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flake-checker" -version = "0.2.0" +version = "0.2.1" dependencies = [ "cel-interpreter", "chrono", diff --git a/Cargo.toml b/Cargo.toml index e12a6fa..74140eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flake-checker" -version = "0.2.0" +version = "0.2.1" edition = "2021" [workspace] diff --git a/flake.nix b/flake.nix index 8980e25..9ed6cf2 100644 --- a/flake.nix +++ b/flake.nix @@ -70,7 +70,7 @@ cargo-bloat cargo-edit cargo-machete - cargo-watch + bacon rust-analyzer # Nix diff --git a/src/condition.rs b/src/condition.rs index 5f2924d..603e7fa 100644 --- a/src/condition.rs +++ b/src/condition.rs @@ -3,7 +3,7 @@ use parse_flake_lock::{FlakeLock, Node}; use crate::{ error::FlakeCheckerError, - flake::{nixpkgs_deps, num_days_old}, + flake::{nixpkgs_deps, num_days_old, FlakeCheckConfig}, issue::{Issue, IssueKind}, }; @@ -14,7 +14,7 @@ const KEY_SUPPORTED_REFS: &str = "supportedRefs"; pub(super) fn evaluate_condition( flake_lock: &FlakeLock, - nixpkgs_keys: &[String], + config: &FlakeCheckConfig, condition: &str, supported_refs: Vec, ) -> Result, FlakeCheckerError> { @@ -22,7 +22,7 @@ pub(super) fn evaluate_condition( let mut ctx = Context::default(); ctx.add_variable_from_value(KEY_SUPPORTED_REFS, supported_refs); - let deps = nixpkgs_deps(flake_lock, nixpkgs_keys)?; + let deps = nixpkgs_deps(flake_lock, config.nixpkgs_keys.clone())?; for (name, node) in deps { let (git_ref, last_modified, owner) = match node { diff --git a/src/flake.rs b/src/flake.rs index 84ebd93..f38add9 100644 --- a/src/flake.rs +++ b/src/flake.rs @@ -15,7 +15,7 @@ pub(crate) struct FlakeCheckConfig { pub check_outdated: bool, pub check_owner: bool, pub fail_mode: bool, - pub nixpkgs_keys: Vec, + pub nixpkgs_keys: Option>, } impl Default for FlakeCheckConfig { @@ -25,52 +25,79 @@ impl Default for FlakeCheckConfig { check_outdated: true, check_owner: true, fail_mode: false, - nixpkgs_keys: vec![String::from("nixpkgs")], + nixpkgs_keys: None, } } } pub(super) fn nixpkgs_deps( flake_lock: &FlakeLock, - keys: &[String], + nixpkgs_keys: Option>, ) -> Result, FlakeCheckerError> { let mut deps: HashMap = HashMap::new(); - for (ref key, node) in flake_lock.root.clone() { - match &node { - Node::Repo(_) => { - if keys.contains(key) { - deps.insert(key.to_string(), node); + if let Some(explicit_keys) = nixpkgs_keys { + for (ref key, node) in flake_lock.root.clone() { + match &node { + Node::Repo(_) => { + if explicit_keys.contains(key) { + deps.insert(key.to_string(), node); + } } - } - Node::Tarball(_) => { - if keys.contains(key) { - deps.insert(key.to_string(), node); + Node::Tarball(_) => { + if explicit_keys.contains(key) { + deps.insert(key.to_string(), node); + } } - } - Node::Indirect(indirect_node) => { - if keys.contains(key) && &indirect_node.original.id == key { - deps.insert(key.to_string(), node); + Node::Indirect(indirect_node) => { + if explicit_keys.contains(key) && &indirect_node.original.id == key { + deps.insert(key.to_string(), node); + } + } + _ => { + // NOTE: it's unclear that a path node for Nixpkgs should be accepted } } - _ => { - // NOTE: it's unclear that a path node for Nixpkgs should be accepted + + let missing: Vec = explicit_keys + .iter() + .filter(|k| !deps.contains_key(*k)) + .map(String::from) + .collect(); + + if !missing.is_empty() { + let error_msg = format!( + "no nixpkgs dependency found for specified {}: {}", + if missing.len() > 1 { "keys" } else { "key" }, + missing.join(", ") + ); + return Err(FlakeCheckerError::Invalid(error_msg)); + } + } + } else { + for (ref key, node) in flake_lock.root.clone() { + match &node { + Node::Repo(repo) => { + if repo.original.owner.to_lowercase() == "nixos" + && repo.original.repo.to_lowercase() == "nixpkgs" + { + deps.insert(key.to_string(), node); + } + } + Node::Tarball(tarball) => { + // If necessary, we can expand this to include other tarball sources + if tarball + .original + .url + .to_lowercase() + .starts_with("https://flakehub.com/f/nixos/nixpkgs/") + { + deps.insert(key.to_string(), node); + } + } + _ => {} } } - } - let missing: Vec = keys - .iter() - .filter(|k| !deps.contains_key(*k)) - .map(String::from) - .collect(); - - if !missing.is_empty() { - let error_msg = format!( - "no nixpkgs dependency found for specified {}: {}", - if missing.len() > 1 { "keys" } else { "key" }, - missing.join(", ") - ); - return Err(FlakeCheckerError::Invalid(error_msg)); } Ok(deps) @@ -83,7 +110,7 @@ pub(crate) fn check_flake_lock( ) -> Result, FlakeCheckerError> { let mut issues = vec![]; - let deps = nixpkgs_deps(flake_lock, &config.nixpkgs_keys)?; + let deps = nixpkgs_deps(flake_lock, config.nixpkgs_keys.clone())?; for (name, node) in deps { let (git_ref, last_modified, owner) = match node { @@ -177,16 +204,11 @@ mod test { for (condition, expected) in cases { let flake_lock = FlakeLock::new(&path).unwrap(); let config = FlakeCheckConfig { - nixpkgs_keys: vec![String::from("nixpkgs")], ..Default::default() }; - let result = evaluate_condition( - &flake_lock, - &config.nixpkgs_keys, - condition, - supported_refs.clone(), - ); + let result = + evaluate_condition(&flake_lock, &config, condition, supported_refs.clone()); if expected { assert!(result.is_ok()); @@ -291,7 +313,7 @@ mod test { let flake_lock = FlakeLock::new(&path).unwrap(); let config = FlakeCheckConfig { check_outdated: false, - nixpkgs_keys, + nixpkgs_keys: Some(nixpkgs_keys), ..Default::default() }; let issues = check_flake_lock(&flake_lock, &config, allowed_refs.clone()).unwrap(); @@ -318,7 +340,7 @@ mod test { let flake_lock = FlakeLock::new(&path).unwrap(); let config = FlakeCheckConfig { check_outdated: false, - nixpkgs_keys, + nixpkgs_keys: Some(nixpkgs_keys), ..Default::default() }; diff --git a/src/main.rs b/src/main.rs index a029aa2..dd0626a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -74,11 +74,10 @@ struct Cli { long, short, env = "NIX_FLAKE_CHECKER_NIXPKGS_KEYS", - default_value = "nixpkgs", value_delimiter = ',', name = "KEY_LIST" )] - nixpkgs_keys: Vec, + nixpkgs_keys: Option>, /// Display Markdown summary (in GitHub Actions). #[arg( @@ -179,7 +178,12 @@ fn main() -> Result { }; let issues = if let Some(condition) = &condition { - evaluate_condition(&flake_lock, &nixpkgs_keys, condition, allowed_refs.clone())? + evaluate_condition( + &flake_lock, + &flake_check_config, + condition, + allowed_refs.clone(), + )? } else { check_flake_lock(&flake_lock, &flake_check_config, allowed_refs.clone())? };