Skip to main content

Mountain/ProcessManagement/NodeResolver/
TryNvm.rs

1
2//! nvm lookup. `NVM_BIN` wins (set inside an nvm-sourced shell). Fallback
3//! walks `$NVM_DIR/versions/node` and picks the lexicographically largest
4//! version (rough proxy for "latest installed").
5
6use std::path::PathBuf;
7
8use crate::ProcessManagement::NodeResolver::{NodeExecutableName, NodeSource, ResolvedNode};
9
10pub fn Fn() -> Option<ResolvedNode::Struct> {
11	if let Ok(NvmBin) = std::env::var("NVM_BIN") {
12		let Candidate = PathBuf::from(NvmBin).join(NodeExecutableName::Fn());
13
14		if Candidate.exists() {
15			return Some(ResolvedNode::Struct { Path:Candidate, Source:NodeSource::Enum::Nvm });
16		}
17	}
18
19	let NvmDir = std::env::var("NVM_DIR").ok().or_else(|| {
20		std::env::var("HOME")
21			.ok()
22			.map(|H| PathBuf::from(H).join(".nvm").to_string_lossy().into_owned())
23	})?;
24
25	let VersionsDirectory = PathBuf::from(&NvmDir).join("versions").join("node");
26
27	let Entries = std::fs::read_dir(&VersionsDirectory).ok()?;
28
29	let mut BestCandidate:Option<PathBuf> = None;
30
31	for Entry in Entries.flatten() {
32		let NodePath = Entry.path().join("bin").join(NodeExecutableName::Fn());
33
34		if !NodePath.exists() {
35			continue;
36		}
37
38		BestCandidate = match BestCandidate {
39			Some(Existing) if Existing > NodePath => Some(Existing),
40
41			_ => Some(NodePath),
42		};
43	}
44
45	BestCandidate.map(|Path| ResolvedNode::Struct { Path, Source:NodeSource::Enum::Nvm })
46}