mirror of
https://github.com/orhun/systeroid
synced 2024-07-21 10:25:00 +00:00
feat(args): add --explain
argument for displaying documentation
This commit is contained in:
parent
4a22e7cc63
commit
2c0010e362
|
@ -186,6 +186,22 @@ impl Sysctl {
|
|||
Ok(Self { parameters })
|
||||
}
|
||||
|
||||
/// Searches and returns the parameter if it exists.
|
||||
pub fn get_parameter(&mut self, param_name: &str) -> Option<&mut Parameter> {
|
||||
let parameter = self
|
||||
.parameters
|
||||
.iter_mut()
|
||||
.find(|param| param.name == *param_name);
|
||||
if parameter.is_none() {
|
||||
eprintln!(
|
||||
"{}: cannot stat /proc/{}: No such file or directory",
|
||||
env!("CARGO_PKG_NAME").split('-').collect::<Vec<_>>()[0],
|
||||
param_name.replace(".", "/")
|
||||
)
|
||||
}
|
||||
parameter
|
||||
}
|
||||
|
||||
/// Updates the descriptions of the kernel parameters.
|
||||
pub fn update_docs(&mut self, kernel_docs: &Path) -> Result<()> {
|
||||
let documents = parse_kernel_docs(kernel_docs)?;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::io::{self, Stdout};
|
||||
use std::io::{self, Stdout, Write};
|
||||
use systeroid_core::config::Config;
|
||||
use systeroid_core::error::Result;
|
||||
use systeroid_core::sysctl::Sysctl;
|
||||
|
@ -33,6 +33,21 @@ impl<'a> App<'a> {
|
|||
.try_for_each(|parameter| parameter.display(&self.config.color, &mut self.stdout))
|
||||
}
|
||||
|
||||
/// Displays the documentation of a parameter.
|
||||
pub fn display_documentation(&mut self, param_name: &str) -> Result<()> {
|
||||
if let Some(parameter) = self.sysctl.get_parameter(param_name) {
|
||||
writeln!(
|
||||
self.stdout,
|
||||
"{}",
|
||||
parameter
|
||||
.description
|
||||
.as_deref()
|
||||
.unwrap_or("No documentation available")
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Updates the parameter if it has the format `name=value`, displays it otherwise.
|
||||
pub fn process_parameter(&mut self, mut param_name: String) -> Result<()> {
|
||||
let new_value = if param_name.contains('=') {
|
||||
|
@ -46,24 +61,12 @@ impl<'a> App<'a> {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
match self
|
||||
.sysctl
|
||||
.parameters
|
||||
.iter_mut()
|
||||
.find(|param| param.name == *param_name)
|
||||
{
|
||||
Some(parameter) => {
|
||||
if let Some(new_value) = new_value {
|
||||
parameter.update(&new_value, &self.config.color, &mut self.stdout)?;
|
||||
} else {
|
||||
parameter.display(&self.config.color, &mut self.stdout)?;
|
||||
}
|
||||
if let Some(parameter) = self.sysctl.get_parameter(¶m_name) {
|
||||
if let Some(new_value) = new_value {
|
||||
parameter.update(&new_value, &self.config.color, &mut self.stdout)?;
|
||||
} else {
|
||||
parameter.display(&self.config.color, &mut self.stdout)?;
|
||||
}
|
||||
None => eprintln!(
|
||||
"{}: cannot stat /proc/{}: No such file or directory",
|
||||
env!("CARGO_PKG_NAME"),
|
||||
param_name.replace(".", "/")
|
||||
),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -17,10 +17,10 @@ For more details see {bin}(8)."#;
|
|||
pub struct Args {
|
||||
/// Path of the Linux kernel documentation.
|
||||
pub kernel_docs: Option<PathBuf>,
|
||||
/// Display all of the kernel parameters.
|
||||
pub display_all: bool,
|
||||
/// Disable colored output.
|
||||
pub no_color: bool,
|
||||
/// Parameter to explain.
|
||||
pub param_to_explain: Option<String>,
|
||||
/// Parameter names.
|
||||
pub param_names: Vec<String>,
|
||||
}
|
||||
|
@ -35,6 +35,12 @@ impl Args {
|
|||
opts.optflag("A", "", "alias of -a");
|
||||
opts.optflag("X", "", "alias of -a");
|
||||
opts.optflag("", "no-color", "disable colored output");
|
||||
opts.optopt(
|
||||
"",
|
||||
"explain",
|
||||
"provide a detailed explanation for a variable",
|
||||
"<var>",
|
||||
);
|
||||
opts.optopt(
|
||||
"d",
|
||||
"docs",
|
||||
|
@ -47,12 +53,13 @@ impl Args {
|
|||
.map_err(|e| eprintln!("error: {}", e))
|
||||
.ok()?;
|
||||
|
||||
let display_all = matches.opt_present("a")
|
||||
let required_args_present = matches.opt_present("a")
|
||||
|| matches.opt_present("A")
|
||||
|| matches.opt_present("X")
|
||||
|| !matches.free.is_empty();
|
||||
|| !matches.free.is_empty()
|
||||
|| matches.opt_str("explain").is_some();
|
||||
|
||||
if matches.opt_present("h") || !display_all {
|
||||
if matches.opt_present("h") || !required_args_present {
|
||||
let usage = opts.usage_with_format(|opts| {
|
||||
HELP_MESSAGE
|
||||
.replace("{bin}", env!("CARGO_PKG_NAME"))
|
||||
|
@ -66,8 +73,8 @@ impl Args {
|
|||
} else {
|
||||
Some(Args {
|
||||
kernel_docs: matches.opt_str("d").map(PathBuf::from),
|
||||
display_all,
|
||||
no_color: matches.opt_present("no-color"),
|
||||
param_to_explain: matches.opt_str("explain"),
|
||||
param_names: matches.free,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@ pub fn run(args: Args) -> Result<()> {
|
|||
|
||||
let mut app = App::new(&mut sysctl, &config);
|
||||
|
||||
if args.param_names.is_empty() {
|
||||
if let Some(param) = args.param_to_explain {
|
||||
app.display_documentation(¶m)?;
|
||||
} else if args.param_names.is_empty() {
|
||||
app.display_parameters()?;
|
||||
} else {
|
||||
for param_name in args.param_names {
|
||||
|
|
Loading…
Reference in a new issue