blob: 19087abee6758b2e5bc7e95d2daad18cec3cc5ab [file] [log] [blame]
//! The cli entrypoint for the `query` subcommand
use std::fs;
use std::path::PathBuf;
use anyhow::Result;
use clap::Parser;
use crate::config::Config;
use crate::context::Context;
use crate::lockfile::Digest;
use crate::splicing::SplicingManifest;
/// Command line options for the `query` subcommand
#[derive(Parser, Debug)]
#[clap(about = "Command line options for the `query` subcommand", version)]
pub struct QueryOptions {
/// The lockfile path for reproducible Cargo->Bazel renderings
#[clap(long)]
pub lockfile: PathBuf,
/// The config file with information about the Bazel and Cargo workspace
#[clap(long)]
pub config: PathBuf,
/// A generated manifest of splicing inputs
#[clap(long)]
pub splicing_manifest: PathBuf,
/// The path to a Cargo binary to use for gathering metadata
#[clap(long, env = "CARGO")]
pub cargo: PathBuf,
/// The path to a rustc binary for use with Cargo
#[clap(long, env = "RUSTC")]
pub rustc: PathBuf,
}
/// Determine if the current lockfile needs to be re-pinned
pub fn query(opt: QueryOptions) -> Result<()> {
// Read the lockfile
let content = match fs::read_to_string(&opt.lockfile) {
Ok(c) => c,
Err(_) => return announce_repin("Unable to read lockfile"),
};
// Deserialize it so we can easily compare it with
let lockfile: Context = match serde_json::from_str(&content) {
Ok(ctx) => ctx,
Err(_) => return announce_repin("Could not load lockfile"),
};
// Check to see if a digest has been set
let digest = match &lockfile.checksum {
Some(d) => d.clone(),
None => return announce_repin("No digest provided in lockfile"),
};
// Load the config file
let config = Config::try_from_path(&opt.config)?;
let splicing_manifest = SplicingManifest::try_from_path(&opt.splicing_manifest)?;
// Generate a new digest so we can compare it with the one in the lockfile
let expected = Digest::new(
&lockfile,
&config,
&splicing_manifest,
&opt.cargo,
&opt.rustc,
)?;
if digest != expected {
return announce_repin(&format!(
"Digests do not match: {:?} != {:?}",
digest, expected
));
}
// There is no need to repin
Ok(())
}
fn announce_repin(reason: &str) -> Result<()> {
eprintln!("{}", reason);
println!("repin");
Ok(())
}