refactor(tvix/cli): consistently assert type unity in known_paths
No situation should be allowed in which a path is inserted into known_paths with different types twice, which we previously enforced only for some path types. Change-Id: I8cb47d4b29c0aab3c58694f8b590e131deba7043 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7843 Reviewed-by: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
This commit is contained in:
parent
bf6f6a0b3f
commit
0cbdfffea2
1 changed files with 41 additions and 46 deletions
|
@ -50,39 +50,46 @@ impl Index<&str> for KnownPaths {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KnownPaths {
|
impl KnownPaths {
|
||||||
|
fn insert_path(&mut self, path: String, path_type: PathType) {
|
||||||
|
match self.paths.entry(path) {
|
||||||
|
hash_map::Entry::Vacant(entry) => {
|
||||||
|
entry.insert(path_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_map::Entry::Occupied(mut entry) => {
|
||||||
|
match (path_type, entry.get_mut()) {
|
||||||
|
// These variant combinations require no "merging action".
|
||||||
|
(PathType::Plain, PathType::Plain) => (),
|
||||||
|
(PathType::Output { .. }, PathType::Output { .. }) => (),
|
||||||
|
|
||||||
|
(
|
||||||
|
PathType::Derivation { output_names: new },
|
||||||
|
PathType::Derivation {
|
||||||
|
output_names: ref mut old,
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
old.extend(new);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => panic!("path '{}' inserted twice with different types", entry.key()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Mark a plain path as known.
|
/// Mark a plain path as known.
|
||||||
pub fn plain<S: ToString>(&mut self, path: S) {
|
pub fn plain<S: ToString>(&mut self, path: S) {
|
||||||
self.paths.insert(path.to_string(), PathType::Plain);
|
self.insert_path(path.to_string(), PathType::Plain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark a derivation as known.
|
/// Mark a derivation as known.
|
||||||
pub fn drv<P: ToString, O: ToString>(&mut self, path: P, outputs: &[O]) {
|
pub fn drv<P: ToString, O: ToString>(&mut self, path: P, outputs: &[O]) {
|
||||||
match self.paths.entry(path.to_string()) {
|
self.insert_path(
|
||||||
hash_map::Entry::Occupied(mut entry) => {
|
path.to_string(),
|
||||||
for output in outputs {
|
|
||||||
match entry.get_mut() {
|
|
||||||
PathType::Derivation {
|
PathType::Derivation {
|
||||||
ref mut output_names,
|
output_names: outputs.into_iter().map(ToString::to_string).collect(),
|
||||||
} => {
|
},
|
||||||
output_names.insert(output.to_string());
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Branches like this explicitly panic right now to find odd
|
|
||||||
// situations where something unexpected is done with the
|
|
||||||
// same path being inserted twice as different types.
|
|
||||||
_ => panic!(
|
|
||||||
"bug: {} is already a known path, but not a derivation!",
|
|
||||||
path.to_string()
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_map::Entry::Vacant(entry) => {
|
|
||||||
let output_names = outputs.iter().map(|o| o.to_string()).collect();
|
|
||||||
entry.insert(PathType::Derivation { output_names });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark a derivation output path as known.
|
/// Mark a derivation output path as known.
|
||||||
|
@ -92,27 +99,15 @@ impl KnownPaths {
|
||||||
name: N,
|
name: N,
|
||||||
drv_path: D,
|
drv_path: D,
|
||||||
) {
|
) {
|
||||||
match self.paths.entry(output_path.to_string()) {
|
self.insert_path(
|
||||||
hash_map::Entry::Occupied(entry) => {
|
output_path.to_string(),
|
||||||
/* nothing to do, really! */
|
PathType::Output {
|
||||||
debug_assert!(
|
|
||||||
*entry.get()
|
|
||||||
== PathType::Output {
|
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
derivation: drv_path.to_string(),
|
derivation: drv_path.to_string(),
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_map::Entry::Vacant(entry) => {
|
|
||||||
entry.insert(PathType::Output {
|
|
||||||
name: name.to_string(),
|
|
||||||
derivation: drv_path.to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a reference scanner from the current set of known paths.
|
/// Create a reference scanner from the current set of known paths.
|
||||||
pub fn reference_scanner(&self) -> ReferenceScanner {
|
pub fn reference_scanner(&self) -> ReferenceScanner {
|
||||||
let candidates = self.paths.keys().map(Clone::clone).collect();
|
let candidates = self.paths.keys().map(Clone::clone).collect();
|
||||||
|
|
Loading…
Reference in a new issue