From a6aa366930f5a7413b99c3a520afab06cdc9e84f Mon Sep 17 00:00:00 2001 From: Luc Perkins Date: Tue, 11 Jul 2023 12:26:24 -0700 Subject: [PATCH] Add Path variant to enum --- parse-flake-lock/src/lib.rs | 46 +++++++++++++++++++++++++++++++++++-- src/flake.rs | 18 +++++++++++---- tests/flake.clean.6.lock | 35 +++++++++++++++++----------- 3 files changed, 79 insertions(+), 20 deletions(-) diff --git a/parse-flake-lock/src/lib.rs b/parse-flake-lock/src/lib.rs index dad5fe1..3c0a677 100644 --- a/parse-flake-lock/src/lib.rs +++ b/parse-flake-lock/src/lib.rs @@ -3,7 +3,7 @@ use std::collections::{HashMap, VecDeque}; use std::fmt; use std::fs::read_to_string; -use std::path::Path; +use std::path::{Path, PathBuf}; use serde::de::{self, MapAccess, Visitor}; use serde::{Deserialize, Deserializer}; @@ -137,7 +137,9 @@ fn chase_input_node( let maybe_node_inputs = match node { Node::Root(_) => None, Node::Repo(node) => node.inputs.to_owned(), + // TODO: investigate Node::Indirect(_) => None, + Node::Path(_) => None, Node::Fallthrough(node) => match node.get("inputs") { Some(node_inputs) => serde_json::from_value(node_inputs.clone()) .map_err(FlakeLockParseError::Json)?, @@ -187,7 +189,10 @@ pub enum Node { /// A [RepoNode] flake input for a [Git](https://git-scm.com) repository (or another version /// control system). Repo(Box), + /// TODO Indirect(IndirectNode), + /// TODO + Path(PathNode), /// A "catch-all" variant for node types that don't (yet) have explicit struct definitions in /// this crate. Fallthrough(serde_json::value::Value), // Covers all other node types @@ -199,6 +204,7 @@ impl Node { Node::Root(_) => "Root", Node::Repo(_) => "Repo", Node::Indirect(_) => "Indirect", + Node::Path(_) => "Path", Node::Fallthrough(_) => "Fallthrough", // Covers all other node types } } @@ -235,6 +241,7 @@ pub struct RepoNode { pub original: RepoOriginal, } +/// Information about the flake input that's "locked" because it's supplied by Nix. #[derive(Clone, Debug, Deserialize)] pub struct Locked { #[serde(alias = "lastModified")] @@ -248,6 +255,7 @@ pub struct Locked { pub node_type: String, } +/// The `original` field of a [Repo][Node::Repo] node. #[derive(Clone, Debug, Deserialize)] pub struct RepoOriginal { pub owner: String, @@ -258,6 +266,9 @@ pub struct RepoOriginal { pub git_ref: Option, } +/// An indirect flake input (using the +/// [flake +/// registry](https://nixos.org/manual/nix/stable/command-ref/conf-file.html#conf-flake-registry)). #[derive(Clone, Debug, Deserialize)] #[serde(deny_unknown_fields)] pub struct IndirectNode { @@ -265,9 +276,40 @@ pub struct IndirectNode { pub original: IndirectOriginal, } +/// The `original` field of an [Indirect][Node::Indirect] node. #[derive(Clone, Debug, Deserialize)] pub struct IndirectOriginal { - id: String, + pub id: String, + #[serde(alias = "type")] + pub node_type: String, +} + +/// TODO +#[derive(Clone, Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct PathNode { + pub locked: PathLocked, + pub original: PathOriginal, +} + +/// TODO +#[derive(Clone, Debug, Deserialize)] +pub struct PathLocked { + #[serde(alias = "lastModified")] + pub last_modified: i64, + #[serde(alias = "narHash")] + pub nar_hash: String, + pub path: PathBuf, + #[serde(alias = "type")] + pub node_type: String, +} + +/// TODO +#[derive(Clone, Debug, Deserialize)] +pub struct PathOriginal { + pub path: PathBuf, + #[serde(alias = "ref")] + pub git_ref: Option, #[serde(alias = "type")] pub node_type: String, } diff --git a/src/flake.rs b/src/flake.rs index 6178ed6..911536c 100644 --- a/src/flake.rs +++ b/src/flake.rs @@ -49,12 +49,20 @@ fn nixpkgs_deps( ) -> Result, FlakeCheckerError> { let mut deps: HashMap = HashMap::new(); - for (key, node) in flake_lock.root.clone() { - if let Node::Repo(_) = node { + for (ref key, node) in flake_lock.root.clone() { + if let Node::Repo(_) = &node { if keys.contains(&key) { - deps.insert(key, node); + deps.insert(key.to_string(), node.clone()); } } + + if let Node::Indirect(indirect_node) = &node { + if &indirect_node.original.id == key { + deps.insert(key.to_string(), node); + } + } + + // NOTE: it's unclear that a path node for Nixpkgs should be accepted } let missing: Vec = keys .iter() @@ -139,7 +147,7 @@ mod test { #[test] fn test_clean_flake_locks() { - for n in 0..=4 { + for n in 0..=6 { let path = PathBuf::from(format!("tests/flake.clean.{n}.lock")); let flake_lock = FlakeLock::new(&path).expect("couldn't create flake.lock"); let config = FlakeCheckConfig { @@ -147,7 +155,7 @@ mod test { ..Default::default() }; let issues = check_flake_lock(&flake_lock, &config) - .expect("couldn't run check_flake_lock function"); + .expect(&format!("couldn't run check_flake_lock function in {path:?}")); assert!(issues.is_empty()); } } diff --git a/tests/flake.clean.6.lock b/tests/flake.clean.6.lock index 50a0da6..89999e8 100644 --- a/tests/flake.clean.6.lock +++ b/tests/flake.clean.6.lock @@ -1,27 +1,36 @@ { "nodes": { - "nixpkgs-test": { + "nixpkgs": { "locked": { - "lastModified": 1685573264, - "narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=", - "owner": "nixos", + "lastModified": 1689078114, + "narHash": "sha256-osG8BrX5RpKJ7wH+vI6auOU+ctvNOblT4XXCgknK47c=", + "owner": "NixOS", "repo": "nixpkgs", - "rev": "380be19fbd2d9079f677978361792cb25e8a3635", + "rev": "b6cc7ff8fee93789bc871a267ab876c3fca042cb", "type": "github" }, "original": { - "owner": "nixos", - "ref": "release-22.05", - "repo": "nixpkgs", - "type": "github" + "id": "nixpkgs", + "ref": "nixpkgs-unstable", + "type": "indirect" } }, "root": { "inputs": { - "nixpkgs": [ - "nixpkgs-test" - ], - "nixpkgs-test": "nixpkgs-test" + "nixpkgs": "nixpkgs", + "sub": "sub" + } + }, + "sub": { + "locked": { + "lastModified": 1, + "narHash": "sha256-+qUhj8mkS6BsSFAOMQek346MHTEDkmoaojSBbLefq7w=", + "path": "./sub", + "type": "path" + }, + "original": { + "path": "./sub", + "type": "path" } } },