This repository was archived by the owner on Sep 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathvars.rs
306 lines (276 loc) · 8.7 KB
/
vars.rs
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
use clap::{Parser, ValueEnum};
use lazy_static::lazy_static;
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::env;
use std::error::Error;
use std::fs::File;
use std::io::{BufRead, BufReader, Cursor};
use std::path::PathBuf;
use std::process::Command;
use log::{error, info};
use requestty::{Answer, Answers, Question};
#[derive(Parser)]
#[command(name = "rkos_builder")]
#[command(author = "xyyy <xyyy1420@gmail>")]
#[command(version = "0.0.1")]
pub struct Cli {
#[arg(value_enum)]
pub build_option: BuildOption,
#[arg(short, long, value_name = "DIR")]
pub config: Option<PathBuf>,
#[arg(value_enum)]
pub operate: StartMode,
//编译中断后,可以填写该字段,避免重复编译成功的部分
#[arg(default_value_t = String::from("NULL"), value_name = "PACKAGE_NAME")]
pub package_name: String,
#[arg(short,long,action=clap::ArgAction::Count)]
pub debug: u8,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
pub enum StartMode {
Start,
Reset,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
pub enum BuildOption {
Build,
HostConfig,
PackageDownload,
BuildTempToolchains,
BuildBasePackages,
CleanUp,
ConfigTargetSystem,
BuildRustSupportPackageAndKernel,
InstallGrub,
}
lazy_static! {
pub static ref DISK_INFO: Answers = req_user_input();
pub static ref BOOT_PARTUUID: String = get_uuid(DISK_INFO["target_boot_part"].clone(), false);
pub static ref BOOT_UUID: String = get_uuid(DISK_INFO["target_boot_part"].clone(), true);
pub static ref ROOT_PARTUUID: String = get_uuid(DISK_INFO["target_root_part"].clone(), false);
pub static ref ROOT_UUID: String = get_uuid(DISK_INFO["target_root_part"].clone(), true);
pub static ref ROOT_DIR: PathBuf = env::current_dir().unwrap();
pub static ref BASE_CONFIG: BaseConfig = {
let temp = parse_json(["configs", "base_configs.json"].iter().collect());
match temp {
Ok(v) => v,
Err(e) => panic!("Cannot load base config , Err msg: {}", e),
}
};
pub static ref STOP_FLAG: PathBuf = PathBuf::from(&BASE_CONFIG.host_info.stop_flag);
pub static ref RUST_SUPPORT_PACKAGES: RustSupportPackages = {
let temp = parse_json(
[
&BASE_CONFIG.configs.root,
&BASE_CONFIG.configs.rust_support_packages,
]
.iter()
.collect(),
);
match temp {
Ok(v) => v,
Err(e) => panic!("Cannot load cross compile packages, Err msg: {}", e),
}
};
pub static ref PACKAGES: Packages = {
let temp = parse_json(
[
&BASE_CONFIG.configs.root,
&BASE_CONFIG.configs.package_config,
]
.iter()
.collect(),
);
match temp {
Ok(v) => v,
Err(e) => panic!("Cannot load cross compile packages, Err msg: {}", e),
}
};
}
#[derive(Debug, Serialize, Deserialize)]
pub struct HostInfo {
pub target_part: String,
pub stop_flag: String,
}
// scripte path in base config
#[derive(Debug, Serialize, Deserialize)]
pub struct ScriptsPath {
pub root: String,
pub build_base_packages: String,
pub build_temp_toolchains: String,
pub build_rust_support_packages: String,
pub chroot: String,
pub clean: String,
pub prepare: String,
pub release: String,
pub sysconfig: String,
}
// base config
#[derive(Debug, Serialize, Deserialize)]
pub struct Configs {
pub root: String,
pub rust_support_packages: String,
pub package_config: String,
}
// path info in base config
#[derive(Debug, Serialize, Deserialize)]
pub struct PathInfo {
pub root: String,
pub package_source: String,
pub package_build: String,
pub package_patches: String,
pub install_path: String,
}
// env config
#[derive(Debug, Serialize, Deserialize)]
pub struct EnvsInfo {
pub name: String,
pub value: String,
}
// env config vec
#[derive(Debug, Serialize, Deserialize)]
pub struct Envs {
pub envs: Vec<EnvsInfo>,
}
// base config
#[derive(Debug, Serialize, Deserialize)]
pub struct BaseConfig {
pub host_info: HostInfo,
pub scripts_path: ScriptsPath,
pub configs: Configs,
pub path: PathInfo,
pub envs: Vec<EnvsInfo>,
}
// rust support package
#[derive(Debug, Serialize, Deserialize)]
pub struct RustSupportPackageInfo {
pub name: String,
pub package_name: String,
pub script: String,
}
// rust support package vec
#[derive(Debug, Serialize, Deserialize)]
pub struct RustSupportPackages {
pub rust_support_packages: Vec<RustSupportPackageInfo>,
}
// package info , todo: auto update
#[derive(Debug, Serialize, Deserialize)]
pub struct PackageInfo {
pub package_name: String,
pub file_name: String,
pub url: String,
pub last_version: String,
pub current_version: String,
}
// package install info , do not try to change this
#[derive(Debug, Serialize, Deserialize)]
pub struct PackageInstallInfo {
pub package_name: String,
pub script_name: String,
}
// install info , do not try to change this
#[derive(Debug, Serialize, Deserialize)]
pub struct InstallInfo {
pub cross_compile_toolchains: Vec<PackageInstallInfo>,
pub cross_compile_packages: Vec<PackageInstallInfo>,
pub after_chroot_packages: Vec<PackageInstallInfo>,
pub base_packages: Vec<PackageInstallInfo>,
}
// package patch info
#[derive(Debug, Serialize, Deserialize)]
pub struct PackagePatch {
pub patch_name: String,
pub url: String,
pub last_version: String,
pub current_version: String,
}
// all packages , package info , patches info , install info
#[derive(Debug, Serialize, Deserialize)]
pub struct Packages {
pub package_info: Vec<PackageInfo>,
pub install_info: InstallInfo,
pub package_patches: Vec<PackagePatch>,
}
pub fn parse_json<T: serde::de::DeserializeOwned>(
json_file_path: PathBuf,
) -> Result<T, Box<dyn Error>> {
info!("{:?}", json_file_path);
let file = File::open(json_file_path)?;
let reader = BufReader::new(file);
let value: T = serde_json::from_reader(reader)?;
Ok(value)
}
pub fn req_user_input() -> Answers {
let option = get_blkid_output();
let questions = vec![
Question::select("target_boot_part")
.message("Which partition you want to use as a boot partition?")
.choices(option.clone())
.build(),
Question::select("target_root_part")
.message("Which partition you want to use as a root partition?")
.choices(option)
.build(),
];
match requestty::prompt(questions) {
Ok(v) => v,
Err(e) => {
error!("Failed get user input Err msg : {}", e);
panic!();
}
}
}
pub fn get_blkid_output() -> Vec<String> {
let blkid = String::from_utf8(Command::new("/usr/bin/blkid").output().unwrap().stdout);
let mut lines: Vec<String> = Vec::new();
match blkid {
Ok(v) => {
//TODO:确认flatten的方式是否可行
let cursor = Cursor::new(v.as_bytes());
//.into_iter()
for line in cursor.lines().flatten() {
lines.push(line);
}
// for line in cursor.lines().into_iter() {
// if let Ok(v) = line {
// lines.push(v);
// }
// }
}
Err(e) => error!("Cannot get blkid output Err msg: {}", e),
}
lines
}
pub fn get_uuid(value: Answer, uuid: bool) -> String {
match uuid {
true => {
if let Answer::ListItem(s) = value {
let pattern = Regex::new("UUID=\"(.*?)\"").unwrap();
if let Some(cap) = pattern.captures_iter(&s.text).next() {
return cap[1].to_string();
}
// for cap in pattern.captures_iter(&s.text) {
// return cap[1].to_string();
// }
"NULL".to_string()
} else {
"NULL".to_string()
}
}
false => {
if let Answer::ListItem(s) = value {
let pattern = Regex::new("PARTUUID=\"(.*?)\"").unwrap();
if let Some(cap) = pattern.captures_iter(&s.text).next() {
return cap[1].to_string();
}
// for cap in pattern.captures_iter(&s.text) {
// return cap[1].to_string();
// }
"NULL".to_string()
} else {
"NULL".to_string()
}
}
}
}