blob: 0edeb1245d52f1e1db1de1b35677e957a01ba190 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
anyhow::{anyhow, bail, Context, Result},
ffx_scrutiny_verify_args::bootfs::Command,
scrutiny_config::{Config, LoggingConfig, PluginConfig, RuntimeConfig},
scrutiny_frontend::{command_builder::CommandBuilder, launcher},
scrutiny_utils::golden::{CompareResult, GoldenFile},
serde_json,
std::{collections::HashSet, path::PathBuf},
};
const SOFT_TRANSITION_MSG : &str = "
If you are making a change in fuchsia.git that causes this, you need to perform a soft transition:
1: Instead of adding lines as written above, add each line prefixed with a question mark to mark it as transitional.
2: Instead of removing lines as written above, prefix the line with a question mark to mark it as transitional.
3: Check in your fuchsia.git change.
4: For each new line you added in 1, remove the question mark.
5: For each existing line you modified in 2, remove the line.
";
pub async fn verify(cmd: Command) -> Result<HashSet<PathBuf>> {
if cmd.golden.len() == 0 {
bail!("Must specify at least one --golden");
}
let mut deps = HashSet::new();
let zbi_path = &cmd.zbi;
let zbi = zbi_path
.to_str()
.ok_or_else(|| anyhow!("Failed to convert ZBI path to string: {:?}", cmd.zbi))?;
deps.insert(zbi_path.clone());
let config = Config::run_command_with_runtime(
CommandBuilder::new("tool.zbi.list.bootfs").param("input", zbi).build(),
RuntimeConfig {
logging: LoggingConfig { silent_mode: true, ..LoggingConfig::minimal() },
plugin: PluginConfig { plugins: vec!["ToolkitPlugin".to_string()] },
..RuntimeConfig::minimal()
},
);
let scrutiny_output =
launcher::launch_from_config(config).context("Failed to launch scrutiny")?;
let bootfs_files: Vec<String> = serde_json::from_str(&scrutiny_output)
.context(format!("Failed to deserialize scrutiny output: {}", scrutiny_output))?;
for golden_file_path in cmd.golden.into_iter() {
let golden_file =
GoldenFile::open(&golden_file_path).context("Failed to open the golden file")?;
match golden_file.compare(bootfs_files.clone()) {
CompareResult::Matches => Ok(()),
CompareResult::Mismatch { errors } => {
println!("Bootfs file mismatch");
println!("");
for error in errors.iter() {
println!("{}", error);
}
println!("");
println!(
"If you intended to change the bootfs contents, please acknowledge it by updating {:?} with the added or removed lines.",
golden_file_path,
);
println!("{}", SOFT_TRANSITION_MSG);
Err(anyhow!("bootfs file mismatch"))
}
}?;
deps.insert(golden_file_path);
}
Ok(deps)
}