Skip to content

Commit

Permalink
feat: support bin/latest-stable
Browse files Browse the repository at this point in the history
Fixes #21
  • Loading branch information
jdx committed Mar 12, 2023
1 parent 9cefc2b commit 5eedd70
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 24 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1213,9 +1213,8 @@ Options:
Examples:
$ rtx install [email protected] # install specific nodejs version
$ rtx install nodejs@18 # install fuzzy nodejs version
$ rtx install nodejs # install version specified in .tool-versions
$ rtx install # installs all runtimes specified in .tool-versions for installed plugins
$ rtx install --all # installs all runtimes and all plugins
$ rtx install nodejs # install version specified in .tool-versions or .rtx.toml
$ rtx install # installs all runtimes specified in .tool-versions or .rtx.toml
```
### `rtx latest`

Expand Down
15 changes: 15 additions & 0 deletions e2e/test_zigmod
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail

assert() {
local actual
actual="$($*)"
if [[ "$actual" != "$2" ]]; then
echo "Expected '$2' but got '$actual'"
exit 1
fi
}

eval "$(rtx activate bash)" && eval "$(rtx hook-env)"
rtx plugin install https://github.com/kachick/asdf-zigmod
rtx x --install-missing zigmod@latest -- zigmod version
5 changes: 2 additions & 3 deletions src/cli/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,8 @@ static AFTER_LONG_HELP: Lazy<String> = Lazy::new(|| {
{}
$ rtx install [email protected] # install specific nodejs version
$ rtx install nodejs@18 # install fuzzy nodejs version
$ rtx install nodejs # install version specified in .tool-versions
$ rtx install # installs all runtimes specified in .tool-versions for installed plugins
$ rtx install --all # installs all runtimes and all plugins
$ rtx install nodejs # install version specified in .tool-versions or .rtx.toml
$ rtx install # installs all runtimes specified in .tool-versions or .rtx.toml
"#, style("Examples:").bold().underlined()}
});

Expand Down
9 changes: 3 additions & 6 deletions src/cli/latest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,8 @@ pub struct Latest {
impl Command for Latest {
fn run(self, config: Config, out: &mut Output) -> Result<()> {
let prefix = match self.runtime.version {
RuntimeArgVersion::None => match self.asdf_version {
Some(version) => version,
None => "latest".to_string(),
},
RuntimeArgVersion::Version(version) => version,
RuntimeArgVersion::None => self.asdf_version,
RuntimeArgVersion::Version(version) => Some(version),
_ => Err(eyre!(
"invalid version: {}",
style(&self.runtime).cyan().for_stderr()
Expand All @@ -47,7 +44,7 @@ impl Command for Latest {
})?;

plugin.clear_remote_version_cache()?;
if let Some(version) = plugin.latest_version(&config.settings, &prefix)? {
if let Some(version) = plugin.latest_version(&config.settings, prefix)? {
rtxprintln!(out, "{}", version);
}
Ok(())
Expand Down
83 changes: 74 additions & 9 deletions src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub struct Plugin {
installs_path: PathBuf,
script_man: ScriptManager,
remote_version_cache: CacheManager<Vec<String>>,
latest_stable_cache: CacheManager<Option<String>>,
alias_cache: CacheManager<Vec<(String, String)>>,
legacy_filename_cache: CacheManager<Vec<String>>,
}
Expand All @@ -64,6 +65,10 @@ impl Plugin {
.with_fresh_duration(fresh_duration)
.with_fresh_file(plugin_path.clone())
.with_fresh_file(plugin_path.join("bin/list-all")),
latest_stable_cache: CacheManager::new(cache_path.join("latest_stable.msgpack.z"))
.with_fresh_duration(fresh_duration)
.with_fresh_file(plugin_path.clone())
.with_fresh_file(plugin_path.join("bin/latest-stable")),
alias_cache: CacheManager::new(cache_path.join("aliases.msgpack.z"))
.with_fresh_file(plugin_path.clone())
.with_fresh_file(plugin_path.join("bin/list-aliases")),
Expand Down Expand Up @@ -186,13 +191,30 @@ impl Plugin {
Ok(())
}

pub fn latest_version(&self, settings: &Settings, query: &str) -> Result<Option<String>> {
let matches = self.list_versions_matching(settings, query)?;
let v = match matches.contains(&query.to_string()) {
true => Some(query.to_string()),
false => matches.last().map(|v| v.to_string()),
};
Ok(v)
pub fn latest_version(
&self,
settings: &Settings,
query: Option<String>,
) -> Result<Option<String>> {
match query {
Some(query) => {
let matches = self.list_versions_matching(settings, &query)?;
let v = match matches.contains(&query) {
true => Some(query),
false => matches.last().map(|v| v.to_string()),
};
Ok(v)
}
None => self.latest_stable_version(settings),
}
}

fn latest_stable_version(&self, settings: &Settings) -> Result<Option<String>> {
if let Some(latest) = self.get_latest_stable(settings)? {
Ok(Some(latest))
} else {
self.latest_version(settings, Some("latest".into()))
}
}

pub fn list_versions_matching(&self, settings: &Settings, query: &str) -> Result<Vec<String>> {
Expand Down Expand Up @@ -228,7 +250,8 @@ impl Plugin {
}

pub fn clear_remote_version_cache(&self) -> Result<()> {
self.remote_version_cache.clear()
self.remote_version_cache.clear()?;
self.latest_stable_cache.clear()
}
pub fn list_remote_versions(&self, settings: &Settings) -> Result<&Vec<String>> {
self.remote_version_cache
Expand Down Expand Up @@ -272,6 +295,20 @@ impl Plugin {
})
.cloned()
}
fn get_latest_stable(&self, settings: &Settings) -> Result<Option<String>> {
if !self.has_latest_stable_script() {
return Ok(None);
}
self.latest_stable_cache
.get_or_try_init(|| self.fetch_latest_stable(settings))
.with_context(|| {
format!(
"Failed fetching latest stable version for plugin {}",
style(&self.name).cyan().for_stderr()
)
})
.cloned()
}

pub fn external_commands(&self) -> Result<Vec<Vec<String>>> {
let command_path = self.plugin_path.join("lib/commands");
Expand Down Expand Up @@ -364,6 +401,18 @@ impl Plugin {
.map(|v| v.into())
.collect())
}
fn fetch_latest_stable(&self, settings: &Settings) -> Result<Option<String>> {
let latest_stable = self
.script_man
.read(settings, &Script::LatestStable, settings.verbose)?
.trim()
.to_string();
Ok(if latest_stable.is_empty() {
None
} else {
Some(latest_stable)
})
}

fn has_list_all_script(&self) -> bool {
self.script_man.script_exists(&Script::ListAll)
Expand All @@ -374,6 +423,9 @@ impl Plugin {
fn has_list_legacy_filenames_script(&self) -> bool {
self.script_man.script_exists(&Script::ListLegacyFilenames)
}
fn has_latest_stable_script(&self) -> bool {
self.script_man.script_exists(&Script::LatestStable)
}
fn fetch_aliases(&self, settings: &Settings) -> Result<Vec<(String, String)>> {
let stdout = self
.script_man
Expand Down Expand Up @@ -469,7 +521,20 @@ mod tests {
assert_cli!("plugin", "add", "tiny");
let settings = Settings::default();
let plugin = Plugin::new(&PluginName::from("tiny"));
let version = plugin.latest_version(&settings, "1.0.0").unwrap().unwrap();
let version = plugin
.latest_version(&settings, Some("1.0.0".into()))
.unwrap()
.unwrap();
assert_str_eq!(version, "1.0.0");
let version = plugin.latest_version(&settings, None).unwrap().unwrap();
assert_str_eq!(version, "3.1.0");
}

#[test]
fn test_latest_stable() {
let settings = Settings::default();
let plugin = Plugin::new(&PluginName::from("dummy"));
let version = plugin.latest_version(&settings, None).unwrap().unwrap();
assert_str_eq!(version, "2.0.0");
}
}
8 changes: 5 additions & 3 deletions src/plugins/script_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,25 @@ pub enum Script {
// PostUninstall,

// Plugin
LatestStable,
ListAliases,
ListAll,
ListLegacyFilenames,
ListAliases,
ParseLegacyFile(String),

// RuntimeVersion
Download,
ExecEnv,
Install,
Uninstall,
ListBinPaths,
ExecEnv,
Uninstall,
}

impl Display for Script {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
// Plugin
Script::LatestStable => write!(f, "latest-stable"),
Script::ListAll => write!(f, "list-all"),
Script::ListLegacyFilenames => write!(f, "list-legacy-filenames"),
Script::ListAliases => write!(f, "list-aliases"),
Expand Down
7 changes: 7 additions & 0 deletions src/toolset/tool_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ impl ToolVersion {
return Ok(rtv);
}

if v == "latest" {
let v = plugin.latest_version(&config.settings, None)?;
if let Some(v) = v {
let rtv = RuntimeVersion::new(config, plugin, v, self.clone());
return Ok(rtv);
}
}
let matches = plugin.list_versions_matching(&config.settings, &v)?;
if matches.contains(&v) {
let rtv = RuntimeVersion::new(config, plugin, v, self.clone());
Expand Down

0 comments on commit 5eedd70

Please sign in to comment.