Rollup merge of #106470 - ehuss:tidy-no-wasm, r=Mark-Simulacrum
tidy: Don't include wasm32 in compiler dependency check This changes the tidy compiler dependency check so that it does not include wasm32-unknown-unknown dependencies in the PERMITTED_RUSTC_DEPENDENCIES. This just helps keep the list cleaner under the assumption that the compiler will never work on wasm32-unknown-unknown. This also fixes a bug in the check to verify there are no unused dependencies in the PERMITTED_RUSTC_DEPENDENCIES. Previously the check was verifying that the dependency was used *anywhere* in the workspace, when it should have been checking if it was used for the compiler. There's also just a little general cleanup here. For example, the old `normal_deps_of_r` function was changed a while ago to return *all* dependencies, but the function name and description wasn't updated to remove `normal_`.
This commit is contained in:
commit
27db39b1b3
@ -5601,6 +5601,7 @@ dependencies = [
|
|||||||
name = "tidy"
|
name = "tidy"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cargo-platform 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cargo_metadata 0.14.0",
|
"cargo_metadata 0.14.0",
|
||||||
"ignore",
|
"ignore",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -6,6 +6,7 @@ autobins = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cargo_metadata = "0.14"
|
cargo_metadata = "0.14"
|
||||||
|
cargo-platform = "0.1.2"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
miropt-test-tools = { path = "../miropt-test-tools" }
|
miropt-test-tools = { path = "../miropt-test-tools" }
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Checks the licenses of third-party dependencies.
|
//! Checks the licenses of third-party dependencies.
|
||||||
|
|
||||||
use cargo_metadata::{Metadata, Package, PackageId, Resolve};
|
use cargo_metadata::{DepKindInfo, Metadata, Package, PackageId};
|
||||||
use std::collections::{BTreeSet, HashSet};
|
use std::collections::HashSet;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
/// These are licenses that are allowed for all crates, including the runtime,
|
/// These are licenses that are allowed for all crates, including the runtime,
|
||||||
@ -98,14 +98,12 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"block-buffer",
|
"block-buffer",
|
||||||
"bumpalo", // Included in Cargo's dep graph but only activated on wasm32-*-unknown.
|
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"chalk-derive",
|
"chalk-derive",
|
||||||
"chalk-engine",
|
"chalk-engine",
|
||||||
"chalk-ir",
|
"chalk-ir",
|
||||||
"chalk-solve",
|
"chalk-solve",
|
||||||
"chrono",
|
|
||||||
"convert_case", // dependency of derive_more
|
"convert_case", // dependency of derive_more
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
@ -124,11 +122,9 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||||||
"dlmalloc",
|
"dlmalloc",
|
||||||
"either",
|
"either",
|
||||||
"ena",
|
"ena",
|
||||||
"env_logger",
|
|
||||||
"expect-test",
|
"expect-test",
|
||||||
"fallible-iterator", // dependency of `thorin`
|
"fallible-iterator", // dependency of `thorin`
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"filetime",
|
|
||||||
"fixedbitset",
|
"fixedbitset",
|
||||||
"flate2",
|
"flate2",
|
||||||
"fluent-bundle",
|
"fluent-bundle",
|
||||||
@ -142,13 +138,11 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||||||
"gsgdt",
|
"gsgdt",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"humantime",
|
|
||||||
"icu_list",
|
"icu_list",
|
||||||
"icu_locid",
|
"icu_locid",
|
||||||
"icu_provider",
|
"icu_provider",
|
||||||
"icu_provider_adapters",
|
"icu_provider_adapters",
|
||||||
"icu_provider_macros",
|
"icu_provider_macros",
|
||||||
"if_chain",
|
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"instant",
|
"instant",
|
||||||
"intl-memoizer",
|
"intl-memoizer",
|
||||||
@ -156,7 +150,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||||||
"itertools",
|
"itertools",
|
||||||
"itoa",
|
"itoa",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"js-sys", // Included in Cargo's dep graph but only activated on wasm32-*-unknown.
|
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
"libloading",
|
||||||
@ -171,8 +164,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||||||
"memmap2",
|
"memmap2",
|
||||||
"memoffset",
|
"memoffset",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"object",
|
"object",
|
||||||
"odht",
|
"odht",
|
||||||
@ -190,7 +181,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"psm",
|
"psm",
|
||||||
"punycode",
|
"punycode",
|
||||||
"quick-error",
|
|
||||||
"quote",
|
"quote",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
@ -235,7 +225,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
"thorin-dwp",
|
"thorin-dwp",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
"time",
|
|
||||||
"tinystr",
|
"tinystr",
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
"tinyvec_macros",
|
"tinyvec_macros",
|
||||||
@ -268,13 +257,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||||||
"valuable",
|
"valuable",
|
||||||
"version_check",
|
"version_check",
|
||||||
"wasi",
|
"wasi",
|
||||||
// vvv Included in Cargo's dep graph but only activated on wasm32-*-unknown.
|
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-backend",
|
|
||||||
"wasm-bindgen-macro",
|
|
||||||
"wasm-bindgen-macro-support",
|
|
||||||
"wasm-bindgen-shared",
|
|
||||||
// ^^^ Included in Cargo's dep graph but only activated on wasm32-*-unknown.
|
|
||||||
"winapi",
|
"winapi",
|
||||||
"winapi-i686-pc-windows-gnu",
|
"winapi-i686-pc-windows-gnu",
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
@ -485,75 +467,57 @@ fn check_permitted_dependencies(
|
|||||||
restricted_dependency_crates: &[&'static str],
|
restricted_dependency_crates: &[&'static str],
|
||||||
bad: &mut bool,
|
bad: &mut bool,
|
||||||
) {
|
) {
|
||||||
|
let mut deps = HashSet::new();
|
||||||
|
for to_check in restricted_dependency_crates {
|
||||||
|
let to_check = pkg_from_name(metadata, to_check);
|
||||||
|
use cargo_platform::Cfg;
|
||||||
|
use std::str::FromStr;
|
||||||
|
// We don't expect the compiler to ever run on wasm32, so strip
|
||||||
|
// out those dependencies to avoid polluting the permitted list.
|
||||||
|
deps_of_filtered(metadata, &to_check.id, &mut deps, &|dep_kinds| {
|
||||||
|
dep_kinds.iter().any(|dep_kind| {
|
||||||
|
dep_kind
|
||||||
|
.target
|
||||||
|
.as_ref()
|
||||||
|
.map(|target| {
|
||||||
|
!target.matches(
|
||||||
|
"wasm32-unknown-unknown",
|
||||||
|
&[
|
||||||
|
Cfg::from_str("target_arch=\"wasm32\"").unwrap(),
|
||||||
|
Cfg::from_str("target_os=\"unknown\"").unwrap(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap_or(true)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Check that the PERMITTED_DEPENDENCIES does not have unused entries.
|
// Check that the PERMITTED_DEPENDENCIES does not have unused entries.
|
||||||
for name in permitted_dependencies {
|
for permitted in permitted_dependencies {
|
||||||
if !metadata.packages.iter().any(|p| p.name == *name) {
|
if !deps.iter().any(|dep_id| &pkg_from_id(metadata, dep_id).name == permitted) {
|
||||||
tidy_error!(
|
tidy_error!(
|
||||||
bad,
|
bad,
|
||||||
"could not find allowed package `{}`\n\
|
"could not find allowed package `{permitted}`\n\
|
||||||
Remove from PERMITTED_DEPENDENCIES list if it is no longer used.",
|
Remove from PERMITTED_DEPENDENCIES list if it is no longer used.",
|
||||||
name
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Get the list in a convenient form.
|
|
||||||
|
// Get in a convenient form.
|
||||||
let permitted_dependencies: HashSet<_> = permitted_dependencies.iter().cloned().collect();
|
let permitted_dependencies: HashSet<_> = permitted_dependencies.iter().cloned().collect();
|
||||||
|
|
||||||
// Check dependencies.
|
for dep in deps {
|
||||||
let mut visited = BTreeSet::new();
|
let dep = pkg_from_id(metadata, dep);
|
||||||
let mut unapproved = BTreeSet::new();
|
// If this path is in-tree, we don't require it to be explicitly permitted.
|
||||||
for &krate in restricted_dependency_crates.iter() {
|
if dep.source.is_some() {
|
||||||
let pkg = pkg_from_name(metadata, krate);
|
if !permitted_dependencies.contains(dep.name.as_str()) {
|
||||||
let mut bad =
|
tidy_error!(bad, "Dependency for {descr} not explicitly permitted: {}", dep.id);
|
||||||
check_crate_dependencies(&permitted_dependencies, metadata, &mut visited, pkg);
|
}
|
||||||
unapproved.append(&mut bad);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !unapproved.is_empty() {
|
|
||||||
tidy_error!(bad, "Dependencies for {} not explicitly permitted:", descr);
|
|
||||||
for dep in unapproved {
|
|
||||||
println!("* {dep}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks the dependencies of the given crate from the given cargo metadata to see if they are on
|
|
||||||
/// the list of permitted dependencies. Returns a list of disallowed dependencies.
|
|
||||||
fn check_crate_dependencies<'a>(
|
|
||||||
permitted_dependencies: &'a HashSet<&'static str>,
|
|
||||||
metadata: &'a Metadata,
|
|
||||||
visited: &mut BTreeSet<&'a PackageId>,
|
|
||||||
krate: &'a Package,
|
|
||||||
) -> BTreeSet<&'a PackageId> {
|
|
||||||
// This will contain bad deps.
|
|
||||||
let mut unapproved = BTreeSet::new();
|
|
||||||
|
|
||||||
// Check if we have already visited this crate.
|
|
||||||
if visited.contains(&krate.id) {
|
|
||||||
return unapproved;
|
|
||||||
}
|
|
||||||
|
|
||||||
visited.insert(&krate.id);
|
|
||||||
|
|
||||||
// If this path is in-tree, we don't require it to be explicitly permitted.
|
|
||||||
if krate.source.is_some() {
|
|
||||||
// If this dependency is not on `PERMITTED_DEPENDENCIES`, add to bad set.
|
|
||||||
if !permitted_dependencies.contains(krate.name.as_str()) {
|
|
||||||
unapproved.insert(&krate.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do a DFS in the crate graph.
|
|
||||||
let to_check = deps_of(metadata, &krate.id);
|
|
||||||
|
|
||||||
for dep in to_check {
|
|
||||||
let mut bad = check_crate_dependencies(permitted_dependencies, metadata, visited, dep);
|
|
||||||
unapproved.append(&mut bad);
|
|
||||||
}
|
|
||||||
|
|
||||||
unapproved
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prevents multiple versions of some expensive crates.
|
/// Prevents multiple versions of some expensive crates.
|
||||||
fn check_crate_duplicate(
|
fn check_crate_duplicate(
|
||||||
metadata: &Metadata,
|
metadata: &Metadata,
|
||||||
@ -588,24 +552,6 @@ fn check_crate_duplicate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of dependencies for the given package.
|
|
||||||
fn deps_of<'a>(metadata: &'a Metadata, pkg_id: &'a PackageId) -> Vec<&'a Package> {
|
|
||||||
let resolve = metadata.resolve.as_ref().unwrap();
|
|
||||||
let node = resolve
|
|
||||||
.nodes
|
|
||||||
.iter()
|
|
||||||
.find(|n| &n.id == pkg_id)
|
|
||||||
.unwrap_or_else(|| panic!("could not find `{pkg_id}` in resolve"));
|
|
||||||
node.deps
|
|
||||||
.iter()
|
|
||||||
.map(|dep| {
|
|
||||||
metadata.packages.iter().find(|pkg| pkg.id == dep.pkg).unwrap_or_else(|| {
|
|
||||||
panic!("could not find dep `{}` for pkg `{}` in resolve", dep.pkg, pkg_id)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finds a package with the given name.
|
/// Finds a package with the given name.
|
||||||
fn pkg_from_name<'a>(metadata: &'a Metadata, name: &'static str) -> &'a Package {
|
fn pkg_from_name<'a>(metadata: &'a Metadata, name: &'static str) -> &'a Package {
|
||||||
let mut i = metadata.packages.iter().filter(|p| p.name == name);
|
let mut i = metadata.packages.iter().filter(|p| p.name == name);
|
||||||
@ -615,41 +561,57 @@ fn pkg_from_name<'a>(metadata: &'a Metadata, name: &'static str) -> &'a Package
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pkg_from_id<'a>(metadata: &'a Metadata, id: &PackageId) -> &'a Package {
|
||||||
|
metadata.packages.iter().find(|p| &p.id == id).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
/// Finds all the packages that are in the rust runtime.
|
/// Finds all the packages that are in the rust runtime.
|
||||||
fn compute_runtime_crates<'a>(metadata: &'a Metadata) -> HashSet<&'a PackageId> {
|
fn compute_runtime_crates<'a>(metadata: &'a Metadata) -> HashSet<&'a PackageId> {
|
||||||
let resolve = metadata.resolve.as_ref().unwrap();
|
|
||||||
let mut result = HashSet::new();
|
let mut result = HashSet::new();
|
||||||
for name in RUNTIME_CRATES {
|
for name in RUNTIME_CRATES {
|
||||||
let id = &pkg_from_name(metadata, name).id;
|
let id = &pkg_from_name(metadata, name).id;
|
||||||
normal_deps_of_r(resolve, id, &mut result);
|
deps_of_filtered(metadata, id, &mut result, &|_| true);
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively find all normal dependencies.
|
/// Recursively find all dependencies.
|
||||||
fn normal_deps_of_r<'a>(
|
fn deps_of_filtered<'a>(
|
||||||
resolve: &'a Resolve,
|
metadata: &'a Metadata,
|
||||||
pkg_id: &'a PackageId,
|
pkg_id: &'a PackageId,
|
||||||
result: &mut HashSet<&'a PackageId>,
|
result: &mut HashSet<&'a PackageId>,
|
||||||
|
filter: &dyn Fn(&[DepKindInfo]) -> bool,
|
||||||
) {
|
) {
|
||||||
if !result.insert(pkg_id) {
|
if !result.insert(pkg_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let node = resolve
|
let node = metadata
|
||||||
|
.resolve
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.nodes
|
.nodes
|
||||||
.iter()
|
.iter()
|
||||||
.find(|n| &n.id == pkg_id)
|
.find(|n| &n.id == pkg_id)
|
||||||
.unwrap_or_else(|| panic!("could not find `{pkg_id}` in resolve"));
|
.unwrap_or_else(|| panic!("could not find `{pkg_id}` in resolve"));
|
||||||
for dep in &node.deps {
|
for dep in &node.deps {
|
||||||
normal_deps_of_r(resolve, &dep.pkg, result);
|
if !filter(&dep.dep_kinds) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
deps_of_filtered(metadata, &dep.pkg, result, filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn direct_deps_of<'a>(metadata: &'a Metadata, pkg_id: &'a PackageId) -> Vec<&'a Package> {
|
||||||
|
let resolve = metadata.resolve.as_ref().unwrap();
|
||||||
|
let node = resolve.nodes.iter().find(|n| &n.id == pkg_id).unwrap();
|
||||||
|
node.deps.iter().map(|dep| pkg_from_id(metadata, &dep.pkg)).collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn check_rustfix(metadata: &Metadata, bad: &mut bool) {
|
fn check_rustfix(metadata: &Metadata, bad: &mut bool) {
|
||||||
let cargo = pkg_from_name(metadata, "cargo");
|
let cargo = pkg_from_name(metadata, "cargo");
|
||||||
let compiletest = pkg_from_name(metadata, "compiletest");
|
let compiletest = pkg_from_name(metadata, "compiletest");
|
||||||
let cargo_deps = deps_of(metadata, &cargo.id);
|
let cargo_deps = direct_deps_of(metadata, &cargo.id);
|
||||||
let compiletest_deps = deps_of(metadata, &compiletest.id);
|
let compiletest_deps = direct_deps_of(metadata, &compiletest.id);
|
||||||
let cargo_rustfix = cargo_deps.iter().find(|p| p.name == "rustfix").unwrap();
|
let cargo_rustfix = cargo_deps.iter().find(|p| p.name == "rustfix").unwrap();
|
||||||
let compiletest_rustfix = compiletest_deps.iter().find(|p| p.name == "rustfix").unwrap();
|
let compiletest_rustfix = compiletest_deps.iter().find(|p| p.name == "rustfix").unwrap();
|
||||||
if cargo_rustfix.version != compiletest_rustfix.version {
|
if cargo_rustfix.version != compiletest_rustfix.version {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user