Skip to content

Commit

Permalink
Implement fall-through mechanism for tools not managed by Rokit (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
filiptibell authored Jun 9, 2024
1 parent 127da30 commit 5bc268d
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 15 deletions.
34 changes: 34 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,20 @@ filepath = "0.1"
flate2 = "1.0"
goblin = "0.8"
once_cell = "1.8"
process-wrap = { version = "8.0", features = ["tokio1"] }
semver = { version = "1.0", features = ["serde"] }
tar = "0.4"
tempfile = "3.3"
thiserror = "1.0"
url = { version = "2.5", features = ["serde"] }
which = "6.0"
zip = "2.1"

# Async / runtime dependencies

async-once-cell = "0.5"
async-signal = "0.2"
futures = "0.3"
process-wrap = { version = "8.0", features = ["tokio1"] }
reqwest = { version = "0.12", default-features = false, features = [
"rustls-tls",
"http2",
Expand Down
26 changes: 26 additions & 0 deletions lib/discovery/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{
collections::HashMap,
env::var_os,
path::{Path, PathBuf},
};

Expand All @@ -8,6 +9,7 @@ use tokio::fs::read_to_string;

use crate::{
manifests::RokitManifest,
storage::Home,
system::current_dir,
tool::{ToolAlias, ToolSpec},
};
Expand Down Expand Up @@ -164,3 +166,27 @@ pub async fn discover_tool_spec(

None
}

/**
Discovers a tool explicitly **not** managed by Rokit,
by traversing the system PATH environment variable.
This means that if Rokit manages a tool with the given alias,
and an executable for it is in the PATH, this function will
ignore that and prefer other tools on the system instead.
*/
pub async fn discover_non_rokit_tool(home: &Home, alias: &ToolAlias) -> Option<PathBuf> {
let cwd = current_dir().await;

let binary_name = alias.name().to_string();
let home_path = home.path().to_owned();
let search_paths = var_os("PATH")?;

let mut found_tool_paths = which::which_in_all(binary_name, Some(search_paths), &cwd)
.ok()
.into_iter()
.flatten()
.filter(|path| !path.starts_with(&home_path));

found_tool_paths.next()
}
31 changes: 17 additions & 14 deletions src/runner/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{env::args, process::exit, str::FromStr};

use anyhow::{Context, Error, Result};
use anyhow::{bail, Error, Result};

use rokit::{
discovery::discover_tool_spec,
discovery::{discover_non_rokit_tool, discover_tool_spec},
storage::Home,
system::{current_exe_name, run_interruptible},
tool::ToolAlias,
Expand Down Expand Up @@ -32,21 +32,24 @@ impl Runner {
let alias = ToolAlias::from_str(&self.exe_name)?;

let home = Home::load_from_env().await?;
let spec = discover_tool_spec(&alias, false, false)
.await
.with_context(|| {
format!(
let spec = discover_tool_spec(&alias, false, false).await;

let program_args = args().skip(1).collect::<Vec<_>>();
let program_path = match spec {
// TODO: Prompt for trust and install tool if not already installed
Some(spec) => home.tool_storage().tool_path(&spec),
// FUTURE: Maybe we should add some kind of "fall-through" setting in
// Rokit manifests instead of always falling through to non-rokit tools?
None => match discover_non_rokit_tool(&home, &alias).await {
Some(path) => path,
None => bail!(
"Failed to find tool '{alias}' in any project manifest file.\
\nAdd the tool to a project using 'rokit add' before running it."
)
})?;

// TODO: Prompt for trust and install tool if not already installed

let path = home.tool_storage().tool_path(&spec);
let args = args().skip(1).collect::<Vec<_>>();
),
},
};

let code = run_interruptible(&path, &args)
let code = run_interruptible(&program_path, &program_args)
.await
.map_err(Error::from)
.inspect_err(|e| inform_user_about_potential_fixes(&alias, e))?;
Expand Down

0 comments on commit 5bc268d

Please sign in to comment.