Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 04d6333

Browse files
authoredNov 27, 2024
Rollup merge of rust-lang#133453 - ferrocene:check-license-metadata, r=Kobzol
Commit license-metadata.json to git and check it's correct in CI This PR adds `license-metadata.json` to the root of the git repo, and changes `mingw-check` to check that the file is still up-to-date. By committing this file, we remove the need for developers to a) have reuse installed or b) run an expensive ~90 second analysis of the files on disk when they want generate the COPYRIGHT.html files which depend on this license metadata. The file will need updating whenever `REUSE.toml` changes, or when git submodules are added, or when git submodules change their license information (as detected by REUSE). You can now run: * `./x run collect-license-metadata` to update the `./license-metadata.json` file * `./x test collect-license-metadata` to test the `./license-metadata.json` file for correctness The comparison is done with two `serde_json::Value` objects, so the map objects they contain should ignore differences in ordering.
2 parents dcebc5e + db71194 commit 04d6333

File tree

9 files changed

+345
-16
lines changed

9 files changed

+345
-16
lines changed
 

‎REUSE.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ path = [
2828
"COPYRIGHT",
2929
"INSTALL.md",
3030
"LICENSE-APACHE",
31+
"license-metadata.json",
3132
"LICENSE-MIT",
3233
"README.md",
3334
"RELEASES.md",

‎license-metadata.json

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
{
2+
"files": {
3+
"children": [
4+
{
5+
"children": [
6+
{
7+
"children": [
8+
{
9+
"children": [
10+
{
11+
"children": [
12+
{
13+
"directories": [],
14+
"files": [
15+
"analyzer-decls.h",
16+
"malloc-macro.h"
17+
],
18+
"license": {
19+
"copyright": [
20+
"2000-2024 Free Software Foundation, Inc"
21+
],
22+
"spdx": "GPL-2.0-only"
23+
},
24+
"type": "group"
25+
}
26+
],
27+
"license": {
28+
"copyright": [
29+
"2007-2011 Atheros Communications Inc",
30+
"2011-2012,2017 Qualcomm Atheros, Inc",
31+
"2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>"
32+
],
33+
"spdx": "ISC"
34+
},
35+
"name": "c-c++-common/analyzer",
36+
"type": "directory"
37+
}
38+
],
39+
"license": {
40+
"copyright": [
41+
"2000-2024 Free Software Foundation, Inc"
42+
],
43+
"spdx": "GPL-2.0-only"
44+
},
45+
"name": "gcc/testsuite",
46+
"type": "directory"
47+
},
48+
{
49+
"license": {
50+
"copyright": [
51+
"2000-2024 Free Software Foundation, Inc"
52+
],
53+
"spdx": "GCC-exception-3.1"
54+
},
55+
"name": "libstdc++-v3/config/os/aix/os_defines.h",
56+
"type": "file"
57+
}
58+
],
59+
"license": {
60+
"copyright": [
61+
"1997-2024 Free Software Foundation, Inc"
62+
],
63+
"spdx": "GPL-3.0-or-later"
64+
},
65+
"name": "src/gcc",
66+
"type": "directory"
67+
},
68+
{
69+
"children": [
70+
{
71+
"license": {
72+
"copyright": [
73+
"The Rust Project Developers (see https://thanks.rust-lang.org)"
74+
],
75+
"spdx": "Apache-2.0 OR MIT"
76+
},
77+
"name": "noscript.css",
78+
"type": "file"
79+
},
80+
{
81+
"license": {
82+
"copyright": [
83+
"Nicolas Gallagher and Jonathan Neal"
84+
],
85+
"spdx": "MIT"
86+
},
87+
"name": "normalize.css",
88+
"type": "file"
89+
}
90+
],
91+
"license": {
92+
"copyright": [
93+
"2016 Ike Ku, Jessica Stokes and Leon Guan",
94+
"The Rust Project Developers (see https://thanks.rust-lang.org)"
95+
],
96+
"spdx": "Apache-2.0 OR MIT"
97+
},
98+
"name": "src/librustdoc/html/static/css",
99+
"type": "directory"
100+
},
101+
{
102+
"children": [
103+
{
104+
"license": {
105+
"copyright": [
106+
"The Rust Project Developers (see https://thanks.rust-lang.org)"
107+
],
108+
"spdx": "Apache-2.0 OR MIT"
109+
},
110+
"name": "README.txt",
111+
"type": "file"
112+
},
113+
{
114+
"directories": [],
115+
"files": [
116+
"FiraSans-LICENSE.txt",
117+
"FiraSans-Medium.woff2",
118+
"FiraSans-Regular.woff2"
119+
],
120+
"license": {
121+
"copyright": [
122+
"2014, Mozilla Foundation",
123+
"2014, Telefonica S.A"
124+
],
125+
"spdx": "OFL-1.1"
126+
},
127+
"type": "group"
128+
},
129+
{
130+
"directories": [],
131+
"files": [
132+
"NanumBarunGothic-LICENSE.txt",
133+
"NanumBarunGothic.ttf.woff2"
134+
],
135+
"license": {
136+
"copyright": [
137+
"2010 NAVER Corporation"
138+
],
139+
"spdx": "OFL-1.1"
140+
},
141+
"type": "group"
142+
}
143+
],
144+
"license": {
145+
"copyright": [
146+
"2010, 2012, 2014-2023, Adobe Systems Incorporated"
147+
],
148+
"spdx": "OFL-1.1"
149+
},
150+
"name": "src/librustdoc/html/static/fonts",
151+
"type": "directory"
152+
},
153+
{
154+
"license": {
155+
"copyright": [
156+
"2003-2019 University of Illinois at Urbana-Champaign",
157+
"The Rust Project Developers (see https://thanks.rust-lang.org)"
158+
],
159+
"spdx": "Apache-2.0 WITH LLVM-exception AND (Apache-2.0 OR MIT)"
160+
},
161+
"name": "compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp",
162+
"type": "file"
163+
},
164+
{
165+
"children": [],
166+
"license": {
167+
"copyright": [
168+
"2014 Alex Crichton",
169+
"The Rust Project Developers (see https://thanks.rust-lang.org)"
170+
],
171+
"spdx": "Apache-2.0 OR MIT"
172+
},
173+
"name": "library/backtrace",
174+
"type": "directory"
175+
},
176+
{
177+
"license": {
178+
"copyright": [
179+
"1991-2024 Unicode, Inc"
180+
],
181+
"spdx": "Unicode-3.0"
182+
},
183+
"name": "library/core/src/unicode/unicode_data.rs",
184+
"type": "file"
185+
},
186+
{
187+
"children": [],
188+
"license": {
189+
"copyright": [
190+
"2019 The Crossbeam Project Developers",
191+
"The Rust Project Developers (see https://thanks.rust-lang.org)"
192+
],
193+
"spdx": "Apache-2.0 OR MIT"
194+
},
195+
"name": "library/std/src/sync/mpmc",
196+
"type": "directory"
197+
},
198+
{
199+
"license": {
200+
"copyright": [
201+
"2016 The Fuchsia Authors",
202+
"The Rust Project Developers (see https://thanks.rust-lang.org)"
203+
],
204+
"spdx": "BSD-2-Clause AND (Apache-2.0 OR MIT)"
205+
},
206+
"name": "library/std/src/sys/sync/mutex/fuchsia.rs",
207+
"type": "file"
208+
},
209+
{
210+
"children": [],
211+
"license": {
212+
"copyright": [
213+
"Rust on Embedded Devices Working Group",
214+
"The Rust Project Developers (see https://thanks.rust-lang.org)"
215+
],
216+
"spdx": "Apache-2.0 OR CC-BY-SA-4.0 OR MIT"
217+
},
218+
"name": "src/doc/embedded-book",
219+
"type": "directory"
220+
},
221+
{
222+
"children": [],
223+
"license": {
224+
"copyright": [
225+
"2014 Jorge Aparicio",
226+
"The Rust Project Developers (see https://thanks.rust-lang.org)"
227+
],
228+
"spdx": "Apache-2.0 OR MIT"
229+
},
230+
"name": "src/doc/rust-by-example",
231+
"type": "directory"
232+
},
233+
{
234+
"license": {
235+
"copyright": [
236+
"2014-2021 Knut Sveidqvist"
237+
],
238+
"spdx": "MIT"
239+
},
240+
"name": "src/doc/rustc-dev-guide/mermaid.min.js",
241+
"type": "file"
242+
},
243+
{
244+
"children": [],
245+
"license": {
246+
"copyright": [
247+
"2003-2019 University of Illinois at Urbana-Champaign",
248+
"2003-2019 by the contributors listed in CREDITS.TXT (https://github.com/rust-lang/llvm-project/blob/7738295178045041669876bf32b0543ec8319a5c/llvm/CREDITS.TXT)",
249+
"2010 Apple Inc"
250+
],
251+
"spdx": "Apache-2.0 WITH LLVM-exception AND NCSA"
252+
},
253+
"name": "src/llvm-project",
254+
"type": "directory"
255+
}
256+
],
257+
"license": {
258+
"copyright": [
259+
"The Rust Project Developers (see https://thanks.rust-lang.org)"
260+
],
261+
"spdx": "Apache-2.0 OR MIT"
262+
},
263+
"name": ".",
264+
"type": "directory"
265+
}
266+
],
267+
"type": "root"
268+
}
269+
}

‎src/bootstrap/src/core/build_steps/run.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,7 @@ impl Step for CollectLicenseMetadata {
181181
panic!("REUSE is required to collect the license metadata");
182182
};
183183

184-
// Temporary location, it will be moved to src/etc once it's accurate.
185-
let dest = builder.out.join("license-metadata.json");
184+
let dest = builder.src.join("license-metadata.json");
186185

187186
let mut cmd = builder.tool_cmd(Tool::CollectLicenseMetadata);
188187
cmd.env("REUSE_EXE", reuse);
@@ -209,8 +208,7 @@ impl Step for GenerateCopyright {
209208
}
210209

211210
fn run(self, builder: &Builder<'_>) -> Self::Output {
212-
let license_metadata = builder.ensure(CollectLicenseMetadata);
213-
211+
let license_metadata = builder.src.join("license-metadata.json");
214212
let dest = builder.out.join("COPYRIGHT.html");
215213
let dest_libstd = builder.out.join("COPYRIGHT-library.html");
216214

‎src/bootstrap/src/core/build_steps/test.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3670,3 +3670,35 @@ impl Step for TestFloatParse {
36703670
cargo_run.into_cmd().run(builder);
36713671
}
36723672
}
3673+
3674+
#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
3675+
pub struct CollectLicenseMetadata;
3676+
3677+
impl Step for CollectLicenseMetadata {
3678+
type Output = PathBuf;
3679+
const ONLY_HOSTS: bool = true;
3680+
3681+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3682+
run.path("src/tools/collect-license-metadata")
3683+
}
3684+
3685+
fn make_run(run: RunConfig<'_>) {
3686+
run.builder.ensure(CollectLicenseMetadata);
3687+
}
3688+
3689+
fn run(self, builder: &Builder<'_>) -> Self::Output {
3690+
let Some(reuse) = &builder.config.reuse else {
3691+
panic!("REUSE is required to collect the license metadata");
3692+
};
3693+
3694+
let dest = builder.src.join("license-metadata.json");
3695+
3696+
let mut cmd = builder.tool_cmd(Tool::CollectLicenseMetadata);
3697+
cmd.env("REUSE_EXE", reuse);
3698+
cmd.env("DEST", &dest);
3699+
cmd.env("ONLY_CHECK", "1");
3700+
cmd.run(builder);
3701+
3702+
dest
3703+
}
3704+
}

‎src/bootstrap/src/core/builder/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ impl<'a> Builder<'a> {
915915
test::HtmlCheck,
916916
test::RustInstaller,
917917
test::TestFloatParse,
918+
test::CollectLicenseMetadata,
918919
// Run bootstrap close to the end as it's unlikely to fail
919920
test::Bootstrap,
920921
// Run run-make last, since these won't pass without make on Windows

‎src/ci/docker/host-x86_64/mingw-check/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ ENV SCRIPT \
6363
/scripts/validate-toolstate.sh && \
6464
/scripts/validate-error-codes.sh && \
6565
reuse --include-submodules lint && \
66+
python3 ../x.py test collect-license-metadata && \
6667
# Runs checks to ensure that there are no issues in our JS code.
6768
es-check es2019 ../src/librustdoc/html/static/js/*.js && \
6869
eslint -c ../src/librustdoc/html/static/.eslintrc.js ../src/librustdoc/html/static/js/*.js && \

‎src/tools/collect-license-metadata/src/main.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,53 @@ mod reuse;
44

55
use std::path::PathBuf;
66

7-
use anyhow::Error;
7+
use anyhow::{Context, Error};
88

99
use crate::licenses::LicensesInterner;
1010

1111
/// The entry point to the binary.
1212
///
1313
/// You should probably let `bootstrap` execute this program instead of running it directly.
1414
///
15-
/// Run `x.py run collect-license-metadata`
15+
/// * Run `x.py run collect-license-metadata` to re-regenerate the file.
16+
/// * Run `x.py test collect-license-metadata` to check if the file you have is correct.
1617
fn main() -> Result<(), Error> {
1718
let reuse_exe: PathBuf = std::env::var_os("REUSE_EXE").expect("Missing REUSE_EXE").into();
1819
let dest: PathBuf = std::env::var_os("DEST").expect("Missing DEST").into();
20+
let only_check = std::env::var_os("ONLY_CHECK").is_some();
1921

2022
let mut interner = LicensesInterner::new();
2123
let paths = crate::reuse::collect(&reuse_exe, &mut interner)?;
2224

2325
let mut tree = crate::path_tree::build(paths);
2426
tree.simplify();
2527

26-
if let Some(parent) = dest.parent() {
27-
std::fs::create_dir_all(parent)?;
28+
let output = serde_json::json!({
29+
"files": crate::path_tree::expand_interned_licenses(tree, &interner)
30+
});
31+
32+
if only_check {
33+
println!("loading existing license information");
34+
let existing = std::fs::read_to_string(&dest).with_context(|| {
35+
format!("Failed to read existing license JSON at {}", dest.display())
36+
})?;
37+
let existing_json: serde_json::Value =
38+
serde_json::from_str(&existing).with_context(|| {
39+
format!("Failed to read existing license JSON at {}", dest.display())
40+
})?;
41+
if existing_json != output {
42+
eprintln!("The existing {} file is out of date.", dest.display());
43+
eprintln!("Run ./x run collect-license-metadata to update it.");
44+
anyhow::bail!("The existing {} file doesn't match what REUSE reports.", dest.display());
45+
}
46+
println!("license information matches");
47+
} else {
48+
if let Some(parent) = dest.parent() {
49+
std::fs::create_dir_all(parent)?;
50+
}
51+
std::fs::write(&dest, &serde_json::to_vec_pretty(&output)?)?;
52+
println!("license information written to {}", dest.display());
2853
}
29-
std::fs::write(
30-
&dest,
31-
&serde_json::to_vec_pretty(&serde_json::json!({
32-
"files": crate::path_tree::expand_interned_licenses(tree, &interner),
33-
}))?,
34-
)?;
3554

3655
Ok(())
3756
}

‎src/tools/collect-license-metadata/src/reuse.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ pub(crate) fn collect(
1010
reuse_exe: &Path,
1111
interner: &mut LicensesInterner,
1212
) -> Result<Vec<(PathBuf, LicenseId)>, Error> {
13-
eprintln!("gathering license information from REUSE");
13+
println!("gathering license information from REUSE (this might take a minute...)");
1414
let start = Instant::now();
1515
let raw = &obtain_spdx_document(reuse_exe)?;
16-
eprintln!("finished gathering the license information from REUSE in {:.2?}", start.elapsed());
16+
println!("finished gathering the license information from REUSE in {:.2?}", start.elapsed());
1717

1818
let document = spdx_rs::parsers::spdx_from_tag_value(&raw)?;
1919

‎src/tools/generate-copyright/src/main.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ fn main() -> Result<(), Error> {
5757
dependencies: collected_cargo_metadata,
5858
};
5959
let output = template.render()?;
60+
// Git stores text files with \n, but this file may contain \r\n in files
61+
// copied from dependencies. Normalise them before we write them out, for
62+
// consistency.
63+
let output = output.replace("\r\n", "\n");
6064
std::fs::write(&dest_file, output)?;
6165

6266
// Output libstd subset file
@@ -65,6 +69,10 @@ fn main() -> Result<(), Error> {
6569
dependencies: library_collected_cargo_metadata,
6670
};
6771
let output = template.render()?;
72+
// Git stores text files with \n, but this file may contain \r\n in files
73+
// copied from dependencies. Normalise them before we write them out, for
74+
// consistency.
75+
let output = output.replace("\r\n", "\n");
6876
std::fs::write(&libstd_dest_file, output)?;
6977

7078
Ok(())

0 commit comments

Comments
 (0)
Please sign in to comment.