blob: 668f64fc80ddec51407112a993a13eb103821a65 [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;
12use crate::splicing::SplicingManifest;
13
14/// Command line options for the `query` subcommand
15#[derive(Parser, Debug)]
16#[clap(about, version)]
17pub struct QueryOptions {
18 /// The lockfile path for reproducible Cargo->Bazel renderings
19 #[clap(long)]
20 pub lockfile: PathBuf,
21
22 /// The config file with information about the Bazel and Cargo workspace
23 #[clap(long)]
24 pub config: PathBuf,
25
26 /// A generated manifest of splicing inputs
27 #[clap(long)]
28 pub splicing_manifest: PathBuf,
29
30 /// The path to a Cargo binary to use for gathering metadata
31 #[clap(long, env = "CARGO")]
32 pub cargo: PathBuf,
33
34 /// The path to a rustc binary for use with Cargo
35 #[clap(long, env = "RUSTC")]
36 pub rustc: PathBuf,
37}
38
39/// Determine if the current lockfile needs to be re-pinned
40pub fn query(opt: QueryOptions) -> Result<()> {
41 // Read the lockfile
42 let content = match fs::read_to_string(&opt.lockfile) {
43 Ok(c) => c,
44 Err(_) => return announce_repin("Unable to read lockfile"),
45 };
46
47 // Deserialize it so we can easily compare it with
48 let lockfile: Context = match serde_json::from_str(&content) {
49 Ok(ctx) => ctx,
50 Err(_) => return announce_repin("Could not load lockfile"),
51 };
52
53 // Check to see if a digest has been set
54 let digest = match &lockfile.checksum {
55 Some(d) => d.clone(),
56 None => return announce_repin("No digest provided in lockfile"),
57 };
58
59 // Load the config file
60 let config = Config::try_from_path(&opt.config)?;
61
62 let splicing_manifest = SplicingManifest::try_from_path(&opt.splicing_manifest)?;
63
64 // Generate a new digest so we can compare it with the one in the lockfile
65 let expected = Digest::new(
66 &lockfile,
67 &config,
68 &splicing_manifest,
69 &opt.cargo,
70 &opt.rustc,
71 )?;
72 if digest != expected {
73 return announce_repin(&format!(
74 "Digests do not match: {:?} != {:?}",
75 digest, expected
76 ));
77 }
78
79 // There is no need to repin
80 Ok(())
81}
82
83fn announce_repin(reason: &str) -> Result<()> {
84 eprintln!("{}", reason);
85 println!("repin");
86 Ok(())
87}