Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config.toml with support for blacklisting crates #182

Merged
merged 2 commits into from
Feb 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# This file allows to customize how crater treats specific crates/repos
#
# The available options for each crate/repo are:
# - skip (bool): ignore this crate/repo
# - skip-tests (bool): don't run tests in this crate/repo
# - quiet (bool): don't kill after two minutes without output
#
# Please add a comment along with each entry explaining the reasons of the
# changes, thanks!


[crates]
# crate_name = { option = true }

[github-repos]
# "org_name/repo_name" = { option = true }
11 changes: 7 additions & 4 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//! application state employs ownership techniques to ensure that
//! parallel access is consistent and race-free.

use crater::config::Config;
use crater::docker;
use crater::errors::*;
use crater::ex;
Expand Down Expand Up @@ -178,6 +179,8 @@ pub enum Crater {

impl Crater {
pub fn run(&self) -> Result<()> {
let config = Config::load()?;

match *self {
Crater::CreateLists => lists::create_all_lists(true)?,
Crater::PrepareLocal { ref env } => {
Expand Down Expand Up @@ -224,13 +227,13 @@ impl Crater {
ref krate,
} => ex_run::delete_result(&ex.0, tc.as_ref(), krate)?,
Crater::Run { ref ex } => {
ex_run::run_ex_all_tcs(&ex.0)?;
ex_run::run_ex_all_tcs(&ex.0, &config)?;
}
Crater::RunTc { ref ex, ref tc } => {
ex_run::run_ex(&ex.0, tc.clone())?;
ex_run::run_ex(&ex.0, tc.clone(), &config)?;
}
Crater::GenReport { ref ex, ref dest } => {
report::gen(&ex.0, &report::FileWriter::create(dest.0.clone())?)?;
report::gen(&ex.0, &report::FileWriter::create(dest.0.clone())?, &config)?;
}
Crater::PublishReport {
ref ex,
Expand All @@ -244,7 +247,7 @@ impl Crater {
prefix
}
};
report::gen(&ex.0, &report::S3Writer::create(s3_prefix)?)?;
report::gen(&ex.0, &report::S3Writer::create(s3_prefix)?, &config)?;
}
Crater::Serve => {
server::start(server::Data);
Expand Down
102 changes: 102 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use errors::*;
use ex::ExCrate;
use std::collections::HashMap;
use std::fs::File;
use std::io::Read;

static CONFIG_FILE: &'static str = "config.toml";

#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct CrateConfig {
#[serde(default = "default_false")]
skip: bool,
#[serde(default = "default_false")]
skip_tests: bool,
#[serde(default = "default_false")]
quiet: bool,
}

fn default_false() -> bool {
false
}

#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Config {
crates: HashMap<String, CrateConfig>,
github_repos: HashMap<String, CrateConfig>,
}

impl Config {
pub fn load() -> Result<Self> {
let mut buffer = String::new();
File::open(CONFIG_FILE)?.read_to_string(&mut buffer)?;

Ok(::toml::from_str(&buffer)?)
}

fn crate_config(&self, ex: &ExCrate) -> Option<&CrateConfig> {
match *ex {
ExCrate::Version { ref name, .. } => self.crates.get(name),
ExCrate::Repo {
ref org, ref name, ..
} => {
let repo_name = format!("{}/{}", org, name);
self.github_repos.get(&repo_name)
}
}
}

pub fn should_skip(&self, ex: &ExCrate) -> bool {
self.crate_config(ex).map(|c| c.skip).unwrap_or(false)
}

pub fn should_skip_tests(&self, ex: &ExCrate) -> bool {
self.crate_config(ex).map(|c| c.skip_tests).unwrap_or(false)
}

pub fn is_quiet(&self, ex: &ExCrate) -> bool {
self.crate_config(ex).map(|c| c.quiet).unwrap_or(false)
}
}

#[cfg(test)]
mod tests {
use super::Config;
use ex::ExCrate;

#[test]
fn test_config() {
// A sample config file loaded from memory
let config = concat!(
"[crates]\n",
"lazy_static = { skip = true }\n",
"\n",
"[github-repos]\n",
"\"rust-lang/rust\" = { quiet = true }\n" // :(
);

let list: Config = ::toml::from_str(&config).unwrap();

assert!(list.should_skip(&ExCrate::Version {
name: "lazy_static".into(),
version: "42".into(),
}));
assert!(!list.should_skip(&ExCrate::Version {
name: "rand".into(),
version: "42".into(),
}));

assert!(list.is_quiet(&ExCrate::Repo {
org: "rust-lang".into(),
name: "rust".into(),
sha: "0".into(),
}));
assert!(!list.is_quiet(&ExCrate::Repo {
org: "rust-lang".into(),
name: "cargo".into(),
sha: "0".into(),
}));
}
}
21 changes: 11 additions & 10 deletions src/docker.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use errors::*;
use run;
use run::RunCommand;
use std::env;
use std::fmt::{self, Display, Formatter};
use std::fs;
Expand All @@ -12,11 +12,10 @@ static IMAGE_NAME: &'static str = "crater";
/// to exist in the `docker` directory, at runtime.
pub fn build_container(docker_env: &str) -> Result<()> {
let dockerfile = format!("docker/Dockerfile.{}", docker_env);
run::run(
RunCommand::new(
"docker",
&["build", "-f", &dockerfile, "-t", IMAGE_NAME, "docker"],
&[],
)
).run()
}

#[derive(Copy, Clone)]
Expand Down Expand Up @@ -60,14 +59,14 @@ pub struct ContainerConfig<'a> {
pub env: Vec<(&'static str, String)>,
}

pub fn run(config: &ContainerConfig) -> Result<()> {
pub fn run(config: &ContainerConfig, quiet: bool) -> Result<()> {
let c = Container::create_container(config)?;
defer!{{
if let Err(e) = c.delete() {
error!{"Cannot delete container: {}", e; "container" => &c.id}
}
}}
c.run()
c.run(quiet)
}

pub fn rust_container(config: RustEnv) -> ContainerConfig {
Expand Down Expand Up @@ -157,15 +156,17 @@ impl Container {
}
args.push(config.image_name.into());

let (out, _) = run::run_capture(None, "docker", &*args, &[])?;
let (out, _) = RunCommand::new("docker", &*args).run_capture()?;
Ok(Self { id: out[0].clone() })
}

pub fn run(&self) -> Result<()> {
run::run("docker", &["start", "-a", &self.id], &[])
pub fn run(&self, quiet: bool) -> Result<()> {
RunCommand::new("docker", &["start", "-a", &self.id])
.quiet(quiet)
.run()
}

pub fn delete(&self) -> Result<()> {
run::run("docker", &["rm", "-f", &self.id], &[])
RunCommand::new("docker", &["rm", "-f", &self.id]).run()
}
}
1 change: 1 addition & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ error_chain! {
SerdeJson(::serde_json::Error);
ReqwestError(::reqwest::Error);
RustupError(::rustup_dist::Error);
TomlDe(::toml::de::Error);
}

links {
Expand Down
10 changes: 6 additions & 4 deletions src/ex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ex_run;
use file;
use gh_mirrors;
use lists::{self, Crate, List};
use run;
use run::RunCommand;
use serde_json;
use std::collections::HashMap;
use std::fmt::{self, Display, Formatter};
Expand Down Expand Up @@ -194,7 +194,9 @@ fn capture_shas(ex: &Experiment) -> Result<()> {
for krate in &ex.crates {
if let Crate::Repo { ref url } = *krate {
let dir = gh_mirrors::repo_dir(url)?;
let r = run::run_capture(Some(&dir), "git", &["log", "-n1", "--pretty=%H"], &[]);
let r = RunCommand::new("git", &["log", "-n1", "--pretty=%H"])
.cd(&dir)
.run_capture();

match r {
Ok((stdout, _)) => if let Some(shaline) = stdout.get(0) {
Expand Down Expand Up @@ -457,7 +459,7 @@ fn capture_lockfile(
) -> Result<()> {
let args = &["generate-lockfile", "--manifest-path", "Cargo.toml"];
toolchain
.run_cargo(&ex.name, path, args, CargoState::Unlocked)
.run_cargo(&ex.name, path, args, CargoState::Unlocked, false)
.chain_err(|| format!("unable to generate lockfile for {}", crate_))?;

let src_lockfile = &path.join("Cargo.lock");
Expand Down Expand Up @@ -507,7 +509,7 @@ fn fetch_deps(ex: &Experiment, toolchain: &Toolchain) -> Result<()> {

let args = &["fetch", "--locked", "--manifest-path", "Cargo.toml"];
toolchain
.run_cargo(&ex.name, path, args, CargoState::Unlocked)
.run_cargo(&ex.name, path, args, CargoState::Unlocked, false)
.chain_err(|| format!("unable to fetch deps for {}", c))?;

Ok(())
Expand Down
Loading