1 //! `cargo audit` subcommands
2 
3 mod audit;
4 
5 use self::audit::AuditCommand;
6 use crate::config::AuditConfig;
7 use abscissa_core::{config::Override, Command, Configurable, FrameworkError, Options, Runnable};
8 use std::{ops::Deref, path::PathBuf};
9 
10 /// Name of the configuration file (located in `~/.cargo`)
11 ///
12 /// This file allows setting some default auditing options.
13 pub const CONFIG_FILE: &str = "audit.toml";
14 
15 /// `cargo audit` subcommands (presently only `audit`)
16 #[derive(Command, Debug, Options, Runnable)]
17 pub enum CargoAuditCommand {
18     /// The `cargo audit` subcommand
19     #[options(help = "Audit Cargo.lock files for vulnerable crates")]
20     Audit(AuditCommand),
21 }
22 
23 impl Configurable<AuditConfig> for CargoAuditCommand {
24     /// Location of `audit.toml` (if it exists)
config_path(&self) -> Option<PathBuf>25     fn config_path(&self) -> Option<PathBuf> {
26         // Check if the config file exists, and if it does not, ignore it.
27         //
28         // The order of precedence for which config file to use is:
29         // 1. The current project's `.cargo` configuration directory.
30         // 2. The current user's home directory configuration.
31 
32         let project_config_filename = PathBuf::from("./.cargo").join(CONFIG_FILE);
33         if project_config_filename.exists() {
34             return Some(project_config_filename);
35         }
36 
37         let home_config_filename = home::cargo_home()
38             .ok()
39             .map(|cargo_home| cargo_home.join(CONFIG_FILE))?;
40 
41         if home_config_filename.exists() {
42             Some(home_config_filename)
43         } else {
44             None
45         }
46     }
47 
48     /// Override loaded config with explicit command-line arguments
process_config(&self, config: AuditConfig) -> Result<AuditConfig, FrameworkError>49     fn process_config(&self, config: AuditConfig) -> Result<AuditConfig, FrameworkError> {
50         match self {
51             CargoAuditCommand::Audit(cmd) => cmd.override_config(config),
52         }
53     }
54 }
55 
56 impl Deref for CargoAuditCommand {
57     type Target = AuditCommand;
58 
deref(&self) -> &AuditCommand59     fn deref(&self) -> &AuditCommand {
60         match self {
61             CargoAuditCommand::Audit(cmd) => cmd,
62         }
63     }
64 }
65