summaryrefslogtreecommitdiffstats
path: root/build.rs
blob: f29159bab6fd5f77f3061ee2b5c447bf423ec8a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std::{collections::HashMap, fs, path::Path};

fn main() -> anyhow::Result<()> {
    #[cfg(feature = "application")]
    gen_man_and_comp()?;

    Ok(())
}

/// Generate manpage and shell completions for the bat application.
#[cfg(feature = "application")]
fn gen_man_and_comp() -> anyhow::Result<()> {
    use std::{env, path::PathBuf};

    // Read environment variables.
    let project_name = env::var("PROJECT_NAME").unwrap_or("bat".into());
    let executable_name = env::var("PROJECT_EXECUTABLE").unwrap_or(project_name.clone());
    let executable_name_uppercase = executable_name.to_uppercase();
    let project_version = env::var("CARGO_PKG_VERSION")?;

    let variables = [
        ("PROJECT_NAME", project_name),
        ("PROJECT_EXECUTABLE", executable_name),
        ("PROJECT_EXECUTABLE_UPPERCASE", executable_name_uppercase),
        ("PROJECT_VERSION", project_version),
    ]
    .into_iter()
    .collect();

    let Some(out_dir) = env::var_os("BAT_ASSETS_GEN_DIR")
        .or_else(|| env::var_os("OUT_DIR"))
        .map(PathBuf::from)
    else {
        anyhow::bail!("BAT_ASSETS_GEN_DIR or OUT_DIR should be set for build.rs");
    };

    fs::create_dir_all(out_dir.join("assets/manual")).unwrap();
    fs::create_dir_all(out_dir.join("assets/completions")).unwrap();

    render_template(
        &variables,
        "assets/manual/bat.1.in",
        out_dir.join("assets/manual/bat.1"),
    )?;
    render_template(
        &variables,
        "assets/completions/bat.bash.in",
        out_dir.join("assets/completions/bat.bash"),
    )?;
    render_template(
        &variables,
        "assets/completions/bat.fish.in",
        out_dir.join("assets/completions/bat.fish"),
    )?;
    render_template(
        &variables,
        "assets/completions/_bat.ps1.in",
        out_dir.join("assets/completions/_bat.ps1"),
    )?;
    render_template(
        &variables,
        "assets/completions/bat.zsh.in",
        out_dir.join("assets/completions/bat.zsh"),
    )?;

    Ok(())
}

/// Generates a file from a template.
#[allow(dead_code)]
fn render_template(
    variables: &HashMap<&str, String>,
    in_file: &str,
    out_file: impl AsRef<Path>,
) -> anyhow::Result<()> {
    let mut content = fs::read_to_string(in_file)?;

    for (variable_name, value) in variables {
        // Replace {{variable_name}} by the value
        let pattern = format!("{{{{{variable_name}}}}}", variable_name = variable_name);
        content = content.replace(&pattern, value);
    }

    fs::write(out_file, content)?;
    Ok(())
}