1use std::{env, process::Command};
16
17use once_cell::sync::OnceCell;
18use serde::Serialize;
19
20pub static ENV_INFO: OnceCell<EnvInfo> = OnceCell::new();
22
23#[allow(dead_code)]
25#[derive(Debug, Serialize)]
26pub struct EnvInfo {
27 package: String,
28 host: String,
29 rustc: String,
30 args: Vec<String>,
31 repo: String,
32 branch: String,
33 commit: String,
34}
35
36impl EnvInfo {
37 pub fn register() {
38 fn command(args: &[&str]) -> String {
40 let mut output = String::from_utf8(
41 Command::new(args[0]).args(&args[1..]).output().map(|out| out.stdout).unwrap_or_default(),
42 )
43 .unwrap_or_default();
44 output.pop(); output
47 }
48
49 let rustc_info = command(&["rustc", "--version", "--verbose"]);
51 let rustc_info = rustc_info.split('\n').map(|line| line.split(": "));
52 let mut rustc = String::new();
53 let mut host = String::new();
54 for mut pair in rustc_info {
55 let key = pair.next();
56 let value = pair.next();
57
58 match (key, value) {
59 (Some(key), None) => {
60 if key.starts_with("rustc ") {
61 rustc = key.trim_start_matches("rustc ").to_owned();
62 }
63 }
64 (Some(key), Some(value)) => {
65 if key == "host" {
66 host = value.to_string();
67 }
68 }
69 _ => {}
70 }
71 }
72
73 let args = env::args().filter(|arg| !arg.starts_with("APrivateKey")).collect::<Vec<_>>();
75
76 let env_info = EnvInfo {
78 package: env::var("CARGO_PKG_VERSION").unwrap_or_default(),
79 host,
80 rustc,
81 args,
82 repo: env::var("CARGO_PKG_REPOSITORY").unwrap_or_default(),
83 branch: command(&["git", "branch", "--show-current"]),
84 commit: command(&["git", "rev-parse", "HEAD"]),
85 };
86
87 ENV_INFO.set(env_info).unwrap();
89 }
90}