Skip to content

Commit e82ebf2

Browse files
committed
Add tidy check for list of proc-macro crate transitive dependencies
1 parent 8742e05 commit e82ebf2

File tree

3 files changed

+227
-3
lines changed

3 files changed

+227
-3
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/// Do not update manually - use `./x.py test tidy --bless`
2+
/// Holds all direct and indirect dependencies of proc-macro crates in tree.
3+
/// See https://github.com/rust-lang/rust/issues/134863
4+
pub static CRATES: &[&str] = &[
5+
// tidy-alphabetical-start
6+
"annotate-snippets",
7+
"anstyle",
8+
"autocfg",
9+
"basic-toml",
10+
"bitflags",
11+
"block-buffer",
12+
"bumpalo",
13+
"byteorder",
14+
"cfg-if",
15+
"clap_derive",
16+
"color-print-proc-macro",
17+
"cpufeatures",
18+
"crossbeam-channel",
19+
"crossbeam-deque",
20+
"crossbeam-epoch",
21+
"crossbeam-utils",
22+
"crypto-common",
23+
"darling",
24+
"darling_core",
25+
"darling_macro",
26+
"derive-where",
27+
"derive_builder_core",
28+
"derive_setters",
29+
"digest",
30+
"displaydoc",
31+
"either",
32+
"equivalent",
33+
"fluent-bundle",
34+
"fluent-langneg",
35+
"fluent-syntax",
36+
"fnv",
37+
"foldhash",
38+
"futf",
39+
"futures-macro",
40+
"generic-array",
41+
"getrandom",
42+
"hashbrown",
43+
"heck",
44+
"hermit-abi",
45+
"html5ever",
46+
"icu_provider_macros",
47+
"ident_case",
48+
"indexmap",
49+
"intl-memoizer",
50+
"intl_pluralrules",
51+
"itoa",
52+
"libc",
53+
"lock_api",
54+
"log",
55+
"mac",
56+
"markup5ever",
57+
"memchr",
58+
"mime",
59+
"mime_guess",
60+
"minimal-lexical",
61+
"new_debug_unreachable",
62+
"nom",
63+
"num_cpus",
64+
"once_cell",
65+
"parking_lot",
66+
"parking_lot_core",
67+
"pest",
68+
"pest_generator",
69+
"pest_meta",
70+
"phf",
71+
"phf_codegen",
72+
"phf_generator",
73+
"phf_shared",
74+
"ppv-lite86",
75+
"precomputed-hash",
76+
"proc-macro-hack",
77+
"proc-macro2",
78+
"quote",
79+
"rand",
80+
"rand_chacha",
81+
"rand_core",
82+
"rayon",
83+
"rayon-core",
84+
"redox_syscall",
85+
"rinja_derive",
86+
"rinja_parser",
87+
"rustc-hash",
88+
"rustc-rayon",
89+
"rustc-rayon-core",
90+
"rustc_fluent_macro",
91+
"rustc_index_macros",
92+
"rustc_macros",
93+
"rustc_type_ir_macros",
94+
"rustfmt-config_proc_macro",
95+
"rustversion",
96+
"ryu",
97+
"scopeguard",
98+
"self_cell",
99+
"serde",
100+
"serde_derive",
101+
"serde_json",
102+
"sha2",
103+
"siphasher",
104+
"smallvec",
105+
"stable_deref_trait",
106+
"string_cache",
107+
"string_cache_codegen",
108+
"strsim",
109+
"strum_macros",
110+
"syn",
111+
"synstructure",
112+
"tendril",
113+
"thiserror",
114+
"thiserror-impl",
115+
"tinystr",
116+
"tracing-attributes",
117+
"type-map",
118+
"typenum",
119+
"ucd-trie",
120+
"unic-langid",
121+
"unic-langid-impl",
122+
"unic-langid-macros",
123+
"unic-langid-macros-impl",
124+
"unicase",
125+
"unicode-ident",
126+
"unicode-width",
127+
"utf-8",
128+
"version_check",
129+
"wasi",
130+
"wasm-bindgen-backend",
131+
"wasm-bindgen-macro-support",
132+
"wasm-bindgen-shared",
133+
"windows-bindgen",
134+
"windows-implement",
135+
"windows-interface",
136+
"windows-metadata",
137+
"windows-targets",
138+
"windows_aarch64_gnullvm",
139+
"windows_aarch64_msvc",
140+
"windows_i686_gnu",
141+
"windows_i686_gnullvm",
142+
"windows_i686_msvc",
143+
"windows_x86_64_gnu",
144+
"windows_x86_64_gnullvm",
145+
"windows_x86_64_msvc",
146+
"yoke",
147+
"yoke-derive",
148+
"zerocopy",
149+
"zerocopy-derive",
150+
"zerofrom",
151+
"zerofrom-derive",
152+
"zerovec",
153+
"zerovec-derive",
154+
// tidy-alphabetical-end
155+
];

src/tools/tidy/src/deps.rs

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
//! Checks the licenses of third-party dependencies.
22
33
use std::collections::HashSet;
4-
use std::fs::read_dir;
4+
use std::fs::{File, read_dir};
5+
use std::io::Write;
56
use std::path::Path;
67

78
use build_helper::ci::CiEnv;
89
use cargo_metadata::{Metadata, Package, PackageId};
910

11+
#[path = "../../../bootstrap/src/utils/proc_macro_deps.rs"]
12+
mod proc_macro_deps;
13+
1014
/// These are licenses that are allowed for all crates, including the runtime,
1115
/// rustc, tools, etc.
1216
#[rustfmt::skip]
@@ -564,9 +568,11 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
564568
///
565569
/// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path
566570
/// to the cargo executable.
567-
pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
571+
pub fn check(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) {
568572
let mut checked_runtime_licenses = false;
569573

574+
check_proc_macro_dep_list(root, cargo, bless, bad);
575+
570576
for &(workspace, exceptions, permitted_deps, submodules) in WORKSPACES {
571577
if has_missing_submodule(root, submodules) {
572578
continue;
@@ -600,6 +606,69 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
600606
assert!(checked_runtime_licenses);
601607
}
602608

609+
/// Ensure the list of proc-macro crate transitive dependencies is up to date
610+
fn check_proc_macro_dep_list(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) {
611+
let mut cmd = cargo_metadata::MetadataCommand::new();
612+
cmd.cargo_path(cargo)
613+
.manifest_path(root.join("Cargo.toml"))
614+
.features(cargo_metadata::CargoOpt::AllFeatures)
615+
.other_options(vec!["--locked".to_owned()]);
616+
let metadata = t!(cmd.exec());
617+
let is_proc_macro_pkg =
618+
|pkg: &&Package| pkg.dependencies.iter().any(|dep| dep.name.as_str() == "proc-macro2");
619+
let mut proc_macro_deps = HashSet::new();
620+
for pkg in metadata.packages.iter().filter(is_proc_macro_pkg) {
621+
deps_of(&metadata, &pkg.id, &mut proc_macro_deps);
622+
}
623+
let proc_macro_deps_iter = proc_macro_deps.into_iter().map(|dep| metadata[dep].name.clone());
624+
625+
if bless {
626+
let mut proc_macro_deps: Vec<_> = proc_macro_deps_iter.collect();
627+
proc_macro_deps.sort();
628+
proc_macro_deps.dedup();
629+
let mut file = File::create(root.join("src/bootstrap/src/utils/proc_macro_deps.rs"))
630+
.expect("`proc_macro_deps` should exist");
631+
writeln!(
632+
&mut file,
633+
"/// Do not update manually - use `./x.py test tidy --bless`
634+
/// Holds all direct and indirect dependencies of proc-macro crates in tree.
635+
/// See https://github.com/rust-lang/rust/issues/134863
636+
pub static CRATES: &[&str] = &[
637+
// tidy-alphabetical-start"
638+
)
639+
.unwrap();
640+
for dep in proc_macro_deps {
641+
writeln!(&mut file, " {dep:?},").unwrap();
642+
}
643+
writeln!(
644+
&mut file,
645+
" // tidy-alphabetical-end
646+
];"
647+
)
648+
.unwrap();
649+
} else {
650+
let proc_macro_deps: HashSet<_> = proc_macro_deps_iter.collect();
651+
let expected =
652+
proc_macro_deps::CRATES.iter().map(|s| s.to_string()).collect::<HashSet<_>>();
653+
let old_bad = *bad;
654+
for missing in proc_macro_deps.difference(&expected) {
655+
tidy_error!(
656+
bad,
657+
"proc-macro crate dependency `{missing}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`",
658+
);
659+
}
660+
for extra in expected.difference(&proc_macro_deps) {
661+
tidy_error!(
662+
bad,
663+
"`{extra}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`, but is not a proc-macro crate dependency",
664+
);
665+
}
666+
if *bad != old_bad {
667+
eprintln!("Run `./x.py test tidy --bless` to regenerate the list");
668+
}
669+
}
670+
}
671+
603672
/// Used to skip a check if a submodule is not checked out, and not in a CI environment.
604673
///
605674
/// This helps prevent enforcing developers to fetch submodules for tidy.

src/tools/tidy/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ fn main() {
9595
check!(target_specific_tests, &tests_path);
9696

9797
// Checks that are done on the cargo workspace.
98-
check!(deps, &root_path, &cargo);
98+
check!(deps, &root_path, &cargo, bless);
9999
check!(extdeps, &root_path);
100100

101101
// Checks over tests.

0 commit comments

Comments
 (0)