@@ -21,38 +21,33 @@ const LICENSES: &[&str] = &[
2121/// should be considered bugs. Exceptions are only allowed in Rust
2222/// tooling. It is _crucial_ that no exception crates be dependencies
2323/// of the Rust runtime (std/test).
24- const EXCEPTIONS : & [ & str ] = & [
25- "mdbook" , // MPL2, mdbook
26- "openssl" , // BSD+advertising clause, cargo, mdbook
27- "pest" , // MPL2, mdbook via handlebars
28- "arrayref" , // BSD-2-Clause, mdbook via handlebars via pest
29- "toml-query" , // MPL-2.0, mdbook
30- "toml-query_derive" , // MPL-2.0, mdbook
31- "is-match" , // MPL-2.0, mdbook
32- "smallvec" , // MPL-2.0, rustdoc
33- "rdrand" , // ISC, mdbook, rustfmt
34- "fuchsia-cprng" , // BSD-3-Clause, mdbook, rustfmt
35- "fuchsia-zircon-sys" , // BSD-3-Clause, rustdoc, rustc, cargo
36- "fuchsia-zircon" , // BSD-3-Clause, rustdoc, rustc, cargo (jobserver & tempdir)
37- "clippy_lints" , // MPL-2.0, rls
38- "colored" , // MPL-2.0, rustfmt
39- "ordslice" , // Apache-2.0, rls
40- "cloudabi" , // BSD-2-Clause, (rls -> crossbeam-channel 0.2 -> rand 0.5)
41- "ryu" , // Apache-2.0, rls/cargo/... (because of serde)
42- "bytesize" , // Apache-2.0, cargo
43- "im-rc" , // MPL-2.0+, cargo
44- "adler32" , // BSD-3-Clause AND Zlib, cargo dep that isn't used
45- "constant_time_eq" , // CC0-1.0, rustfmt
46- "utf8parse" , // Apache-2.0 OR MIT, cargo via strip-ansi-escapes
47- "vte" , // Apache-2.0 OR MIT, cargo via strip-ansi-escapes
48- "sized-chunks" , // MPL-2.0+, cargo via im-rc
49- "bitmaps" , // MPL-2.0+, cargo via im-rc
24+ const EXCEPTIONS : & [ ( & str , & str ) ] = & [
25+ ( "mdbook" , "MPL-2.0" ) , // mdbook
26+ ( "openssl" , "Apache-2.0" ) , // cargo, mdbook
27+ ( "arrayref" , "BSD-2-Clause" ) , // mdbook via handlebars via pest
28+ ( "toml-query" , "MPL-2.0" ) , // mdbook
29+ ( "toml-query_derive" , "MPL-2.0" ) , // mdbook
30+ ( "is-match" , "MPL-2.0" ) , // mdbook
31+ ( "rdrand" , "ISC" ) , // mdbook, rustfmt
32+ ( "fuchsia-cprng" , "BSD-3-Clause" ) , // mdbook, rustfmt
33+ ( "fuchsia-zircon-sys" , "BSD-3-Clause" ) , // rustdoc, rustc, cargo
34+ ( "fuchsia-zircon" , "BSD-3-Clause" ) , // rustdoc, rustc, cargo (jobserver & tempdir)
35+ ( "colored" , "MPL-2.0" ) , // rustfmt
36+ ( "ordslice" , "Apache-2.0" ) , // rls
37+ ( "cloudabi" , "BSD-2-Clause" ) , // (rls -> crossbeam-channel 0.2 -> rand 0.5)
38+ ( "ryu" , "Apache-2.0 OR BSL-1.0" ) , // rls/cargo/... (because of serde)
39+ ( "bytesize" , "Apache-2.0" ) , // cargo
40+ ( "im-rc" , "MPL-2.0+" ) , // cargo
41+ ( "adler32" , "BSD-3-Clause AND Zlib" ) , // cargo dep that isn't used
42+ ( "constant_time_eq" , "CC0-1.0" ) , // rustfmt
43+ ( "sized-chunks" , "MPL-2.0+" ) , // cargo via im-rc
44+ ( "bitmaps" , "MPL-2.0+" ) , // cargo via im-rc
5045 // FIXME: this dependency violates the documentation comment above:
51- "fortanix-sgx-abi" , // MPL-2.0+, libstd but only for `sgx` target
52- "dunce" , // CC0-1.0 mdbook-linkcheck
53- "codespan-reporting" , // Apache-2.0 mdbook-linkcheck
54- "codespan" , // Apache-2.0 mdbook-linkcheck
55- "crossbeam-channel" , // MIT/Apache-2.0 AND BSD-2-Clause, cargo
46+ ( "fortanix-sgx-abi" , " MPL-2.0" ) , // libstd but only for `sgx` target
47+ ( "dunce" , "CC0-1.0" ) , // mdbook-linkcheck
48+ ( "codespan-reporting" , " Apache-2.0" ) , // mdbook-linkcheck
49+ ( "codespan" , "Apache-2.0" ) , // mdbook-linkcheck
50+ ( "crossbeam-channel" , " MIT/Apache-2.0 AND BSD-2-Clause" ) , // cargo
5651] ;
5752
5853/// Which crates to check against the whitelist?
@@ -193,24 +188,53 @@ pub fn check(path: &Path, cargo: &Path, bad: &mut bool) {
193188///
194189/// Packages listed in `EXCEPTIONS` are allowed for tools.
195190fn check_exceptions ( metadata : & Metadata , bad : & mut bool ) {
196- // Check that the EXCEPTIONS list does not have unused entries.
197- for exception in EXCEPTIONS {
198- if !metadata. packages . iter ( ) . any ( |p| p. name == * exception) {
191+ // Validate the EXCEPTIONS list hasn't changed.
192+ for ( name, license) in EXCEPTIONS {
193+ // Check that the package actually exists.
194+ if !metadata. packages . iter ( ) . any ( |p| p. name == * name) {
199195 println ! (
200196 "could not find exception package `{}`\n \
201197 Remove from EXCEPTIONS list if it is no longer used.",
202- exception
198+ name
203199 ) ;
204200 * bad = true ;
205201 }
202+ // Check that the license hasn't changed.
203+ for pkg in metadata. packages . iter ( ) . filter ( |p| p. name == * name) {
204+ if pkg. name == "fuchsia-cprng" {
205+ // This package doesn't declare a license expression. Manual
206+ // inspection of the license file is necessary, which appears
207+ // to be BSD-3-Clause.
208+ assert ! ( pkg. license. is_none( ) ) ;
209+ continue ;
210+ }
211+ match & pkg. license {
212+ None => {
213+ println ! (
214+ "dependency exception `{}` does not declare a license expression" ,
215+ pkg. id
216+ ) ;
217+ * bad = true ;
218+ }
219+ Some ( pkg_license) => {
220+ if pkg_license. as_str ( ) != * license {
221+ println ! ( "dependency exception `{}` license has changed" , name) ;
222+ println ! ( " previously `{}` now `{}`" , license, pkg_license) ;
223+ println ! ( " update EXCEPTIONS for the new license" ) ;
224+ * bad = true ;
225+ }
226+ }
227+ }
228+ }
206229 }
230+ let exception_names: Vec < _ > = EXCEPTIONS . iter ( ) . map ( |( name, _license) | * name) . collect ( ) ;
207231 // Check if any package does not have a valid license.
208232 for pkg in & metadata. packages {
209233 if pkg. source . is_none ( ) {
210234 // No need to check local packages.
211235 continue ;
212236 }
213- if EXCEPTIONS . contains ( & pkg. name . as_str ( ) ) {
237+ if exception_names . contains ( & pkg. name . as_str ( ) ) {
214238 continue ;
215239 }
216240 let license = match & pkg. license {
0 commit comments