Skip to content

Commit dd2de6d

Browse files
generate-copyright: Produce HTML, not Markdown
This format works better with large amounts of structured data. We also mark which deps are in the stdlib
1 parent f13323c commit dd2de6d

File tree

3 files changed

+152
-103
lines changed

3 files changed

+152
-103
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ impl Step for GenerateCopyright {
212212
let license_metadata = builder.ensure(CollectLicenseMetadata);
213213

214214
// Temporary location, it will be moved to the proper one once it's accurate.
215-
let dest = builder.out.join("COPYRIGHT.md");
215+
let dest = builder.out.join("COPYRIGHT.html");
216216

217217
let mut cmd = builder.tool_cmd(Tool::GenerateCopyright);
218218
cmd.env("LICENSE_METADATA", &license_metadata);

src/tools/generate-copyright/src/cargo_metadata.rs

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Gets metadata about a workspace from Cargo
22
3-
use std::collections::{BTreeMap, BTreeSet};
3+
use std::collections::BTreeMap;
44
use std::ffi::{OsStr, OsString};
55
use std::path::Path;
66

@@ -23,13 +23,18 @@ pub enum Error {
2323
RunningVendor,
2424
}
2525

26-
/// Describes one of our dependencies
26+
/// Uniquely describes a package on crates.io
2727
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
28-
pub struct Dependency {
28+
pub struct Package {
2929
/// The name of the package
3030
pub name: String,
3131
/// The version number
3232
pub version: String,
33+
}
34+
35+
/// Extra data about a package
36+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
37+
pub struct PackageMetadata {
3338
/// The license it is under
3439
pub license: String,
3540
/// The list of authors from the package metadata
@@ -40,20 +45,44 @@ pub struct Dependency {
4045
pub notices: BTreeMap<OsString, String>,
4146
}
4247

43-
/// Use `cargo` to get a list of dependencies and their license data.
48+
/// Use `cargo metadata` and `cargo vendor` to get a list of dependencies and their license data.
4449
///
4550
/// This will involve running `cargo vendor` into `${BUILD}/vendor` so we can
4651
/// grab the license files.
4752
///
4853
/// Any dependency with a path beginning with `root_path` is ignored, as we
4954
/// assume `reuse` has covered it already.
50-
pub fn get(
55+
pub fn get_metadata_and_notices(
5156
cargo: &Path,
5257
dest: &Path,
5358
root_path: &Path,
5459
manifest_paths: &[&Path],
55-
) -> Result<BTreeSet<Dependency>, Error> {
56-
let mut temp_set = BTreeSet::new();
60+
) -> Result<BTreeMap<Package, PackageMetadata>, Error> {
61+
let mut output = get_metadata(cargo, root_path, manifest_paths)?;
62+
63+
// Now do a cargo-vendor and grab everything
64+
let vendor_path = dest.join("vendor");
65+
println!("Vendoring deps into {}...", vendor_path.display());
66+
run_cargo_vendor(cargo, &vendor_path, manifest_paths)?;
67+
68+
// Now for each dependency we found, go and grab any important looking files
69+
for (package, metadata) in output.iter_mut() {
70+
load_important_files(package, metadata, &vendor_path)?;
71+
}
72+
73+
Ok(output)
74+
}
75+
76+
/// Use `cargo metadata` to get a list of dependencies and their license data.
77+
///
78+
/// Any dependency with a path beginning with `root_path` is ignored, as we
79+
/// assume `reuse` has covered it already.
80+
pub fn get_metadata(
81+
cargo: &Path,
82+
root_path: &Path,
83+
manifest_paths: &[&Path],
84+
) -> Result<BTreeMap<Package, PackageMetadata>, Error> {
85+
let mut output = BTreeMap::new();
5786
// Look at the metadata for each manifest
5887
for manifest_path in manifest_paths {
5988
if manifest_path.file_name() != Some(OsStr::new("Cargo.toml")) {
@@ -71,7 +100,7 @@ pub fn get(
71100
.and_then(|v| v.as_str())
72101
.map(Path::new)
73102
.ok_or_else(|| Error::MissingJsonElement("package.manifest_path"))?;
74-
if manifest_path.starts_with(&root_path) {
103+
if manifest_path.starts_with(root_path) {
75104
// it's an in-tree dependency and reuse covers it
76105
continue;
77106
}
@@ -93,28 +122,14 @@ pub fn get(
93122
.ok_or_else(|| Error::MissingJsonElement("package.authors"))?;
94123
let authors: Vec<String> =
95124
authors_list.iter().filter_map(|v| v.as_str()).map(|s| s.to_owned()).collect();
96-
temp_set.insert(Dependency {
97-
name: name.to_owned(),
98-
version: version.to_owned(),
99-
license: license.to_owned(),
100-
authors,
101-
notices: BTreeMap::new(),
102-
});
125+
let package = Package { name: name.to_owned(), version: version.to_owned() };
126+
output.insert(
127+
package.clone(),
128+
PackageMetadata { license: license.to_owned(), authors, notices: BTreeMap::new() },
129+
);
103130
}
104131
}
105132

106-
// Now do a cargo-vendor and grab everything
107-
let vendor_path = dest.join("vendor");
108-
println!("Vendoring deps into {}...", vendor_path.display());
109-
run_cargo_vendor(cargo, &vendor_path, manifest_paths)?;
110-
111-
// Now for each dependency we found, go and grab any important looking files
112-
let mut output = BTreeSet::new();
113-
for mut dep in temp_set {
114-
load_important_files(&mut dep, &vendor_path)?;
115-
output.insert(dep);
116-
}
117-
118133
Ok(output)
119134
}
120135

@@ -128,7 +143,7 @@ fn get_metadata_json(cargo: &Path, manifest_path: &Path) -> Result<serde_json::V
128143
.arg(manifest_path)
129144
.env("RUSTC_BOOTSTRAP", "1")
130145
.output()
131-
.map_err(|e| Error::LaunchingMetadata(e))?;
146+
.map_err(Error::LaunchingMetadata)?;
132147
if !metadata_output.status.success() {
133148
return Err(Error::GettingMetadata(
134149
String::from_utf8(metadata_output.stderr).expect("UTF-8 output from cargo"),
@@ -151,7 +166,7 @@ fn run_cargo_vendor(cargo: &Path, dest: &Path, manifest_paths: &[&Path]) -> Resu
151166
}
152167
vendor_command.arg(dest);
153168

154-
let vendor_status = vendor_command.status().map_err(|e| Error::LaunchingVendor(e))?;
169+
let vendor_status = vendor_command.status().map_err(Error::LaunchingVendor)?;
155170

156171
if !vendor_status.success() {
157172
return Err(Error::RunningVendor);
@@ -164,8 +179,12 @@ fn run_cargo_vendor(cargo: &Path, dest: &Path, manifest_paths: &[&Path]) -> Resu
164179
///
165180
/// Maybe one-day Cargo.toml will contain enough information that we don't need
166181
/// to do this manual scraping.
167-
fn load_important_files(dep: &mut Dependency, vendor_root: &Path) -> Result<(), Error> {
168-
let name_version = format!("{}-{}", dep.name, dep.version);
182+
fn load_important_files(
183+
package: &Package,
184+
dep: &mut PackageMetadata,
185+
vendor_root: &Path,
186+
) -> Result<(), Error> {
187+
let name_version = format!("{}-{}", package.name, package.version);
169188
println!("Scraping notices for {}...", name_version);
170189
let dep_vendor_path = vendor_root.join(name_version);
171190
for entry in std::fs::read_dir(dep_vendor_path)? {

0 commit comments

Comments
 (0)