Merge branch 'feature/lookup-installed'

main
trivernis 2 years ago
commit 91f5570032
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -19,8 +19,14 @@ pub struct VersionError {
impl VersionError { impl VersionError {
pub fn new<S1: ToString, S2: ToString>(src: S1, detail: S2) -> Self { pub fn new<S1: ToString, S2: ToString>(src: S1, detail: S2) -> Self {
let src = src.to_string(); let mut src = src.to_string();
let pos = (0, src.len()).into(); 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 { Self {
src, src,
@ -40,6 +46,13 @@ impl VersionError {
pub fn not_installed<S: ToString>(src: S) -> Self { pub fn not_installed<S: ToString>(src: S) -> Self {
Self::new(src, "The version is not installed.") 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)] #[derive(Debug, Error, Diagnostic)]
@ -132,14 +145,18 @@ pub struct CommandNotFoundError {
impl CommandNotFoundError { impl CommandNotFoundError {
pub fn new(command: String, args: Vec<OsString>, path: PathBuf) -> Self { pub fn new(command: String, args: Vec<OsString>, path: PathBuf) -> Self {
let pos = (0, command.len()).into(); let (full_command, pos) = find_in_args(&command).unwrap_or_else(|| {
let full_command = format!( let pos = (0, command.len()).into();
"{command} {}", let full_command = format!(
args.into_iter() "{command} {}",
.map(|a| a.into_string().unwrap_or_default()) args.into_iter()
.collect::<Vec<_>>() .map(|a| a.into_string().unwrap_or_default())
.join(" ") .collect::<Vec<_>>()
); .join(" ")
);
(full_command, pos)
});
Self { Self {
command, command,
full_command, full_command,
@ -161,3 +178,11 @@ pub struct MapDirError {
#[source] #[source]
pub caused_by: std::io::Error, 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()))
}

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

@ -66,18 +66,6 @@ impl InstalledVersions {
self.ordered_versions.iter().map(|(v, _)| v).collect() 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> { pub fn lts<S: AsRef<str>>(&self, lts: S) -> Option<&VersionMetadata> {
self.ordered_versions self.ordered_versions
.iter() .iter()

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

Loading…
Cancel
Save