Compare commits

...

14 Commits

Author SHA1 Message Date
a3fb70c55c
Update README 2025-08-27 21:29:20 -04:00
7bf4dfe8a8
Updated README.md 2024-09-30 10:30:51 -04:00
Shibe Drill
1f56893387
Update README.md 2024-09-18 13:59:56 -04:00
Shibe Drill
23286a7539
Update README.md 2024-08-15 17:55:44 -04:00
shibedrill
03e9dfebee Clippy autofixes 2024-08-15 17:47:26 -04:00
shibedrill
8f6aa2a6f4 Add support for NixOS 2024-08-15 17:47:11 -04:00
shibedrill
0701c34673 Fixed logic that would panic 2024-05-07 17:06:04 -04:00
shibedrill
9b689dabaf add steamOS support 2024-05-03 14:29:45 -04:00
Shibe Drill
c4cffa0b3c subdevice instead of full name 2024-03-07 17:03:37 -05:00
shibedrill
c0f7467e3e fixed some more stuff 2024-03-07 15:57:57 -05:00
shibedrill
3d8d0f14fe updated APIs, and serialization 2024-03-07 15:57:40 -05:00
shibedrill
73c5245100 more detailed test output 2024-02-13 13:52:02 -05:00
shibedrill
a437c5f34f clippy fixes, changed libpci-rs source to git 2024-02-13 13:42:07 -05:00
shibedrill
5cb6a8b9f3 stack swap, doc fixes. waiting on PCIIDs 2024-02-13 13:34:41 -05:00
4 changed files with 842 additions and 295 deletions

936
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
[package]
name = "oxidefetch"
description = "A fast, cross platform Fetch program for your terminal"
version = "1.4.8"
version = "2.0.0-beta.4"
edition = "2021"
authors = [ "NamedNeon", "shibedrill" ]
license = "MIT"
@ -21,6 +21,9 @@ ron = "0.8.1"
sysinfo = "0.29.1"
whoami = "1.3.0"
[dependencies.libpci-rs]
git = "https://github.com/gibsonpil/libpci-rs"
[dependencies.serde]
version = "1.0.192"
features = ["derive"]

View File

@ -1,20 +1,25 @@
# oxidefetch 1.4.8
# oxidefetch 2.0.0-beta.4
Fully cross platform Neofetch clone written in Rust. Up to 25 times faster than Neofetch!
![alt text](image.png "Example output of OxideFetch on a WSL2 Arch Linux host")
### Why Oxidefetch?
## Why Oxidefetch
Neofetch, being a BASH script, has a few downsides in my opinion.
1: It's slow.
2: It only works on platforms which have the BASH shell.
3: It's kinda big, and I like having more compact info.
As such, I wrote OxideFetch. How cool is that? It displays your information in a manner that's compact, cross-platform, and BLAZINGLY fast. I've measured speeds of up to 25 times faster than normal Neofetch on WSL2.
As such, I wrote OxideFetch. How cool is that? It displays your information in a manner that's compact, cross-platform, and BLAZINGLY fast. I've measured speeds of up to 25 times faster than normal Neofetch on WSL2. Its primary advantage over other fetch programs is its usage of [libpci-rs](https://github.com/gibsonpil/libpci-rs), which is significantly (up to 35 times) faster than the system-provided `lspci` on Linux when looking up display names for GPUs.
### Special Thanks
The most heartfelt of thanks goes out to NamedNeon, who contributed the code to perform terminal detection.
The most heartfelt of thanks goes out to NamedNeon, who contributed the code to perform terminal detection, and to perform GPU detection on Darwin and Windows.
### Features
OxideFetch can display all of the following information:
- Date, time, and day of week
- Username and hostname
- Operating system name, symbol, and matching color
@ -28,33 +33,35 @@ OxideFetch can display all of the following information:
Also, the field-titles feature can be enabled at compile-time, which will display the name of each field in white before the information within that field. By default, it is disabled.
### Installation
### Installation
Download a binary for your platform, and place it in your `$PATH`.
Currently, only Windows (x86_64, gnu/msvc) and Linux (x86_64/aarch64, gnu/musl) have binaries available. If you want a binary for another platform, you will have to follow the instructions to build from source.
### Dependencies
### Dependencies
#### Build/Install
To build Oxidefetch, you need Cargo. If you do not already have Cargo installed on your system, you can do so by installing Rustup- either via the [instructions on their website](https://doc.rust-lang.org/cargo/getting-started/installation.html "instructions on their website") or via your system package manager.
You will also probably need a C/C++ compiler and a build system- most likely CMake and Visual Studio Build Tools, or GNU Make and the GNU compiler collection. You will be prompted to install these if they're not found during compilation.
You can use Cargo, once it's installed, to automatically build and install Oxidefetch like so:
`cargo install --git https://github.com/shibedrill/oxidefetch`.
`cargo install --git https://git.shibedrill.site/shibedrill/oxidefetch`.
Alternatively, you can get it from the Crates repos, using `cargo install oxidefetch`. But it might be slightly out of date.
From there, it *should* be in your `$PATH`. If not, add `source ~/.cargo/env` to your profile, or add `~/.cargo/bin` to your `$PATH`.
#### Runtime
There's only a couple runtime dependencies for this project.
1: `sh` shell installed for GPU detection on \*nix systems.
2: `lspci` installed for GPU detection on \*nix systems.
(If either of these above dependencies are absent, chances are the GPU field will simply not show up. It won't crash or anything.
GPU detection runs on Windows without any dependencies.)
3: Nerd fonts symbols are used in the output. Install a patched font on your system, or patch an already installed font.
The only runtime dependency for this project is a font with Nerd Fonts Symbols. If this is not used, the symbols in the output will not appear correctly.
### How you can help with the project
I need to verify the output of the OS information detection libraries I'm pulling in. To do this, I need the help of people with varying types of systems. I've tested a few, but there's some I'm unable to test. To help, you can kindly clone this repo, and inside the folder, run `cargo test -- --nocapture`, and send the resultant `test_output.txt` file to my noreply email address, or directly to me on Discord at `@shibedrill`. This program does NOT collect information regarding your real name, IP, location, hardware serial numbers, etc. You can look at the file it generates to be sure- it's all plaintext, babey. Also, consider contributing to [libpci-rs](https://github.com/namedneon/libpci-rs), which will eventually take responsibility for the GPU detection.
#### Tested distributions/platforms:
I need to verify the output of the OS information detection libraries I'm pulling in. To do this, I need the help of people with varying types of systems. I've tested a few, but there's some I'm unable to test. To help, you can kindly clone this repo, and inside the folder, run `cargo test -- --nocapture`, and send the resultant `test_output.txt` file to my noreply email address, or directly to me on Discord at `@shibedrill`. This program does NOT collect information regarding your real name, IP, location, hardware serial numbers, etc. You can look at the file it generates to be sure- it's all plaintext, babey. Also, consider contributing to [libpci-rs](https://github.com/namedneon/libpci-rs) to improve its functionality, efficiency, and cleanliness.
#### Tested distributions/platforms
- Alma Linux
- Alpine Linux
- Android
- Arch Linux
- CentOS
- Debian GNU/Linux
@ -67,28 +74,39 @@ I need to verify the output of the OS information detection libraries I'm pullin
- Ubuntu
- Windows
### Bugs, Quirks, Unintended Behavior, And Other Shenanigans
No weird quirks to report at this time.
### Bugs, Quirks, Unintended Behavior, And Other Shenanigans
- Some information may be vague or incorrect on Android. I might consider switching to new stacks for certain pieces of information.
- GPU detection might require root on certain platforms, such as Android and MacOS.
### To Do & Roadmap
#### Semi-urgent fixes
### To Do & Roadmap
#### Semi-urgent fixes:
- None so far.
#### Very near future:
- Add support for user configurability for entries (whether or not an entry shows, its color, units for memory and time)
#### Very near future
- Add support for user configurability for entries (whether or not an entry shows, its color, units for memory and time)
- Add process count detection
- Refactor logic for cleaner code
- Edit \*nix GPU detection to include GPUs that do not include `VGA Compatible Controller` in the name
#### Future:
- Refactor logic for cleaner code
- Fix Android-specific problems
- Make GPU display names more compact (how?)
#### Future
- Add host system name detection such as "Windows Subsystem for Linux", "IdeaPad 3", "Dell Optiplex", etc.
- Add package count/package manager detection
- Crosstest on more distributions to verify `sys.name()` outputs
- Refactor GPU detection logic into separate crate, remove dependencies on `sh` and `lspci`, and put any platform-specific code in separate files (This is slated for the 2.0.0 release. If you want to help accelerate this effort, consider contributing to [libpci-rs](https://github.com/namedneon/libpci-rs).)
#### Distant future:
#### Distant future
- More extensible user configuration for entry formatting
- Separate all information-getting logic into a new Fetch crate, allowing people to make their own fetch programs using a unified cross-platform API
### Changelog
**1.0.0:** Official full stable release
**1.0.0:** Official full stable release
**1.0.1:** Fixed distro name for Debian GNU/Linux. Logo & color works now.
**1.1.0:** Refactored some poorly written typing, and added support for memory.
**1.1.1:** Made sure that linux system detection won't fail if Linux has a capital L.
@ -107,6 +125,12 @@ No weird quirks to report at this time.
**1.4.6:** Cargo formatting applied to all files. Mild string reformatting in print statements.
**1.4.7:** Removed several `unwrap()` calls. Changed debug output to serialize to RON.
**1.4.8:** Applied Clippy suggestions. Added stuff to README.
**2.0.0-beta.0:** Switch from deprecated, platform-dependent GPU backends to [libpci-rs](https://github.com/gibsonpil/libpci-rs)
**2.0.0-beta.1:** Updated test functionality to include package version in the log file.
**2.0.0-beta.2:** Updated use of `libpci-rs` as its API approaches stability.
**2.0.0-beta.3:** GPU subsystem names will display instead of long names, if available.
**2.0.0-beta.4:** Added NixOS as a recognized distro.
### License
This software is covered by the MIT license. See license.txt for details.

View File

@ -28,11 +28,10 @@ use crate::terminal::get_terminal;
use byte_unit::*;
use chrono::*;
use colored::*;
use libpci_rs::{ids::*, pci::*};
use std::env;
use sysinfo::*;
#[cfg(test)]
use serde::Serialize;
@ -55,7 +54,11 @@ fn main() {
color_print(
"Host:\t",
'',
&Some(format!("{}@{}", sys_info.username, sys_info.hostname)),
&Some(format!(
"{}@{}",
sys_info.username,
sys_info.hostname.unwrap_or("unknown".to_string())
)),
"purple",
);
color_print("OS:\t", sys_info.icon, &sys_info.os_name, &sys_info.color);
@ -64,7 +67,7 @@ fn main() {
color_print("Uptime:\t", '', &Some(sys_info.uptime), "bright gray");
color_print("Shell:\t", '', &sys_info.shell, "bright magenta");
color_print("Terminal:\t", '', &sys_info.terminal, "magenta");
color_print("CPU:\t", '', &Some(sys_info.cpu), "green");
color_print("CPU:\t", '', &sys_info.cpu, "green");
if let Some(gpuvec) = sys_info.gpu {
for gpu in gpuvec {
@ -81,10 +84,7 @@ fn color_print(field_title: &str, icon: char, field: &Option<String>, color: &st
if let Some(fieldvalue) = field {
#[cfg(feature = "field-titles")]
print!("{} ", field_title.bright_white());
println!(
"{}",
format!("{} {}", icon, fieldvalue).color(color)
);
println!("{}", format!("{} {}", icon, fieldvalue).color(color));
}
}
@ -96,14 +96,14 @@ struct Information {
// within the args of color_print, since that function only accepts args of
// type Option<String>.
username: String,
hostname: String,
hostname: Option<String>,
os_name: Option<String>,
os_ver: Option<String>,
kernel_ver: Option<String>,
uptime: String,
shell: Option<String>,
terminal: Option<String>,
cpu: String,
cpu: Option<String>,
gpu: Option<Vec<String>>,
memory: String,
icon: char,
@ -131,7 +131,7 @@ impl Information {
Self {
username: whoami::username(),
hostname: whoami::hostname(),
hostname: whoami::fallible::hostname().ok(),
os_name: os_name.clone(),
os_ver: sys.os_version(),
kernel_ver: sys.kernel_version(),
@ -148,60 +148,46 @@ impl Information {
},
terminal: get_terminal(),
cpu: String::from(sys.cpus()[0].brand()),
cpu: {
let cpus = sys.cpus();
cpus.first().map(|first_cpu| first_cpu.brand().into())
},
gpu: {
match sys
.name()
.unwrap_or(String::from("Unknown System"))
.as_ref()
{
"Windows" => {
// On windows, we run "wmic path win32_VideoController get name" and
// the second line is our GPU name.
let command_output = std::process::Command::new("wmic")
.args(["path", "win32_VideoController", "get", "name"])
.output();
match command_output {
Ok(gpu_info) => {
let gpu_info_as_string = String::from_utf8(gpu_info.stdout);
Some(vec![String::from(
gpu_info_as_string
.unwrap() // TODO: Please figure out a way to get rid of this unwrap() call.
// I feel like I did so well avoiding unwrap calls everywhere except for here.
.lines()
.collect::<Vec<&str>>()[1],
)])
}
Err(_) => None,
}
}
_ => {
// On *nix, hopefully, "lspci | grep VGA | awk -F 'VGA compatible controller: ' '{print $2}'" gives us our GPU name.
// Since pipes can't be processed as arguments, we need to do all this in a subshell under SH.
let command_output = std::process::Command::new("sh")
.args(["-c", "lspci | grep VGA | awk -F'VGA compatible controller: ' '{print $2}'"])
.output();
// Check if running the command resulted in an error. If not, convert to a vector.
// TODO: Please fix this horrible logic. It needs refactoring.
match command_output {
Err(_) => None,
Ok(output_bytes) => match String::from_utf8(output_bytes.stdout) {
Err(_) => None,
Ok(output_string) => match output_string.as_ref() {
"" => None,
_ => {
let mut gpu_vec = vec![];
for s in output_string.trim().split('\n') {
gpu_vec.push(s.to_string());
}
Some(gpu_vec)
if let Ok(pci_list) = get_pci_list() {
let mut gpu_name_vec: Vec<String> = vec![];
for device in pci_list {
if device.class == 3 {
let vendor_entry = lookup_vendor(device.vendor_id).unwrap();
let device_entry = vendor_entry.device(device.device_id).unwrap();
gpu_name_vec.push(format!(
"{} {} {}",
vendor_entry.name(),
// Get the subdevice name if it's available. Otherwise, use the long device name.
{
if let Some(subsystem_entry) = device_entry.subsystem(device.subsys_device_id, device.subsys_vendor_id) {
subsystem_entry.name()
} else {
device_entry.name()
}
},
},
// Only show the revision when it's relevant.
{
if device.revision_id != 0 {
format!(" (rev {:02x})", device.revision_id)
} else {
"".to_string()
}
}
));
}
}
match gpu_name_vec.len() {
0 => None,
1.. => Some(gpu_name_vec),
}
} else {
None
}
},
@ -235,10 +221,12 @@ impl Information {
"openSUSE Tumbleweed" | "openSUSE Leap" => '',
"PopOS" => '',
"Ubuntu" => '',
"SteamOS" => '',
"Windows" => '',
"Android" => '',
"iOS" => '',
"MacOS" => '',
"NixOS" => '󱄅',
"Unknown System" => '?',
_ => {
if sys
@ -268,10 +256,10 @@ impl Information {
"FreeBSD" => "red",
"Ubuntu" => "orange",
"Arch Linux" | "Windows" | "PopOS" => "bright cyan",
"Fedora Linux" | "Kali GNU/Linux" | "Alpine Linux" => "bright blue",
"Fedora Linux" | "Kali GNU/Linux" | "Alpine Linux" | "NixOS" => "bright blue",
"openSUSE Tumbleweed" | "openSUSE Leap" | "Linux Mint" | "Android" => "bright green",
"EndeavourOS" | "Gentoo" | "CentOS Linux" | "CentOS Stream" => "purple",
"iOS" | "macOS" | "ElementaryOS" => "bright white",
"iOS" | "macOS" | "ElementaryOS" | "SteamOS" => "bright white",
"AlmaLinux" => "yellow",
_ => "bright white",
@ -292,8 +280,12 @@ mod test {
pub fn log_gathered_data() {
let sys_info = Information::new();
//let data_string = format!("{:#?}", sys_info);
let data_string = ron::ser::to_string_pretty(&sys_info, ron::ser::PrettyConfig::default())
.expect("Failed to serialize data structure. Aborting...");
let data_string = format!(
"// Version: {}\n// Begin structure dump:\n{}",
env!("CARGO_PKG_VERSION"),
ron::ser::to_string_pretty(&sys_info, ron::ser::PrettyConfig::default())
.expect("Failed to serialize data structure. Aborting...")
);
let result = fs::write("./test_output.ron", data_string);
if result.is_ok() {