]> git.lizzy.rs Git - rust.git/blob - src/tools/tidy/src/deps.rs
3bf396db4d39da9fe845523b35bdf7993218749d
[rust.git] / src / tools / tidy / src / deps.rs
1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Check license of third-party deps by inspecting src/vendor
12
13 use std::fs::File;
14 use std::io::Read;
15 use std::path::Path;
16
17 static LICENSES: &'static [&'static str] = &[
18     "MIT/Apache-2.0",
19     "MIT / Apache-2.0",
20     "Apache-2.0/MIT",
21     "MIT OR Apache-2.0",
22     "MIT",
23     "Unlicense/MIT",
24 ];
25
26 /// These MPL licensed projects are acceptable, but only these.
27 static EXCEPTIONS: &'static [&'static str] = &[
28     "mdbook",
29     "openssl",
30     "pest",
31     "thread-id",
32 ];
33
34 pub fn check(path: &Path, bad: &mut bool) {
35     let path = path.join("vendor");
36     assert!(path.exists(), "vendor directory missing");
37     let mut saw_dir = false;
38     'next_path: for dir in t!(path.read_dir()) {
39         saw_dir = true;
40         let dir = t!(dir);
41
42         // skip our exceptions
43         for exception in EXCEPTIONS {
44             if dir.path()
45                 .to_str()
46                 .unwrap()
47                 .contains(&format!("src/vendor/{}", exception)) {
48                 continue 'next_path;
49             }
50         }
51
52         let toml = dir.path().join("Cargo.toml");
53         if !check_license(&toml) {
54             *bad = true;
55         }
56     }
57     assert!(saw_dir, "no vendored source");
58 }
59
60 fn check_license(path: &Path) -> bool {
61     if !path.exists() {
62         panic!("{} does not exist", path.display());
63     }
64     let mut contents = String::new();
65     t!(t!(File::open(path)).read_to_string(&mut contents));
66
67     let mut found_license = false;
68     for line in contents.lines() {
69         if !line.starts_with("license") {
70             continue;
71         }
72         let license = extract_license(line);
73         if !LICENSES.contains(&&*license) {
74             println!("invalid license {} in {}", license, path.display());
75             return false;
76         }
77         found_license = true;
78         break;
79     }
80     if !found_license {
81         println!("no license in {}", path.display());
82         return false;
83     }
84
85     true
86 }
87
88 fn extract_license(line: &str) -> String {
89     let first_quote = line.find('"');
90     let last_quote = line.rfind('"');
91     if let (Some(f), Some(l)) = (first_quote, last_quote) {
92         let license = &line[f + 1 .. l];
93         license.into()
94     } else {
95         "bad-license-parse".into()
96     }
97 }