@@ -31,12 +31,34 @@ const LICENSES: &[&str] = &[
3131 // tidy-alphabetical-end
3232] ;
3333
34+ type ExceptionList = & ' static [ ( & ' static str , & ' static str ) ] ;
35+
36+ /// The workspaces to check for licensing and optionally permitted dependencies.
37+ ///
38+ /// Each entry consists of a tuple with the following elements:
39+ ///
40+ /// * The path to the workspace root Cargo.toml file.
41+ /// * The list of license exceptions.
42+ /// * Optionally a tuple of:
43+ /// * A list of crates for which dependencies need to be explicitly allowed.
44+ /// * The list of allowed dependencies.
45+ const WORKSPACES : & [ ( & str , ExceptionList , Option < ( & [ & str ] , & [ & str ] ) > ) ] = & [
46+ ( "Cargo.toml" , EXCEPTIONS , Some ( ( & [ "rustc-main" ] , PERMITTED_RUSTC_DEPENDENCIES ) ) ) ,
47+ ( "src/tools/cargo/Cargo.toml" , EXCEPTIONS_CARGO , None ) ,
48+ (
49+ "compiler/rustc_codegen_cranelift/Cargo.toml" ,
50+ EXCEPTIONS_CRANELIFT ,
51+ Some ( ( & [ "rustc_codegen_cranelift" ] , PERMITTED_CRANELIFT_DEPENDENCIES ) ) ,
52+ ) ,
53+ ( "src/bootstrap/Cargo.toml" , EXCEPTIONS_BOOTSTRAP , None ) ,
54+ ] ;
55+
3456/// These are exceptions to Rust's permissive licensing policy, and
3557/// should be considered bugs. Exceptions are only allowed in Rust
3658/// tooling. It is _crucial_ that no exception crates be dependencies
3759/// of the Rust runtime (std/test).
3860#[ rustfmt:: skip]
39- const EXCEPTIONS : & [ ( & str , & str ) ] = & [
61+ const EXCEPTIONS : ExceptionList = & [
4062 // tidy-alphabetical-start
4163 ( "ar_archive_writer" , "Apache-2.0 WITH LLVM-exception" ) , // rustc
4264 ( "colored" , "MPL-2.0" ) , // rustfmt
@@ -55,7 +77,7 @@ const EXCEPTIONS: &[(&str, &str)] = &[
5577 // tidy-alphabetical-end
5678] ;
5779
58- const EXCEPTIONS_CARGO : & [ ( & str , & str ) ] = & [
80+ const EXCEPTIONS_CARGO : ExceptionList = & [
5981 // tidy-alphabetical-start
6082 ( "bitmaps" , "MPL-2.0+" ) ,
6183 ( "bytesize" , "Apache-2.0" ) ,
@@ -78,7 +100,7 @@ const EXCEPTIONS_CARGO: &[(&str, &str)] = &[
78100 // tidy-alphabetical-end
79101] ;
80102
81- const EXCEPTIONS_CRANELIFT : & [ ( & str , & str ) ] = & [
103+ const EXCEPTIONS_CRANELIFT : ExceptionList = & [
82104 // tidy-alphabetical-start
83105 ( "cranelift-bforest" , "Apache-2.0 WITH LLVM-exception" ) ,
84106 ( "cranelift-codegen" , "Apache-2.0 WITH LLVM-exception" ) ,
@@ -99,7 +121,7 @@ const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[
99121 // tidy-alphabetical-end
100122] ;
101123
102- const EXCEPTIONS_BOOTSTRAP : & [ ( & str , & str ) ] = & [
124+ const EXCEPTIONS_BOOTSTRAP : ExceptionList = & [
103125 ( "ryu" , "Apache-2.0 OR BSL-1.0" ) , // through serde
104126] ;
105127
@@ -383,54 +405,40 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
383405/// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path
384406/// to the cargo executable.
385407pub fn check ( root : & Path , cargo : & Path , bad : & mut bool ) {
386- let mut cmd = cargo_metadata:: MetadataCommand :: new ( ) ;
387- cmd. cargo_path ( cargo)
388- . manifest_path ( root. join ( "Cargo.toml" ) )
389- . features ( cargo_metadata:: CargoOpt :: AllFeatures ) ;
390- let metadata = t ! ( cmd. exec( ) ) ;
391-
392- let runtime_ids = compute_runtime_crates ( & metadata) ;
393- check_runtime_license_exceptions ( & metadata, runtime_ids, bad) ;
394-
395- check_license_exceptions ( & metadata, EXCEPTIONS , bad) ;
396- check_permitted_dependencies (
397- & metadata,
398- "rustc" ,
399- PERMITTED_RUSTC_DEPENDENCIES ,
400- & [ "rustc-main" ] ,
401- bad,
402- ) ;
403-
404- // Check cargo independently as it has it's own workspace.
405- let mut cmd = cargo_metadata:: MetadataCommand :: new ( ) ;
406- cmd. cargo_path ( cargo)
407- . manifest_path ( root. join ( "src/tools/cargo/Cargo.toml" ) )
408- . features ( cargo_metadata:: CargoOpt :: AllFeatures ) ;
409- let cargo_metadata = t ! ( cmd. exec( ) ) ;
410- check_license_exceptions ( & cargo_metadata, EXCEPTIONS_CARGO , bad) ;
411- check_rustfix ( & metadata, & cargo_metadata, bad) ;
412-
413- // Check rustc_codegen_cranelift independently as it has it's own workspace.
414- let mut cmd = cargo_metadata:: MetadataCommand :: new ( ) ;
415- cmd. cargo_path ( cargo)
416- . manifest_path ( root. join ( "compiler/rustc_codegen_cranelift/Cargo.toml" ) )
417- . features ( cargo_metadata:: CargoOpt :: AllFeatures ) ;
418- let metadata = t ! ( cmd. exec( ) ) ;
419- check_license_exceptions ( & metadata, EXCEPTIONS_CRANELIFT , bad) ;
420- check_permitted_dependencies (
421- & metadata,
422- "cranelift" ,
423- PERMITTED_CRANELIFT_DEPENDENCIES ,
424- & [ "rustc_codegen_cranelift" ] ,
425- bad,
426- ) ;
427-
428- let mut cmd = cargo_metadata:: MetadataCommand :: new ( ) ;
429- cmd. cargo_path ( cargo)
430- . manifest_path ( root. join ( "src/bootstrap/Cargo.toml" ) )
431- . features ( cargo_metadata:: CargoOpt :: AllFeatures ) ;
432- let metadata = t ! ( cmd. exec( ) ) ;
433- check_license_exceptions ( & metadata, EXCEPTIONS_BOOTSTRAP , bad) ;
408+ let mut checked_runtime_licenses = false ;
409+ let mut rust_metadata = None ;
410+
411+ for & ( workspace, exceptions, permitted_deps) in WORKSPACES {
412+ let mut cmd = cargo_metadata:: MetadataCommand :: new ( ) ;
413+ cmd. cargo_path ( cargo)
414+ . manifest_path ( root. join ( workspace) )
415+ . features ( cargo_metadata:: CargoOpt :: AllFeatures ) ;
416+ let metadata = t ! ( cmd. exec( ) ) ;
417+
418+ check_license_exceptions ( & metadata, exceptions, bad) ;
419+ if let Some ( ( crates, permitted_deps) ) = permitted_deps {
420+ check_permitted_dependencies ( & metadata, workspace, permitted_deps, crates, bad) ;
421+ }
422+
423+ if workspace == "Cargo.toml" {
424+ let runtime_ids = compute_runtime_crates ( & metadata) ;
425+ check_runtime_license_exceptions ( & metadata, runtime_ids, bad) ;
426+ checked_runtime_licenses = true ;
427+ rust_metadata = Some ( metadata) ;
428+ } else if workspace == "src/tools/cargo/Cargo.toml" {
429+ check_rustfix (
430+ rust_metadata
431+ . as_ref ( )
432+ . expect ( "The root workspace should be the first to be checked" ) ,
433+ & metadata,
434+ bad,
435+ ) ;
436+ }
437+ }
438+
439+ // Sanity check to ensure we don't accidentally remove the workspace containing the runtime
440+ // crates.
441+ assert ! ( checked_runtime_licenses) ;
434442}
435443
436444/// Check that all licenses of runtime dependencies are in the valid list in `LICENSES`.
0 commit comments