1
1
use anyhow:: Error ;
2
- use std:: collections:: BTreeSet ;
2
+ use std:: collections:: { BTreeMap , BTreeSet } ;
3
3
use std:: io:: Write ;
4
4
use std:: path:: { Path , PathBuf } ;
5
5
6
6
mod cargo_metadata;
7
7
8
- static TOP_BOILERPLATE : & ' static str = r##"
8
+ static TOP_BOILERPLATE : & str = r##"
9
9
<!DOCTYPE html>
10
10
<html>
11
11
<head>
@@ -27,7 +27,7 @@ when building the Rust toolchain (including the Rust Standard Library).</p>
27
27
</ul>
28
28
"## ;
29
29
30
- static BOTTOM_BOILERPLATE : & ' static str = r#"
30
+ static BOTTOM_BOILERPLATE : & str = r#"
31
31
</body>
32
32
</html>
33
33
"# ;
@@ -53,9 +53,10 @@ fn main() -> Result<(), Error> {
53
53
Path :: new ( "./library/std/Cargo.toml" ) ,
54
54
] ;
55
55
let collected_cargo_metadata =
56
- cargo_metadata:: get ( & cargo, & out_dir, & root_path, & workspace_paths) ?;
56
+ cargo_metadata:: get_metadata_and_notices ( & cargo, & out_dir, & root_path, & workspace_paths) ?;
57
57
58
- let mut license_set = BTreeSet :: new ( ) ;
58
+ let stdlib_set =
59
+ cargo_metadata:: get_metadata ( & cargo, & root_path, & [ Path :: new ( "./library/std/Cargo.toml" ) ] ) ?;
59
60
60
61
let mut buffer = Vec :: new ( ) ;
61
62
@@ -65,13 +66,13 @@ fn main() -> Result<(), Error> {
65
66
buffer,
66
67
r#"<h2 id="in-tree-files">In-tree files</h2><p>The following licenses cover the in-tree source files that were used in this release:</p>"#
67
68
) ?;
68
- render_tree_recursive ( & collected_tree_metadata. files , & mut buffer, 0 , & mut license_set ) ?;
69
+ render_tree_recursive ( & collected_tree_metadata. files , & mut buffer) ?;
69
70
70
71
writeln ! (
71
72
buffer,
72
73
r#"<h2 id="out-of-tree-dependencies">Out-of-tree dependencies</h2><p>The following licenses cover the out-of-tree crates that were used in this release:</p>"#
73
74
) ?;
74
- render_deps ( collected_cargo_metadata. iter ( ) , & mut buffer , & mut license_set ) ?;
75
+ render_deps ( & collected_cargo_metadata, & stdlib_set , & mut buffer ) ?;
75
76
76
77
writeln ! ( buffer, "{}" , BOTTOM_BOILERPLATE ) ?;
77
78
@@ -82,46 +83,35 @@ fn main() -> Result<(), Error> {
82
83
83
84
/// Recursively draw the tree of files/folders we found on disk and their licenses, as
84
85
/// markdown, into the given Vec.
85
- fn render_tree_recursive (
86
- node : & Node ,
87
- buffer : & mut Vec < u8 > ,
88
- depth : usize ,
89
- license_set : & mut BTreeSet < String > ,
90
- ) -> Result < ( ) , Error > {
86
+ fn render_tree_recursive ( node : & Node , buffer : & mut Vec < u8 > ) -> Result < ( ) , Error > {
91
87
writeln ! ( buffer, r#"<div style="border:1px solid black; padding: 5px;">"# ) ?;
92
88
match node {
93
89
Node :: Root { children } => {
94
90
for child in children {
95
- render_tree_recursive ( child, buffer, depth , license_set ) ?;
91
+ render_tree_recursive ( child, buffer) ?;
96
92
}
97
93
}
98
94
Node :: Directory { name, children, license } => {
99
- render_tree_license ( std:: iter:: once ( name) , license. iter ( ) , buffer, license_set ) ?;
95
+ render_tree_license ( std:: iter:: once ( name) , license. iter ( ) , buffer) ?;
100
96
if !children. is_empty ( ) {
101
97
writeln ! ( buffer, "<p><b>Exceptions:</b></p>" ) ?;
102
98
for child in children {
103
- render_tree_recursive ( child, buffer, depth + 1 , license_set ) ?;
99
+ render_tree_recursive ( child, buffer) ?;
104
100
}
105
101
}
106
102
}
107
103
Node :: CondensedDirectory { name, licenses } => {
108
- render_tree_license ( std:: iter:: once ( name) , licenses. iter ( ) , buffer, license_set ) ?;
104
+ render_tree_license ( std:: iter:: once ( name) , licenses. iter ( ) , buffer) ?;
109
105
}
110
106
Node :: Group { files, directories, license } => {
111
107
render_tree_license (
112
108
directories. iter ( ) . chain ( files. iter ( ) ) ,
113
109
std:: iter:: once ( license) ,
114
110
buffer,
115
- license_set,
116
111
) ?;
117
112
}
118
113
Node :: File { name, license } => {
119
- render_tree_license (
120
- std:: iter:: once ( name) ,
121
- std:: iter:: once ( license) ,
122
- buffer,
123
- license_set,
124
- ) ?;
114
+ render_tree_license ( std:: iter:: once ( name) , std:: iter:: once ( license) , buffer) ?;
125
115
}
126
116
}
127
117
writeln ! ( buffer, "</div>" ) ?;
@@ -134,14 +124,12 @@ fn render_tree_license<'a>(
134
124
names : impl Iterator < Item = & ' a String > ,
135
125
licenses : impl Iterator < Item = & ' a License > ,
136
126
buffer : & mut Vec < u8 > ,
137
- license_set : & mut BTreeSet < String > ,
138
127
) -> Result < ( ) , Error > {
139
128
// de-duplicate and sort SPDX and Copyright strings
140
129
let mut spdxs = BTreeSet :: new ( ) ;
141
130
let mut copyrights = BTreeSet :: new ( ) ;
142
131
for license in licenses {
143
132
spdxs. insert ( & license. spdx ) ;
144
- license_set. insert ( license. spdx . clone ( ) ) ;
145
133
for copyright in & license. copyright {
146
134
copyrights. insert ( copyright) ;
147
135
}
@@ -168,34 +156,38 @@ fn render_tree_license<'a>(
168
156
}
169
157
170
158
/// Render a list of out-of-tree dependencies as markdown into the given Vec.
171
- fn render_deps < ' a , ' b > (
172
- deps : impl Iterator < Item = & ' a cargo_metadata:: Dependency > ,
173
- buffer : & ' b mut Vec < u8 > ,
174
- license_set : & mut BTreeSet < String > ,
159
+ fn render_deps (
160
+ all_deps : & BTreeMap < cargo_metadata :: Package , cargo_metadata:: PackageMetadata > ,
161
+ stdlib_set : & BTreeMap < cargo_metadata :: Package , cargo_metadata :: PackageMetadata > ,
162
+ buffer : & mut Vec < u8 > ,
175
163
) -> Result < ( ) , Error > {
176
- for dep in deps {
177
- let authors_list = if dep . authors . is_empty ( ) {
164
+ for ( package , metadata ) in all_deps {
165
+ let authors_list = if metadata . authors . is_empty ( ) {
178
166
"None Specified" . to_owned ( )
179
167
} else {
180
- dep . authors . join ( ", " )
168
+ metadata . authors . join ( ", " )
181
169
} ;
182
- let url = format ! ( "https://crates.io/crates/{}/{}" , dep . name, dep . version) ;
170
+ let url = format ! ( "https://crates.io/crates/{}/{}" , package . name, package . version) ;
183
171
writeln ! ( buffer) ?;
184
172
writeln ! (
185
173
buffer,
186
174
r#"<h3>📦 {name}-{version}</h3>"# ,
187
- name = dep . name,
188
- version = dep . version,
175
+ name = package . name,
176
+ version = package . version,
189
177
) ?;
190
178
writeln ! ( buffer, r#"<p><b>URL:</b> <a href="{url}">{url}</a></p>"# , ) ?;
179
+ writeln ! (
180
+ buffer,
181
+ "<p><b>In libstd:</b> {}</p>" ,
182
+ if stdlib_set. contains_key( package) { "Yes" } else { "No" }
183
+ ) ?;
191
184
writeln ! ( buffer, "<p><b>Authors:</b> {}</p>" , escape_html( & authors_list) ) ?;
192
- writeln ! ( buffer, "<p><b>License:</b> {}</p>" , escape_html( & dep. license) ) ?;
193
- license_set. insert ( dep. license . clone ( ) ) ;
185
+ writeln ! ( buffer, "<p><b>License:</b> {}</p>" , escape_html( & metadata. license) ) ?;
194
186
writeln ! ( buffer, "<p><b>Notices:</b> " ) ?;
195
- if dep . notices . is_empty ( ) {
187
+ if metadata . notices . is_empty ( ) {
196
188
writeln ! ( buffer, "None" ) ?;
197
189
} else {
198
- for ( name, contents) in & dep . notices {
190
+ for ( name, contents) in & metadata . notices {
199
191
writeln ! (
200
192
buffer,
201
193
"<details><summary><code>{}</code></summary>" ,
@@ -244,7 +236,7 @@ fn env_path(var: &str) -> Result<PathBuf, Error> {
244
236
245
237
/// Escapes any invalid HTML characters
246
238
fn escape_html ( input : & str ) -> String {
247
- static MAPPING : [ ( char , & ' static str ) ; 3 ] = [ ( '&' , "&" ) , ( '<' , "<" ) , ( '>' , ">" ) ] ;
239
+ static MAPPING : [ ( char , & str ) ; 3 ] = [ ( '&' , "&" ) , ( '<' , "<" ) , ( '>' , ">" ) ] ;
248
240
let mut output = input. to_owned ( ) ;
249
241
for ( ch, s) in & MAPPING {
250
242
output = output. replace ( * ch, s) ;
0 commit comments