Start adding a whitelist for rustc dependencies

This commit is contained in:
Mark Mansi 2018-02-22 19:52:56 -06:00
parent 2cb8c5fff6
commit 3ee410498d
4 changed files with 82 additions and 9 deletions

5
src/Cargo.lock generated
View File

@ -2585,6 +2585,11 @@ dependencies = [
[[package]]
name = "tidy"
version = "0.1.0"
dependencies = [
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"

View File

@ -2,3 +2,8 @@
name = "tidy"
version = "0.1.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
[dependencies]
serde = "1.0.8"
serde_derive = "1.0.8"
serde_json = "1.0.2"

View File

@ -14,6 +14,10 @@ use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::process::Command;
use serde_json;
static LICENSES: &'static [&'static str] = &[
"MIT/Apache-2.0",
"MIT / Apache-2.0",
@ -44,31 +48,68 @@ static EXCEPTIONS: &'static [&'static str] = &[
"clippy_lints", // MPL-2.0 rls
];
// Whitelist of crates rustc is allowed to depend on. Avoid adding to the list if possible.
static WHITELIST: &'static [(&'static str, &'static str)] = &[];
// Some type for Serde to deserialize the output of `cargo metadata` to...
#[derive(Deserialize)]
struct Output {
packages: Vec<Package>,
_resolve: String,
}
#[derive(Deserialize)]
struct Package {
_id: String,
name: String,
version: String,
_source: Option<String>,
_manifest_path: String,
}
/// Checks the dependency at the given path. Changes `bad` to `true` if a check failed.
///
/// Specifically, this checks that the license is correct and that the dependencies are on the
/// whitelist.
pub fn check(path: &Path, bad: &mut bool) {
// Check licences
let path = path.join("vendor");
assert!(path.exists(), "vendor directory missing");
let mut saw_dir = false;
'next_path: for dir in t!(path.read_dir()) {
for dir in t!(path.read_dir()) {
saw_dir = true;
let dir = t!(dir);
// skip our exceptions
for exception in EXCEPTIONS {
if dir.path()
if EXCEPTIONS.iter().any(|exception| {
dir.path()
.to_str()
.unwrap()
.contains(&format!("src/vendor/{}", exception))
{
continue 'next_path;
}
}) {
continue;
}
let toml = dir.path().join("Cargo.toml");
if !check_license(&toml) {
*bad = true;
}
*bad = *bad || !check_license(&toml);
}
assert!(saw_dir, "no vendored source");
// Check dependencies
let deps = get_deps(&path);
*bad = *bad
|| deps.iter().any(
|&Package {
ref name,
ref version,
..
}| {
WHITELIST
.iter()
.all(|&(wname, wversion)| name != wname || version != wversion)
},
);
}
fn check_license(path: &Path) -> bool {
@ -109,3 +150,20 @@ fn extract_license(line: &str) -> String {
"bad-license-parse".into()
}
}
fn get_deps(path: &Path) -> Vec<Package> {
// Run `cargo metadata` to get the set of dependencies
let output = Command::new("cargo")
.arg("metadata")
.arg("--format-version")
.arg("1")
.arg("--manifest-path")
.arg(path.join("Cargo.toml"))
.output()
.expect("Unable to run `cargo metadata`")
.stdout;
let output = String::from_utf8_lossy(&output);
let output: Output = serde_json::from_str(&output).unwrap();
output.packages
}

View File

@ -15,6 +15,11 @@
#![deny(warnings)]
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
use std::fs;
use std::path::Path;