Skip to content

Commit

Permalink
internal: Clean up CLI args. (#680)
Browse files Browse the repository at this point in the history
  • Loading branch information
milesj committed Dec 25, 2024
1 parent 258ee46 commit 1f9a982
Show file tree
Hide file tree
Showing 33 changed files with 228 additions and 286 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- Added a `--json` option to `proto clean`, to capture the cleaned result as JSON.
- Added a new command, `proto versions <tool>`, that lists all available remote and installed versions/aliases.
- Updated `proto clean` to accept a target in which to clean as the 1st argument. For example, `proto clean cache`.
- Moved the `--json` and `--yes` options into global options.

## 0.43.3

Expand Down
42 changes: 29 additions & 13 deletions crates/cli/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::commands::{
debug::{DebugConfigArgs, DebugEnvArgs},
plugin::{AddPluginArgs, InfoPluginArgs, ListPluginsArgs, RemovePluginArgs, SearchPluginArgs},
ActivateArgs, AliasArgs, BinArgs, CleanArgs, CompletionsArgs, DiagnoseArgs, InstallArgs,
MigrateArgs, OutdatedArgs, PinArgs, RegenArgs, RunArgs, SetupArgs, StatusArgs, UnaliasArgs,
Expand Down Expand Up @@ -80,6 +79,7 @@ fn create_styles() -> Styles {
)]
pub struct App {
#[arg(
value_enum,
long,
short = 'c',
global = true,
Expand All @@ -98,32 +98,48 @@ pub struct App {

#[arg(
value_enum,
default_value_t,
long,
global = true,
env = "PROTO_LOG",
help = "Lowest log level to output"
)]
pub log: Option<LogLevel>,
pub log: LogLevel,

#[arg(
long,
short = 'y',
global = true,
env = "PROTO_YES",
help = "Avoid all interactive prompts and use defaults"
)]
pub yes: bool,

#[arg(
long,
global = true,
env = "PROTO_JSON",
help = "Print as JSON (when applicable)"
)]
pub json: bool,

#[command(subcommand)]
pub command: Commands,
}

impl App {
pub fn setup_env_vars(&self) {
let version = env!("CARGO_PKG_VERSION");

if let Some(level) = &self.log {
env::set_var("PROTO_APP_LOG", level.to_string());
} else if let Ok(level) = env::var("PROTO_LOG") {
env::set_var("PROTO_APP_LOG", level);
}

env::set_var("PROTO_VERSION", version);
env::set_var("PROTO_APP_LOG", self.log.to_string());
env::set_var("PROTO_VERSION", env!("CARGO_PKG_VERSION"));

if let Ok(value) = env::var("PROTO_DEBUG_COMMAND") {
env::set_var("WARPGATE_DEBUG_COMMAND", value);
}

// Disable ANSI colors in JSON output
if self.json {
env::set_var("NO_COLOR", "1");
}
}
}

Expand Down Expand Up @@ -278,10 +294,10 @@ pub enum DebugCommands {
name = "config",
about = "Debug all loaded .prototools config's for the current directory."
)]
Config(DebugConfigArgs),
Config,

#[command(name = "env", about = "Debug the current proto environment and store.")]
Env(DebugEnvArgs),
Env,
}

#[derive(Clone, Debug, Subcommand)]
Expand Down
9 changes: 3 additions & 6 deletions crates/cli/src/commands/activate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ pub struct ActivateArgs {
)]
export: bool,

#[arg(long, help = "Print the activate instructions in JSON format")]
json: bool,

#[arg(long, help = "Don't include ~/.proto/bin in path lookup")]
no_bin: bool,

Expand All @@ -77,7 +74,7 @@ pub async fn activate(session: ProtoSession, args: ActivateArgs) -> AppResult {
};

// If not exporting data, just print the activation syntax immediately
if !args.export && !args.json {
if !args.export && !session.should_print_json() {
return print_activation_hook(&session, &shell_type, &args);
}

Expand Down Expand Up @@ -140,7 +137,7 @@ pub async fn activate(session: ProtoSession, args: ActivateArgs) -> AppResult {
if !info.env.contains_key("PROTO_HOME") && env::var("PROTO_HOME").is_err() {
info.env.insert(
"PROTO_HOME".into(),
session.env.root.to_str().map(|root| root.to_owned()),
session.env.store.dir.to_str().map(|root| root.to_owned()),
);
}

Expand Down Expand Up @@ -172,7 +169,7 @@ pub async fn activate(session: ProtoSession, args: ActivateArgs) -> AppResult {
return Ok(None);
}

if args.json {
if session.should_print_json() {
session.console.out.write_line(json::format(&info, true)?)?;

return Ok(None);
Expand Down
28 changes: 12 additions & 16 deletions crates/cli/src/commands/alias.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::error::ProtoCliError;
use crate::helpers::{map_pin_type, PinOption};
use crate::session::ProtoSession;
use clap::Args;
use iocraft::prelude::element;
use proto_core::{is_alias_name, Id, ProtoConfig, UnresolvedVersionSpec};
use proto_core::{is_alias_name, Id, PinLocation, ProtoConfig, UnresolvedVersionSpec};
use starbase::AppResult;
use starbase_console::ui::*;

Expand All @@ -18,8 +17,8 @@ pub struct AliasArgs {
#[arg(required = true, help = "Version or alias to associate with")]
spec: UnresolvedVersionSpec,

#[arg(long, help = "Location of .prototools to add to")]
to: Option<PinOption>,
#[arg(long, default_value_t, help = "Location of .prototools to add to")]
to: PinLocation,
}

#[tracing::instrument(skip_all)]
Expand All @@ -39,19 +38,16 @@ pub async fn alias(session: ProtoSession, args: AliasArgs) -> AppResult {

let tool = session.load_tool(&args.id).await?;

let config_path = ProtoConfig::update(
tool.proto.get_config_dir(map_pin_type(false, args.to)),
|config| {
let tool_configs = config.tools.get_or_insert(Default::default());
let config_path = ProtoConfig::update(tool.proto.get_config_dir(args.to), |config| {
let tool_configs = config.tools.get_or_insert(Default::default());

tool_configs
.entry(tool.id.clone())
.or_default()
.aliases
.get_or_insert(Default::default())
.insert(args.alias.clone(), args.spec.clone());
},
)?;
tool_configs
.entry(tool.id.clone())
.or_default()
.aliases
.get_or_insert(Default::default())
.insert(args.alias.clone(), args.spec.clone());
})?;

session.console.render(element! {
Notice(variant: Variant::Success) {
Expand Down
45 changes: 21 additions & 24 deletions crates/cli/src/commands/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ pub struct CleanArgs {
help = "Clean tools and plugins older than the specified number of days"
)]
pub days: u8,

#[arg(long, help = "Print the clean result in JSON format")]
pub json: bool,

#[arg(long, help = "Avoid and force confirm prompts", env = "PROTO_YES")]
pub yes: bool,
}

#[derive(Default, Serialize)]
Expand Down Expand Up @@ -73,7 +67,6 @@ pub async fn clean_tool(
mut tool: Tool,
now: SystemTime,
days: u64,
skip_prompts: bool,
) -> miette::Result<Vec<StaleTool>> {
let mut cleaned = vec![];

Expand Down Expand Up @@ -172,6 +165,7 @@ pub async fn clean_tool(
return Ok(cleaned);
}

let skip_prompts = session.should_skip_prompts();
let mut confirmed = false;

if !skip_prompts {
Expand Down Expand Up @@ -297,7 +291,6 @@ pub async fn clean_dir(dir: &Path, now: SystemTime, days: u64) -> miette::Result
pub async fn internal_clean(
session: &ProtoSession,
args: &CleanArgs,
skip_prompts: bool,
) -> miette::Result<CleanResult> {
let days = args.days as u64;
let now = SystemTime::now();
Expand All @@ -309,7 +302,7 @@ pub async fn internal_clean(
for tool in session.load_tools().await? {
result
.tools
.extend(clean_tool(session, tool.tool, now, days, skip_prompts).await?);
.extend(clean_tool(session, tool.tool, now, days).await?);
}

result
Expand Down Expand Up @@ -340,15 +333,19 @@ pub async fn internal_clean(

#[instrument(skip_all)]
pub async fn clean(session: ProtoSession, args: CleanArgs) -> AppResult {
let data = internal_clean(&session, &args, session.skip_prompts(args.yes)).await?;
let result = internal_clean(&session, &args).await?;

if args.json {
session.console.out.write_line(json::format(&data, true)?)?;
if session.should_print_json() {
session
.console
.out
.write_line(json::format(&result, true)?)?;

return Ok(None);
}

let remove_count = data.cache.len() + data.plugins.len() + data.temp.len() + data.tools.len();
let remove_count =
result.cache.len() + result.plugins.len() + result.temp.len() + result.tools.len();

if remove_count == 0 {
session.console.render(element! {
Expand All @@ -365,60 +362,60 @@ pub async fn clean(session: ProtoSession, args: CleanArgs) -> AppResult {
content: format!("Clean complete, {} artifacts removed:", remove_count)
)
List {
#(if data.cache.is_empty() {
#(if result.cache.is_empty() {
None
} else {
Some(element! {
ListItem {
Text(
content: format!(
"{} cached items ({} bytes)",
data.cache.len(),
data.cache.iter().fold(0, |acc, x| acc + x.size)
result.cache.len(),
result.cache.iter().fold(0, |acc, x| acc + x.size)
)
)
}
})
})
#(if data.plugins.is_empty() {
#(if result.plugins.is_empty() {
None
} else {
Some(element! {
ListItem {
Text(
content: format!(
"{} downloaded plugins ({} bytes)",
data.plugins.len(),
data.plugins.iter().fold(0, |acc, x| acc + x.size)
result.plugins.len(),
result.plugins.iter().fold(0, |acc, x| acc + x.size)
)
)
}
})
})
#(if data.temp.is_empty() {
#(if result.temp.is_empty() {
None
} else {
Some(element! {
ListItem {
Text(
content: format!(
"{} temporary files ({} bytes)",
data.temp.len(),
data.temp.iter().fold(0, |acc, x| acc + x.size)
result.temp.len(),
result.temp.iter().fold(0, |acc, x| acc + x.size)
)
)
}
})
})
#(if data.tools.is_empty() {
#(if result.tools.is_empty() {
None
} else {
Some(element! {
ListItem {
Text(
content: format!(
"{} installed tool versions",
data.tools.len(),
result.tools.len(),
)
)
}
Expand Down
11 changes: 2 additions & 9 deletions crates/cli/src/commands/debug/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::session::{ProtoConsole, ProtoSession};
use clap::Args;
use iocraft::prelude::*;
use proto_core::{ProtoConfig, ProtoConfigFile};
use serde::Serialize;
Expand All @@ -14,12 +13,6 @@ struct DebugConfigResult<'a> {
files: Vec<&'a ProtoConfigFile>,
}

#[derive(Args, Clone, Debug)]
pub struct DebugConfigArgs {
#[arg(long, help = "Print the data in JSON format")]
json: bool,
}

fn print_toml(console: &ProtoConsole, value: impl Serialize) -> miette::Result<()> {
let contents = toml::format(&value, true)?
.lines()
Expand All @@ -45,12 +38,12 @@ fn print_toml(console: &ProtoConsole, value: impl Serialize) -> miette::Result<(
}

#[tracing::instrument(skip_all)]
pub async fn config(session: ProtoSession, args: DebugConfigArgs) -> AppResult {
pub async fn config(session: ProtoSession) -> AppResult {
let env = &session.env;
let manager = env.load_config_manager()?;
let config = env.load_config()?;

if args.json {
if session.should_print_json() {
let result = DebugConfigResult {
config,
files: manager.files.iter().rev().collect::<Vec<_>>(),
Expand Down
15 changes: 4 additions & 11 deletions crates/cli/src/commands/debug/env.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::components::is_path_like;
use crate::session::ProtoSession;
use clap::Args;
use iocraft::prelude::*;
use proto_core::layout::Store;
use proto_pdk_api::{HostArch, HostOS};
Expand All @@ -25,17 +24,11 @@ struct EnvironmentInfo {
#[derive(Serialize)]
struct DebugEnvResult<'a> {
store: &'a Store,
env: EnvironmentInfo,
}

#[derive(Args, Clone, Debug)]
pub struct DebugEnvArgs {
#[arg(long, help = "Print the data in JSON format")]
json: bool,
env: &'a EnvironmentInfo,
}

#[tracing::instrument(skip_all)]
pub async fn env(session: ProtoSession, args: DebugEnvArgs) -> AppResult {
pub async fn env(session: ProtoSession) -> AppResult {
let env = &session.env;
let manager = env.load_config_manager()?;

Expand Down Expand Up @@ -66,10 +59,10 @@ pub async fn env(session: ProtoSession, args: DebugEnvArgs) -> AppResult {
virtual_paths: env.get_virtual_paths(),
};

if args.json {
if session.should_print_json() {
let result = DebugEnvResult {
store: &env.store,
env: environment,
env: &environment,
};

session
Expand Down
Loading

0 comments on commit 1f9a982

Please sign in to comment.