diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c32935f57..ad9b8909b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,8 +66,9 @@ jobs: - uses: moonrepo/setup-rust@v1 with: bins: cargo-wasi, cargo-nextest, just - cache: ${{ runner.os != 'Linux' }} - cache-base: "^(master|develop-)" + cache: false + # cache: ${{ runner.os != 'Linux' }} + # cache-base: "^(master|develop-)" - if: ${{ runner.os != 'Windows' }} run: just build-wasm env: @@ -95,7 +96,8 @@ jobs: - uses: moonrepo/setup-rust@v1 with: bins: cargo-wasi, just - cache-base: "^(master|develop-)" + cache: false + # cache-base: "^(master|develop-)" - run: just build - run: just build-wasm - run: cargo run -- --help diff --git a/CHANGELOG.md b/CHANGELOG.md index cde867fec..d5e913560 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,16 @@ #### 🚀 Updates +- Added support for updating the `~/.prototools` file (root of user home directory). +- Added `--pin=user` to `proto install`. +- Added `--to=global|local|user` to `proto alias`, `pin`, and `plugin add`. +- Added `--from=global|local|user` to `proto unalias`, `unpin`, and `plugin remove`. +- Added aliases for pin locations. + - `cwd` -> `local` + - `home` -> `user` + - `store` -> `global` - Added new `settings.offline` settings that control how offline checks work. +- Deprecated the `--global` flag. #### ⚙️ Internal diff --git a/crates/cli/src/commands/alias.rs b/crates/cli/src/commands/alias.rs index f886fe652..b1381cf56 100644 --- a/crates/cli/src/commands/alias.rs +++ b/crates/cli/src/commands/alias.rs @@ -1,4 +1,5 @@ use crate::error::ProtoCliError; +use crate::helpers::{map_pin_type, PinOption}; use crate::session::ProtoSession; use clap::Args; use proto_core::{is_alias_name, Id, ProtoConfig, UnresolvedVersionSpec}; @@ -16,11 +17,11 @@ pub struct AliasArgs { #[arg(required = true, help = "Version or alias to associate with")] spec: UnresolvedVersionSpec, - #[arg( - long, - help = "Add to the global ~/.proto/.prototools instead of local ./.prototools" - )] + #[arg(long, group = "pin", help = "Add to the global ~/.proto/.prototools")] global: bool, + + #[arg(long, group = "pin", help = "Location of .prototools to add to")] + to: Option, } #[tracing::instrument(skip_all)] @@ -40,16 +41,20 @@ 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(args.global), |config| { - let tool_configs = config.tools.get_or_insert(Default::default()); + let config_path = ProtoConfig::update( + tool.proto + .get_config_dir(map_pin_type(args.global, 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()); + }, + )?; println!( "Added alias {} ({}) to config {}", diff --git a/crates/cli/src/commands/install.rs b/crates/cli/src/commands/install.rs index 29bc44a11..0dfe152a6 100644 --- a/crates/cli/src/commands/install.rs +++ b/crates/cli/src/commands/install.rs @@ -3,7 +3,7 @@ use crate::helpers::*; use crate::session::ProtoSession; use crate::shell::{self, Export}; use crate::telemetry::{track_usage, Metric}; -use clap::{Args, ValueEnum}; +use clap::Args; use indicatif::ProgressBar; use miette::IntoDiagnostic; use proto_core::flow::install::{InstallOptions, InstallPhase}; @@ -19,12 +19,6 @@ use tokio::task::JoinSet; use tokio::time::sleep; use tracing::{debug, instrument}; -#[derive(Clone, Debug, ValueEnum)] -pub enum PinOption { - Global, - Local, -} - #[derive(Args, Clone, Debug, Default)] pub struct InstallArgs { #[arg(help = "ID of a single tool to install")] @@ -62,6 +56,7 @@ impl InstallArgs { fn get_pin_type(&self) -> Option { self.pin.as_ref().map(|pin| match pin { Some(PinOption::Global) => PinType::Global, + Some(PinOption::User) => PinType::User, _ => PinType::Local, }) } @@ -82,30 +77,30 @@ async fn pin_version( ) -> miette::Result { let config = tool.proto.load_config()?; let spec = tool.get_resolved_version().to_unresolved_spec(); - let mut global = false; + let mut pin_type = PinType::Local; let mut pin = false; // via `--pin` arg - if let Some(pin_type) = arg_pin_type { - global = matches!(pin_type, PinType::Global); + if let Some(custom_type) = arg_pin_type { + pin_type = *custom_type; pin = true; } // Or the first time being installed else if !config.versions.contains_key(&tool.id) { - global = true; + pin_type = PinType::Global; pin = true; } // via `pin-latest` setting if initial_version.is_latest() { - if let Some(pin_type) = &config.settings.pin_latest { - global = matches!(pin_type, PinType::Global); + if let Some(custom_type) = &config.settings.pin_latest { + pin_type = *custom_type; pin = true; } } if pin { - internal_pin(tool, &spec, global, true).await?; + internal_pin(tool, &spec, pin_type, true).await?; } Ok(pin) diff --git a/crates/cli/src/commands/pin.rs b/crates/cli/src/commands/pin.rs index 779c87504..fc8d96981 100644 --- a/crates/cli/src/commands/pin.rs +++ b/crates/cli/src/commands/pin.rs @@ -1,6 +1,7 @@ +use crate::helpers::{map_pin_type, PinOption}; use crate::session::ProtoSession; use clap::Args; -use proto_core::{Id, ProtoConfig, Tool, UnresolvedVersionSpec}; +use proto_core::{Id, PinType, ProtoConfig, Tool, UnresolvedVersionSpec}; use starbase::AppResult; use starbase_styles::color; use std::collections::BTreeMap; @@ -15,28 +16,28 @@ pub struct PinArgs { #[arg(required = true, help = "Version or alias of tool")] pub spec: UnresolvedVersionSpec, - #[arg( - long, - help = "Pin to the global ~/.proto/.prototools instead of local ./.prototools" - )] + #[arg(long, group = "pin", help = "Pin to the global ~/.proto/.prototools")] pub global: bool, #[arg(long, help = "Resolve the version before pinning")] pub resolve: bool, + + #[arg(long, group = "pin", help = "Location of .prototools to pin to")] + pub to: Option, } pub async fn internal_pin( tool: &mut Tool, spec: &UnresolvedVersionSpec, - global: bool, + pin: PinType, link: bool, ) -> miette::Result { // Create symlink to this new version - if global && link { + if pin == PinType::Global && link { tool.symlink_bins(true).await?; } - let config_path = ProtoConfig::update(tool.proto.get_config_dir(global), |config| { + let config_path = ProtoConfig::update(tool.proto.get_config_dir(pin), |config| { config .versions .get_or_insert(BTreeMap::default()) @@ -63,7 +64,8 @@ pub async fn pin(session: ProtoSession, args: PinArgs) -> AppResult { args.spec.clone() }; - let config_path = internal_pin(&mut tool, &spec, args.global, false).await?; + let config_path = + internal_pin(&mut tool, &spec, map_pin_type(args.global, args.to), false).await?; println!( "Pinned {} to {} in {}", diff --git a/crates/cli/src/commands/plugin/add.rs b/crates/cli/src/commands/plugin/add.rs index ffbcbb6dc..6f4d234d4 100644 --- a/crates/cli/src/commands/plugin/add.rs +++ b/crates/cli/src/commands/plugin/add.rs @@ -1,3 +1,4 @@ +use crate::helpers::{map_pin_type, PinOption}; use crate::session::ProtoSession; use clap::Args; use proto_core::{Id, PluginLocator, ProtoConfig}; @@ -12,21 +13,26 @@ pub struct AddPluginArgs { #[arg(required = true, help = "Locator string to find and load the plugin")] plugin: PluginLocator, - #[arg( - long, - help = "Add to the global ~/.proto/.prototools instead of local ./.prototools" - )] + #[arg(long, group = "pin", help = "Add to the global ~/.proto/.prototools")] global: bool, + + #[arg(long, group = "pin", help = "Location of .prototools to add to")] + to: Option, } #[tracing::instrument(skip_all)] pub async fn add(session: ProtoSession, args: AddPluginArgs) -> AppResult { - let config_path = ProtoConfig::update(session.env.get_config_dir(args.global), |config| { - config - .plugins - .get_or_insert(Default::default()) - .insert(args.id.clone(), args.plugin.clone()); - })?; + let config_path = ProtoConfig::update( + session + .env + .get_config_dir(map_pin_type(args.global, args.to)), + |config| { + config + .plugins + .get_or_insert(Default::default()) + .insert(args.id.clone(), args.plugin.clone()); + }, + )?; println!( "Added plugin {} to config {}", diff --git a/crates/cli/src/commands/plugin/remove.rs b/crates/cli/src/commands/plugin/remove.rs index 67647a453..891221dec 100644 --- a/crates/cli/src/commands/plugin/remove.rs +++ b/crates/cli/src/commands/plugin/remove.rs @@ -1,4 +1,5 @@ use crate::error::ProtoCliError; +use crate::helpers::{map_pin_type, PinOption}; use crate::session::ProtoSession; use clap::Args; use proto_core::{Id, ProtoConfig, PROTO_CONFIG_NAME}; @@ -12,22 +13,27 @@ pub struct RemovePluginArgs { #[arg( long, - help = "Remove from the global ~/.proto/.prototools instead of local ./.prototools" + group = "pin", + help = "Remove from the global ~/.proto/.prototools" )] global: bool, + + #[arg(long, group = "pin", help = "Location of .prototools to remove from")] + from: Option, } #[tracing::instrument(skip_all)] pub async fn remove(session: ProtoSession, args: RemovePluginArgs) -> AppResult { - if !args.global { - let config_path = session.env.cwd.join(PROTO_CONFIG_NAME); + let config_dir = session + .env + .get_config_dir(map_pin_type(args.global, args.from)); + let config_path = config_dir.join(PROTO_CONFIG_NAME); - if !config_path.exists() { - return Err(ProtoCliError::MissingToolsConfigInCwd { path: config_path }.into()); - } + if !config_path.exists() { + return Err(ProtoCliError::MissingToolsConfigInCwd { path: config_path }.into()); } - let config_path = ProtoConfig::update(session.env.get_config_dir(args.global), |config| { + let config_path = ProtoConfig::update(config_dir, |config| { if let Some(plugins) = &mut config.plugins { plugins.remove(&args.id); } diff --git a/crates/cli/src/commands/unalias.rs b/crates/cli/src/commands/unalias.rs index 6f7a7a048..2a029ba98 100644 --- a/crates/cli/src/commands/unalias.rs +++ b/crates/cli/src/commands/unalias.rs @@ -1,3 +1,4 @@ +use crate::helpers::{map_pin_type, PinOption}; use crate::session::ProtoSession; use clap::Args; use proto_core::{Id, ProtoConfig}; @@ -15,9 +16,13 @@ pub struct UnaliasArgs { #[arg( long, - help = "Remove from the global ~/.proto/.prototools instead of local ./.prototools" + group = "pin", + help = "Remove from the global ~/.proto/.prototools" )] global: bool, + + #[arg(long, group = "pin", help = "Location of .prototools to remove from")] + from: Option, } #[tracing::instrument(skip_all)] @@ -25,15 +30,19 @@ pub async fn unalias(session: ProtoSession, args: UnaliasArgs) -> AppResult { let tool = session.load_tool(&args.id).await?; let mut value = None; - let config_path = ProtoConfig::update(tool.proto.get_config_dir(args.global), |config| { - if let Some(tool_configs) = &mut config.tools { - if let Some(tool_config) = tool_configs.get_mut(&tool.id) { - if let Some(aliases) = &mut tool_config.aliases { - value = aliases.remove(&args.alias); + let config_path = ProtoConfig::update( + tool.proto + .get_config_dir(map_pin_type(args.global, args.from)), + |config| { + if let Some(tool_configs) = &mut config.tools { + if let Some(tool_config) = tool_configs.get_mut(&tool.id) { + if let Some(aliases) = &mut tool_config.aliases { + value = aliases.remove(&args.alias); + } } } - } - })?; + }, + )?; let Some(value) = value else { eprintln!( diff --git a/crates/cli/src/commands/unpin.rs b/crates/cli/src/commands/unpin.rs index 15c5c2ab2..be1dbd030 100644 --- a/crates/cli/src/commands/unpin.rs +++ b/crates/cli/src/commands/unpin.rs @@ -1,3 +1,4 @@ +use crate::helpers::{map_pin_type, PinOption}; use crate::session::ProtoSession; use clap::Args; use proto_core::{Id, ProtoConfig}; @@ -12,9 +13,13 @@ pub struct UnpinArgs { #[arg( long, - help = "Unpin from the global ~/.proto/.prototools instead of local ./.prototools" + group = "pin", + help = "Unpin from the global ~/.proto/.prototools" )] pub global: bool, + + #[arg(long, group = "pin", help = "Location of .prototools to unpin from")] + pub from: Option, } #[tracing::instrument(skip_all)] @@ -22,16 +27,20 @@ pub async fn unpin(session: ProtoSession, args: UnpinArgs) -> AppResult { let tool = session.load_tool(&args.id).await?; let mut value = None; - let config_path = ProtoConfig::update(tool.proto.get_config_dir(args.global), |config| { - if let Some(versions) = &mut config.versions { - value = versions.remove(&tool.id); - } - - // Remove these also just in case - if let Some(versions) = &mut config.unknown { - versions.remove(tool.id.as_str()); - } - })?; + let config_path = ProtoConfig::update( + tool.proto + .get_config_dir(map_pin_type(args.global, args.from)), + |config| { + if let Some(versions) = &mut config.versions { + value = versions.remove(&tool.id); + } + + // Remove these also just in case + if let Some(versions) = &mut config.unknown { + versions.remove(tool.id.as_str()); + } + }, + )?; let Some(value) = value else { eprintln!("No version pinned in config {}", color::path(config_path)); diff --git a/crates/cli/src/helpers.rs b/crates/cli/src/helpers.rs index 1eb5c0861..e3082d131 100644 --- a/crates/cli/src/helpers.rs +++ b/crates/cli/src/helpers.rs @@ -1,14 +1,43 @@ +use clap::ValueEnum; use dialoguer::{ console::{style, Style}, theme::ColorfulTheme, }; use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle}; use miette::IntoDiagnostic; +use proto_core::PinType; use starbase_styles::color::{self, Color}; use starbase_utils::env::bool_var; use std::{io::IsTerminal, time::Duration}; use tracing::debug; +#[derive(Clone, Copy, Debug, Default, ValueEnum)] +pub enum PinOption { + #[value(alias = "store")] + Global, + #[default] + #[value(alias = "cwd")] + Local, + #[value(alias = "home")] + User, +} + +pub fn map_pin_type(global: bool, option: Option) -> PinType { + if let Some(option) = option { + return match option { + PinOption::Global => PinType::Global, + PinOption::Local => PinType::Local, + PinOption::User => PinType::User, + }; + } + + if global { + PinType::Global + } else { + PinType::Local + } +} + pub fn create_theme() -> ColorfulTheme { ColorfulTheme { defaults_style: Style::new().for_stderr().color256(Color::Pink as u8), diff --git a/crates/cli/src/systems.rs b/crates/cli/src/systems.rs index bee7c2843..8f6dd30b6 100644 --- a/crates/cli/src/systems.rs +++ b/crates/cli/src/systems.rs @@ -20,6 +20,14 @@ use tracing::{debug, instrument}; #[instrument(skip_all)] pub fn detect_proto_env(cli: &CLI) -> AppResult { + #[cfg(debug_assertions)] + let mut env = if let Ok(sandbox) = env::var("PROTO_SANDBOX") { + ProtoEnvironment::new_testing(&std::path::PathBuf::from(&sandbox))? + } else { + ProtoEnvironment::new()? + }; + + #[cfg(not(debug_assertions))] let mut env = ProtoEnvironment::new()?; env.config_mode = cli.config_mode.unwrap_or(match cli.command { @@ -38,6 +46,7 @@ pub fn detect_proto_env(cli: &CLI) -> AppResult { #[instrument(skip_all)] pub fn load_proto_configs(env: &ProtoEnvironment) -> AppResult { debug!( + working_dir = ?env.cwd, "Loading configuration in {} mode", env.config_mode.to_string() ); diff --git a/crates/cli/tests/alias_test.rs b/crates/cli/tests/alias_test.rs index e9781eb31..602522980 100644 --- a/crates/cli/tests/alias_test.rs +++ b/crates/cli/tests/alias_test.rs @@ -146,3 +146,38 @@ mod alias_global { ); } } + +mod alias_user { + use super::*; + + #[test] + fn updates_config_file() { + let sandbox = create_empty_proto_sandbox(); + let config_file = sandbox.path().join(".home/.prototools"); + + assert!(!config_file.exists()); + + sandbox + .run_bin(|cmd| { + cmd.arg("alias") + .arg("node") + .arg("example") + .arg("19.0.0") + .arg("--to") + .arg("user"); + }) + .success(); + + assert!(config_file.exists()); + + let config = load_config(sandbox.path().join(".home")); + + assert_eq!( + config.tools.get("node").unwrap().aliases, + BTreeMap::from_iter([( + "example".into(), + UnresolvedVersionSpec::parse("19.0.0").unwrap() + )]) + ); + } +} diff --git a/crates/cli/tests/pin_test.rs b/crates/cli/tests/pin_test.rs index 69256873a..71ce40ca6 100644 --- a/crates/cli/tests/pin_test.rs +++ b/crates/cli/tests/pin_test.rs @@ -253,3 +253,31 @@ mod pin_global { assert!(!link.exists()); } } + +mod pin_user { + use super::*; + + #[test] + fn writes_user_version_file() { + let sandbox = create_empty_proto_sandbox(); + let version_file = sandbox.path().join(".home/.prototools"); + + assert!(!version_file.exists()); + + sandbox + .run_bin(|cmd| { + cmd.arg("pin") + .arg("node") + .arg("19.0.0") + .arg("--to") + .arg("home"); + }) + .success(); + + assert!(version_file.exists()); + assert_eq!( + fs::read_to_string(version_file).unwrap(), + "node = \"19.0.0\"\n" + ) + } +} diff --git a/crates/cli/tests/plugin_add_test.rs b/crates/cli/tests/plugin_add_test.rs index 2580a9f2e..c12fbb254 100644 --- a/crates/cli/tests/plugin_add_test.rs +++ b/crates/cli/tests/plugin_add_test.rs @@ -83,4 +83,36 @@ mod plugin_add { })) ); } + + #[test] + fn updates_user_file() { + let sandbox = create_empty_proto_sandbox(); + let config_file = sandbox.path().join(".home/.prototools"); + + assert!(!config_file.exists()); + + sandbox + .run_bin(|cmd| { + cmd.arg("plugin") + .arg("add") + .arg("id") + .arg("https://github.com/moonrepo/tools/releases/latest/download/example_plugin.wasm") + .arg("--to") + .arg("user"); + }) + .success(); + + assert!(config_file.exists()); + + let config = load_config(sandbox.path().join(".home")); + + assert_eq!( + config.plugins.get("id").unwrap(), + &PluginLocator::Url(Box::new(UrlLocator { + url: + "https://github.com/moonrepo/tools/releases/latest/download/example_plugin.wasm" + .into() + })) + ); + } } diff --git a/crates/cli/tests/plugin_remove_test.rs b/crates/cli/tests/plugin_remove_test.rs index 1cadc235e..64af64797 100644 --- a/crates/cli/tests/plugin_remove_test.rs +++ b/crates/cli/tests/plugin_remove_test.rs @@ -75,4 +75,38 @@ mod plugin_remove { assert!(!config.plugins.contains_key("id")); } + + #[test] + fn updates_user_file() { + let sandbox = create_empty_proto_sandbox(); + + ProtoConfig::update(sandbox.path().join(".home"), |config| { + config + .plugins + .get_or_insert(Default::default()) + .insert( + Id::raw("id"), + PluginLocator::Url(Box::new(UrlLocator { + url: "https://github.com/moonrepo/tools/releases/latest/download/example_plugin.wasm".into() + })), + ); + }) + .unwrap(); + + sandbox.debug_files(); + + sandbox + .run_bin(|cmd| { + cmd.arg("plugin") + .arg("remove") + .arg("id") + .arg("--from") + .arg("user"); + }) + .success(); + + let config = load_config(sandbox.path().join(".home")); + + assert!(!config.plugins.contains_key("id")); + } } diff --git a/crates/cli/tests/unalias_test.rs b/crates/cli/tests/unalias_test.rs index 010cedb85..25b2e5ad2 100644 --- a/crates/cli/tests/unalias_test.rs +++ b/crates/cli/tests/unalias_test.rs @@ -39,13 +39,11 @@ mod unalias_local { }) .unwrap(); - sandbox.debug_files(); - sandbox .run_bin(|cmd| { cmd.arg("unalias").arg("node").arg("example"); }) - .debug(); + .success(); let config = load_config(sandbox.path()); @@ -123,3 +121,40 @@ mod unalias_global { assert!(config.tools.get("node").unwrap().aliases.is_empty()); } } + +mod unalias_user { + use super::*; + + #[test] + fn removes_existing_alias() { + let sandbox = create_empty_proto_sandbox(); + + ProtoConfig::update(sandbox.path().join(".home"), |config| { + config.tools.get_or_insert(Default::default()).insert( + Id::raw("node"), + PartialProtoToolConfig { + aliases: Some(BTreeMap::from_iter([( + "example".into(), + UnresolvedVersionSpec::parse("19.0.0").unwrap(), + )])), + ..Default::default() + }, + ); + }) + .unwrap(); + + sandbox + .run_bin(|cmd| { + cmd.arg("unalias") + .arg("node") + .arg("example") + .arg("--from") + .arg("user"); + }) + .success(); + + let config = load_config(sandbox.path().join(".home")); + + assert!(config.tools.get("node").unwrap().aliases.is_empty()); + } +} diff --git a/crates/cli/tests/unpin_test.rs b/crates/cli/tests/unpin_test.rs index 2e731f445..7cc7b3ea8 100644 --- a/crates/cli/tests/unpin_test.rs +++ b/crates/cli/tests/unpin_test.rs @@ -97,3 +97,30 @@ mod unpin_global { assert!(!config.versions.contains_key("node")); } } + +mod unpin_user { + use super::*; + + #[test] + fn removes_existing_pin() { + let sandbox = create_empty_proto_sandbox(); + + ProtoConfig::update(sandbox.path().join(".home"), |config| { + config + .versions + .get_or_insert(Default::default()) + .insert(Id::raw("node"), UnresolvedVersionSpec::Canary); + }) + .unwrap(); + + sandbox + .run_bin(|cmd| { + cmd.arg("unpin").arg("node").arg("--from").arg("user"); + }) + .success(); + + let config = load_config(sandbox.path().join(".home")); + + assert!(!config.versions.contains_key("node")); + } +} diff --git a/crates/cli/tests/utils.rs b/crates/cli/tests/utils.rs index 5d3eda2d3..7ccb83a26 100644 --- a/crates/cli/tests/utils.rs +++ b/crates/cli/tests/utils.rs @@ -29,12 +29,19 @@ impl Deref for ProtoSandbox { } fn apply_settings(sandbox: &mut Sandbox) { + let root = sandbox.path().to_path_buf(); + let home_dir = sandbox.path().join(".home"); let proto_dir = sandbox.path().join(".proto"); + // Folders must exist or tests fail! + fs::create_dir_all(&home_dir).unwrap(); + fs::create_dir_all(&proto_dir).unwrap(); + let mut env = HashMap::new(); env.insert("RUST_BACKTRACE", "1"); env.insert("WASMTIME_BACKTRACE_DETAILS", "1"); env.insert("NO_COLOR", "1"); + env.insert("PROTO_SANDBOX", root.to_str().unwrap()); env.insert("PROTO_HOME", proto_dir.to_str().unwrap()); env.insert("PROTO_LOG", "trace"); env.insert("PROTO_TEST", "true"); diff --git a/crates/core/src/flow/setup.rs b/crates/core/src/flow/setup.rs index f78e92743..f2c79ed79 100644 --- a/crates/core/src/flow/setup.rs +++ b/crates/core/src/flow/setup.rs @@ -1,5 +1,5 @@ use crate::flow::install::InstallOptions; -use crate::proto_config::ProtoConfig; +use crate::proto_config::{PinType, ProtoConfig}; use crate::tool::Tool; use crate::tool_manifest::ToolManifestVersion; use proto_pdk_api::*; @@ -78,7 +78,7 @@ impl Tool { manifest.save()?; // Pin the global version - ProtoConfig::update(self.proto.get_config_dir(true), |config| { + ProtoConfig::update(self.proto.get_config_dir(PinType::Global), |config| { config .versions .get_or_insert(Default::default()) @@ -112,7 +112,7 @@ impl Tool { manifest.save()?; // Unpin global version if a match - ProtoConfig::update(self.proto.get_config_dir(true), |config| { + ProtoConfig::update(self.proto.get_config_dir(PinType::Global), |config| { if let Some(versions) = &mut config.versions { if versions.get(&self.id).is_some_and(|v| v == &version) { debug!("Unpinning global version"); diff --git a/crates/core/src/proto.rs b/crates/core/src/proto.rs index 40c27ca94..357721423 100644 --- a/crates/core/src/proto.rs +++ b/crates/core/src/proto.rs @@ -2,7 +2,7 @@ use crate::error::ProtoError; use crate::helpers::is_offline; use crate::layout::Store; use crate::proto_config::{ - ConfigMode, ProtoConfig, ProtoConfigFile, ProtoConfigManager, PROTO_CONFIG_NAME, + ConfigMode, PinType, ProtoConfig, ProtoConfigFile, ProtoConfigManager, PROTO_CONFIG_NAME, }; use once_cell::sync::OnceCell; use starbase_utils::dirs::home_dir; @@ -39,7 +39,6 @@ impl ProtoEnvironment { pub fn new_testing(sandbox: &Path) -> miette::Result { let mut env = Self::from(sandbox.join(".proto"), sandbox.join(".home"))?; - env.cwd = sandbox.to_path_buf(); env.test_only = true; Ok(env) @@ -47,14 +46,19 @@ impl ProtoEnvironment { pub fn from, H: AsRef>(root: R, home: H) -> miette::Result { let root = root.as_ref(); + let home = home.as_ref(); - debug!(store = ?root, "Creating proto environment, detecting store"); + debug!( + store = ?root, + home = ?home, + "Creating proto environment, detecting store", + ); Ok(ProtoEnvironment { config_mode: ConfigMode::Upwards, cwd: env::current_dir().expect("Unable to determine current working directory!"), env_mode: env::var("PROTO_ENV").ok(), - home: home.as_ref().to_owned(), + home: home.to_owned(), root: root.to_owned(), config_manager: Arc::new(OnceCell::new()), plugin_loader: Arc::new(OnceCell::new()), @@ -63,11 +67,11 @@ impl ProtoEnvironment { }) } - pub fn get_config_dir(&self, global: bool) -> &Path { - if global { - &self.root - } else { - &self.cwd + pub fn get_config_dir(&self, pin: PinType) -> &Path { + match pin { + PinType::Global => &self.root, + PinType::Local => &self.cwd, + PinType::User => &self.home, } } diff --git a/crates/core/src/proto_config.rs b/crates/core/src/proto_config.rs index dd1ff523a..446f27fe5 100644 --- a/crates/core/src/proto_config.rs +++ b/crates/core/src/proto_config.rs @@ -120,10 +120,14 @@ derive_enum!( ); derive_enum!( - #[derive(ConfigEnum)] + #[derive(Copy, ConfigEnum)] pub enum PinType { + #[serde(alias = "store")] Global, + #[serde(alias = "cwd")] Local, + #[serde(alias = "home")] + User, } );