Skip to content

Commit

Permalink
perf: make ls --offline default behavior (#3409)
Browse files Browse the repository at this point in the history
This made more sense before the dedicated `mise outdated` command and before
backends since now people have a lot more tools generally

Fixes #3408
  • Loading branch information
jdx authored Dec 8, 2024
1 parent 7b45f19 commit ca0cff2
Show file tree
Hide file tree
Showing 16 changed files with 142 additions and 93 deletions.
2 changes: 1 addition & 1 deletion docs/cli/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Set the environment for loading `mise.<ENV>.toml`

### `-j --jobs <JOBS>`

How many jobs to run in parallel [default: 4]
How many jobs to run in parallel [default: 8]

### `-q --quiet`

Expand Down
4 changes: 4 additions & 0 deletions docs/cli/ls.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ Only show tool versions that are installed (Hides tools defined in mise.toml but

Don't fetch information such as outdated versions

### `--outdated`

Display whether a version is outdated

### `-J --json`

Output in JSON format
Expand Down
2 changes: 1 addition & 1 deletion e2e/cli/test_upgrade
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ rm -f .tool-versions
echo "tools.dummy = 'prefix:1'" >mise.toml
mise uninstall dummy --all
mkdir -p "$MISE_DATA_DIR/installs/dummy/1.0.0"
assert "mise ls dummy" "dummy 1.0.0 (outdated) ~/workdir/mise.toml prefix:1"
assert "mise ls dummy --outdated" "dummy 1.0.0 (outdated) ~/workdir/mise.toml prefix:1"
assert "mise up -n" "Would uninstall dummy@1.0.0
Would install dummy@1.1.0"
mise up
Expand Down
2 changes: 1 addition & 1 deletion man/man1/mise.1
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Change directory before running command
Set the environment for loading `mise.<ENV>.toml`
.TP
\fB\-j\fR, \fB\-\-jobs\fR=\fIJOBS\fR
How many jobs to run in parallel [default: 4]
How many jobs to run in parallel [default: 8]
.RS
May also be specified with the \fBMISE_JOBS\fR environment variable.
.RE
Expand Down
3 changes: 2 additions & 1 deletion mise.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ flag "-E --env" help="Set the environment for loading `mise.<ENV>.toml`" var=tru
}
flag "-f --force" help="Force the operation" hide=true
flag "-i --interleave" help="Set the log output verbosity" hide=true
flag "-j --jobs" help="How many jobs to run in parallel [default: 4]" global=true {
flag "-j --jobs" help="How many jobs to run in parallel [default: 8]" global=true {
arg "<JOBS>"
}
flag "--log-level" hide=true global=true {
Expand Down Expand Up @@ -685,6 +685,7 @@ It's a useful command to get the current state of your tools."#
flag "-g --global" help="Only show tool versions currently specified in the global mise.toml"
flag "-i --installed" help="Only show tool versions that are installed (Hides tools defined in mise.toml but not installed)"
flag "-o --offline" help="Don't fetch information such as outdated versions"
flag "--outdated" help="Display whether a version is outdated"
flag "-J --json" help="Output in JSON format"
flag "-m --missing" help="Display missing tool versions"
flag "--prefix" help="Display versions matching this prefix" {
Expand Down
4 changes: 2 additions & 2 deletions schema/mise.json
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
"type": "string"
},
"fetch_remote_versions_timeout": {
"default": "10s",
"default": "5s",
"description": "Timeout in seconds for HTTP requests to fetch new tool versions in mise.",
"type": "string"
},
Expand Down Expand Up @@ -338,7 +338,7 @@
}
},
"jobs": {
"default": 4,
"default": 8,
"description": "How many jobs to run concurrently such as tool installs.",
"type": "number"
},
Expand Down
4 changes: 2 additions & 2 deletions settings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ cached. For "slow" commands like `mise ls-remote` or `mise install`:
[fetch_remote_versions_timeout]
env = "MISE_FETCH_REMOTE_VERSIONS_TIMEOUT"
type = "Duration"
default = "10s"
default = "5s"
description = "Timeout in seconds for HTTP requests to fetch new tool versions in mise."
aliases = ["fetch_remote_version_timeout"]

Expand Down Expand Up @@ -391,7 +391,7 @@ description = "This is a list of config paths that mise will ignore."
env = "MISE_JOBS"
type = "Integer"
rust_type = "usize"
default = 4
default = 8
description = "How many jobs to run concurrently such as tool installs."

[legacy_version_file]
Expand Down
30 changes: 18 additions & 12 deletions src/backend/asdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::plugins::asdf_plugin::AsdfPlugin;
use crate::plugins::mise_plugin_toml::MisePluginToml;
use crate::plugins::Script::{Download, ExecEnv, Install, ParseIdiomaticFile};
use crate::plugins::{Plugin, PluginType, Script, ScriptManager};
use crate::timeout::run_with_timeout;
use crate::toolset::{ToolRequest, ToolVersion, Toolset};
use crate::ui::progress_report::SingleReport;
use crate::{dirs, env, file};
Expand Down Expand Up @@ -236,18 +237,23 @@ impl Backend for AsdfBackend {
}

fn latest_stable_version(&self) -> Result<Option<String>> {
if !self.plugin.has_latest_stable_script() {
return self.latest_version(Some("latest".into()));
}
self.latest_stable_cache
.get_or_try_init(|| self.plugin.fetch_latest_stable())
.wrap_err_with(|| {
eyre!(
"Failed fetching latest stable version for plugin {}",
style(&self.name).blue().for_stderr(),
)
})
.cloned()
run_with_timeout(
|| {
if !self.plugin.has_latest_stable_script() {
return self.latest_version(Some("latest".into()));
}
self.latest_stable_cache
.get_or_try_init(|| self.plugin.fetch_latest_stable())
.wrap_err_with(|| {
eyre!(
"Failed fetching latest stable version for plugin {}",
style(&self.name).blue().for_stderr(),
)
})
.cloned()
},
SETTINGS.fetch_remote_versions_timeout(),
)
}

fn get_aliases(&self) -> Result<BTreeMap<String, String>> {
Expand Down
48 changes: 27 additions & 21 deletions src/backend/go.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::cli::args::BackendArg;
use crate::cmd::CmdLineRunner;
use crate::config::SETTINGS;
use crate::install_context::InstallContext;
use crate::timeout;
use crate::toolset::ToolVersion;

#[derive(Debug)]
Expand All @@ -27,29 +28,34 @@ impl Backend for GoBackend {
}

fn _list_remote_versions(&self) -> eyre::Result<Vec<String>> {
let mut mod_path = Some(self.tool_name());

while let Some(cur_mod_path) = mod_path {
let res = cmd!("go", "list", "-m", "-versions", "-json", &cur_mod_path)
.full_env(self.dependency_env()?)
.read();
if let Ok(raw) = res {
let res = serde_json::from_str::<GoModInfo>(&raw);
if let Ok(mut mod_info) = res {
// remove the leading v from the versions
mod_info.versions = mod_info
.versions
.into_iter()
.map(|v| v.trim_start_matches('v').to_string())
.collect();
return Ok(mod_info.versions);
timeout::run_with_timeout(
|| {
let mut mod_path = Some(self.tool_name());

while let Some(cur_mod_path) = mod_path {
let res = cmd!("go", "list", "-m", "-versions", "-json", &cur_mod_path)
.full_env(self.dependency_env()?)
.read();
if let Ok(raw) = res {
let res = serde_json::from_str::<GoModInfo>(&raw);
if let Ok(mut mod_info) = res {
// remove the leading v from the versions
mod_info.versions = mod_info
.versions
.into_iter()
.map(|v| v.trim_start_matches('v').to_string())
.collect();
return Ok(mod_info.versions);
}
};

mod_path = trim_after_last_slash(cur_mod_path);
}
};

mod_path = trim_after_last_slash(cur_mod_path);
}

Ok(vec![])
Ok(vec![])
},
SETTINGS.fetch_remote_versions_timeout(),
)
}

fn install_version_(&self, ctx: &InstallContext, tv: ToolVersion) -> eyre::Result<ToolVersion> {
Expand Down
2 changes: 1 addition & 1 deletion src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ pub trait Backend: Debug + Send + Sync {
let latest = match tv.latest_version() {
Ok(latest) => latest,
Err(e) => {
debug!(
warn!(
"Error getting latest version for {}: {:#}",
self.ba().to_string(),
e
Expand Down
53 changes: 32 additions & 21 deletions src/backend/npm.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use serde_json::Value;
use std::fmt::Debug;

use crate::backend::backend_type::BackendType;
use crate::backend::Backend;
use crate::cache::{CacheManager, CacheManagerBuilder};
use crate::cli::args::BackendArg;
use crate::cmd::CmdLineRunner;
use crate::config::{Config, SETTINGS};
use crate::install_context::InstallContext;
use crate::timeout;
use crate::toolset::ToolVersion;
use serde_json::Value;
use std::fmt::Debug;

#[derive(Debug)]
pub struct NPMBackend {
Expand All @@ -32,27 +32,38 @@ impl Backend for NPMBackend {
}

fn _list_remote_versions(&self) -> eyre::Result<Vec<String>> {
let raw = cmd!(NPM_PROGRAM, "view", self.tool_name(), "versions", "--json")
.full_env(self.dependency_env()?)
.read()?;
let versions: Vec<String> = serde_json::from_str(&raw)?;
Ok(versions)
timeout::run_with_timeout(
|| {
let raw = cmd!(NPM_PROGRAM, "view", self.tool_name(), "versions", "--json")
.full_env(self.dependency_env()?)
.read()?;
let versions: Vec<String> = serde_json::from_str(&raw)?;
Ok(versions)
},
SETTINGS.fetch_remote_versions_timeout(),
)
}

fn latest_stable_version(&self) -> eyre::Result<Option<String>> {
self.latest_version_cache
.get_or_try_init(|| {
let raw = cmd!(NPM_PROGRAM, "view", self.tool_name(), "dist-tags", "--json")
.full_env(self.dependency_env()?)
.read()?;
let dist_tags: Value = serde_json::from_str(&raw)?;
let latest = match dist_tags["latest"] {
Value::String(ref s) => Some(s.clone()),
_ => self.latest_version(Some("latest".into())).unwrap(),
};
Ok(latest)
})
.cloned()
timeout::run_with_timeout(
|| {
self.latest_version_cache
.get_or_try_init(|| {
let raw =
cmd!(NPM_PROGRAM, "view", self.tool_name(), "dist-tags", "--json")
.full_env(self.dependency_env()?)
.read()?;
let dist_tags: Value = serde_json::from_str(&raw)?;
let latest = match dist_tags["latest"] {
Value::String(ref s) => Some(s.clone()),
_ => self.latest_version(Some("latest".into())).unwrap(),
};
Ok(latest)
})
.cloned()
},
SETTINGS.fetch_remote_versions_timeout(),
)
}

fn install_version_(&self, ctx: &InstallContext, tv: ToolVersion) -> eyre::Result<ToolVersion> {
Expand Down
25 changes: 15 additions & 10 deletions src/backend/vfox.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::env;
use crate::{env, timeout};
use heck::ToKebabCase;
use std::collections::{BTreeMap, HashMap};
use std::fmt::Debug;
Expand All @@ -10,7 +10,7 @@ use crate::backend::backend_type::BackendType;
use crate::backend::Backend;
use crate::cache::{CacheManager, CacheManagerBuilder};
use crate::cli::args::BackendArg;
use crate::config::Config;
use crate::config::{Config, SETTINGS};
use crate::dirs;
use crate::install_context::InstallContext;
use crate::plugins::vfox_plugin::VfoxPlugin;
Expand Down Expand Up @@ -41,14 +41,19 @@ impl Backend for VfoxBackend {
}

fn _list_remote_versions(&self) -> eyre::Result<Vec<String>> {
let (vfox, _log_rx) = self.plugin.vfox();
self.ensure_plugin_installed()?;
let versions = RUNTIME.block_on(vfox.list_available_versions(&self.pathname))?;
Ok(versions
.into_iter()
.rev()
.map(|v| v.version)
.collect::<Vec<String>>())
timeout::run_with_timeout(
|| {
let (vfox, _log_rx) = self.plugin.vfox();
self.ensure_plugin_installed()?;
let versions = RUNTIME.block_on(vfox.list_available_versions(&self.pathname))?;
Ok(versions
.into_iter()
.rev()
.map(|v| v.version)
.collect::<Vec<String>>())
},
SETTINGS.fetch_remote_versions_timeout(),
)
}

fn install_version_(
Expand Down
10 changes: 7 additions & 3 deletions src/cli/ls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ pub struct Ls {
#[clap(long, short)]
offline: bool,

/// Display whether a version is outdated
#[clap(long)]
outdated: bool,

/// Output in JSON format
#[clap(long, short = 'J')]
json: bool,
Expand Down Expand Up @@ -291,10 +295,10 @@ impl From<(&Ls, &dyn Backend, &ToolVersion, &ToolSource)> for VersionStatus {
} else if !p.is_version_installed(tv, true) {
VersionStatus::Missing(tv.version.clone())
} else if !source.is_unknown() {
let outdated = if ls.offline {
false
} else {
let outdated = if ls.outdated {
p.is_version_outdated(tv)
} else {
false
};
VersionStatus::Active(tv.version.clone(), outdated)
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ pub struct Cli {
/// Set the log output verbosity
#[clap(long, short, hide = true, overrides_with = "prefix")]
pub interleave: bool,
/// How many jobs to run in parallel [default: 4]
/// How many jobs to run in parallel [default: 8]
#[clap(long, short, global = true, env = "MISE_JOBS")]
pub jobs: Option<usize>,
#[clap(long, global = true, hide = true, value_name = "LEVEL", value_enum)]
Expand Down
Loading

0 comments on commit ca0cff2

Please sign in to comment.