Add version detection via package.json

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

@ -1,6 +1,6 @@
use std::ffi::OsString;
use consts::{DATA_DIR, VERSION_FILE_PATH};
use consts::VERSION_FILE_PATH;
use crossterm::style::Stylize;
use mapper::Mapper;
use repository::{config::Config, NodeVersion, Repository};
@ -80,5 +80,5 @@ async fn get_repository() -> Result<Repository> {
}
async fn get_mapper() -> Result<Mapper> {
Ok(Mapper::new(get_repository().await?))
Ok(Mapper::load(get_repository().await?).await)
}

@ -8,11 +8,16 @@ use crate::{
repository::{NodeVersion, Repository},
};
use self::{error::MapperError, mapped_command::MappedCommand, mapped_dir::map_node_bin};
use self::{
error::MapperError, mapped_command::MappedCommand, mapped_dir::map_node_bin,
package_info::PackageInfo,
};
pub mod error;
mod mapped_command;
mod mapped_dir;
mod package_info;
/// Responsible for mapping to node executables
/// and managing node versions
pub struct Mapper {
@ -21,9 +26,10 @@ pub struct Mapper {
}
impl Mapper {
pub fn new(repository: Repository) -> Self {
let version =
Self::get_version().unwrap_or_else(|| repository.config.default_version.to_owned());
pub async fn load(repository: Repository) -> Self {
let version = Self::get_version()
.await
.unwrap_or_else(|| repository.config.default_version.to_owned());
Self {
repo: repository,
active_version: version,
@ -77,10 +83,20 @@ impl Mapper {
Ok(())
}
fn get_version() -> Option<NodeVersion> {
env::var("NODE_VERSION")
async fn get_version() -> Option<NodeVersion> {
if let Some(version) = PackageInfo::find()
.await
.ok()
.and_then(|v| NodeVersion::from_str(&v).ok())
.and_then(|i| i)
.and_then(|i| i.engines)
.and_then(|e| e.node)
{
Some(NodeVersion::Req(version))
} else {
env::var("NODE_VERSION")
.ok()
.and_then(|v| NodeVersion::from_str(&v).ok())
}
}
/// creates wrapper scripts for the current version

@ -0,0 +1,56 @@
use std::{collections::HashMap, path::Path};
use semver::VersionReq;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tokio::fs;
use crate::error::LibResult;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PackageInfo {
pub engines: Option<EngineInfo>,
#[serde(flatten)]
other: HashMap<String, Value>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct EngineInfo {
pub node: Option<VersionReq>,
#[serde(flatten)]
other: HashMap<String, Value>,
}
impl PackageInfo {
pub async fn find() -> LibResult<Option<Self>> {
let mut dir = std::env::current_dir()?;
let file_path = dir.join("package.json");
if file_path.exists() {
let info = Self::load(&file_path).await?;
Ok(Some(info))
} else {
while let Some(parent) = dir.parent() {
dir = parent.to_owned();
let file_path = dir.join("package.json");
if file_path.exists() {
let info = Self::load(&file_path).await?;
return Ok(Some(info));
}
}
Ok(None)
}
}
/// Loads the package.json config file
pub async fn load(path: &Path) -> LibResult<Self> {
let file_content = fs::read_to_string(&path).await?;
let cfg = serde_json::from_str(&file_content)?;
Ok(cfg)
}
}
Loading…
Cancel
Save