os-release-0.1.0/.gitignore010066400017500001750000000000231336666157300137750ustar0000000000000000target/ Cargo.lock os-release-0.1.0/Cargo.toml.orig010066400017500001750000000006621336666231000146730ustar0000000000000000[package] name = "os-release" version = "0.1.0" authors = ["Jeremy Soller ", "Michael Aaron Murphy "] description = "Parse /etc/os-release files on Linux distributions" repository = "https://github.com/pop-os/os-release" readme = "README.md" license = "MIT" categories = ["os::unix-apis", "parser-implementations"] keywords = ["linux", "os", "release"] [dependencies] lazy_static = "1.1.0" os-release-0.1.0/Cargo.toml0000644000000017050000000000000111310ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "os-release" version = "0.1.0" authors = ["Jeremy Soller ", "Michael Aaron Murphy "] description = "Parse /etc/os-release files on Linux distributions" readme = "README.md" keywords = ["linux", "os", "release"] categories = ["os::unix-apis", "parser-implementations"] license = "MIT" repository = "https://github.com/pop-os/os-release" [dependencies.lazy_static] version = "1.1.0" os-release-0.1.0/LICENSE010064400017500001750000000020511336665264100130070ustar0000000000000000MIT License Copyright (c) 2018 System76 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. os-release-0.1.0/README.md010064400017500001750000000005071336710264100132540ustar0000000000000000# os-release Rust crate that provides a type for parsing the `/etc/os-release` file, or any file with an `os-release`-like format. ```rust extern crate os_release; use os_release::OsRelease; use std::io; pub fn main() -> io::Result<()> { let release = OsRelease::new()?; println!("{:#?}", release); Ok(()) } ```os-release-0.1.0/examples/example.rs010066400017500001750000000003201336710236000156050ustar0000000000000000extern crate os_release; use os_release::OsRelease; use std::io; pub fn main() -> io::Result<()> { let release = OsRelease::new_from("examples/pop_cosmic")?; println!("{:#?}", release); Ok(()) }os-release-0.1.0/examples/pop_cosmic010066400017500001750000000005131336710222600156670ustar0000000000000000NAME="Pop!_OS" VERSION="18.10" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Pop!_OS 18.10" VERSION_ID="18.10" HOME_URL="https://system76.com/pop" SUPPORT_URL="http://support.system76.com" BUG_REPORT_URL="https://github.com/pop-os/pop/issues" PRIVACY_POLICY_URL="https://system76.com/privacy" VERSION_CODENAME=cosmic UBUNTU_CODENAME=cosmicos-release-0.1.0/src/lib.rs010066400017500001750000000135551336710253500137130ustar0000000000000000//! Type for parsing the `/etc/os-release` file. #[macro_use] extern crate lazy_static; use std::collections::BTreeMap; use std::fs::File; use std::io::{self, BufRead, BufReader}; use std::iter::FromIterator; use std::path::Path; lazy_static! { /// The OS release detected on this host's environment. /// /// # Notes /// If an OS Release was not found, an error will be in its place. pub static ref OS_RELEASE: io::Result = OsRelease::new(); } macro_rules! map_keys { ($item:expr, { $($pat:expr => $field:expr),+ }) => {{ $( if $item.starts_with($pat) { $field = parse_line($item, $pat.len()).into(); continue; } )+ }}; } fn is_enclosed_with(line: &str, pattern: char) -> bool { line.starts_with(pattern) && line.ends_with(pattern) } fn parse_line(line: &str, skip: usize) -> &str { let line = line[skip..].trim(); if is_enclosed_with(line, '"') || is_enclosed_with(line, '\'') { &line[1..line.len() - 1] } else { line } } /// Contents of the `/etc/os-release` file, as a data structure. #[derive(Clone, Debug, Default, PartialEq)] pub struct OsRelease { /// The URL where bugs should be reported for this OS. pub bug_report_url: String, /// The homepage of this OS. pub home_url: String, /// Identifier of the original upstream OS that this release is a derivative of. /// /// **IE:** `debian` pub id_like: String, /// An identifier which describes this release, such as `ubuntu`. /// /// **IE:** `ubuntu` pub id: String, /// The name of this release, without the version string. /// /// **IE:** `Ubuntu` pub name: String, /// The name of this release, with th eversion stirng. /// /// **IE:** `Ubuntu 18.04 LTS` pub pretty_name: String, /// The URL describing this OS's privacy policy. pub privacy_policy_url: String, /// The URL for seeking support with this OS release. pub support_url: String, /// The codename of this version. /// /// **IE:** `bionic` pub version_codename: String, /// The version of this OS release, with additional details about the release. /// /// **IE:** `18.04 LTS (Bionic Beaver)` pub version_id: String, /// The version of this OS release. /// /// **IE:** `18.04` pub version: String, /// Additional keys not covered by the API. pub extra: BTreeMap } impl OsRelease { /// Attempt to parse the contents of `/etc/os-release`. pub fn new() -> io::Result { let file = BufReader::new(open("/etc/os-release")?); Ok(OsRelease::from_iter(file.lines().flat_map(|line| line))) } /// Attempt to parse any `/etc/os-release`-like file. pub fn new_from>(path: P) -> io::Result { let file = BufReader::new(open(&path)?); Ok(OsRelease::from_iter(file.lines().flat_map(|line| line))) } } impl FromIterator for OsRelease { fn from_iter>(lines: I) -> Self { let mut os_release = Self::default(); for line in lines { let line = line.trim(); map_keys!(line, { "NAME=" => os_release.name, "VERSION=" => os_release.version, "ID=" => os_release.id, "ID_LIKE=" => os_release.id_like, "PRETTY_NAME=" => os_release.pretty_name, "VERSION_ID=" => os_release.version_id, "HOME_URL=" => os_release.home_url, "SUPPORT_URL=" => os_release.support_url, "BUG_REPORT_URL=" => os_release.bug_report_url, "PRIVACY_POLICY_URL=" => os_release.privacy_policy_url, "VERSION_CODENAME=" => os_release.version_codename }); if let Some(pos) = line.find('=') { if line.len() > pos+1 { os_release.extra.insert(line[..pos].to_owned(), line[pos+1..].to_owned()); } } } os_release } } fn open>(path: P) -> io::Result { File::open(&path).map_err(|why| io::Error::new( io::ErrorKind::Other, format!("unable to open file at {:?}: {}", path.as_ref(), why) )) } #[cfg(test)] mod tests { use super::*; const EXAMPLE: &str = r#"NAME="Pop!_OS" VERSION="18.04 LTS" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Pop!_OS 18.04 LTS" VERSION_ID="18.04" HOME_URL="https://system76.com/pop" SUPPORT_URL="http://support.system76.com" BUG_REPORT_URL="https://github.com/pop-os/pop/issues" PRIVACY_POLICY_URL="https://system76.com/privacy" VERSION_CODENAME=bionic EXTRA_KEY=thing ANOTHER_KEY="#; #[test] fn os_release() { let os_release = OsRelease::from_iter(EXAMPLE.lines().map(|x| x.into())); assert_eq!( os_release, OsRelease { name: "Pop!_OS".into(), version: "18.04 LTS".into(), id: "ubuntu".into(), id_like: "debian".into(), pretty_name: "Pop!_OS 18.04 LTS".into(), version_id: "18.04".into(), home_url: "https://system76.com/pop".into(), support_url: "http://support.system76.com".into(), bug_report_url: "https://github.com/pop-os/pop/issues".into(), privacy_policy_url: "https://system76.com/privacy".into(), version_codename: "bionic".into(), extra: { let mut map = BTreeMap::new(); map.insert("EXTRA_KEY".to_owned(), "thing".to_owned()); map } } ) } }