Improve performance

feature/lookup-installed
trivernis 1 year ago
parent 8d304a7169
commit 1a3811d81b
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -19,7 +19,7 @@ pub async fn install_version(version: NodeVersion) -> Result<()> {
fs::remove_file(&*VERSION_FILE_PATH).await?;
let repo = get_repository().await?;
if repo.is_installed(&version).await? {
if repo.is_installed(&version) {
if !Confirm::new()
.with_prompt("The version {version} is already installed. Reinstall?")
.default(false)
@ -38,7 +38,7 @@ pub async fn install_version(version: NodeVersion) -> Result<()> {
pub async fn set_default_version(version: NodeVersion) -> Result<()> {
let mut mapper = get_mapper().await?;
if !mapper.repository().is_installed(&version).await?
if !mapper.repository().is_installed(&version)
&& Confirm::new()
.with_prompt(format!(
"The version {version} is not installed. Do you want to install it?"
@ -56,11 +56,12 @@ pub async fn set_default_version(version: NodeVersion) -> Result<()> {
Ok(())
}
#[inline]
pub async fn exec(command: String, args: Vec<OsString>) -> Result<i32> {
let mapper = get_mapper().await?;
let active_version = mapper.active_version();
if !mapper.repository().is_installed(active_version).await? {
if !mapper.repository().is_installed(active_version) {
mapper.repository().install_version(&active_version).await?;
}
let exit_status = mapper.exec(command, args).await?;

@ -9,6 +9,7 @@ mod args;
async fn main() -> nenv::error::Result<()> {
color_eyre::install().unwrap();
let args: Args = Args::parse();
match args.commmand {
args::Command::Version => Ok(print_version()),
args::Command::Install(v) => nenv::install_version(v.version).await,

@ -58,11 +58,9 @@ impl Mapper {
/// Executes a mapped command with the given node environment
pub async fn exec(&self, command: String, args: Vec<OsString>) -> LibResult<ExitStatus> {
self.map_active_version().await?;
let node_path = self
.repo
.get_version_path(&self.active_version)
.await?
.expect("version not installed");
let executable = node_path.bin().join(command);
let exit_status = MappedCommand::new(executable, args)
@ -104,7 +102,6 @@ impl Mapper {
let dir = self
.repo
.get_version_path(&self.active_version)
.await?
.expect("missing version");
map_node_bin(dir).await?;

@ -90,15 +90,7 @@ impl Repository {
pub async fn init(config: Config) -> LibResult<Self> {
Self::create_folders().await?;
let web_api = WebApi::new(&config.dist_base_url);
let versions = if let Some(v) = Versions::load().await {
v
} else {
let all_versions = web_api.get_versions().await?;
let v = Versions::new(all_versions);
v.save().await?;
v
};
let versions = load_versions(&web_api).await?;
Ok(Self {
config,
@ -125,24 +117,15 @@ impl Repository {
}
/// Returns the path for the given node version
pub async fn get_version_path(&self, version: &NodeVersion) -> LibResult<Option<NodePath>> {
pub fn get_version_path(&self, version: &NodeVersion) -> Option<NodePath> {
let info = self.parse_req(&version);
let mut iter = fs::read_dir(&*NODE_VERSIONS_DIR).await?;
let mut path = None;
let path = build_version_path(&info.version);
while let Some(entry) = iter.next_entry().await? {
if let Ok(version) = Version::parse(entry.file_name().to_string_lossy().as_ref()) {
if version == info.version {
path = Some(entry.path());
}
};
if path.exists() {
Some(NodePath::new(path))
} else {
None
}
let Some(path) = path else {
return Ok(None);
};
let path = path.join(format!("node-v{}-{}-{}", info.version, OS, ARCH));
Ok(Some(NodePath::new(path)))
}
/// Returns a list of installed versions
@ -160,10 +143,10 @@ impl Repository {
}
/// Returns if the given version is installed
pub async fn is_installed(&self, version: &NodeVersion) -> LibResult<bool> {
pub fn is_installed(&self, version: &NodeVersion) -> bool {
let info = self.parse_req(version);
Ok(self.installed_versions().await?.contains(&info.version))
build_version_path(&info.version).exists()
}
/// Installs a specified node version
@ -208,3 +191,22 @@ impl Repository {
}
}
}
#[inline]
async fn load_versions(web_api: &WebApi) -> Result<Versions, crate::error::Error> {
let versions = if let Some(v) = Versions::load().await {
v
} else {
let all_versions = web_api.get_versions().await?;
let v = Versions::new(all_versions);
v.save().await?;
v
};
Ok(versions)
}
fn build_version_path(version: &Version) -> PathBuf {
NODE_VERSIONS_DIR
.join(version.to_string())
.join(format!("node-v{}-{}-{}", version, OS, ARCH))
}

@ -10,6 +10,7 @@ use crate::{consts::VERSION_FILE_PATH, error::LibResult, web_api::VersionInfo};
pub struct Versions {
lts_versions: HashMap<String, VersionReq>,
versions: HashMap<Version, VersionInfo>,
sorted_versions: Vec<Version>,
}
impl Versions {
@ -35,6 +36,12 @@ impl Versions {
))
})
.collect::<HashMap<_, _>>();
let mut sorted_versions = all_versions
.iter()
.map(|v| v.version.to_owned())
.collect::<Vec<_>>();
sorted_versions.sort();
let versions = all_versions
.into_iter()
.map(|v| (v.version.to_owned(), v))
@ -43,6 +50,7 @@ impl Versions {
Self {
lts_versions,
versions,
sorted_versions,
}
}
@ -55,11 +63,8 @@ impl Versions {
/// Returns the latest known node version
pub fn latest(&self) -> &VersionInfo {
let mut versions = self.versions.keys().collect::<Vec<_>>();
versions.sort();
self.versions
.get(versions.last().expect("No known node versions"))
.get(self.sorted_versions.last().expect("No known node versions"))
.unwrap()
}
@ -82,13 +87,12 @@ impl Versions {
/// Returns any version that fulfills the given requirement
pub fn get_fulfilling(&self, req: &VersionReq) -> Option<&VersionInfo> {
let mut versions = self
.versions
.keys()
let fulfilling_versions = self
.sorted_versions
.iter()
.filter(|v| req.matches(v))
.collect::<Vec<_>>();
versions.sort();
self.versions.get(versions.last()?)
self.versions.get(fulfilling_versions.last()?)
}
}

@ -3,7 +3,10 @@ use std::{
fmt::{Debug, Display},
};
use crate::{consts::NODE_ARCHIVE_SUFFIX, utils::progress_bar};
use crate::{
consts::{NODE_ARCHIVE_SUFFIX, NODE_DIST_URL},
utils::progress_bar,
};
use self::error::{ApiError, ApiResult};
@ -26,7 +29,7 @@ pub struct WebApi {
impl Default for WebApi {
fn default() -> Self {
Self::new("https://nodejs.org/dist")
Self::new(NODE_DIST_URL)
}
}

Loading…
Cancel
Save