blob: 51bacaa0eea0609b47d435f5eaed1e224e671cfa [file] [log] [blame]
Brian Silvermancc09f182022-03-09 15:40:20 -08001//! The cli entrypoint for the `query` subcommand
2
3use std::fs;
4use std::path::PathBuf;
5
6use anyhow::Result;
7use clap::Parser;
8
9use crate::config::Config;
10use crate::context::Context;
11use crate::lockfile::Digest;
Adam Snaider1c095c92023-07-08 02:09:58 -040012use crate::metadata::Cargo;
Brian Silvermancc09f182022-03-09 15:40:20 -080013use crate::splicing::SplicingManifest;
14
15/// Command line options for the `query` subcommand
16#[derive(Parser, Debug)]
Brian Silverman5f6f2762022-08-13 19:30:05 -070017#[clap(about = "Command line options for the `query` subcommand", version)]
Brian Silvermancc09f182022-03-09 15:40:20 -080018pub struct QueryOptions {
19 /// The lockfile path for reproducible Cargo->Bazel renderings
20 #[clap(long)]
21 pub lockfile: PathBuf,
22
23 /// The config file with information about the Bazel and Cargo workspace
24 #[clap(long)]
25 pub config: PathBuf,
26
27 /// A generated manifest of splicing inputs
28 #[clap(long)]
29 pub splicing_manifest: PathBuf,
30
31 /// The path to a Cargo binary to use for gathering metadata
32 #[clap(long, env = "CARGO")]
33 pub cargo: PathBuf,
34
35 /// The path to a rustc binary for use with Cargo
36 #[clap(long, env = "RUSTC")]
37 pub rustc: PathBuf,
38}
39
40/// Determine if the current lockfile needs to be re-pinned
41pub fn query(opt: QueryOptions) -> Result<()> {
42 // Read the lockfile
43 let content = match fs::read_to_string(&opt.lockfile) {
44 Ok(c) => c,
45 Err(_) => return announce_repin("Unable to read lockfile"),
46 };
47
48 // Deserialize it so we can easily compare it with
49 let lockfile: Context = match serde_json::from_str(&content) {
50 Ok(ctx) => ctx,
51 Err(_) => return announce_repin("Could not load lockfile"),
52 };
53
54 // Check to see if a digest has been set
55 let digest = match &lockfile.checksum {
56 Some(d) => d.clone(),
57 None => return announce_repin("No digest provided in lockfile"),
58 };
59
60 // Load the config file
61 let config = Config::try_from_path(&opt.config)?;
62
63 let splicing_manifest = SplicingManifest::try_from_path(&opt.splicing_manifest)?;
64
65 // Generate a new digest so we can compare it with the one in the lockfile
66 let expected = Digest::new(
67 &lockfile,
68 &config,
69 &splicing_manifest,
Adam Snaider1c095c92023-07-08 02:09:58 -040070 &Cargo::new(opt.cargo),
Brian Silvermancc09f182022-03-09 15:40:20 -080071 &opt.rustc,
72 )?;
73 if digest != expected {
Adam Snaider1c095c92023-07-08 02:09:58 -040074 return announce_repin(&format!("Digests do not match: {digest:?} != {expected:?}",));
Brian Silvermancc09f182022-03-09 15:40:20 -080075 }
76
77 // There is no need to repin
78 Ok(())
79}
80
81fn announce_repin(reason: &str) -> Result<()> {
Adam Snaider1c095c92023-07-08 02:09:58 -040082 eprintln!("{reason}");
Brian Silvermancc09f182022-03-09 15:40:20 -080083 println!("repin");
84 Ok(())
85}