Get distro name from neofetch
This commit is contained in:
parent
290445110d
commit
ae1f6a2b3f
8 changed files with 157 additions and 7 deletions
2
.cargo/config.toml
Normal file
2
.cargo/config.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
[env]
|
||||
CARGO_WORKSPACE_DIR = { value = "", relative = true }
|
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -125,6 +125,7 @@ dependencies = [
|
|||
"indexmap",
|
||||
"log",
|
||||
"rgb",
|
||||
"shell-words",
|
||||
"strum",
|
||||
]
|
||||
|
||||
|
@ -180,6 +181,12 @@ version = "1.0.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
|
||||
|
||||
[[package]]
|
||||
name = "shell-words"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.26.3"
|
||||
|
|
|
@ -20,4 +20,5 @@ env_logger = { version = "0.11.3", default-features = false }
|
|||
indexmap = { version = "2.2.6", default-features = false }
|
||||
log = { version = "0.4.21", default-features = false }
|
||||
rgb = { version = "0.8.37", default-features = false }
|
||||
shell-words = { version = "1.1.0", default-features = false }
|
||||
strum = { version = "0.26.3", default-features = false }
|
||||
|
|
|
@ -17,6 +17,7 @@ env_logger = { workspace = true, features = ["auto-color", "humantime", "unstabl
|
|||
indexmap = { workspace = true, features = ["std"] }
|
||||
log = { workspace = true, features = ["kv"] }
|
||||
rgb = { workspace = true, features = [] }
|
||||
shell-words = { workspace = true, features = ["std"] }
|
||||
strum = { workspace = true, features = ["derive", "std"] }
|
||||
|
||||
[features]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use anyhow::Result;
|
||||
use anyhow::{Context, Result};
|
||||
use hyfetch::cli_options::options;
|
||||
use hyfetch::neofetch_util::get_distro_ascii;
|
||||
use log::debug;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
|
@ -10,5 +11,15 @@ fn main() -> Result<()> {
|
|||
|
||||
// TODO
|
||||
|
||||
if options.test_print {
|
||||
println!(
|
||||
"{}",
|
||||
get_distro_ascii(None).context("Failed to get distro ascii")?
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Context;
|
||||
#[cfg(feature = "autocomplete")]
|
||||
use bpaf::ShellComp;
|
||||
use bpaf::{construct, long, OptionParser, Parser};
|
||||
|
@ -16,7 +17,7 @@ pub struct Options {
|
|||
pub preset: Option<Preset>,
|
||||
pub mode: Option<AnsiMode>,
|
||||
pub backend: Option<Backend>,
|
||||
pub backend_args: Option<String>,
|
||||
pub backend_args: Vec<String>,
|
||||
pub colors_scale: Option<f32>,
|
||||
pub colors_set_lightness: Option<f32>,
|
||||
pub colors_use_overlay: bool,
|
||||
|
@ -47,7 +48,9 @@ PRESET={{{}}}",
|
|||
.argument("PRESET");
|
||||
#[cfg(feature = "autocomplete")]
|
||||
let preset = preset.complete(complete_preset);
|
||||
let preset = preset.parse(|s| Preset::from_str(&s)).optional();
|
||||
let preset = preset
|
||||
.parse(|s| Preset::from_str(&s).with_context(|| format!("Failed to parse preset `{s}`")))
|
||||
.optional();
|
||||
let mode = long("mode")
|
||||
.short('m')
|
||||
.help(&*format!(
|
||||
|
@ -58,7 +61,9 @@ MODE={{{}}}",
|
|||
.argument("MODE");
|
||||
#[cfg(feature = "autocomplete")]
|
||||
let mode = mode.complete(complete_mode);
|
||||
let mode = mode.parse(|s| AnsiMode::from_str(&s)).optional();
|
||||
let mode = mode
|
||||
.parse(|s| AnsiMode::from_str(&s).with_context(|| format!("Failed to parse mode `{s}`")))
|
||||
.optional();
|
||||
let backend = long("backend")
|
||||
.short('b')
|
||||
.help(&*format!(
|
||||
|
@ -69,11 +74,14 @@ BACKEND={{{}}}",
|
|||
.argument("BACKEND");
|
||||
#[cfg(feature = "autocomplete")]
|
||||
let backend = backend.complete(complete_backend);
|
||||
let backend = backend.parse(|s| Backend::from_str(&s)).optional();
|
||||
let backend = backend
|
||||
.parse(|s| Backend::from_str(&s).with_context(|| format!("Failed to parse backend `{s}`")))
|
||||
.optional();
|
||||
let backend_args = long("args")
|
||||
.help("Additional arguments pass-through to backend")
|
||||
.argument("ARGS")
|
||||
.optional();
|
||||
.argument::<String>("ARGS")
|
||||
.parse(|s| shell_words::split(&s).context("Failed to split args for shell"))
|
||||
.fallback(vec![]);
|
||||
let colors_scale = long("c-scale")
|
||||
.help("Lighten colors by a multiplier")
|
||||
.argument("SCALE")
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pub mod cli_options;
|
||||
pub mod color_util;
|
||||
pub mod neofetch_util;
|
||||
pub mod presets;
|
||||
pub mod types;
|
||||
|
|
119
crates/hyfetch/src/neofetch_util.rs
Normal file
119
crates/hyfetch/src/neofetch_util.rs
Normal file
|
@ -0,0 +1,119 @@
|
|||
use std::ffi::OsStr;
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::process::ExitStatusExt as _;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::{env, fmt};
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use log::debug;
|
||||
|
||||
/// Gets the absolute path of the neofetch command.
|
||||
pub fn get_command_path() -> Result<PathBuf> {
|
||||
if let Some(workspace_dir) = option_env!("CARGO_WORKSPACE_DIR") {
|
||||
let path = PathBuf::from(workspace_dir);
|
||||
if path.exists() {
|
||||
let path = path.join("neofetch");
|
||||
match path.try_exists() {
|
||||
Ok(true) => {
|
||||
return path.canonicalize().context("Failed to canonicalize path");
|
||||
},
|
||||
Ok(false) => {
|
||||
Err(anyhow!("{path:?} does not exist or is not readable"))?;
|
||||
},
|
||||
Err(err) => {
|
||||
Err(err)
|
||||
.with_context(|| format!("Failed to check for existence of {path:?}"))?;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let Ok(path_env) = env::var("PATH") else {
|
||||
return Err(anyhow!("`PATH` env var is not set or invalid"));
|
||||
};
|
||||
|
||||
for search_path in env::split_paths(&path_env) {
|
||||
let path = search_path.join("neowofetch");
|
||||
if !path.is_file() {
|
||||
continue;
|
||||
}
|
||||
return path.canonicalize().context("Failed to canonicalize path");
|
||||
}
|
||||
|
||||
Err(anyhow!("neofetch command not found"))
|
||||
}
|
||||
|
||||
pub fn get_distro_ascii(distro: Option<String>) -> Result<String> {
|
||||
// TODO
|
||||
|
||||
let distro = if let Some(distro) = distro {
|
||||
distro
|
||||
} else {
|
||||
get_distro_name().context("Failed to get distro name")?
|
||||
};
|
||||
debug!(distro:% = distro; "resolved distro name");
|
||||
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Runs neofetch command, returning the piped stdout output.
|
||||
fn run_neofetch_command_piped<S>(args: &[S]) -> Result<String>
|
||||
where
|
||||
S: AsRef<OsStr> + fmt::Debug,
|
||||
{
|
||||
let mut command = make_neofetch_command(args).context("Failed to make neofetch command")?;
|
||||
|
||||
let output = command
|
||||
.output()
|
||||
.context("Failed to execute neofetch as child process")?;
|
||||
debug!(output:?, args:?; "neofetch output");
|
||||
|
||||
if !output.status.success() {
|
||||
let err = if let Some(code) = output.status.code() {
|
||||
anyhow!("neofetch process exited with status code: {code}")
|
||||
} else {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
anyhow!(
|
||||
"neofetch process terminated by signal: {}",
|
||||
output
|
||||
.status
|
||||
.signal()
|
||||
.expect("either one of status code or signal should be set")
|
||||
)
|
||||
}
|
||||
#[cfg(not(unix))]
|
||||
unimplemented!("status code not expected to be `None` on non-Unix platforms")
|
||||
};
|
||||
Err(err)?;
|
||||
}
|
||||
|
||||
let out = String::from_utf8(output.stdout)
|
||||
.context("Failed to process neofetch output as it contains invalid UTF-8")?
|
||||
.trim()
|
||||
.to_owned();
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn make_neofetch_command<S>(args: &[S]) -> Result<Command>
|
||||
where
|
||||
S: AsRef<OsStr>,
|
||||
{
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
let mut command = Command::new("bash");
|
||||
command.arg(get_command_path().context("Failed to get neofetch command path")?);
|
||||
command.args(args);
|
||||
Ok(command)
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_distro_name() -> Result<String> {
|
||||
run_neofetch_command_piped(&["ascii_distro_name"])
|
||||
.context("Failed to get distro name from neofetch")
|
||||
}
|
Loading…
Reference in a new issue