Skip to main content

changepacks_java/
version_updater.rs

1use regex::Regex;
2use std::sync::LazyLock;
3
4static KTS_SIMPLE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
5    Regex::new(r#"(?m)^(version\s*=\s*)"[^"]+""#).expect("hardcoded regex must compile")
6});
7
8static KTS_FALLBACK_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
9    Regex::new(r#"(?m)^(version\s*=\s*project\.findProperty\([^)]+\)\s*\?:\s*)"[^"]+""#)
10        .expect("hardcoded regex must compile")
11});
12
13/// Update version in build.gradle.kts content
14#[must_use]
15pub fn update_version_in_kts(content: &str, new_version: &str) -> String {
16    // Pattern 1: version = "1.0.0"
17    if KTS_SIMPLE_PATTERN.is_match(content) {
18        return KTS_SIMPLE_PATTERN
19            .replace(content, format!(r#"${{1}}"{new_version}""#))
20            .to_string();
21    }
22
23    // Pattern 2: version = project.findProperty("...") ?: "1.0.0"
24    if KTS_FALLBACK_PATTERN.is_match(content) {
25        return KTS_FALLBACK_PATTERN
26            .replace(content, format!(r#"${{1}}"{new_version}""#))
27            .to_string();
28    }
29
30    content.to_string()
31}
32
33static GROOVY_ASSIGN_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
34    Regex::new(r#"(?m)^(version\s*=\s*)['"][^'"]+['"]"#).expect("hardcoded regex must compile")
35});
36
37static GROOVY_SPACE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
38    Regex::new(r#"(?m)^(version\s+)['"][^'"]+['"]"#).expect("hardcoded regex must compile")
39});
40
41/// Update version in build.gradle (Groovy) content
42#[must_use]
43pub fn update_version_in_groovy(content: &str, new_version: &str) -> String {
44    // Pattern 1: version = '1.0.0' or version = "1.0.0"
45    if GROOVY_ASSIGN_PATTERN.is_match(content) {
46        return GROOVY_ASSIGN_PATTERN
47            .replace(content, format!(r"${{1}}'{new_version}'"))
48            .to_string();
49    }
50
51    // Pattern 2: version '1.0.0' or version "1.0.0"
52    if GROOVY_SPACE_PATTERN.is_match(content) {
53        return GROOVY_SPACE_PATTERN
54            .replace(content, format!(r"${{1}}'{new_version}'"))
55            .to_string();
56    }
57
58    content.to_string()
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn test_update_version_in_kts_simple() {
67        let content = r#"
68plugins {
69    id("java")
70}
71
72group = "com.example"
73version = "1.0.0"
74"#;
75        let updated = update_version_in_kts(content, "1.0.1");
76        assert!(updated.contains(r#"version = "1.0.1""#));
77    }
78
79    #[test]
80    fn test_update_version_in_kts_with_fallback() {
81        let content = r#"
82group = "com.devfive"
83version = project.findProperty("releaseVersion") ?: "1.0.11"
84"#;
85        let updated = update_version_in_kts(content, "1.0.12");
86        assert!(
87            updated.contains(r#"version = project.findProperty("releaseVersion") ?: "1.0.12""#)
88        );
89    }
90
91    #[test]
92    fn test_update_version_in_groovy_assign() {
93        let content = r#"
94group = 'com.example'
95version = '2.0.0'
96"#;
97        let updated = update_version_in_groovy(content, "2.0.1");
98        assert!(updated.contains("version = '2.0.1'"));
99    }
100
101    #[test]
102    fn test_update_version_in_groovy_space() {
103        let content = r#"
104group = 'com.example'
105version '3.0.0'
106"#;
107        let updated = update_version_in_groovy(content, "3.0.1");
108        assert!(updated.contains("version '3.0.1'"));
109    }
110
111    #[test]
112    fn test_update_version_in_kts_no_match() {
113        let content = r#"
114plugins {
115    id("java")
116}
117
118group = "com.example"
119"#;
120        let result = update_version_in_kts(content, "2.0.0");
121        assert_eq!(result, content);
122    }
123
124    #[test]
125    fn test_update_version_in_groovy_no_match() {
126        let content = r#"
127plugins {
128    id 'java'
129}
130
131group = 'com.example'
132"#;
133        let result = update_version_in_groovy(content, "2.0.0");
134        assert_eq!(result, content);
135    }
136}