11use anyhow:: Error ;
2- use std:: collections:: BTreeSet ;
2+ use std:: collections:: { BTreeMap , BTreeSet } ;
33use std:: io:: Write ;
44use std:: path:: { Path , PathBuf } ;
55
66mod cargo_metadata;
77
8- static TOP_BOILERPLATE : & ' static str = r##"
8+ static TOP_BOILERPLATE : & str = r##"
99<!DOCTYPE html>
1010<html>
1111<head>
@@ -27,7 +27,7 @@ when building the Rust toolchain (including the Rust Standard Library).</p>
2727</ul>
2828"## ;
2929
30- static BOTTOM_BOILERPLATE : & ' static str = r#"
30+ static BOTTOM_BOILERPLATE : & str = r#"
3131</body>
3232</html>
3333"# ;
@@ -53,9 +53,10 @@ fn main() -> Result<(), Error> {
5353 Path :: new ( "./library/std/Cargo.toml" ) ,
5454 ] ;
5555 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) ?;
5757
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" ) ] ) ?;
5960
6061 let mut buffer = Vec :: new ( ) ;
6162
@@ -65,13 +66,13 @@ fn main() -> Result<(), Error> {
6566 buffer,
6667 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>"#
6768 ) ?;
68- render_tree_recursive ( & collected_tree_metadata. files , & mut buffer, 0 , & mut license_set ) ?;
69+ render_tree_recursive ( & collected_tree_metadata. files , & mut buffer) ?;
6970
7071 writeln ! (
7172 buffer,
7273 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>"#
7374 ) ?;
74- render_deps ( collected_cargo_metadata. iter ( ) , & mut buffer , & mut license_set ) ?;
75+ render_deps ( & collected_cargo_metadata, & stdlib_set , & mut buffer ) ?;
7576
7677 writeln ! ( buffer, "{}" , BOTTOM_BOILERPLATE ) ?;
7778
@@ -82,46 +83,35 @@ fn main() -> Result<(), Error> {
8283
8384/// Recursively draw the tree of files/folders we found on disk and their licenses, as
8485/// 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 > {
9187 writeln ! ( buffer, r#"<div style="border:1px solid black; padding: 5px;">"# ) ?;
9288 match node {
9389 Node :: Root { children } => {
9490 for child in children {
95- render_tree_recursive ( child, buffer, depth , license_set ) ?;
91+ render_tree_recursive ( child, buffer) ?;
9692 }
9793 }
9894 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) ?;
10096 if !children. is_empty ( ) {
10197 writeln ! ( buffer, "<p><b>Exceptions:</b></p>" ) ?;
10298 for child in children {
103- render_tree_recursive ( child, buffer, depth + 1 , license_set ) ?;
99+ render_tree_recursive ( child, buffer) ?;
104100 }
105101 }
106102 }
107103 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) ?;
109105 }
110106 Node :: Group { files, directories, license } => {
111107 render_tree_license (
112108 directories. iter ( ) . chain ( files. iter ( ) ) ,
113109 std:: iter:: once ( license) ,
114110 buffer,
115- license_set,
116111 ) ?;
117112 }
118113 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) ?;
125115 }
126116 }
127117 writeln ! ( buffer, "</div>" ) ?;
@@ -134,14 +124,12 @@ fn render_tree_license<'a>(
134124 names : impl Iterator < Item = & ' a String > ,
135125 licenses : impl Iterator < Item = & ' a License > ,
136126 buffer : & mut Vec < u8 > ,
137- license_set : & mut BTreeSet < String > ,
138127) -> Result < ( ) , Error > {
139128 // de-duplicate and sort SPDX and Copyright strings
140129 let mut spdxs = BTreeSet :: new ( ) ;
141130 let mut copyrights = BTreeSet :: new ( ) ;
142131 for license in licenses {
143132 spdxs. insert ( & license. spdx ) ;
144- license_set. insert ( license. spdx . clone ( ) ) ;
145133 for copyright in & license. copyright {
146134 copyrights. insert ( copyright) ;
147135 }
@@ -168,34 +156,38 @@ fn render_tree_license<'a>(
168156}
169157
170158/// 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 > ,
175163) -> 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 ( ) {
178166 "None Specified" . to_owned ( )
179167 } else {
180- dep . authors . join ( ", " )
168+ metadata . authors . join ( ", " )
181169 } ;
182- let url = format ! ( "https://crates.io/crates/{}/{}" , dep . name, dep . version) ;
170+ let url = format ! ( "https://crates.io/crates/{}/{}" , package . name, package . version) ;
183171 writeln ! ( buffer) ?;
184172 writeln ! (
185173 buffer,
186174 r#"<h3>📦 {name}-{version}</h3>"# ,
187- name = dep . name,
188- version = dep . version,
175+ name = package . name,
176+ version = package . version,
189177 ) ?;
190178 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+ ) ?;
191184 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) ) ?;
194186 writeln ! ( buffer, "<p><b>Notices:</b> " ) ?;
195- if dep . notices . is_empty ( ) {
187+ if metadata . notices . is_empty ( ) {
196188 writeln ! ( buffer, "None" ) ?;
197189 } else {
198- for ( name, contents) in & dep . notices {
190+ for ( name, contents) in & metadata . notices {
199191 writeln ! (
200192 buffer,
201193 "<details><summary><code>{}</code></summary>" ,
@@ -244,7 +236,7 @@ fn env_path(var: &str) -> Result<PathBuf, Error> {
244236
245237/// Escapes any invalid HTML characters
246238fn escape_html ( input : & str ) -> String {
247- static MAPPING : [ ( char , & ' static str ) ; 3 ] = [ ( '&' , "&" ) , ( '<' , "<" ) , ( '>' , ">" ) ] ;
239+ static MAPPING : [ ( char , & str ) ; 3 ] = [ ( '&' , "&" ) , ( '<' , "<" ) , ( '>' , ">" ) ] ;
248240 let mut output = input. to_owned ( ) ;
249241 for ( ch, s) in & MAPPING {
250242 output = output. replace ( * ch, s) ;
0 commit comments