1use std::io::Write;
43use std::process::{Command, Stdio};
44use std::time::{SystemTime, UNIX_EPOCH};
45
46pub fn run(template: &str){
56 let args :Vec<String> = std::env::args().collect();
57
58 if !is_runtime(&args){
59 let mut content_template = "
60 =============== z1info extended data ====================
61 | Extended data added to binary file through z1info.
62 |--------------- z1info parameter ----------------------
63 | {z1_info}
64 |--------------- git info ------------------------------
65 | commit id: {git_info}
66 |--------------- build time ----------------------------
67 | {build_time}
68 =========================================================
69 ";
70
71 if "z1template"!=template {
72 content_template = template;
73 }
74
75 let mut content = str::replace(content_template,"{z1_info}",&args[args.len()-1]);
76 content = str::replace(&content[..],"{git_info}",&get_commit_id());
77 content = str::replace(&content[..],"{build_time}",&format!("{}",get_current_time()));
78
79 write_to_tmp(&content,)
83 } else {
84 println!("{}",include_str!("../z1info_tmp"));
85 }
86}
87
88fn is_runtime(args: &Vec<String>)->bool{
89 let lenght = args.len();
90
91 if 0 < lenght {
92 let flag = "z1info=";
93 let flag_length = flag.len();
94 let last_length = args[lenght-1].len();
95 if last_length >= flag_length {
96 return !(flag == &args[lenght-1][0..flag_length]);
97 }
98 }
99
100 return true;
101}
102
103fn get_commit_id()->String{
104 let cmd_str = "git rev-parse HEAD";
106 let out_str: String;
107
108 if cfg!(target_os = "windows") {
109 let output = Command::new("cmd")
110 .arg("/c")
111 .arg(&cmd_str)
112 .stdout(Stdio::piped())
113 .output()
114 .expect(&format!("cmd exec error!"));
115
116 out_str = format!("{}", String::from_utf8_lossy(&output.stdout));
117 } else {
118 let output= Command::new("sh")
119 .arg("/c")
120 .arg(&cmd_str)
121 .stdout(Stdio::piped())
122 .output()
123 .expect(&format!("sh exec error!"));
124
125 out_str = format!("{}", String::from_utf8_lossy(&output.stdout));
126 };
127
128 let ret_end = str::replace(&out_str[..],"\n","");
129
130 return ret_end;
131}
132
133fn get_current_timestamp()->u64{
134 let start = SystemTime::now();
135 let since_the_epoch = start
136 .duration_since(UNIX_EPOCH)
137 .expect("Time went backwards");
138
139 return since_the_epoch.as_secs();
140}
141
142fn path_exist(path: &str) -> bool {
143 return match std::path::Path::new(path).canonicalize() {
144 Ok(_buf) => true,
145 Err(_error) => false,
146 };
147}
148
149fn write_to_tmp(content: &str) {
150 let cargo_toml = format!("{:?}", std::fs::read_to_string("Cargo.toml"));
151 let mut write_to_crate = true;
152
153 let cargo_toml_info: Vec<&str> = cargo_toml.split("z1info_rust = ").collect();
154 if cargo_toml_info.len()>1{
155 let cargo_toml_info2: Vec<&str> = cargo_toml_info[1].split("\\\"").collect();
156
157 if cargo_toml_info2.len()>1{
158 let cargo_toml_info2: Vec<&str> = cargo_toml_info[1].split("\\\"").collect();
159 let mut cargo_registry = String::from("");
160
161 match std::env::var("CARGO_HOME") {
162 Ok(val) => cargo_registry = format!("{}/registry/src", val),
163 Err(_e) => println!("{:?}",_e),
164 }
165
166 let paths = std::fs::read_dir(cargo_registry).unwrap();
167 for path in paths {
168 let tmp_file = &format!("{}/z1info_rust-{}/z1info_tmp", path.unwrap().path().display(),cargo_toml_info2[1])[..];
169
170 if path_exist(tmp_file){
171 let mut file = std::fs::File::create(tmp_file).unwrap();
172 file.write_all(content.as_bytes()).expect("write z1info failed");
173
174 write_to_crate = false;
175 }
176 }
177 }
178 }
179
180 if write_to_crate{
181 let mut file = std::fs::File::create("z1info_tmp").unwrap();
182 file.write_all(content.as_bytes()).expect("write z1info failed");
183 }
184}
185
186fn get_current_time()-> String {
187 let out_str: String;
188
189 if cfg!(target_os = "windows") {
190 let output = Command::new("cmd")
191 .arg("/c")
192 .arg("echo %date:~0,4%-%date:~5,2%-%date:~8,2% %time:~0,2%:%time:~3,2%:%time:~6,2%")
193 .stdout(Stdio::piped())
194 .output()
195 .expect(&format!("cmd exec error!"));
196
197 out_str = format!("{}", String::from_utf8_lossy(&output.stdout));
198 } else {
199 let output= Command::new("sh")
200 .arg("/c")
201 .arg("echo $(date '+%Y-%m-%d %H:%M:%S')")
202 .stdout(Stdio::piped())
203 .output()
204 .expect(&format!("sh exec error!"));
205
206 out_str = format!("{}", String::from_utf8_lossy(&output.stdout));
207 };
208
209 let ret_end = str::replace(&out_str[..],"\n","");
210
211 return ret_end;
212}