vx_tool_uv/
config.rs

1//! UV installation configuration
2//!
3//! This module provides UV-specific installation configuration,
4//! including URL building, platform detection, and installation methods.
5
6use std::path::PathBuf;
7use vx_installer::{ArchiveFormat, InstallConfig, InstallMethod};
8use vx_tool_standard::{StandardToolConfig, StandardUrlBuilder, ToolDependency};
9
10/// Standard configuration for UV tool
11pub struct Config;
12
13/// UV URL builder for consistent download URL generation
14#[derive(Debug, Clone)]
15pub struct UvUrlBuilder;
16
17impl Default for UvUrlBuilder {
18    fn default() -> Self {
19        Self::new()
20    }
21}
22
23impl UvUrlBuilder {
24    pub fn new() -> Self {
25        Self
26    }
27}
28
29impl StandardUrlBuilder for UvUrlBuilder {
30    /// Generate download URL for UV version
31    fn download_url(version: &str) -> Option<String> {
32        let filename = Self::get_filename(version);
33
34        Some(format!(
35            "https://github.com/astral-sh/uv/releases/download/{}/{}",
36            version, filename
37        ))
38    }
39
40    /// Get platform-specific filename
41    fn get_filename(version: &str) -> String {
42        let platform = Self::get_platform_string();
43        if cfg!(windows) {
44            format!("uv-{}-{}.zip", platform, version)
45        } else {
46            format!("uv-{}-{}.tar.gz", platform, version)
47        }
48    }
49
50    /// Get platform string for downloads
51    fn get_platform_string() -> String {
52        if cfg!(target_os = "windows") {
53            if cfg!(target_arch = "x86_64") {
54                "x86_64-pc-windows-msvc".to_string()
55            } else if cfg!(target_arch = "x86") {
56                "i686-pc-windows-msvc".to_string()
57            } else {
58                "unknown-pc-windows-msvc".to_string()
59            }
60        } else if cfg!(target_os = "macos") {
61            if cfg!(target_arch = "x86_64") {
62                "x86_64-apple-darwin".to_string()
63            } else if cfg!(target_arch = "aarch64") {
64                "aarch64-apple-darwin".to_string()
65            } else {
66                "unknown-apple-darwin".to_string()
67            }
68        } else if cfg!(target_os = "linux") {
69            if cfg!(target_arch = "x86_64") {
70                "x86_64-unknown-linux-gnu".to_string()
71            } else if cfg!(target_arch = "aarch64") {
72                "aarch64-unknown-linux-gnu".to_string()
73            } else {
74                "unknown-unknown-linux-gnu".to_string()
75            }
76        } else {
77            "unknown".to_string()
78        }
79    }
80}
81
82impl StandardToolConfig for Config {
83    fn tool_name() -> &'static str {
84        "uv"
85    }
86
87    fn create_install_config(version: &str, install_dir: PathBuf) -> InstallConfig {
88        create_install_config(version, install_dir)
89    }
90
91    fn get_install_methods() -> Vec<String> {
92        vec!["archive".to_string(), "binary".to_string()]
93    }
94
95    fn supports_auto_install() -> bool {
96        true
97    }
98
99    fn get_manual_instructions() -> String {
100        "Visit https://docs.astral.sh/uv/getting-started/installation/ to install UV manually"
101            .to_string()
102    }
103
104    fn get_dependencies() -> Vec<ToolDependency> {
105        vec![]
106    }
107
108    fn get_default_version() -> &'static str {
109        "latest"
110    }
111}
112
113/// Create installation configuration for UV
114pub fn create_install_config(version: &str, install_dir: PathBuf) -> InstallConfig {
115    let download_url = UvUrlBuilder::download_url(version);
116
117    InstallConfig::builder()
118        .tool_name(Config::tool_name())
119        .version(version)
120        .download_url(download_url.unwrap_or_default())
121        .install_method(InstallMethod::Archive {
122            format: if cfg!(windows) {
123                ArchiveFormat::Zip
124            } else {
125                ArchiveFormat::TarGz
126            },
127        })
128        .install_dir(install_dir)
129        .build()
130}
131
132#[cfg(test)]
133mod tests {
134    use super::*;
135
136    #[test]
137    fn test_uv_url_builder() {
138        let url = UvUrlBuilder::download_url("0.1.0");
139        assert!(url.is_some());
140        assert!(url.unwrap().contains("github.com"));
141    }
142
143    #[test]
144    fn test_platform_string() {
145        let platform = UvUrlBuilder::get_platform_string();
146        assert!(!platform.is_empty());
147    }
148
149    #[test]
150    fn test_create_install_config() {
151        let config = create_install_config("0.1.0", PathBuf::from("/tmp/uv"));
152        assert_eq!(config.tool_name, "uv");
153        assert_eq!(config.version, "0.1.0");
154        assert!(config.download_url.is_some());
155    }
156}