| //! The cli entrypoint for the `query` subcommand |
| |
| use std::fs; |
| use std::path::PathBuf; |
| |
| use anyhow::{bail, Result}; |
| use clap::Parser; |
| |
| use crate::config::Config; |
| use crate::context::Context; |
| use crate::lockfile::Digest; |
| use crate::metadata::Cargo; |
| 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(_) => bail!("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(_) => bail!("Could not load lockfile"), |
| }; |
| |
| // Check to see if a digest has been set |
| let digest = match &lockfile.checksum { |
| Some(d) => d.clone(), |
| None => bail!("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, |
| &Cargo::new(opt.cargo, opt.rustc.clone()), |
| &opt.rustc, |
| )?; |
| |
| if digest != expected { |
| bail!("Digests do not match: Current {digest:?} != Expected {expected:?}"); |
| } |
| |
| // There is no need to repin |
| Ok(()) |
| } |