Skip to main content

vx_tool_pnpm/
config.rs

1//! PNPM package manager configuration
2//!
3//! This module provides PNPM-specific configuration,
4//! including dependencies and installation methods.
5
6use std::path::PathBuf;
7use vx_installer::{InstallConfig, InstallMethod};
8use vx_tool_standard::{StandardToolConfig, StandardUrlBuilder, ToolDependency};
9
10/// Standard configuration for PNPM tool
11pub struct Config;
12
13/// PNPM URL builder for consistent download URL generation
14pub struct PnpmUrlBuilder;
15
16impl StandardUrlBuilder for PnpmUrlBuilder {
17    /// Generate download URL for PNPM version
18    fn download_url(version: &str) -> Option<String> {
19        let _platform = Self::get_platform_string();
20        let filename = Self::get_filename(version);
21
22        Some(format!(
23            "https://github.com/pnpm/pnpm/releases/download/v{}/{}",
24            version, filename
25        ))
26    }
27
28    /// Get platform-specific filename
29    fn get_filename(version: &str) -> String {
30        let platform = Self::get_platform_string();
31        if cfg!(windows) {
32            format!("pnpm-{}-{}.exe", platform, version)
33        } else {
34            format!("pnpm-{}-{}", platform, version)
35        }
36    }
37
38    /// Get platform string for PNPM downloads
39    fn get_platform_string() -> String {
40        match (std::env::consts::OS, std::env::consts::ARCH) {
41            ("windows", "x86_64") => "win-x64".to_string(),
42            ("windows", "aarch64") => "win-arm64".to_string(),
43            ("macos", "x86_64") => "macos-x64".to_string(),
44            ("macos", "aarch64") => "macos-arm64".to_string(),
45            ("linux", "x86_64") => "linux-x64".to_string(),
46            ("linux", "aarch64") => "linux-arm64".to_string(),
47            _ => "linux-x64".to_string(), // Default fallback
48        }
49    }
50}
51
52/// Implementation of standard tool configuration for PNPM
53impl StandardToolConfig for Config {
54    fn tool_name() -> &'static str {
55        "pnpm"
56    }
57
58    fn create_install_config(version: &str, install_dir: PathBuf) -> InstallConfig {
59        create_install_config(version, install_dir)
60    }
61
62    fn get_install_methods() -> Vec<String> {
63        get_install_methods()
64    }
65
66    fn supports_auto_install() -> bool {
67        true
68    }
69
70    fn get_manual_instructions() -> String {
71        get_manual_instructions()
72    }
73
74    fn get_dependencies() -> Vec<ToolDependency> {
75        vec![
76            ToolDependency::required("node", "PNPM requires Node.js runtime")
77                .with_version(">=16.14.0"),
78        ]
79    }
80
81    fn get_default_version() -> &'static str {
82        "latest"
83    }
84}
85
86/// Create PNPM installation configuration
87pub fn create_install_config(version: &str, install_dir: PathBuf) -> InstallConfig {
88    let actual_version = if version == "latest" {
89        "8.15.0" // Default to stable version
90    } else {
91        version
92    };
93
94    let download_url = PnpmUrlBuilder::download_url(actual_version);
95    let install_method = InstallMethod::Binary;
96
97    InstallConfig::builder()
98        .tool_name("pnpm")
99        .version(version.to_string())
100        .install_method(install_method)
101        .download_url(download_url.unwrap_or_default())
102        .install_dir(install_dir)
103        .build()
104}
105
106/// Get available PNPM installation methods
107pub fn get_install_methods() -> Vec<String> {
108    vec![
109        "GitHub releases (recommended)".to_string(),
110        "NPM global install".to_string(),
111        if cfg!(target_os = "macos") {
112            "Homebrew".to_string()
113        } else {
114            "Package manager".to_string()
115        },
116    ]
117}
118
119/// Check if PNPM supports automatic installation
120pub fn supports_auto_install() -> bool {
121    true
122}
123
124/// Get manual installation instructions for PNPM
125pub fn get_manual_instructions() -> String {
126    "To install PNPM manually:\n\
127     • npm install -g pnpm\n\
128     • Or visit: https://pnpm.io/installation\n\
129     • Requires Node.js >=16.14.0"
130        .to_string()
131}
132
133#[cfg(test)]
134mod tests {
135    use super::*;
136
137    #[test]
138    fn test_pnpm_dependencies() {
139        let deps = Config::get_dependencies();
140        assert_eq!(deps.len(), 1);
141        assert_eq!(deps[0].tool_name, "node");
142        assert!(deps[0].required);
143        assert_eq!(deps[0].version_requirement, Some(">=16.14.0".to_string()));
144    }
145
146    #[test]
147    fn test_pnpm_config() {
148        assert_eq!(Config::tool_name(), "pnpm");
149        assert!(Config::supports_auto_install());
150        assert_eq!(Config::get_default_version(), "latest");
151    }
152
153    #[test]
154    fn test_pnpm_url_builder() {
155        let url = PnpmUrlBuilder::download_url("8.15.0");
156        assert!(url.is_some());
157        assert!(url.unwrap().contains("github.com/pnpm/pnpm"));
158    }
159
160    #[test]
161    fn test_create_install_config() {
162        let config = create_install_config("latest", PathBuf::from("/tmp/pnpm"));
163        assert_eq!(config.tool_name, "pnpm");
164        assert_eq!(config.version, "latest");
165    }
166}