Skip to content

Commit bc738f2

Browse files
committed
tidy: Verify the runtime crates don't have license exceptions.
1 parent be10f14 commit bc738f2

File tree

1 file changed

+57
-6
lines changed

1 file changed

+57
-6
lines changed

src/tools/tidy/src/deps.rs

+57-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Checks the licenses of third-party dependencies.
22
3-
use cargo_metadata::{Metadata, Package, PackageId};
3+
use cargo_metadata::{Metadata, Package, PackageId, Resolve};
44
use std::collections::{BTreeSet, HashSet};
55
use std::path::Path;
66

@@ -50,6 +50,10 @@ const EXCEPTIONS: &[(&str, &str)] = &[
5050
("crossbeam-channel", "MIT/Apache-2.0 AND BSD-2-Clause"), // cargo
5151
];
5252

53+
/// These are the root crates that are part of the runtime. The licenses for
54+
/// these and all their dependencies *must not* be in the exception list.
55+
const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "panic_abort", "panic_unwind"];
56+
5357
/// Which crates to check against the whitelist?
5458
const WHITELIST_CRATES: &[&str] = &["rustc", "rustc_codegen_llvm"];
5559

@@ -227,14 +231,17 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) {
227231
}
228232
}
229233
}
234+
230235
let exception_names: Vec<_> = EXCEPTIONS.iter().map(|(name, _license)| *name).collect();
236+
let runtime_ids = compute_runtime_crates(metadata);
237+
231238
// Check if any package does not have a valid license.
232239
for pkg in &metadata.packages {
233240
if pkg.source.is_none() {
234241
// No need to check local packages.
235242
continue;
236243
}
237-
if exception_names.contains(&pkg.name.as_str()) {
244+
if !runtime_ids.contains(&pkg.id) && exception_names.contains(&pkg.name.as_str()) {
238245
continue;
239246
}
240247
let license = match &pkg.license {
@@ -246,6 +253,13 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) {
246253
}
247254
};
248255
if !LICENSES.contains(&license.as_str()) {
256+
if pkg.name == "fortanix-sgx-abi" {
257+
// This is a specific exception because SGX is considered
258+
// "third party". See
259+
// https://github.com/rust-lang/rust/issues/62620 for more. In
260+
// general, these should never be added.
261+
continue;
262+
}
249263
println!("invalid license `{}` in `{}`", license, pkg.id);
250264
*bad = true;
251265
}
@@ -366,10 +380,8 @@ fn check_crate_duplicate(metadata: &Metadata, bad: &mut bool) {
366380

367381
/// Returns a list of dependencies for the given package.
368382
fn deps_of<'a>(metadata: &'a Metadata, pkg_id: &'a PackageId) -> Vec<&'a Package> {
369-
let node = metadata
370-
.resolve
371-
.as_ref()
372-
.unwrap()
383+
let resolve = metadata.resolve.as_ref().unwrap();
384+
let node = resolve
373385
.nodes
374386
.iter()
375387
.find(|n| &n.id == pkg_id)
@@ -392,3 +404,42 @@ fn pkg_from_name<'a>(metadata: &'a Metadata, name: &'static str) -> &'a Package
392404
assert!(i.next().is_none(), "more than one package found for `{}`", name);
393405
result
394406
}
407+
408+
/// Finds all the packages that are in the rust runtime.
409+
fn compute_runtime_crates<'a>(metadata: &'a Metadata) -> HashSet<&'a PackageId> {
410+
let resolve = metadata.resolve.as_ref().unwrap();
411+
let mut result = HashSet::new();
412+
for name in RUNTIME_CRATES {
413+
let id = &pkg_from_name(metadata, name).id;
414+
normal_deps_of_r(resolve, id, &mut result);
415+
}
416+
result
417+
}
418+
419+
/// Recursively find all normal dependencies.
420+
fn normal_deps_of_r<'a>(
421+
resolve: &'a Resolve,
422+
pkg_id: &'a PackageId,
423+
result: &mut HashSet<&'a PackageId>,
424+
) {
425+
if !result.insert(pkg_id) {
426+
return;
427+
}
428+
let node = resolve
429+
.nodes
430+
.iter()
431+
.find(|n| &n.id == pkg_id)
432+
.unwrap_or_else(|| panic!("could not find `{}` in resolve", pkg_id));
433+
// Don't care about dev-dependencies.
434+
// Build dependencies *shouldn't* matter unless they do some kind of
435+
// codegen. For now we'll assume they don't.
436+
let deps = node.deps.iter().filter(|node_dep| {
437+
node_dep
438+
.dep_kinds
439+
.iter()
440+
.any(|kind_info| kind_info.kind == cargo_metadata::DependencyKind::Normal)
441+
});
442+
for dep in deps {
443+
normal_deps_of_r(resolve, &dep.pkg, result);
444+
}
445+
}

0 commit comments

Comments
 (0)