use crate::cli::args::BackendArg;
use crate::config::SETTINGS;
use crate::http::HTTP_FETCH;
use crate::plugins::core::CORE_PLUGINS;
use crate::registry::REGISTRY;
use crate::{http, registry};
use std::collections::HashSet;
use std::sync::LazyLock as Lazy;
use url::Url;
static PLUGINS_USE_VERSION_HOST: Lazy<HashSet<&str>> = Lazy::new(|| {
CORE_PLUGINS
.iter()
.map(|(name, _)| name.as_str())
.chain(REGISTRY.keys().copied())
.filter(|name| !matches!(*name, "java" | "python"))
.collect()
});
pub fn list_versions(ba: &BackendArg) -> eyre::Result<Option<Vec<String>>> {
if !SETTINGS.use_versions_host
|| ba.short.contains(':')
|| !PLUGINS_USE_VERSION_HOST.contains(ba.short.as_str())
{
return Ok(None);
}
if let Some(plugin) = ba.backend()?.plugin() {
if let Ok(Some(remote_url)) = plugin.get_remote_url() {
let normalized_remote = normalize_remote(&remote_url).unwrap_or("INVALID_URL".into());
let shorthand_remote = REGISTRY
.get(plugin.name())
.and_then(|rt| rt.backends().first().map(|b| registry::full_to_url(b)))
.unwrap_or_default();
if normalized_remote != normalize_remote(&shorthand_remote).unwrap_or_default() {
trace!(
"Skipping versions host check for {} because it has a non-default remote",
ba.short
);
return Ok(None);
}
}
}
let response = match SETTINGS.paranoid {
true => HTTP_FETCH.get_text(format!("https://mise-versions.jdx.dev/{}", &ba.short)),
false => HTTP_FETCH.get_text(format!("http://mise-versions.jdx.dev/{}", &ba.short)),
};
let versions =
match response {
Err(err) if http::error_code(&err) == Some(404) => return Ok(None),
res => res?,
};
let versions = versions
.lines()
.map(|v| v.trim().to_string())
.filter(|v| !v.is_empty())
.collect::<Vec<String>>();
trace!(
"got {} {} versions from versions host",
versions.len(),
&ba.short
);
match versions.is_empty() {
true => Ok(None),
false => Ok(Some(versions)),
}
}
fn normalize_remote(remote: &str) -> eyre::Result<String> {
let url = Url::parse(remote)?;
let host = url.host_str().unwrap();
let path = url.path().trim_end_matches(".git");
Ok(format!("{host}{path}"))
}