Skip to content

Commit

Permalink
Remove unrelated output from parse-sandboxed
Browse files Browse the repository at this point in the history
This patch removes all output from `parse-sandboxed` that isn't directly
related to its purpose of parsing dependency files. This includes
omitting both config and update messages.

Closes #1328.
  • Loading branch information
cd-work committed Jan 10, 2024
1 parent 18ab883 commit 38fc964
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 52 deletions.
5 changes: 5 additions & 0 deletions cli/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ pub fn app() -> Command {
.value_name("FILE")
.help("Sets a custom config file")
.value_hint(ValueHint::FilePath),
Arg::new("no-config")
.long("no-config")
.help("Ignore all configuration files")
.conflicts_with("config")
.action(ArgAction::SetTrue),
Arg::new("timeout")
.short('t')
.long("timeout")
Expand Down
49 changes: 18 additions & 31 deletions cli/src/bin/phylum.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::fmt::Display;
use std::path::{Path, PathBuf};
use std::time::UNIX_EPOCH;

use anyhow::{anyhow, Context, Result};
use anyhow::{Context, Result};
#[cfg(feature = "selfmanage")]
use clap::ArgMatches;
use env_logger::Env;
Expand Down Expand Up @@ -34,24 +33,21 @@ fn exit_fail(message: impl Display, exit_code: ExitCode) -> ! {

/// Construct an instance of `PhylumApi` given configuration, optional timeout,
/// and whether we need API to ignore certificates.
async fn api_factory(
config: Config,
config_path: PathBuf,
timeout: Option<u64>,
) -> Result<PhylumApi> {
async fn api_factory(config: Config, timeout: Option<u64>) -> Result<PhylumApi> {
let api = PhylumApi::new(config, timeout).await?;

// PhylumApi may have had to log in, updating the auth info so we should save
// the config
config::save_config(&config_path, api.config()).with_context(|| {
format!("Failed to save configuration to '{}'", config_path.to_string_lossy())
})?;
let api_config = api.config();
api_config
.save()
.with_context(|| format!("Failed to save configuration to {:?}", api_config.path))?;

Ok(api)
}

/// Check for an updated release of the CLI
async fn check_for_updates(config: &mut Config, config_path: &Path) -> Result<()> {
async fn check_for_updates(config: &mut Config) -> Result<()> {
let now = UNIX_EPOCH.elapsed().expect("Time went backwards").as_secs() as usize;

if let Some(last_update) = config.last_update {
Expand All @@ -66,8 +62,7 @@ async fn check_for_updates(config: &mut Config, config_path: &Path) -> Result<()

// Update last update check timestamp.
config.last_update = Some(now);
config::save_config(config_path, &config)
.unwrap_or_else(|e| log::error!("Failed to save config: {}", e));
config.save().unwrap_or_else(|e| log::error!("Failed to save config: {}", e));

if update::needs_update(false).await {
print::print_update_message();
Expand Down Expand Up @@ -104,41 +99,33 @@ async fn handle_commands() -> CommandResult {
None => env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init(),
};

let settings_path = config::get_home_settings_path()?;
let config_path = matches
.get_one::<String>("config")
.and_then(|config_path| shellexpand::env(config_path).ok())
.map(|config_path| PathBuf::from(config_path.to_string()))
.unwrap_or(settings_path);

log::debug!("Reading config from {}", config_path.to_string_lossy());
let mut config: Config = config::read_configuration(&config_path).map_err(|err| {
anyhow!("Failed to read configuration at `{}`: {}", config_path.to_string_lossy(), err)
})?;
config.set_ignore_certs_cli(matches.get_flag("no-check-certificate"));
let mut config = config::load_config(&matches)?;

config.set_ignore_certs_cli(matches.get_flag("no-check-certificate"));
if config.ignore_certs() {
log::warn!("Ignoring TLS server certificate verification per user request.");
}

// We initialize these value here, for later use by the PhylumApi object.
let timeout = matches.get_one::<String>("timeout").and_then(|t| t.parse::<u64>().ok());

// Check for updates if enabled and if we haven't explicitly invoked `update`.
if cfg!(feature = "selfmanage") && matches.subcommand_matches("update").is_none() {
check_for_updates(&mut config, &config_path).await?;
let (subcommand, sub_matches) = matches.subcommand().unwrap();

// Check for updates if enabled and if we haven't explicitly invoked `update` or
// `parse-sandboxed`.
if cfg!(feature = "selfmanage") && subcommand != "update" && subcommand != "parse-sandboxed" {
check_for_updates(&mut config).await?;
}

// Get the future, but don't await. Commands that require access to the API will
// await on this, so that the API is not instantiated ahead of time for
// subcommands that don't require it.
let api = api_factory(config.clone(), config_path.clone(), timeout);
let api = api_factory(config.clone(), timeout);

let (subcommand, sub_matches) = matches.subcommand().unwrap();
match subcommand {
"auth" => {
drop(api);
auth::handle_auth(config, &config_path, sub_matches, timeout).await
auth::handle_auth(config, sub_matches, timeout).await
},
"version" => handle_version(&app_name, &ver),
"parse" => parse::handle_parse(sub_matches),
Expand Down
29 changes: 9 additions & 20 deletions cli/src/commands/auth.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::borrow::Cow;
use std::path::Path;

use anyhow::{anyhow, Context, Result};
use chrono::{Duration, Utc};
Expand All @@ -11,17 +10,13 @@ use tokio::io::{self, AsyncBufReadExt, BufReader};
use crate::api::PhylumApi;
use crate::auth::{is_locksmith_token, AuthAction};
use crate::commands::{CommandResult, ExitCode};
use crate::config::{save_config, Config};
use crate::config::Config;
use crate::format::Format;
use crate::{auth, print_user_failure, print_user_success, print_user_warning};

/// Register a user. Opens a browser, and redirects the user to the oauth server
/// registration page
async fn handle_auth_register(
mut config: Config,
config_path: &Path,
matches: &ArgMatches,
) -> Result<()> {
async fn handle_auth_register(mut config: Config, matches: &ArgMatches) -> Result<()> {
let api_uri = &config.connection.uri;
let ignore_certs = config.ignore_certs();
config.auth_info = PhylumApi::register(
Expand All @@ -31,17 +26,13 @@ async fn handle_auth_register(
api_uri,
)
.await?;
save_config(config_path, &config).map_err(|error| anyhow!(error))?;
config.save().map_err(|error| anyhow!(error))?;
Ok(())
}

/// Login a user. Opens a browser, and redirects the user to the oauth server
/// login page
async fn handle_auth_login(
mut config: Config,
config_path: &Path,
matches: &ArgMatches,
) -> Result<()> {
async fn handle_auth_login(mut config: Config, matches: &ArgMatches) -> Result<()> {
let api_uri = &config.connection.uri;
let ignore_certs = config.ignore_certs();
config.auth_info = PhylumApi::login(
Expand All @@ -52,7 +43,7 @@ async fn handle_auth_login(
matches.get_flag("reauth"),
)
.await?;
save_config(config_path, &config).map_err(|error| anyhow!(error))?;
config.save().map_err(|error| anyhow!(error))?;
Ok(())
}

Expand Down Expand Up @@ -133,14 +124,13 @@ async fn stdin_read_token() -> Result<RefreshToken> {
pub async fn handle_auth_set_token(
mut config: Config,
matches: &clap::ArgMatches,
config_path: &Path,
) -> CommandResult {
let offline_access = match matches.get_one::<String>("token") {
Some(t) => RefreshToken::new(t),
None => stdin_read_token().await?,
};
config.auth_info.set_offline_access(offline_access);
save_config(config_path, &config)?;
config.save()?;
Ok(ExitCode::Ok)
}

Expand Down Expand Up @@ -247,19 +237,18 @@ pub async fn handle_auth_create_token(
/// Handle the subcommands for the `auth` subcommand.
pub async fn handle_auth(
config: Config,
config_path: &Path,
matches: &clap::ArgMatches,
timeout: Option<u64>,
) -> CommandResult {
match matches.subcommand() {
Some(("register", _)) => match handle_auth_register(config, config_path, matches).await {
Some(("register", _)) => match handle_auth_register(config, matches).await {
Ok(_) => {
print_user_success!("{}", "User successfuly regsistered");
Ok(ExitCode::Ok)
},
Err(error) => Err(error).context("User registration failed"),
},
Some(("login", matches)) => match handle_auth_login(config, config_path, matches).await {
Some(("login", matches)) => match handle_auth_login(config, matches).await {
Ok(_) => {
print_user_success!("{}", "User login successful");
Ok(ExitCode::Ok)
Expand All @@ -268,7 +257,7 @@ pub async fn handle_auth(
},
Some(("status", _)) => handle_auth_status(config, timeout).await,
Some(("token", matches)) => handle_auth_token(&config, matches).await,
Some(("set-token", matches)) => handle_auth_set_token(config, matches, config_path).await,
Some(("set-token", matches)) => handle_auth_set_token(config, matches).await,
Some(("list-tokens", matches)) => handle_auth_list_tokens(config, matches, timeout).await,
Some(("revoke-token", matches)) => handle_auth_revoke_token(config, matches, timeout).await,
Some(("create-token", matches)) => handle_auth_create_token(config, matches, timeout).await,
Expand Down
1 change: 1 addition & 0 deletions cli/src/commands/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ fn parse_sandboxed_command(
) -> Result<Command> {
let current_exe = env::current_exe()?;
let mut command = Command::new(current_exe);
command.arg("--no-config");

command.arg("parse-sandboxed");
command.arg(path);
Expand Down
41 changes: 40 additions & 1 deletion cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::path::{Path, PathBuf};
use std::{env, fs};

use anyhow::{anyhow, Result};
use clap::ArgMatches;
use phylum_project::{DepfileConfig, ProjectConfig};
use phylum_types::types::auth::RefreshToken;
use serde::{Deserialize, Deserializer, Serialize};
Expand Down Expand Up @@ -50,6 +51,8 @@ pub struct Config {
pub auth_info: AuthInfo,
pub last_update: Option<usize>,
#[serde(skip)]
pub path: Option<PathBuf>,
#[serde(skip)]
ignore_certs_cli: bool,
#[serde(deserialize_with = "default_option_bool")]
ignore_certs: bool,
Expand All @@ -63,6 +66,7 @@ impl Default for Config {
ignore_certs_cli: false,
ignore_certs: false,
last_update: None,
path: None,
}
}
}
Expand All @@ -77,6 +81,16 @@ impl Config {
pub fn set_ignore_certs_cli(&mut self, ignore_certs_cli: bool) {
self.ignore_certs_cli = ignore_certs_cli;
}

/// Write updates to the configuration file.
pub fn save(&self) -> Result<()> {
let path = match &self.path {
Some(path) => path,
None => return Ok(()),
};

save_config(path, self)
}
}

fn default_option_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
Expand All @@ -86,6 +100,30 @@ where
Ok(Option::<bool>::deserialize(deserializer)?.unwrap_or_default())
}

/// Load the configuration file.
pub fn load_config(matches: &ArgMatches) -> Result<Config> {
// Early return with configuration disabled.
if matches.get_flag("no-config") {
return Ok(Config::default());
}

let settings_path = get_home_settings_path()?;
let config_path = matches
.get_one::<String>("config")
.and_then(|config_path| shellexpand::env(config_path).ok())
.map(|config_path| PathBuf::from(config_path.to_string()))
.unwrap_or(settings_path);

log::debug!("Reading config from {}", config_path.to_string_lossy());
let mut config: Config = read_configuration(&config_path).map_err(|err| {
anyhow!("Failed to read configuration at `{}`: {}", config_path.to_string_lossy(), err)
})?;

config.path = Some(config_path);

Ok(config)
}

/// Atomically overwrite the configuration file.
#[cfg(unix)]
pub fn save_config<T>(path: &Path, config: &T) -> Result<()>
Expand Down Expand Up @@ -151,7 +189,7 @@ where
Ok(serde_yaml::from_str::<T>(&contents)?)
}

pub fn read_configuration(path: &Path) -> Result<Config> {
fn read_configuration(path: &Path) -> Result<Config> {
let mut config: Config = match parse_config(path) {
Ok(c) => c,
Err(orig_err) => match orig_err.downcast_ref::<io::Error>() {
Expand Down Expand Up @@ -244,6 +282,7 @@ mod tests {
ignore_certs_cli: false,
ignore_certs: false,
last_update: None,
path: None,
}
}

Expand Down

0 comments on commit 38fc964

Please sign in to comment.