forked from Timi16/soroban-debugger
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.rs
More file actions
123 lines (103 loc) · 3.5 KB
/
build.rs
File metadata and controls
123 lines (103 loc) · 3.5 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use clap::CommandFactory;
use std::fs;
use std::io;
use std::path::Path;
use std::process::Command;
use std::time::{SystemTime, UNIX_EPOCH};
// Mock crate root modules that src/cli/args.rs depends on
#[allow(dead_code)]
mod config {
pub struct Config {
pub debug: DebugConfig,
pub output: OutputConfig,
}
pub struct DebugConfig {
pub breakpoints: Vec<String>,
pub verbosity: Option<u8>,
}
pub struct OutputConfig {
pub format: Option<String>,
pub show_events: Option<bool>,
}
}
#[allow(dead_code)]
#[path = "src/cli/args.rs"]
mod args;
use args::Cli;
fn main() -> std::io::Result<()> {
emit_build_metadata();
generate_man_pages()?;
println!("cargo:rerun-if-changed=.git/HEAD");
println!("cargo:rerun-if-changed=src/cli/args.rs");
println!("cargo:rerun-if-changed=build.rs");
Ok(())
}
fn emit_build_metadata() {
let git_hash = command_stdout("git", &["rev-parse", "--short", "HEAD"])
.unwrap_or_else(|| "unknown".to_string());
let rustc_version =
command_stdout("rustc", &["--version"]).unwrap_or_else(|| "unknown".to_string());
let build_date = SystemTime::now()
.duration_since(UNIX_EPOCH)
.ok()
.map(|d| d.as_secs())
.unwrap_or(0);
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
println!("cargo:rustc-env=RUSTC_VERSION={}", rustc_version);
println!("cargo:rustc-env=BUILD_DATE={}", build_date);
println!("cargo:rerun-if-changed=.git/HEAD");
}
fn command_stdout(program: &str, args: &[&str]) -> Option<String> {
Command::new(program)
.args(args)
.output()
.ok()
.and_then(|output| String::from_utf8(output.stdout).ok())
.map(|s| s.trim().to_string())
}
fn generate_man_pages() -> std::io::Result<()> {
let cmd = Cli::command();
// Allow CI diff script to redirect output to a temp dir via MAN_OUT_DIR env var.
// Falls back to the committed man/man1 directory for normal builds.
let target_dir = if let Ok(override_dir) = std::env::var("MAN_OUT_DIR") {
std::path::PathBuf::from(override_dir)
} else {
Path::new("man").join("man1")
};
match render_to_dir(&cmd, &target_dir) {
Ok(()) => Ok(()),
Err(err) if err.kind() == io::ErrorKind::PermissionDenied => {
let out_dir = std::env::var("OUT_DIR").unwrap_or_else(|_| "target".to_string());
let fallback_dir = Path::new(&out_dir).join("man1");
println!(
"cargo:warning=Cannot write man pages to {} (permission denied). Writing to {} instead.",
target_dir.display(),
fallback_dir.display()
);
render_to_dir(&cmd, &fallback_dir)
}
Err(err) => Err(err),
}
}
fn render_to_dir(cmd: &clap::Command, dir: &Path) -> std::io::Result<()> {
fs::create_dir_all(dir)?;
render_recursive(cmd, dir, "")
}
fn render_recursive(cmd: &clap::Command, out_dir: &Path, prefix: &str) -> std::io::Result<()> {
let name = if prefix.is_empty() {
cmd.get_name().to_string()
} else {
format!("{}-{}", prefix, cmd.get_name())
};
let cmd = cmd.clone();
let man = clap_mangen::Man::new(cmd.clone());
let mut buffer: Vec<u8> = Default::default();
man.render(&mut buffer)?;
fs::write(out_dir.join(format!("{}.1", name)), buffer)?;
for sub in cmd.get_subcommands() {
if !sub.is_hide_set() {
render_recursive(sub, out_dir, &name)?;
}
}
Ok(())
}