Skip to content

Conversation

@LIghtJUNction
Copy link

@LIghtJUNction LIghtJUNction commented Nov 15, 2025

Summary

Migrate the usage of the sys_info crate to the sysinfo crate throughout the project.

Key changes:

  • Replace sys_info::os_type() with std::env::consts::OS (standardized to lowercase) or sysinfo equivalents for consistency.
  • Replace sys_info::os_release() with sysinfo::System::kernel_version().
  • Replace sys_info::linux_os_release() with sysinfo::System::name() and os_version(), plus custom parsing of /etc/os-release for VERSION_CODENAME (as sysinfo lacks direct support).
  • Add heck dependency to uv-python for string case conversion (e.g., title casing OS names).
  • Update linehaul.rs and related tests to use the new system info retrieval methods.
  • Ensure backward compatibility in user agent and distro detection.

This migration eliminates reliance on the unmaintained sys_info crate, improves cross-platform system info accuracy, and aligns with modern Rust ecosystem practices.

build

ubuntu(wsl)
图片

windows(host)
图片

android(cross)
图片

Test Plan

  • Compare the differences between the two libraries
  • Download this test project, I tested it on Windows (host) and ubuntu (wsl).
    test_sysinfo.zip
图片
  • Both changes are not perfect and require developer input
  1. I couldn't find the method to obtain version odename in the sysinfo library. I copied the corresponding function source code directly from the sys info source code and added a private function, which is not elegant, so it still needs to be confirmed by the developer.

  2. To ensure consistency, I need to add a string (std::env::consts::OS), for which I added a dependency to the heck library, I'm not sure if I agree to add a dependency, this task is very simple, if you don't want to add a dependency, you can change it to a standard library implementation.

  • Finally, list the specific substitutions
    sys_info::linux_os_release : remove
    id: info.version_codename --> Find the source code for this function from the sys_info library and apply it.
    name: info.name --> sysinfo::System::name() e.g Some("Ubuntu")
    version: info.version_id --> sysinfo::System::os_version() Some("24.04")

...
sys_info::os_release() -->sysinfo::System::kernel_version() e.g Some("6.6.87.2-microsoft-standard-WSL2")

If you find that sysinfo provides version_codename relevant API, please alert me.

- Replace sys_info::os_type() with std::env::consts::OS and sysinfo equivalents
- Replace sys_info::os_release() with sysinfo::System::kernel_version()
- Replace sys_info::linux_os_release() with sysinfo::System::name(), os_version(), and custom parsing for VERSION_CODENAME
- Add heck dependency for string case conversion
- Update linehaul.rs and tests to use new system info retrieval
- Fix Clippy disallowed_types by using fs_err instead of std::fs
- Ensure cross-platform compatibility and test coverage
@LIghtJUNction LIghtJUNction marked this pull request as ready for review November 15, 2025 14:25
@samypr100
Copy link
Collaborator

samypr100 commented Nov 16, 2025

Thanks for the contribution. From a historical perspective, I did not use sysinfo due to its performance at the time and yielding wildly different results than what's expected in linehaul for some distros (when compared to pip). Things may have changed by now though, so I believe we'll need to look at two things here:

  1. Compatibility: matching existing linehaul information output across different distributions (Ubuntu, Fedora, RHEL, RPI, OSX, etc.), not just WSL. Extensive manual testing was done previously across many OSes to ensure parity with existing tooling (e.g. pip). It would be great to see the user agent output for each platform (before and after) to note any differences (if any).
  2. Performance: determine how performance is impacted as sys-info only added 50us of overhead. Generally querying system information is expensive and sysinfo was prohibitively expensive at the time (in the 50+ms realm). Some hyperfine results would be great.

@samypr100
Copy link
Collaborator

If you're trying to build uv for termux, I'd encourage you to take a look at https://github.com/termux/termux-packages/tree/master/packages/uv which shows the minimal patches needed to get uv to build for it.

@LIghtJUNction
Copy link
Author

Thanks for the contribution. From a historical perspective, I did not use sysinfo due to its performance at the time and yielding wildly different results than what's expected in linehaul for some distros (when compared to pip). Things may have changed by now though, so I believe we'll need to look at two things here:

  1. Compatibility: matching existing linehaul information output across different distributions (Ubuntu, Fedora, RHEL, RPI, OSX, etc.), not just WSL. Extensive manual testing was done previously across many OSes to ensure parity with existing tooling (e.g. pip). It would be great to see the user agent output for each platform (before and after) to note any differences (if any).
  2. Performance: determine how performance is impacted as sys-info only added 50us of overhead. Generally querying system information is expensive and sysinfo was prohibitively expensive at the time (in the 50+ms realm). Some hyperfine results would be great.

But now is different from the past, sys-info has not been updated for a long time.Sysinfo has been updated in recent months.I can try measuring the performance difference between the two, and I can also test it on a Linux system without using WSL.

@LIghtJUNction
Copy link
Author

If you're trying to build uv for termux, I'd encourage you to take a look at https://github.com/termux/termux-packages/tree/master/packages/uv which shows the minimal patches needed to get uv to build for it.

Thank you, successfully compiling on termux is not very interesting. Becoming one of the contributors to UV is my goal. I will continue testing, and if I find that it is really as you described, I will close this PR. Thank you

@LIghtJUNction
Copy link
Author

LIghtJUNction commented Nov 16, 2025

Benchmark-sys-info::os_release vs sysinfo::System::kernel_version
图片

fn benchmark_os_release() {
use std::time::Instant;

const ITERATIONS: u32 = 10000;

// Benchmark sys_info::os_release
let start = Instant::now();
for _ in 0..ITERATIONS {
    let _ = sys_info::os_release();
}
let duration = start.elapsed();
println!("sys_info::os_release average time: {:.2} μs per call", duration.as_micros() as f64 / ITERATIONS as f64);

// Benchmark sysinfo::System::kernel_version
let start = Instant::now();
for _ in 0..ITERATIONS {
    let _ = sysinfo::System::kernel_version();
}
let duration = start.elapsed();
println!("sysinfo::System::kernel_version average time: {:.2} μs per call", duration.as_micros() as f64 / ITERATIONS as f64);

// Compare values
if let (Ok(sys_info_rel), Some(sysinfo_rel)) = (sys_info::os_release(), sysinfo::System::kernel_version()) {
    println!("Values equal: {}", sys_info_rel == sysinfo_rel);
}

}

Benchmark-os_type

图片

fn benchmark_os_type() {
use std::time::Instant;
use heck::ToTitleCase;

const ITERATIONS: u32 = 10000;

// Pre-fetch values to simulate initialization once
let sys_info_os = sys_info::os_type().unwrap_or_default();
let env_os_title = std::env::consts::OS.to_title_case();

// Benchmark accessing pre-fetched sys_info value
let start = Instant::now();
for _ in 0..ITERATIONS {
    let _ = &sys_info_os; // Simulate reading the value
}
let duration = start.elapsed();
println!("Pre-fetched sys_info::os_type value access average time: {:.2} μs per call", duration.as_micros() as f64 / ITERATIONS as f64);

// Benchmark accessing pre-fetched env OS title case value
let start = Instant::now();
for _ in 0..ITERATIONS {
    let _ = &env_os_title; // Simulate reading the value
}
let duration = start.elapsed();
println!("Pre-fetched std::env::consts::OS.to_title_case() value access average time: {:.2} μs per call", duration.as_micros() as f64 / ITERATIONS as f64);

// Compare values
println!("Values equal: {}", sys_info_os == env_os_title);

}
Here the latter uses the Heck library to capitalize the initials, but the time difference is almost non-existent.

Benchmark-sys-info::linux_os_release vs sysinfo::System::name() / sysinfo::System::os_version()
This is not a fair estimate and is therefore for reference only

图片

@zanieb
Copy link
Member

zanieb commented Nov 16, 2025

As an aside, please don't use screenshots of text.

@konstin
Copy link
Member

konstin commented Nov 19, 2025

While I agree that sysinfo looks better than sys_info, this PR is hard to review, because we need to ensure that the linehaul data doesn't have regressions from this, and we need to check this for Windows, macOS, and major Linux distros, across several versions.

@LIghtJUNction
Copy link
Author

While I agree that sysinfo looks better than sys_info, this PR is hard to review, because we need to ensure that the linehaul data doesn't have regressions from this, and we need to check this for Windows, macOS, and major Linux distros, across several versions.

By directly comparing the source code, I found the API mappings; only one was missing. Also, feel free to modify the code here; you have a better understanding of this project. I haven't strictly followed the project's coding style here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants