Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new: Add "user" pin location. #608

Merged
merged 10 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
31 changes: 18 additions & 13 deletions crates/cli/src/commands/alias.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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<PinOption>,
}

#[tracing::instrument(skip_all)]
Expand 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 {}",
Expand Down
23 changes: 9 additions & 14 deletions crates/cli/src/commands/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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")]
Expand Down Expand Up @@ -62,6 +56,7 @@ impl InstallArgs {
fn get_pin_type(&self) -> Option<PinType> {
self.pin.as_ref().map(|pin| match pin {
Some(PinOption::Global) => PinType::Global,
Some(PinOption::User) => PinType::User,
_ => PinType::Local,
})
}
Expand All @@ -82,30 +77,30 @@ async fn pin_version(
) -> miette::Result<bool> {
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)
Expand Down
20 changes: 11 additions & 9 deletions crates/cli/src/commands/pin.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<PinOption>,
}

pub async fn internal_pin(
tool: &mut Tool,
spec: &UnresolvedVersionSpec,
global: bool,
pin: PinType,
link: bool,
) -> miette::Result<PathBuf> {
// 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())
Expand All @@ -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 {}",
Expand Down
26 changes: 16 additions & 10 deletions crates/cli/src/commands/plugin/add.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::helpers::{map_pin_type, PinOption};
use crate::session::ProtoSession;
use clap::Args;
use proto_core::{Id, PluginLocator, ProtoConfig};
Expand All @@ -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<PinOption>,
}

#[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 {}",
Expand Down
20 changes: 13 additions & 7 deletions crates/cli/src/commands/plugin/remove.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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<PinOption>,
}

#[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);
}
Expand Down
25 changes: 17 additions & 8 deletions crates/cli/src/commands/unalias.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::helpers::{map_pin_type, PinOption};
use crate::session::ProtoSession;
use clap::Args;
use proto_core::{Id, ProtoConfig};
Expand All @@ -15,25 +16,33 @@ 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<PinOption>,
}

#[tracing::instrument(skip_all)]
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!(
Expand Down
31 changes: 20 additions & 11 deletions crates/cli/src/commands/unpin.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::helpers::{map_pin_type, PinOption};
use crate::session::ProtoSession;
use clap::Args;
use proto_core::{Id, ProtoConfig};
Expand All @@ -12,26 +13,34 @@ 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<PinOption>,
}

#[tracing::instrument(skip_all)]
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));
Expand Down
Loading