Improve local version caching and error messages

main
trivernis 1 year ago
parent ea64470f69
commit 8bb500d1a3
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -19,8 +19,14 @@ pub struct VersionError {
impl VersionError {
pub fn new<S1: ToString, S2: ToString>(src: S1, detail: S2) -> Self {
let src = src.to_string();
let pos = (0, src.len()).into();
let mut src = src.to_string();
let mut pos = (0, src.len()).into();
let clean_src = src.trim_start_matches('^');
if let Some((arg_str, arg_pos)) = find_in_args(&clean_src) {
pos = arg_pos;
src = arg_str;
}
Self {
src,
@ -40,6 +46,13 @@ impl VersionError {
pub fn not_installed<S: ToString>(src: S) -> Self {
Self::new(src, "The version is not installed.")
}
pub fn unsupported<S: ToString>(src: S) -> Self {
Self::new(
src,
"This type of version string is not supported with this operation.",
)
}
}
#[derive(Debug, Error, Diagnostic)]
@ -132,14 +145,18 @@ pub struct CommandNotFoundError {
impl CommandNotFoundError {
pub fn new(command: String, args: Vec<OsString>, path: PathBuf) -> Self {
let pos = (0, command.len()).into();
let full_command = format!(
"{command} {}",
args.into_iter()
.map(|a| a.into_string().unwrap_or_default())
.collect::<Vec<_>>()
.join(" ")
);
let (full_command, pos) = find_in_args(&command).unwrap_or_else(|| {
let pos = (0, command.len()).into();
let full_command = format!(
"{command} {}",
args.into_iter()
.map(|a| a.into_string().unwrap_or_default())
.collect::<Vec<_>>()
.join(" ")
);
(full_command, pos)
});
Self {
command,
full_command,
@ -161,3 +178,11 @@ pub struct MapDirError {
#[source]
pub caused_by: std::io::Error,
}
pub fn find_in_args(query: &str) -> Option<(String, SourceSpan)> {
let args_string = std::env::args().fold(String::new(), |s, acc| format!("{s} {acc}"));
args_string
.find(&query)
.map(|index| (args_string, (index, query.len()).into()))
}

@ -64,6 +64,8 @@ impl Nenv {
#[tracing::instrument(skip(self))]
pub async fn uninstall(&mut self, version: NodeVersion) -> Result<()> {
self.repo.lookup_local_version(&version)?;
if prompt(
false,
format!(
@ -237,7 +239,8 @@ impl Nenv {
async fn get_mapper(&mut self) -> Result<Mapper> {
let node_path = self
.repo
.get_version_path(&self.active_version)?
.get_version_path(&self.active_version)
.await?
.ok_or_else(|| VersionError::not_installed(self.active_version.to_owned()))?;
Ok(Mapper::new(node_path))
}

@ -66,18 +66,6 @@ impl InstalledVersions {
self.ordered_versions.iter().map(|(v, _)| v).collect()
}
pub fn latest(&self) -> Option<&VersionMetadata> {
self.ordered_versions.last().map(|(_, m)| m)
}
pub fn latest_lts(&self) -> Option<&VersionMetadata> {
self.ordered_versions
.iter()
.filter(|(_, m)| m.lts.is_some())
.last()
.map(|(_, m)| m)
}
pub fn lts<S: AsRef<str>>(&self, lts: S) -> Option<&VersionMetadata> {
self.ordered_versions
.iter()

@ -149,8 +149,12 @@ impl Repository {
/// Returns the path for the given node version
#[tracing::instrument(level = "debug", skip(self))]
pub fn get_version_path(&mut self, version: &NodeVersion) -> Result<Option<NodePath>> {
let info = self.lookup_local_version(version)?;
pub async fn get_version_path(&mut self, version: &NodeVersion) -> Result<Option<NodePath>> {
let info = if let Ok(i) = self.lookup_local_version(version) {
i
} else {
self.lookup_remote_version(version).await?
};
let path = build_version_path(&info.version);
Ok(if path.exists() {
@ -239,18 +243,13 @@ impl Repository {
pub fn lookup_local_version(&self, version_req: &NodeVersion) -> Result<&VersionMetadata> {
let versions = &self.installed_versions;
let version = match version_req {
NodeVersion::Latest => versions
.latest()
.ok_or_else(|| VersionError::not_installed("latest"))?,
NodeVersion::LatestLts => versions
.latest_lts()
.ok_or_else(|| VersionError::not_installed("lts"))?,
NodeVersion::Lts(lts) => versions
.lts(lts)
.ok_or_else(|| VersionError::unknown_version(lts.to_owned()))?,
NodeVersion::Req(req) => versions
.fulfilling(req)
.ok_or_else(|| VersionError::unfulfillable_version(req.to_owned()))?,
_ => return Err(VersionError::unsupported(version_req.to_owned()).into()),
};
Ok(version)

Loading…
Cancel
Save