#![warn(missing_docs)]
extern crate semver;
use semver::{Version, VersionReq, Identifier};
use std::process::Command;
use std::env;
use std::ffi::OsString;
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Channel {
Dev,
Nightly,
Beta,
Stable,
}
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct VersionMeta {
pub semver: Version,
pub git_short_hash: String,
pub date: String,
pub channel: Channel
}
pub fn version() -> Version {
version_meta().semver
}
pub fn version_meta() -> VersionMeta {
let cmd = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
let out = Command::new(&cmd)
.arg("--version")
.output()
.unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
let version_string = String::from_utf8(out.stdout).unwrap();
let mut parts_iter = version_string.split_whitespace();
let rustc_string = parts_iter.next().unwrap();
assert!(rustc_string == "rustc");
let version_string = parts_iter.next().unwrap();
let version = Version::parse(version_string).unwrap();
let hash_string = parts_iter.next().unwrap();
assert!(hash_string.starts_with('('));
let hash_string = &hash_string[1..];
let date_string = parts_iter.next().unwrap();
assert!(date_string.ends_with(')'));
let date_string = &date_string[..date_string.len() - 1];
let channel = if version.pre.is_empty() {
Channel::Stable
} else {
match version.pre[0] {
Identifier::AlphaNumeric(ref s)
if s == "dev" => Channel::Dev,
Identifier::AlphaNumeric(ref s)
if s == "beta" => Channel::Beta,
Identifier::AlphaNumeric(ref s)
if s == "nightly" => Channel::Nightly,
_ => panic!(),
}
};
VersionMeta {
semver: version,
git_short_hash: hash_string.to_string(),
date: date_string.to_string(),
channel: channel,
}
}
pub fn version_matches(req: &str) -> bool {
VersionReq::parse(req).unwrap().matches(&version())
}
#[test]
fn smoketest() {
let v = version();
assert!(v.major >= 1);
assert!(v.minor >= 2);
let v = version_meta();
assert!(v.semver.major >= 1);
assert!(v.semver.minor >= 2);
assert!(version_matches(">= 1.2.0"));
}