lscpu
: Use recursive printing logic to output nested fields
This commit is contained in:
parent
98689faad2
commit
1e456daff5
@ -52,46 +52,101 @@ impl CpuInfos {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct OutputOptions {
|
||||||
|
json: bool,
|
||||||
|
_hex: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?;
|
let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?;
|
||||||
|
|
||||||
let system = System::new_all();
|
let system = System::new_all();
|
||||||
|
|
||||||
let _hex = matches.get_flag(options::HEX);
|
let output_opts = OutputOptions {
|
||||||
let json = matches.get_flag(options::JSON);
|
_hex: matches.get_flag(options::HEX),
|
||||||
|
json: matches.get_flag(options::JSON),
|
||||||
|
};
|
||||||
|
|
||||||
let mut cpu_infos = CpuInfos::new();
|
let mut cpu_infos = CpuInfos::new();
|
||||||
cpu_infos.push("Architecture", &get_architecture(), None);
|
|
||||||
cpu_infos.push("CPU(s)", &format!("{}", system.cpus().len()), None);
|
cpu_infos.push("CPU(s)", &format!("{}", system.cpus().len()), None);
|
||||||
// Add more CPU information here...
|
// Add more CPU information here...
|
||||||
|
|
||||||
if let Ok(contents) = fs::read_to_string("/proc/cpuinfo") {
|
let contents = match fs::read_to_string("/proc/cpuinfo") {
|
||||||
if let Some(cpu_model) = find_cpuinfo_value(&contents, "model name") {
|
// Early return if we can't read /proc/cpuinfo for whatever reason
|
||||||
if let Some(addr_sizes) = find_cpuinfo_value(&contents, "address sizes") {
|
// TODO: Should this return an non-zero exit code to user, or do we just ignore it and display whatever CPU info we could find?
|
||||||
cpu_infos.push(
|
Err(_) => return Ok(()),
|
||||||
"Model name",
|
Ok(contents) => contents,
|
||||||
cpu_model.as_str(),
|
};
|
||||||
Some(vec![CpuInfo {
|
|
||||||
field: "Address sizes".to_string(),
|
let mut arch_children: Vec<CpuInfo> = vec![];
|
||||||
data: addr_sizes,
|
|
||||||
children: vec![],
|
if let Some(addr_sizes) = find_cpuinfo_value(&contents, "address sizes") {
|
||||||
}]),
|
arch_children.push(CpuInfo {
|
||||||
);
|
field: "Address sizes".to_string(),
|
||||||
} else {
|
data: addr_sizes,
|
||||||
cpu_infos.push("Model name", cpu_model.as_str(), None);
|
children: vec![],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu_infos.push("Architecture", &get_architecture(), Some(arch_children));
|
||||||
|
|
||||||
|
// TODO: This is currently quite verbose and doesn't strictly respect the hierarchy of `/proc/cpuinfo` contents
|
||||||
|
// ie. the file might contain multiple sections, each with their own vendor_id/model name etc. but right now
|
||||||
|
// we're just taking whatever our regex matches first and using that
|
||||||
|
if let Some(vendor) = find_cpuinfo_value(&contents, "vendor_id") {
|
||||||
|
let mut vendor_children: Vec<CpuInfo> = vec![];
|
||||||
|
|
||||||
|
if let Some(model_name) = find_cpuinfo_value(&contents, "model name") {
|
||||||
|
let mut model_children: Vec<CpuInfo> = vec![];
|
||||||
|
|
||||||
|
if let Some(family) = find_cpuinfo_value(&contents, "cpu family") {
|
||||||
|
model_children.push(CpuInfo {
|
||||||
|
field: "CPU Family".to_string(),
|
||||||
|
data: family,
|
||||||
|
children: vec![],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(model) = find_cpuinfo_value(&contents, "model") {
|
||||||
|
model_children.push(CpuInfo {
|
||||||
|
field: "Model".to_string(),
|
||||||
|
data: model,
|
||||||
|
children: vec![],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
vendor_children.push(CpuInfo {
|
||||||
|
field: "Model name".to_string(),
|
||||||
|
data: model_name,
|
||||||
|
children: model_children,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
cpu_infos.push("Vendor ID", vendor.as_str(), Some(vendor_children));
|
||||||
|
}
|
||||||
|
|
||||||
|
print_output(cpu_infos, output_opts);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_output(infos: CpuInfos, out_opts: OutputOptions) {
|
||||||
|
if out_opts.json {
|
||||||
|
println!("{}", infos.to_json());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursive function to print nested CpuInfo entries
|
||||||
|
fn print_entries(entries: Vec<CpuInfo>, depth: usize, _out_opts: &OutputOptions) {
|
||||||
|
let indent = " ".repeat(depth);
|
||||||
|
for entry in entries {
|
||||||
|
// TODO: Align `data` values to form a column
|
||||||
|
println!("{}{}: {}", indent, entry.field, entry.data);
|
||||||
|
print_entries(entry.children, depth + 1, _out_opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if json {
|
print_entries(infos.lscpu, 0, &out_opts);
|
||||||
println!("{}", cpu_infos.to_json());
|
|
||||||
} else {
|
|
||||||
for elt in cpu_infos.lscpu {
|
|
||||||
println!("{}: {}", elt.field, elt.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_cpuinfo_value(contents: &str, key: &str) -> Option<String> {
|
fn find_cpuinfo_value(contents: &str, key: &str) -> Option<String> {
|
||||||
@ -101,11 +156,11 @@ fn find_cpuinfo_value(contents: &str, key: &str) -> Option<String> {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if let Some(cap) = re.captures_iter(contents).next() {
|
let value = re
|
||||||
return Some(cap[1].to_string());
|
.captures_iter(contents)
|
||||||
};
|
.next()
|
||||||
|
.map(|cap| cap[1].to_string());
|
||||||
None
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_architecture() -> String {
|
fn get_architecture() -> String {
|
||||||
@ -137,6 +192,7 @@ pub fn uu_app() -> Command {
|
|||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::JSON)
|
Arg::new(options::JSON)
|
||||||
|
.short('J')
|
||||||
.long("json")
|
.long("json")
|
||||||
.help(
|
.help(
|
||||||
"Use JSON output format for the default summary or extended output \
|
"Use JSON output format for the default summary or extended output \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user