Better Linux distribution detection (fix #146)

This commit is contained in:
Roey Darwish Dror
2019-05-07 16:21:51 +03:00
parent 6186eadb70
commit 9f054308c8
3 changed files with 63 additions and 44 deletions

18
Cargo.lock generated
View File

@@ -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"

View File

@@ -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"

View File

@@ -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<String>,
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<Self, Error> {
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<Self, Error> {
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<PathBuf>, run_type: RunType) -> Result<(), Error
Ok(())
}
fn upgrade_opensuse(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error> {
fn upgrade_suse(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error> {
if let Some(sudo) = &sudo {
run_type
.execute(&sudo)