• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! The cli entrypoint for the `query` subcommand
2 
3 use std::fs;
4 use std::path::PathBuf;
5 
6 use anyhow::Result;
7 use clap::Parser;
8 
9 use crate::config::Config;
10 use crate::context::Context;
11 use crate::lockfile::Digest;
12 use crate::metadata::Cargo;
13 use crate::splicing::SplicingManifest;
14 
15 /// Command line options for the `query` subcommand
16 #[derive(Parser, Debug)]
17 #[clap(about = "Command line options for the `query` subcommand", version)]
18 pub 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
query(opt: QueryOptions) -> Result<()>41 pub 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,
70         &Cargo::new(opt.cargo),
71         &opt.rustc,
72     )?;
73     if digest != expected {
74         return announce_repin(&format!("Digests do not match: {digest:?} != {expected:?}",));
75     }
76 
77     // There is no need to repin
78     Ok(())
79 }
80 
announce_repin(reason: &str) -> Result<()>81 fn announce_repin(reason: &str) -> Result<()> {
82     eprintln!("{reason}");
83     println!("repin");
84     Ok(())
85 }
86