use std::io::Write;
use std::process::{Command, Stdio};
use std::time::{SystemTime, UNIX_EPOCH};
pub fn run(template: &str){
let args :Vec<String> = std::env::args().collect();
if !is_runtime(&args){
let mut content_template = "
=============== z1info extended data ====================
| Extended data added to binary file through z1info.
|--------------- z1info parameter ----------------------
| {z1_info}
|--------------- git info ------------------------------
| commit id: {git_info}
|--------------- build time ----------------------------
| {build_time}
=========================================================
";
if "z1template"!=template {
content_template = template;
}
let mut content = str::replace(content_template,"{z1_info}",&args[args.len()-1]);
content = str::replace(&content[..],"{git_info}",&get_commit_id());
content = str::replace(&content[..],"{build_time}",&format!("{}",get_current_time()));
write_to_tmp(&content,)
} else {
println!("{}",include_str!("../z1info_tmp"));
}
}
fn is_runtime(args: &Vec<String>)->bool{
let lenght = args.len();
if 0 < lenght {
let flag = "z1info=";
let flag_length = flag.len();
let last_length = args[lenght-1].len();
if last_length >= flag_length {
return !(flag == &args[lenght-1][0..flag_length]);
}
}
return true;
}
fn get_commit_id()->String{
let cmd_str = "git rev-parse HEAD";
let out_str: String;
if cfg!(target_os = "windows") {
let output = Command::new("cmd")
.arg("/c")
.arg(&cmd_str)
.stdout(Stdio::piped())
.output()
.expect(&format!("cmd exec error!"));
out_str = format!("{}", String::from_utf8_lossy(&output.stdout));
} else {
let output= Command::new("sh")
.arg("/c")
.arg(&cmd_str)
.stdout(Stdio::piped())
.output()
.expect(&format!("sh exec error!"));
out_str = format!("{}", String::from_utf8_lossy(&output.stdout));
};
let ret_end = str::replace(&out_str[..],"\n","");
return ret_end;
}
fn get_current_timestamp()->u64{
let start = SystemTime::now();
let since_the_epoch = start
.duration_since(UNIX_EPOCH)
.expect("Time went backwards");
return since_the_epoch.as_secs();
}
fn path_exist(path: &str) -> bool {
return match std::path::Path::new(path).canonicalize() {
Ok(_buf) => true,
Err(_error) => false,
};
}
fn write_to_tmp(content: &str) {
let cargo_toml = format!("{:?}", std::fs::read_to_string("Cargo.toml"));
let mut write_to_crate = true;
let cargo_toml_info: Vec<&str> = cargo_toml.split("z1info_rust = ").collect();
if cargo_toml_info.len()>1{
let cargo_toml_info2: Vec<&str> = cargo_toml_info[1].split("\\\"").collect();
if cargo_toml_info2.len()>1{
let cargo_toml_info2: Vec<&str> = cargo_toml_info[1].split("\\\"").collect();
let mut cargo_registry = String::from("");
match std::env::var("CARGO_HOME") {
Ok(val) => cargo_registry = format!("{}/registry/src", val),
Err(_e) => println!("{:?}",_e),
}
let paths = std::fs::read_dir(cargo_registry).unwrap();
for path in paths {
let tmp_file = &format!("{}/z1info_rust-{}/z1info_tmp", path.unwrap().path().display(),cargo_toml_info2[1])[..];
if path_exist(tmp_file){
let mut file = std::fs::File::create(tmp_file).unwrap();
file.write_all(content.as_bytes()).expect("write z1info failed");
write_to_crate = false;
}
}
}
}
if write_to_crate{
let mut file = std::fs::File::create("z1info_tmp").unwrap();
file.write_all(content.as_bytes()).expect("write z1info failed");
}
}
fn get_current_time()-> String {
let out_str: String;
if cfg!(target_os = "windows") {
let output = Command::new("cmd")
.arg("/c")
.arg("echo %date:~0,4%-%date:~5,2%-%date:~8,2% %time:~0,2%:%time:~3,2%:%time:~6,2%")
.stdout(Stdio::piped())
.output()
.expect(&format!("cmd exec error!"));
out_str = format!("{}", String::from_utf8_lossy(&output.stdout));
} else {
let output= Command::new("sh")
.arg("/c")
.arg("echo $(date '+%Y-%m-%d %H:%M:%S')")
.stdout(Stdio::piped())
.output()
.expect(&format!("sh exec error!"));
out_str = format!("{}", String::from_utf8_lossy(&output.stdout));
};
let ret_end = str::replace(&out_str[..],"\n","");
return ret_end;
}