Skip to main content

vs_config/
resolution.rs

1//! Result types and helpers for resolving active tool versions.
2
3use std::path::{Path, PathBuf};
4
5use crate::ConfigError;
6use crate::config_file::read_tool_versions;
7use crate::legacy::{find_legacy_file, read_legacy_versions};
8use crate::project::find_project_file;
9use crate::types::{ResolvedToolVersion, Scope};
10
11fn session_file(home: &Path, session_id: &str) -> PathBuf {
12    home.join("sessions").join(format!("{session_id}.toml"))
13}
14
15fn global_file(home: &Path) -> PathBuf {
16    home.join("global").join("tools.toml")
17}
18
19/// Returns the canonical global tools file path.
20pub fn global_tools_file(home: &Path) -> PathBuf {
21    global_file(home)
22}
23
24/// Returns the canonical session tools file path.
25pub fn session_tools_file(home: &Path, session_id: &str) -> PathBuf {
26    session_file(home, session_id)
27}
28
29/// Resolves a tool version using `Project > Session > Global > System` precedence.
30pub fn resolve_tool_version(
31    home: &Path,
32    cwd: &Path,
33    session_id: Option<&str>,
34    plugin: &str,
35) -> Result<Option<ResolvedToolVersion>, ConfigError> {
36    if let Some(path) = find_project_file(cwd) {
37        let versions = read_tool_versions(&path)?;
38        if let Some(version) = versions.tools.get(plugin) {
39            return Ok(Some(ResolvedToolVersion {
40                plugin: plugin.to_string(),
41                version: version.clone(),
42                scope: Scope::Project,
43                source: path,
44            }));
45        }
46    }
47
48    if let Some(path) = find_legacy_file(cwd) {
49        let versions = read_legacy_versions(&path)?;
50        if let Some(version) = versions.tools.get(plugin) {
51            return Ok(Some(ResolvedToolVersion {
52                plugin: plugin.to_string(),
53                version: version.clone(),
54                scope: Scope::Project,
55                source: path,
56            }));
57        }
58    }
59
60    if let Some(session_id) = session_id {
61        let path = session_file(home, session_id);
62        if path.exists() {
63            let versions = read_tool_versions(&path)?;
64            if let Some(version) = versions.tools.get(plugin) {
65                return Ok(Some(ResolvedToolVersion {
66                    plugin: plugin.to_string(),
67                    version: version.clone(),
68                    scope: Scope::Session,
69                    source: path,
70                }));
71            }
72        }
73    }
74
75    let path = global_file(home);
76    if path.exists() {
77        let versions = read_tool_versions(&path)?;
78        if let Some(version) = versions.tools.get(plugin) {
79            return Ok(Some(ResolvedToolVersion {
80                plugin: plugin.to_string(),
81                version: version.clone(),
82                scope: Scope::Global,
83                source: path,
84            }));
85        }
86    }
87
88    Ok(None)
89}