1
1
//! Gets metadata about a workspace from Cargo
2
2
3
- use std:: collections:: { BTreeMap , BTreeSet } ;
3
+ use std:: collections:: BTreeMap ;
4
4
use std:: ffi:: { OsStr , OsString } ;
5
5
use std:: path:: Path ;
6
6
@@ -23,13 +23,18 @@ pub enum Error {
23
23
RunningVendor ,
24
24
}
25
25
26
- /// Describes one of our dependencies
26
+ /// Uniquely describes a package on crates.io
27
27
#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
28
- pub struct Dependency {
28
+ pub struct Package {
29
29
/// The name of the package
30
30
pub name : String ,
31
31
/// The version number
32
32
pub version : String ,
33
+ }
34
+
35
+ /// Extra data about a package
36
+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
37
+ pub struct PackageMetadata {
33
38
/// The license it is under
34
39
pub license : String ,
35
40
/// The list of authors from the package metadata
@@ -40,20 +45,44 @@ pub struct Dependency {
40
45
pub notices : BTreeMap < OsString , String > ,
41
46
}
42
47
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.
44
49
///
45
50
/// This will involve running `cargo vendor` into `${BUILD}/vendor` so we can
46
51
/// grab the license files.
47
52
///
48
53
/// Any dependency with a path beginning with `root_path` is ignored, as we
49
54
/// assume `reuse` has covered it already.
50
- pub fn get (
55
+ pub fn get_metadata_and_notices (
51
56
cargo : & Path ,
52
57
dest : & Path ,
53
58
root_path : & Path ,
54
59
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 ( ) ;
57
86
// Look at the metadata for each manifest
58
87
for manifest_path in manifest_paths {
59
88
if manifest_path. file_name ( ) != Some ( OsStr :: new ( "Cargo.toml" ) ) {
@@ -71,7 +100,7 @@ pub fn get(
71
100
. and_then ( |v| v. as_str ( ) )
72
101
. map ( Path :: new)
73
102
. ok_or_else ( || Error :: MissingJsonElement ( "package.manifest_path" ) ) ?;
74
- if manifest_path. starts_with ( & root_path) {
103
+ if manifest_path. starts_with ( root_path) {
75
104
// it's an in-tree dependency and reuse covers it
76
105
continue ;
77
106
}
@@ -93,28 +122,14 @@ pub fn get(
93
122
. ok_or_else ( || Error :: MissingJsonElement ( "package.authors" ) ) ?;
94
123
let authors: Vec < String > =
95
124
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
+ ) ;
103
130
}
104
131
}
105
132
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
-
118
133
Ok ( output)
119
134
}
120
135
@@ -128,7 +143,7 @@ fn get_metadata_json(cargo: &Path, manifest_path: &Path) -> Result<serde_json::V
128
143
. arg ( manifest_path)
129
144
. env ( "RUSTC_BOOTSTRAP" , "1" )
130
145
. output ( )
131
- . map_err ( |e| Error :: LaunchingMetadata ( e ) ) ?;
146
+ . map_err ( Error :: LaunchingMetadata ) ?;
132
147
if !metadata_output. status . success ( ) {
133
148
return Err ( Error :: GettingMetadata (
134
149
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
151
166
}
152
167
vendor_command. arg ( dest) ;
153
168
154
- let vendor_status = vendor_command. status ( ) . map_err ( |e| Error :: LaunchingVendor ( e ) ) ?;
169
+ let vendor_status = vendor_command. status ( ) . map_err ( Error :: LaunchingVendor ) ?;
155
170
156
171
if !vendor_status. success ( ) {
157
172
return Err ( Error :: RunningVendor ) ;
@@ -164,8 +179,12 @@ fn run_cargo_vendor(cargo: &Path, dest: &Path, manifest_paths: &[&Path]) -> Resu
164
179
///
165
180
/// Maybe one-day Cargo.toml will contain enough information that we don't need
166
181
/// 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) ;
169
188
println ! ( "Scraping notices for {}..." , name_version) ;
170
189
let dep_vendor_path = vendor_root. join ( name_version) ;
171
190
for entry in std:: fs:: read_dir ( dep_vendor_path) ? {
0 commit comments