-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Wire up tidy dependency checks for cg_clif #84872
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
d7cd6e2
Fix RESTRICTED_DEPENDENCY_CRATES to list rustc_driver instead of rust…
bjorn3 2fa18b8
Remove obsolete crate exceptions
bjorn3 5db01aa
Take build dependencies into account during license checks
bjorn3 24def63
Wire up tidy dependency checks for cg_clif
bjorn3 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,12 +44,29 @@ const EXCEPTIONS: &[(&str, &str)] = &[ | |
("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target | ||
]; | ||
|
||
const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[ | ||
("cranelift-bforest", "Apache-2.0 WITH LLVM-exception"), | ||
("cranelift-codegen", "Apache-2.0 WITH LLVM-exception"), | ||
("cranelift-codegen-meta", "Apache-2.0 WITH LLVM-exception"), | ||
("cranelift-codegen-shared", "Apache-2.0 WITH LLVM-exception"), | ||
("cranelift-entity", "Apache-2.0 WITH LLVM-exception"), | ||
("cranelift-frontend", "Apache-2.0 WITH LLVM-exception"), | ||
("cranelift-jit", "Apache-2.0 WITH LLVM-exception"), | ||
("cranelift-module", "Apache-2.0 WITH LLVM-exception"), | ||
("cranelift-native", "Apache-2.0 WITH LLVM-exception"), | ||
("cranelift-object", "Apache-2.0 WITH LLVM-exception"), | ||
("libloading", "ISC"), | ||
("mach", "BSD-2-Clause"), | ||
Comment on lines
+58
to
+59
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both of these licenses are equivalent to MIT I believe, but IANAL. |
||
("regalloc", "Apache-2.0 WITH LLVM-exception"), | ||
("target-lexicon", "Apache-2.0 WITH LLVM-exception"), | ||
]; | ||
|
||
/// These are the root crates that are part of the runtime. The licenses for | ||
/// these and all their dependencies *must not* be in the exception list. | ||
const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "test", "panic_abort", "panic_unwind"]; | ||
|
||
/// Crates whose dependencies must be explicitly permitted. | ||
const RESTRICTED_DEPENDENCY_CRATES: &[&str] = &["rustc_middle", "rustc_codegen_llvm"]; | ||
const RESTRICTED_DEPENDENCY_CRATES: &[&str] = &["rustc_driver", "rustc_codegen_llvm"]; | ||
|
||
/// Crates rustc is allowed to depend on. Avoid adding to the list if possible. | ||
/// | ||
|
@@ -72,7 +89,10 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ | |
"cc", | ||
"cfg-if", | ||
"chalk-derive", | ||
"chalk-engine", | ||
"chalk-ir", | ||
"chalk-solve", | ||
"chrono", | ||
"cmake", | ||
"compiler_builtins", | ||
"cpuid-bool", | ||
|
@@ -92,6 +112,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ | |
"expect-test", | ||
"fake-simd", | ||
"filetime", | ||
"fixedbitset", | ||
"flate2", | ||
"fortanix-sgx-abi", | ||
"fuchsia-zircon", | ||
|
@@ -107,13 +128,15 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ | |
"indexmap", | ||
"instant", | ||
"itertools", | ||
"itoa", | ||
"jobserver", | ||
"kernel32-sys", | ||
"lazy_static", | ||
"libc", | ||
"libz-sys", | ||
"lock_api", | ||
"log", | ||
"matchers", | ||
"maybe-uninit", | ||
"md-5", | ||
"measureme", | ||
|
@@ -123,13 +146,16 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ | |
"memoffset", | ||
"miniz_oxide", | ||
"num_cpus", | ||
"num-integer", | ||
"num-traits", | ||
"object", | ||
"once_cell", | ||
"opaque-debug", | ||
"parking_lot", | ||
"parking_lot_core", | ||
"pathdiff", | ||
"perf-event-open-sys", | ||
"petgraph", | ||
"pin-project-lite", | ||
"pkg-config", | ||
"polonius-engine", | ||
|
@@ -147,22 +173,28 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ | |
"rand_xorshift", | ||
"redox_syscall", | ||
"regex", | ||
"regex-automata", | ||
"regex-syntax", | ||
"remove_dir_all", | ||
"rls-data", | ||
"rls-span", | ||
"rustc-demangle", | ||
"rustc-hash", | ||
"rustc-rayon", | ||
"rustc-rayon-core", | ||
"rustc_version", | ||
"ryu", | ||
"scoped-tls", | ||
"scopeguard", | ||
"semver", | ||
"semver-parser", | ||
"serde", | ||
"serde_derive", | ||
"serde_json", | ||
"sha-1", | ||
"sha2", | ||
"smallvec", | ||
"sharded-slab", | ||
"snap", | ||
"stable_deref_trait", | ||
"stacker", | ||
|
@@ -172,9 +204,15 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ | |
"termcolor", | ||
"termize", | ||
"thread_local", | ||
"time", | ||
"tinyvec", | ||
"tracing", | ||
"tracing-attributes", | ||
"tracing-core", | ||
"tracing-log", | ||
"tracing-serde", | ||
"tracing-subscriber", | ||
"tracing-tree", | ||
"typenum", | ||
"unicode-normalization", | ||
"unicode-script", | ||
|
@@ -191,6 +229,59 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ | |
"winapi-x86_64-pc-windows-gnu", | ||
]; | ||
|
||
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ | ||
"anyhow", | ||
"ar", | ||
"autocfg", | ||
"bitflags", | ||
"byteorder", | ||
"cfg-if", | ||
"cranelift-bforest", | ||
"cranelift-codegen", | ||
"cranelift-codegen-meta", | ||
"cranelift-codegen-shared", | ||
"cranelift-entity", | ||
"cranelift-frontend", | ||
"cranelift-jit", | ||
"cranelift-module", | ||
"cranelift-native", | ||
"cranelift-object", | ||
"crc32fast", | ||
"errno", | ||
"errno-dragonfly", | ||
"gcc", | ||
"gimli", | ||
"hashbrown", | ||
"indexmap", | ||
"libc", | ||
"libloading", | ||
"log", | ||
"mach", | ||
"object", | ||
"proc-macro2", | ||
"quote", | ||
"regalloc", | ||
"region", | ||
"rustc-hash", | ||
"smallvec", | ||
"syn", | ||
"target-lexicon", | ||
"thiserror", | ||
"thiserror-impl", | ||
"unicode-xid", | ||
"winapi", | ||
"winapi-i686-pc-windows-gnu", | ||
"winapi-x86_64-pc-windows-gnu", | ||
]; | ||
|
||
const FORBIDDEN_TO_HAVE_DUPLICATES: &[&str] = &[ | ||
// These two crates take quite a long time to build, so don't allow two versions of them | ||
// to accidentally sneak into our dependency graph, in order to ensure we keep our CI times | ||
// under control. | ||
"cargo", | ||
"rustc-ap-rustc_ast", | ||
]; | ||
|
||
/// Dependency checks. | ||
/// | ||
/// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path | ||
|
@@ -201,17 +292,39 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { | |
.manifest_path(root.join("Cargo.toml")) | ||
.features(cargo_metadata::CargoOpt::AllFeatures); | ||
let metadata = t!(cmd.exec()); | ||
check_exceptions(&metadata, bad); | ||
check_dependencies(&metadata, bad); | ||
check_crate_duplicate(&metadata, bad); | ||
let runtime_ids = compute_runtime_crates(&metadata); | ||
check_exceptions(&metadata, EXCEPTIONS, runtime_ids, bad); | ||
check_dependencies(&metadata, PERMITTED_DEPENDENCIES, RESTRICTED_DEPENDENCY_CRATES, bad); | ||
check_crate_duplicate(&metadata, FORBIDDEN_TO_HAVE_DUPLICATES, bad); | ||
|
||
// Check rustc_codegen_cranelift independently as it has it's own workspace. | ||
let mut cmd = cargo_metadata::MetadataCommand::new(); | ||
cmd.cargo_path(cargo) | ||
.manifest_path(root.join("compiler/rustc_codegen_cranelift/Cargo.toml")) | ||
.features(cargo_metadata::CargoOpt::AllFeatures); | ||
let metadata = t!(cmd.exec()); | ||
let runtime_ids = HashSet::new(); | ||
check_exceptions(&metadata, EXCEPTIONS_CRANELIFT, runtime_ids, bad); | ||
check_dependencies( | ||
&metadata, | ||
PERMITTED_CRANELIFT_DEPENDENCIES, | ||
&["rustc_codegen_cranelift"], | ||
bad, | ||
); | ||
check_crate_duplicate(&metadata, &[], bad); | ||
} | ||
|
||
/// Check that all licenses are in the valid list in `LICENSES`. | ||
/// | ||
/// Packages listed in `EXCEPTIONS` are allowed for tools. | ||
fn check_exceptions(metadata: &Metadata, bad: &mut bool) { | ||
fn check_exceptions( | ||
metadata: &Metadata, | ||
exceptions: &[(&str, &str)], | ||
runtime_ids: HashSet<&PackageId>, | ||
bad: &mut bool, | ||
) { | ||
// Validate the EXCEPTIONS list hasn't changed. | ||
for (name, license) in EXCEPTIONS { | ||
for (name, license) in exceptions { | ||
// Check that the package actually exists. | ||
if !metadata.packages.iter().any(|p| p.name == *name) { | ||
tidy_error!( | ||
|
@@ -223,13 +336,6 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) { | |
} | ||
// Check that the license hasn't changed. | ||
for pkg in metadata.packages.iter().filter(|p| p.name == *name) { | ||
if pkg.name == "fuchsia-cprng" { | ||
// This package doesn't declare a license expression. Manual | ||
// inspection of the license file is necessary, which appears | ||
// to be BSD-3-Clause. | ||
assert!(pkg.license.is_none()); | ||
continue; | ||
} | ||
match &pkg.license { | ||
None => { | ||
tidy_error!( | ||
|
@@ -240,14 +346,6 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) { | |
} | ||
Some(pkg_license) => { | ||
if pkg_license.as_str() != *license { | ||
if *name == "crossbeam-queue" | ||
&& *license == "MIT/Apache-2.0 AND BSD-2-Clause" | ||
{ | ||
// We have two versions of crossbeam-queue and both | ||
// are fine. | ||
continue; | ||
} | ||
|
||
println!("dependency exception `{}` license has changed", name); | ||
println!(" previously `{}` now `{}`", license, pkg_license); | ||
println!(" update EXCEPTIONS for the new license"); | ||
|
@@ -258,8 +356,7 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) { | |
} | ||
} | ||
|
||
let exception_names: Vec<_> = EXCEPTIONS.iter().map(|(name, _license)| *name).collect(); | ||
let runtime_ids = compute_runtime_crates(metadata); | ||
let exception_names: Vec<_> = exceptions.iter().map(|(name, _license)| *name).collect(); | ||
|
||
// Check if any package does not have a valid license. | ||
for pkg in &metadata.packages { | ||
|
@@ -294,9 +391,14 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) { | |
/// `true` if a check failed. | ||
/// | ||
/// Specifically, this checks that the dependencies are on the `PERMITTED_DEPENDENCIES`. | ||
fn check_dependencies(metadata: &Metadata, bad: &mut bool) { | ||
fn check_dependencies( | ||
metadata: &Metadata, | ||
permitted_dependencies: &[&'static str], | ||
restricted_dependency_crates: &[&'static str], | ||
bad: &mut bool, | ||
) { | ||
// Check that the PERMITTED_DEPENDENCIES does not have unused entries. | ||
for name in PERMITTED_DEPENDENCIES { | ||
for name in permitted_dependencies { | ||
if !metadata.packages.iter().any(|p| p.name == *name) { | ||
tidy_error!( | ||
bad, | ||
|
@@ -307,12 +409,12 @@ fn check_dependencies(metadata: &Metadata, bad: &mut bool) { | |
} | ||
} | ||
// Get the list in a convenient form. | ||
let permitted_dependencies: HashSet<_> = PERMITTED_DEPENDENCIES.iter().cloned().collect(); | ||
let permitted_dependencies: HashSet<_> = permitted_dependencies.iter().cloned().collect(); | ||
|
||
// Check dependencies. | ||
let mut visited = BTreeSet::new(); | ||
let mut unapproved = BTreeSet::new(); | ||
for &krate in RESTRICTED_DEPENDENCY_CRATES.iter() { | ||
for &krate in restricted_dependency_crates.iter() { | ||
let pkg = pkg_from_name(metadata, krate); | ||
let mut bad = | ||
check_crate_dependencies(&permitted_dependencies, metadata, &mut visited, pkg); | ||
|
@@ -365,16 +467,12 @@ fn check_crate_dependencies<'a>( | |
} | ||
|
||
/// Prevents multiple versions of some expensive crates. | ||
fn check_crate_duplicate(metadata: &Metadata, bad: &mut bool) { | ||
const FORBIDDEN_TO_HAVE_DUPLICATES: &[&str] = &[ | ||
// These two crates take quite a long time to build, so don't allow two versions of them | ||
// to accidentally sneak into our dependency graph, in order to ensure we keep our CI times | ||
// under control. | ||
"cargo", | ||
"rustc-ap-rustc_ast", | ||
]; | ||
|
||
for &name in FORBIDDEN_TO_HAVE_DUPLICATES { | ||
fn check_crate_duplicate( | ||
metadata: &Metadata, | ||
forbidden_to_have_duplicates: &[&str], | ||
bad: &mut bool, | ||
) { | ||
for &name in forbidden_to_have_duplicates { | ||
let matches: Vec<_> = metadata.packages.iter().filter(|pkg| pkg.name == name).collect(); | ||
match matches.len() { | ||
0 => { | ||
|
@@ -454,16 +552,7 @@ fn normal_deps_of_r<'a>( | |
.iter() | ||
.find(|n| &n.id == pkg_id) | ||
.unwrap_or_else(|| panic!("could not find `{}` in resolve", pkg_id)); | ||
// Don't care about dev-dependencies. | ||
// Build dependencies *shouldn't* matter unless they do some kind of | ||
// codegen. For now we'll assume they don't. | ||
let deps = node.deps.iter().filter(|node_dep| { | ||
node_dep | ||
.dep_kinds | ||
.iter() | ||
.any(|kind_info| kind_info.kind == cargo_metadata::DependencyKind::Normal) | ||
}); | ||
for dep in deps { | ||
for dep in &node.deps { | ||
normal_deps_of_r(resolve, &dep.pkg, result); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This license is used by LLVM too, so it shouldn't be a problem.