Skip to main content

gitversion_rs/output/
generator.rs

1//! Output formatters: JSON, dotenv, single variable, format string, AssemblyInfo.
2//!
3//! Corresponds to `GitVersion.Output/OutputGenerator` in the original.
4
5use super::variables::VersionVariables;
6use anyhow::{bail, Result};
7use regex::Regex;
8use rust_i18n::t;
9
10/// JSON output (PascalCase keys matching the original, pretty-printed).
11pub fn to_json(vars: &VersionVariables) -> Result<String> {
12    Ok(serde_json::to_string_pretty(vars)?)
13}
14
15/// dotenv output: `GitVersion_Major='1'` format.
16pub fn to_dotenv(vars: &VersionVariables) -> String {
17    let mut out = String::new();
18    for (k, v) in vars.to_map() {
19        out.push_str(&format!("GitVersion_{k}='{v}'\n"));
20    }
21    out
22}
23
24/// Output a single variable value. Returns an error if the variable does not exist.
25pub fn show_variable(vars: &VersionVariables, name: &str) -> Result<String> {
26    let map = vars.to_map();
27    match map.get(name) {
28        Some(v) => Ok(v.clone()),
29        None => {
30            let known: Vec<_> = map.keys().cloned().collect();
31            bail!(
32                "{}",
33                t!(
34                    "output.unknown_variable",
35                    name = name,
36                    known = known.join(", ")
37                )
38            )
39        }
40    }
41}
42
43/// Substitute `{Variable}` tokens in a format string. `{env:VAR}` is also supported.
44pub fn format_template(vars: &VersionVariables, template: &str) -> Result<String> {
45    let map = vars.to_map();
46    let re = Regex::new(r"\{(?<token>[A-Za-z0-9_:]+)\}").unwrap();
47    let mut missing: Option<String> = None;
48    let result = re
49        .replace_all(template, |caps: &regex::Captures| {
50            let token = &caps["token"];
51            if let Some(env_var) = token.strip_prefix("env:") {
52                std::env::var(env_var).unwrap_or_default()
53            } else if let Some(v) = map.get(token) {
54                v.clone()
55            } else {
56                missing.get_or_insert_with(|| token.to_string());
57                String::new()
58            }
59        })
60        .into_owned();
61    if let Some(m) = missing {
62        bail!("{}", t!("output.unknown_token", token = m));
63    }
64    Ok(result)
65}
66
67/// Environment-variable export lines for build servers (GitHub Actions and similar).
68pub fn to_buildserver_env(vars: &VersionVariables) -> String {
69    let mut out = String::new();
70    for (k, v) in vars.to_map() {
71        out.push_str(&format!("GitVersion_{k}={v}\n"));
72    }
73    out
74}