diff options
| -rw-r--r-- | mullvad-version/build.rs | 31 | ||||
| -rw-r--r-- | mullvad-version/src/lib.rs | 1 | ||||
| -rw-r--r-- | mullvad-version/src/main.rs | 235 |
3 files changed, 146 insertions, 121 deletions
diff --git a/mullvad-version/build.rs b/mullvad-version/build.rs index b2cd98db77..11a1855252 100644 --- a/mullvad-version/build.rs +++ b/mullvad-version/build.rs @@ -11,28 +11,39 @@ const GIT_HASH_DEV_SUFFIX_LEN: usize = 6; const ANDROID_VERSION_FILE_PATH: &str = "../dist-assets/android-version-name.txt"; const DESKTOP_VERSION_FILE_PATH: &str = "../dist-assets/desktop-product-version.txt"; -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] enum Target { Android, Desktop, } impl Target { - pub fn current_target() -> Self { + fn current_target() -> Result<Self, String> { println!("cargo:rerun-if-env-changed=CARGO_CFG_TARGET_OS"); - match env::var("CARGO_CFG_TARGET_OS") - .expect("CARGO_CFG_TARGET_OS should be set") - .as_str() - { - "android" => Self::Android, - "linux" | "windows" | "macos" => Self::Desktop, - target_os => panic!("Unsupported target OS: {target_os}"), + let s = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS should be set"); + match s.as_str() { + "android" => Ok(Self::Android), + "linux" | "windows" | "macos" => Ok(Self::Desktop), + _ => Err(s), } } } fn main() { - let product_version = get_product_version(Target::current_target()); + // Mark "has_version" as a conditional configuration flag + println!("cargo::rustc-check-cfg=cfg(has_version)"); + + let target = match Target::current_target() { + Ok(target) => target, + Err(other) => { + eprintln!("No version available for target {other}"); + return; + } + }; + + println!(r#"cargo::rustc-cfg=has_version"#); + + let product_version = get_product_version(target); let android_product_version = get_product_version(Target::Android); let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); diff --git a/mullvad-version/src/lib.rs b/mullvad-version/src/lib.rs index 6dd411f1be..e88cf490e1 100644 --- a/mullvad-version/src/lib.rs +++ b/mullvad-version/src/lib.rs @@ -6,6 +6,7 @@ use std::sync::LazyLock; use regex_lite::Regex; /// The Mullvad VPN app product version +#[cfg(has_version)] pub const VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/product-version.txt")); #[derive(Debug, Clone, PartialEq)] diff --git a/mullvad-version/src/main.rs b/mullvad-version/src/main.rs index 9d5cf6d152..68906e4360 100644 --- a/mullvad-version/src/main.rs +++ b/mullvad-version/src/main.rs @@ -1,134 +1,147 @@ -use mullvad_version::{PreStableType, Version}; -use std::env::VarError; -use std::{env, process::exit}; +#[cfg(has_version)] +mod inner { + use mullvad_version::{PreStableType, Version}; + use std::env::VarError; + use std::{env, process::exit}; -const ANDROID_VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/android-version-name.txt")); + const ANDROID_VERSION: &str = + include_str!(concat!(env!("OUT_DIR"), "/android-version-name.txt")); -fn main() { - let android_version_env = env::var("ANDROID_VERSION"); - if matches!(android_version_env, Err(VarError::NotUnicode(_))) { - eprintln!("ANDROID_VERSION is not valid unicode."); - exit(1); - } - let android_version = android_version_env.unwrap_or(ANDROID_VERSION.to_string()); - - let command = env::args().nth(1); - match command.as_deref() { - None => println!("{}", mullvad_version::VERSION), - Some("semver") => println!("{}", to_semver(mullvad_version::VERSION)), - Some("version.h") => println!("{}", to_windows_h_format(mullvad_version::VERSION)), - Some("versionName") => println!("{android_version}"), - Some("versionCode") => println!("{}", to_android_version_code(&android_version)), - Some(command) => { - eprintln!("Unknown command: {command}"); + pub fn main() { + let android_version_env = env::var("ANDROID_VERSION"); + if matches!(android_version_env, Err(VarError::NotUnicode(_))) { + eprintln!("ANDROID_VERSION is not valid unicode."); exit(1); } + let android_version = android_version_env.unwrap_or(ANDROID_VERSION.to_string()); + + let command = env::args().nth(1); + match command.as_deref() { + None => println!("{}", mullvad_version::VERSION), + Some("semver") => println!("{}", to_semver(mullvad_version::VERSION)), + Some("version.h") => println!("{}", to_windows_h_format(mullvad_version::VERSION)), + Some("versionName") => println!("{android_version}"), + Some("versionCode") => println!("{}", to_android_version_code(&android_version)), + Some(command) => { + eprintln!("Unknown command: {command}"); + exit(1); + } + } } -} -/// Takes a version without a patch number and adds the patch (set to zero). -/// -/// Converts `x.y[-z]` into `x.y.0[-z]` to make the version semver compatible. -fn to_semver(version: &str) -> String { - let mut parts = version.splitn(2, '-'); + /// Takes a version without a patch number and adds the patch (set to zero). + /// + /// Converts `x.y[-z]` into `x.y.0[-z]` to make the version semver compatible. + fn to_semver(version: &str) -> String { + let mut parts = version.splitn(2, '-'); - let version = parts.next().expect("Year component"); - let remainder = parts.next().map(|s| format!("-{s}")).unwrap_or_default(); - assert_eq!(parts.next(), None); + let version = parts.next().expect("Year component"); + let remainder = parts.next().map(|s| format!("-{s}")).unwrap_or_default(); + assert_eq!(parts.next(), None); - format!("{version}.0{remainder}") -} + format!("{version}.0{remainder}") + } -/// Takes a version in the normal Mullvad VPN app version format and returns the Android -/// `versionCode` formatted version. -/// -/// The format of the code is: YYVVXZZZ -/// Last two digits of the year (major)---------^^ -/// Incrementing version (minor)------------------^^ -/// Build type (0=alpha, 1=beta, 9=stable/dev)------^ -/// Build number (000 if stable/dev)-----------------^^^ -/// -/// # Examples -/// -/// Version: 2021.1-alpha1 -/// versionCode: 21010001 -/// -/// Version: 2021.34-beta5 -/// versionCode: 21341005 -/// -/// Version: 2021.34 -/// versionCode: 21349000 -/// -/// Version: 2021.34-dev -/// versionCode: 21349000 -fn to_android_version_code(version: &str) -> String { - let version: Version = version.parse().unwrap(); + /// Takes a version in the normal Mullvad VPN app version format and returns the Android + /// `versionCode` formatted version. + /// + /// The format of the code is: YYVVXZZZ + /// Last two digits of the year (major)---------^^ + /// Incrementing version (minor)------------------^^ + /// Build type (0=alpha, 1=beta, 9=stable/dev)------^ + /// Build number (000 if stable/dev)-----------------^^^ + /// + /// # Examples + /// + /// Version: 2021.1-alpha1 + /// versionCode: 21010001 + /// + /// Version: 2021.34-beta5 + /// versionCode: 21341005 + /// + /// Version: 2021.34 + /// versionCode: 21349000 + /// + /// Version: 2021.34-dev + /// versionCode: 21349000 + fn to_android_version_code(version: &str) -> String { + let version: Version = version.parse().unwrap(); - let (build_type, build_number) = if version.dev.is_some() { - ("9", "000".to_string()) - } else { - match &version.pre_stable { - Some(PreStableType::Alpha(v)) => ("0", v.to_string()), - Some(PreStableType::Beta(v)) => ("1", v.to_string()), - // Stable version - None => ("9", "000".to_string()), - } - }; + let (build_type, build_number) = if version.dev.is_some() { + ("9", "000".to_string()) + } else { + match &version.pre_stable { + Some(PreStableType::Alpha(v)) => ("0", v.to_string()), + Some(PreStableType::Beta(v)) => ("1", v.to_string()), + // Stable version + None => ("9", "000".to_string()), + } + }; - let year_last_two_digits = version.year % 100; + let year_last_two_digits = version.year % 100; - format!( - "{}{:0>2}{}{:0>3}", - year_last_two_digits, version.incremental, build_type, build_number, - ) -} + format!( + "{}{:0>2}{}{:0>3}", + year_last_two_digits, version.incremental, build_type, build_number, + ) + } -fn to_windows_h_format(version_str: &str) -> String { - let version = version_str.parse().unwrap(); + fn to_windows_h_format(version_str: &str) -> String { + let version = version_str.parse().unwrap(); - let Version { - year, incremental, .. - } = version; + let Version { + year, incremental, .. + } = version; - format!( - "#define MAJOR_VERSION {year} -#define MINOR_VERSION {incremental} -#define PATCH_VERSION 0 -#define PRODUCT_VERSION \"{version_str}\"" - ) -} + format!( + "#define MAJOR_VERSION {year} + #define MINOR_VERSION {incremental} + #define PATCH_VERSION 0 + #define PRODUCT_VERSION \"{version_str}\"" + ) + } -#[cfg(test)] -mod tests { - use super::*; + #[cfg(test)] + mod tests { + use super::*; - #[test] - fn test_version_code() { - assert_eq!("21349000", to_android_version_code("2021.34")); - } + #[test] + fn test_version_code() { + assert_eq!("21349000", to_android_version_code("2021.34")); + } - #[test] - fn test_version_code_alpha() { - assert_eq!("21010001", to_android_version_code("2021.1-alpha1")); - } + #[test] + fn test_version_code_alpha() { + assert_eq!("21010001", to_android_version_code("2021.1-alpha1")); + } - #[test] - fn test_version_code_beta() { - assert_eq!("21341005", to_android_version_code("2021.34-beta5")); - } + #[test] + fn test_version_code_beta() { + assert_eq!("21341005", to_android_version_code("2021.34-beta5")); + } - #[test] - fn test_version_code_dev() { - assert_eq!("21349000", to_android_version_code("2021.34-dev-be846a5f0")); - } + #[test] + fn test_version_code_dev() { + assert_eq!("21349000", to_android_version_code("2021.34-dev-be846a5f0")); + } - #[test] - fn test_windows_version_h() { - let version_h = to_windows_h_format("2025.4-beta2-dev-abcdef"); - let expected_version_h = "#define MAJOR_VERSION 2025 -#define MINOR_VERSION 4 -#define PATCH_VERSION 0 -#define PRODUCT_VERSION \"2025.4-beta2-dev-abcdef\""; - assert_eq!(expected_version_h, version_h); + #[test] + fn test_windows_version_h() { + let version_h = to_windows_h_format("2025.4-beta2-dev-abcdef"); + let expected_version_h = "#define MAJOR_VERSION 2025 + #define MINOR_VERSION 4 + #define PATCH_VERSION 0 + #define PRODUCT_VERSION \"2025.4-beta2-dev-abcdef\""; + assert_eq!(expected_version_h, version_h); + } } } + +#[cfg(not(has_version))] +mod inner { + pub fn main() {} +} + +fn main() { + inner::main(); +} |
