diff --git a/README.md b/README.md index 33344dc..5c3d339 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,32 @@ nix run github:DeterminateSystems/flake-checker nix run github:DeterminateSystems/flake-checker /path/to/flake.lock ``` -Nix Flake Checker looks at your `flake.lock`'s root-level [Nixpkgs] inputs and checks that: +Nix Flake Checker looks at your `flake.lock`'s root-level [Nixpkgs] inputs. +There are two ways to express flake policies: + +* Via [policy conditions](#policy-conditions) using [Common Expression Language][cel] (CEL) +* Via [parameters](#parameters) + +## Policy conditions + + + +## Parameters + +and checks that: - Any explicit Nixpkgs Git refs are in this list: - - `nixos-23.11` - - `nixos-23.11-small` - - `nixos-unstable` - - `nixos-unstable-small` - - `nixpkgs-23.11-darwin` - - `nixpkgs-unstable` + + * `nixos-23.11` + * `nixos-23.11-small` + * `nixos-24.05` + * `nixos-24.05-small` + * `nixos-unstable` + * `nixos-unstable-small` + * `nixpkgs-23.11-darwin` + * `nixpkgs-24.05-darwin` + * `nixpkgs-unstable` + - Any Nixpkgs dependencies are less than 30 days old - Any Nixpkgs dependencies have the [`NixOS`][nixos-org] org as the GitHub owner (and thus that the dependency isn't a fork or non-upstream variant) @@ -96,6 +113,7 @@ The `parse-flake-lock` crate doesn't yet exhaustively parse all input node types If you'd like to help make the parser more exhaustive, [pull requests][prs] are quite welcome. [action]: https://github.com/DeterminateSystems/flake-checker-action +[cel]: https://cel.dev [detsys]: https://determinate.systems [flakes]: https://zero-to-nix.com/concepts/flakes [install]: https://zero-to-nix.com/start/install diff --git a/src/condition.rs b/src/condition.rs index f9ebc03..bf5526a 100644 --- a/src/condition.rs +++ b/src/condition.rs @@ -11,6 +11,7 @@ pub(super) fn evaluate_condition( flake_lock: &FlakeLock, nixpkgs_keys: &[String], condition: &str, + allowed_refs: Vec, ) -> Result, FlakeCheckerError> { let mut issues: Vec = vec![]; let mut ctx = Context::default(); @@ -19,6 +20,15 @@ pub(super) fn evaluate_condition( for (name, dep) in deps { if let Node::Repo(repo) = dep { + let allowed_refs: Value = Value::from( + allowed_refs + .iter() + .map(|r| Value::from(r.to_string())) + .collect::>(), + ); + + ctx.add_variable_from_value("allowed_refs", allowed_refs); + for (k, v) in nixpkgs_cel_values(repo) { ctx.add_variable_from_value(k, v); } diff --git a/src/flake.rs b/src/flake.rs index c0b1a35..8d237b4 100644 --- a/src/flake.rs +++ b/src/flake.rs @@ -147,19 +147,29 @@ mod test { #[test] fn test_cel_conditions() { + let allowed_refs: Vec = + serde_json::from_str(include_str!("../allowed-refs.json")).unwrap(); // (n, condition, expected) - let cases: Vec<(usize, &str, bool)> = - vec![(0, "has(git_ref) && has(days_old) && has(owner)", true)]; + let cases: Vec<(usize, &str, bool)> = vec![( + 0, + "has(git_ref) && has(days_old) && has(owner) && has(allowed_refs) && allowed_refs.contains(git_ref) && owner == 'NixOS'", + true, + )]; for (n, condition, expected) in cases { - let path = PathBuf::from(format!("tests/flake.cel.{n}.lock")); + let path = PathBuf::from(format!("tests/flake.cel.clean.{n}.lock")); let flake_lock = FlakeLock::new(&path).unwrap(); let config = FlakeCheckConfig { check_outdated: false, ..Default::default() }; - let result = evaluate_condition(&flake_lock, &config.nixpkgs_keys, condition); + let result = evaluate_condition( + &flake_lock, + &config.nixpkgs_keys, + condition, + allowed_refs.clone(), + ); if expected { assert!(result.is_ok()); diff --git a/src/main.rs b/src/main.rs index 66f580a..a029aa2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -179,7 +179,7 @@ fn main() -> Result { }; let issues = if let Some(condition) = &condition { - evaluate_condition(&flake_lock, &nixpkgs_keys, condition)? + evaluate_condition(&flake_lock, &nixpkgs_keys, condition, allowed_refs.clone())? } else { check_flake_lock(&flake_lock, &flake_check_config, allowed_refs.clone())? }; diff --git a/tests/flake.cel.0.lock b/tests/flake.cel.clean.0.lock similarity index 100% rename from tests/flake.cel.0.lock rename to tests/flake.cel.clean.0.lock