diff --git a/Cargo.lock b/Cargo.lock index f884ec65..84b49853 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1060,6 +1060,11 @@ dependencies = [ "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "result" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-demangle" version = "0.1.13" @@ -1174,6 +1179,16 @@ dependencies = [ "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_ini" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "result 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde_json" version = "1.0.39" @@ -1499,6 +1514,7 @@ dependencies = [ "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "self_update 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_ini 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1830,6 +1846,7 @@ dependencies = [ "checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum reqwest 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3c4ef83e0beb14bfe38b9f01330a5bc8e965a9f9628690aa28383746dac1e925" +"checksum result 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "194d8e591e405d1eecf28819740abed6d719d1a2db87fc0bcdedee9a26d55560" "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" @@ -1844,6 +1861,7 @@ dependencies = [ "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "aa5f7c20820475babd2c077c3ab5f8c77a31c15e16ea38687b4c02d3e48680f4" "checksum serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "58fc82bec244f168b23d1963b45c8bf5726e9a15a9d146a067f9081aeed2de79" +"checksum serde_ini 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb236687e2bb073a7521c021949be944641e671b8505a94069ca37b656c81139" "checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" "checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2" "checksum shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de7a5b5a9142fd278a10e0209b021a1b85849352e6951f4f914735c976737564" diff --git a/Cargo.toml b/Cargo.toml index 2d0aca90..837e3d28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ walkdir = "2.2.7" console = "0.7.5" self_update_crate = { version = "0.5.1", optional = true, package = "self_update" } lazy_static = "1.2.0" +serde_ini = "0.2.0" [target.'cfg(unix)'.dependencies] nix = "0.13.0" diff --git a/src/steps/os/linux.rs b/src/steps/os/linux.rs index da01f350..98fa0f9f 100644 --- a/src/steps/os/linux.rs +++ b/src/steps/os/linux.rs @@ -3,62 +3,64 @@ use crate::executor::RunType; use crate::terminal::{print_separator, print_warning}; use crate::utils::{require, require_option, which}; use failure::ResultExt; +use serde::Deserialize; +use serde_ini; use std::fs; use std::path::PathBuf; use walkdir::WalkDir; +static OS_RELEASE_PATH: &str = "/etc/os-release"; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "UPPERCASE")] +struct OsRelease { + id_like: Option, + id: String, +} + #[derive(Copy, Clone, Debug)] pub enum Distribution { Arch, CentOS, Fedora, Debian, - Ubuntu, Gentoo, - OpenSuse, + Suse, Void, Solus, - Mint, } impl Distribution { + fn parse_os_release() -> Result { + let os_release: OsRelease = + serde_ini::de::from_read(fs::File::open(OS_RELEASE_PATH).context(ErrorKind::UnknownLinuxDistribution)?) + .context(ErrorKind::UnknownLinuxDistribution)?; + + match os_release.id_like.as_ref().map(String::as_str) { + Some("debian") => { + return Ok(Distribution::Debian); + } + Some("\"suse\"") => { + return Ok(Distribution::Suse); + } + _ => (), + } + + if let Some("debian") = os_release.id_like.as_ref().map(String::as_str) {} + + Ok(match os_release.id.as_ref() { + "arch" => Distribution::Arch, + "centos" => Distribution::CentOS, + "fedora" => Distribution::Fedora, + "void" => Distribution::Void, + "solus" => Distribution::Solus, + _ => Err(ErrorKind::UnknownLinuxDistribution)?, + }) + } + pub fn detect() -> Result { - let content = fs::read_to_string("/etc/os-release").context(ErrorKind::UnknownLinuxDistribution)?; - - if content.contains("Arch") | content.contains("Manjaro") | content.contains("Antergos") { - return Ok(Distribution::Arch); - } - - if content.contains("CentOS") || content.contains("Oracle Linux") { - return Ok(Distribution::CentOS); - } - - if content.contains("Fedora") { - return Ok(Distribution::Fedora); - } - - if content.contains("Ubuntu") { - return Ok(Distribution::Ubuntu); - } - - if content.contains("Debian") { - return Ok(Distribution::Debian); - } - - if content.contains("openSUSE") { - return Ok(Distribution::OpenSuse); - } - - if content.contains("void") { - return Ok(Distribution::Void); - } - - if content.contains("Solus") { - return Ok(Distribution::Solus); - } - - if content.contains("Mint") { - return Ok(Distribution::Mint); + if PathBuf::from(OS_RELEASE_PATH).exists() { + return Self::parse_os_release(); } if PathBuf::from("/etc/gentoo-release").exists() { @@ -76,11 +78,9 @@ impl Distribution { Distribution::Arch => upgrade_arch_linux(&sudo, cleanup, run_type), Distribution::CentOS => upgrade_redhat(&sudo, run_type), Distribution::Fedora => upgrade_fedora(&sudo, run_type), - Distribution::Ubuntu | Distribution::Debian | Distribution::Mint => { - upgrade_debian(&sudo, cleanup, run_type) - } + Distribution::Debian => upgrade_debian(&sudo, cleanup, run_type), Distribution::Gentoo => upgrade_gentoo(&sudo, run_type), - Distribution::OpenSuse => upgrade_opensuse(&sudo, run_type), + Distribution::Suse => upgrade_suse(&sudo, run_type), Distribution::Void => upgrade_void(&sudo, run_type), Distribution::Solus => upgrade_solus(&sudo, run_type), } @@ -152,7 +152,7 @@ fn upgrade_redhat(sudo: &Option, run_type: RunType) -> Result<(), Error Ok(()) } -fn upgrade_opensuse(sudo: &Option, run_type: RunType) -> Result<(), Error> { +fn upgrade_suse(sudo: &Option, run_type: RunType) -> Result<(), Error> { if let Some(sudo) = &sudo { run_type .execute(&sudo)