Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make all dependencies optional (#100)
* make all dependencies optional * add a script for running test permutations
- Loading branch information
Showing
16 changed files
with
819 additions
and
409 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
name = "ci" | ||
version = "0.0.0" | ||
authors = ["The Rust Project Developers"] | ||
publish = false | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
mod task; | ||
mod permute; | ||
|
||
fn main() { | ||
let features = [ | ||
"termcolor", | ||
"humantime", | ||
"atty", | ||
"regex", | ||
]; | ||
|
||
// Run a default build | ||
if !task::test(Default::default()) { | ||
panic!("default test execution failed"); | ||
} | ||
|
||
// Run a set of permutations | ||
let failed = permute::all(&features) | ||
.into_iter() | ||
.filter(|features| | ||
!task::test(task::TestArgs { | ||
features: features.clone(), | ||
default_features: false, | ||
lib_only: true, | ||
})) | ||
.collect::<Vec<_>>(); | ||
|
||
if failed.len() > 0 { | ||
for failed in failed { | ||
eprintln!("FAIL: {:?}", failed); | ||
} | ||
|
||
panic!("test execution failed"); | ||
} else { | ||
println!("test execution succeeded"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use std::collections::BTreeSet; | ||
|
||
pub fn all<T>(input: &[T]) -> BTreeSet<BTreeSet<T>> where T: Ord + Eq + Clone { | ||
let mut permutations = BTreeSet::new(); | ||
|
||
if input.len() == 0 { | ||
return permutations; | ||
} | ||
|
||
permutations.insert(input.iter().cloned().collect()); | ||
|
||
if input.len() > 1 { | ||
for t in input { | ||
let mut p = input | ||
.iter() | ||
.filter(|pt| *pt != t) | ||
.cloned() | ||
.collect::<Vec<_>>(); | ||
|
||
for pt in all(&p) { | ||
permutations.insert(pt); | ||
} | ||
} | ||
} | ||
|
||
permutations | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
use std::collections::BTreeSet; | ||
use std::process::{ | ||
Command, | ||
Stdio, | ||
}; | ||
|
||
pub type Feature = &'static str; | ||
|
||
pub struct TestArgs { | ||
pub features: BTreeSet<Feature>, | ||
pub default_features: bool, | ||
pub lib_only: bool, | ||
} | ||
|
||
impl Default for TestArgs { | ||
fn default() -> Self { | ||
TestArgs { | ||
features: BTreeSet::new(), | ||
default_features: true, | ||
lib_only: false, | ||
} | ||
} | ||
} | ||
|
||
impl TestArgs { | ||
fn features_string(&self) -> Option<String> { | ||
if self.features.len() == 0 { | ||
return None; | ||
} | ||
|
||
let s = self.features.iter().fold(String::new(), |mut s, f| { | ||
if s.len() > 0 { | ||
s.push_str(" "); | ||
} | ||
s.push_str(f); | ||
|
||
s | ||
}); | ||
|
||
Some(s) | ||
} | ||
} | ||
|
||
pub fn test(args: TestArgs) -> bool { | ||
let features = args.features_string(); | ||
|
||
let mut command = Command::new("cargo"); | ||
|
||
command | ||
.stdout(Stdio::inherit()) | ||
.stderr(Stdio::inherit()) | ||
.arg("test") | ||
.arg("--verbose"); | ||
|
||
if !args.default_features { | ||
command.arg("--no-default-features"); | ||
} | ||
|
||
if args.lib_only { | ||
command.arg("--lib"); | ||
} | ||
|
||
if let Some(ref features) = features { | ||
command.args(&["--features", features]); | ||
} | ||
|
||
println!("running {:?}", command); | ||
|
||
let status = command | ||
.status() | ||
.expect("Failed to execute command"); | ||
|
||
if !status.success() { | ||
eprintln!("test execution failed for features: {}", features.as_ref().map(AsRef::as_ref).unwrap_or("")); | ||
false | ||
} else { | ||
true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
This internal module contains the terminal detection implementation. | ||
If the `atty` crate is available then we use it to detect whether we're | ||
attached to a particular TTY. If the `atty` crate is not available we | ||
assume we're not attached to anything. This effectively prevents styles | ||
from being printed. | ||
*/ | ||
|
||
#[cfg(feature = "atty")] | ||
mod imp { | ||
use atty; | ||
|
||
pub(in ::fmt) fn is_stdout() -> bool { | ||
atty::is(atty::Stream::Stdout) | ||
} | ||
|
||
pub(in ::fmt) fn is_stderr() -> bool { | ||
atty::is(atty::Stream::Stderr) | ||
} | ||
} | ||
|
||
#[cfg(not(feature = "atty"))] | ||
mod imp { | ||
pub(in ::fmt) fn is_stdout() -> bool { | ||
false | ||
} | ||
|
||
pub(in ::fmt) fn is_stderr() -> bool { | ||
false | ||
} | ||
} | ||
|
||
pub(in ::fmt) use self::imp::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
use std::fmt; | ||
use std::time::SystemTime; | ||
|
||
use humantime::{format_rfc3339_nanos, format_rfc3339_seconds}; | ||
|
||
use ::fmt::Formatter; | ||
|
||
pub(in ::fmt) mod pub_use_in_super { | ||
pub use super::*; | ||
} | ||
|
||
impl Formatter { | ||
/// Get a [`Timestamp`] for the current date and time in UTC. | ||
/// | ||
/// # Examples | ||
/// | ||
/// Include the current timestamp with the log record: | ||
/// | ||
/// ``` | ||
/// use std::io::Write; | ||
/// | ||
/// let mut builder = env_logger::Builder::new(); | ||
/// | ||
/// builder.format(|buf, record| { | ||
/// let ts = buf.timestamp(); | ||
/// | ||
/// writeln!(buf, "{}: {}: {}", ts, record.level(), record.args()) | ||
/// }); | ||
/// ``` | ||
/// | ||
/// [`Timestamp`]: struct.Timestamp.html | ||
pub fn timestamp(&self) -> Timestamp { | ||
Timestamp(SystemTime::now()) | ||
} | ||
|
||
/// Get a [`PreciseTimestamp`] for the current date and time in UTC with nanos. | ||
pub fn precise_timestamp(&self) -> PreciseTimestamp { | ||
PreciseTimestamp(SystemTime::now()) | ||
} | ||
} | ||
|
||
/// An [RFC3339] formatted timestamp. | ||
/// | ||
/// The timestamp implements [`Display`] and can be written to a [`Formatter`]. | ||
/// | ||
/// [RFC3339]: https://www.ietf.org/rfc/rfc3339.txt | ||
/// [`Display`]: https://doc.rust-lang.org/stable/std/fmt/trait.Display.html | ||
/// [`Formatter`]: struct.Formatter.html | ||
pub struct Timestamp(SystemTime); | ||
|
||
/// An [RFC3339] formatted timestamp with nanos. | ||
/// | ||
/// [RFC3339]: https://www.ietf.org/rfc/rfc3339.txt | ||
#[derive(Debug)] | ||
pub struct PreciseTimestamp(SystemTime); | ||
|
||
impl fmt::Debug for Timestamp { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
/// A `Debug` wrapper for `Timestamp` that uses the `Display` implementation. | ||
struct TimestampValue<'a>(&'a Timestamp); | ||
|
||
impl<'a> fmt::Debug for TimestampValue<'a> { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
fmt::Display::fmt(&self.0, f) | ||
} | ||
} | ||
|
||
f.debug_tuple("Timestamp") | ||
.field(&TimestampValue(&self)) | ||
.finish() | ||
} | ||
} | ||
|
||
impl fmt::Display for Timestamp { | ||
fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { | ||
format_rfc3339_seconds(self.0).fmt(f) | ||
} | ||
} | ||
|
||
impl fmt::Display for PreciseTimestamp { | ||
fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { | ||
format_rfc3339_nanos(self.0).fmt(f) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* | ||
This internal module contains the timestamp implementation. | ||
Its public API is available when the `humantime` crate is available. | ||
*/ | ||
|
||
#[cfg_attr(feature = "humantime", path = "extern_impl.rs")] | ||
#[cfg_attr(not(feature = "humantime"), path = "shim_impl.rs")] | ||
mod imp; | ||
|
||
pub(in ::fmt) use self::imp::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/* | ||
Timestamps aren't available when we don't have a `humantime` dependency. | ||
*/ | ||
|
||
pub(in ::fmt) mod pub_use_in_super { | ||
|
||
} |
Oops, something went wrong.