@@ -10,10 +10,13 @@ use std::str;
10
10
use std:: thread;
11
11
use std:: time:: Duration ;
12
12
13
+ use cargo_metadata:: { Metadata , Package } ;
14
+
13
15
const PREFIX : & str = "ra-ap" ;
14
16
15
17
fn main ( ) {
16
- let token = std:: env:: args ( ) . nth ( 1 ) ;
18
+ let do_publish = std:: env:: args ( ) . nth ( 1 ) . unwrap ( ) == "publish" ;
19
+ let token = std:: env:: args ( ) . nth ( 2 ) ;
17
20
let commit = latest_master_commit ( & token) ;
18
21
println ! ( "latest commit: {}" , commit) ;
19
22
@@ -27,48 +30,50 @@ fn main() {
27
30
28
31
let target_crates = vec ! [
29
32
RustcApCrate {
30
- name: "rustc_lexer" ,
31
- dir: "compiler/rustc_lexer" ,
32
- } ,
33
- RustcApCrate {
34
- name: "rustc_serialize" ,
35
- dir: "compiler/rustc_serialize" ,
36
- } ,
37
- RustcApCrate {
38
- name: "rustc_macros" ,
39
- dir: "compiler/rustc_macros" ,
40
- } ,
41
- RustcApCrate {
42
- name: "rustc_index" ,
43
- dir: "compiler/rustc_index" ,
33
+ name: "rustc_lexer" . to_owned( ) ,
34
+ dir: "compiler/rustc_lexer" . to_owned( ) ,
44
35
} ,
45
36
RustcApCrate {
46
- name: "rustc_parse_format" ,
47
- dir: "compiler/rustc_parse_format" ,
37
+ name: "rustc_parse_format" . to_owned ( ) ,
38
+ dir: "compiler/rustc_parse_format" . to_owned ( ) ,
48
39
} ,
49
40
RustcApCrate {
50
- name: "rustc_abi" ,
51
- dir: "compiler/rustc_abi" ,
41
+ name: "rustc_abi" . to_owned ( ) ,
42
+ dir: "compiler/rustc_abi" . to_owned ( ) ,
52
43
} ,
53
44
] ;
54
45
55
46
println ! ( "learning about the dependency graph" ) ;
56
47
let rustc_packages = get_rustc_packages ( & target_crates, & dst) ;
48
+ println ! (
49
+ "found packages: {:?}" ,
50
+ rustc_packages
51
+ . iter( )
52
+ . map( |it| & it. package. name)
53
+ . collect:: <Vec <_>>( )
54
+ ) ;
57
55
let mut crates = Vec :: new ( ) ;
58
56
let mut seen = HashSet :: new ( ) ;
59
57
60
58
for RustcPackageInfo { package, metadata } in rustc_packages. iter ( ) {
61
59
fill ( & metadata, & package, & mut crates, & mut seen) ;
62
60
}
61
+ let crates = crates_in_topological_order ( & crates) ;
63
62
64
- let version_to_publish = get_version_to_publish ( & crates) ;
65
- println ! ( "going to publish {}" , version_to_publish) ;
63
+ println ! (
64
+ "topologically sorted: {:?}" ,
65
+ crates. iter( ) . map( |it| & it. name) . collect:: <Vec <_>>( )
66
+ ) ;
67
+ if do_publish {
68
+ let version_to_publish = get_version_to_publish ( & crates) ;
69
+ println ! ( "going to publish {}" , version_to_publish) ;
66
70
67
- for p in crates. iter ( ) {
68
- publish ( p, & commit, & version_to_publish) ;
71
+ for p in crates {
72
+ publish ( p, & commit, & version_to_publish) ;
69
73
70
- // Give the crates time to make their way into the index
71
- thread:: sleep ( Duration :: from_secs ( 45 ) ) ;
74
+ // Give the crates time to make their way into the index
75
+ thread:: sleep ( Duration :: from_secs ( 45 ) ) ;
76
+ }
72
77
}
73
78
}
74
79
@@ -134,31 +139,38 @@ fn download_src(dst: &Path, commit: &str) {
134
139
}
135
140
136
141
fn get_rustc_packages ( target_crates : & [ RustcApCrate ] , dst : & Path ) -> Vec < RustcPackageInfo > {
142
+ let mut work = target_crates. to_vec ( ) ;
137
143
let mut packages = Vec :: new ( ) ;
138
144
139
- for RustcApCrate { name, dir } in target_crates. iter ( ) {
140
- let metadata = Command :: new ( "cargo" )
141
- . current_dir ( dst. join ( dir) )
142
- . arg ( "metadata" )
143
- . arg ( "--format-version=1" )
144
- . output ( )
145
- . expect ( "failed to execute cargo" ) ;
146
- if !metadata. status . success ( ) {
147
- panic ! ( "failed to run rustc: {:?}" , metadata) ;
145
+ while let Some ( RustcApCrate { name, dir } ) = work. pop ( ) {
146
+ if packages
147
+ . iter ( )
148
+ . any ( |it : & RustcPackageInfo | it. package . name == name)
149
+ {
150
+ continue ;
148
151
}
149
- let output = str:: from_utf8 ( & metadata. stdout ) . unwrap ( ) ;
150
- let output: Metadata = serde_json:: from_str ( output) . unwrap ( ) ;
152
+ let mut cmd = cargo_metadata:: MetadataCommand :: new ( ) ;
153
+ cmd. manifest_path ( dst. join ( dir) . join ( "Cargo.toml" ) ) ;
154
+ let metadata = cmd. exec ( ) . unwrap ( ) ;
151
155
152
- let rustc_package = output
156
+ let rustc_package = metadata
153
157
. packages
154
158
. iter ( )
155
159
. find ( |p| p. name == * name)
156
160
. expect ( & format ! ( "failed to find {}" , & name) )
157
161
. clone ( ) ;
162
+ for dep in rustc_package. dependencies . iter ( ) {
163
+ if let Some ( path) = & dep. path {
164
+ work. push ( RustcApCrate {
165
+ name : dep. name . clone ( ) ,
166
+ dir : path. to_string ( ) ,
167
+ } )
168
+ }
169
+ }
158
170
159
171
packages. push ( RustcPackageInfo {
160
172
package : rustc_package,
161
- metadata : output ,
173
+ metadata,
162
174
} )
163
175
}
164
176
@@ -176,6 +188,8 @@ fn fill<'a>(
176
188
}
177
189
let node = output
178
190
. resolve
191
+ . as_ref ( )
192
+ . unwrap ( )
179
193
. nodes
180
194
. iter ( )
181
195
. find ( |n| n. id == pkg. id )
@@ -189,34 +203,38 @@ fn fill<'a>(
189
203
pkgs. push ( pkg) ;
190
204
}
191
205
192
- #[ derive( Deserialize ) ]
193
- struct Metadata {
194
- packages : Vec < Package > ,
195
- resolve : Resolve ,
196
- }
206
+ // dirt topo sort
207
+ fn crates_in_topological_order < ' a > ( pkgs : & [ & ' a Package ] ) -> Vec < & ' a Package > {
208
+ let mut res = Vec :: new ( ) ;
209
+ let mut visited = HashSet :: default ( ) ;
197
210
198
- #[ derive( Deserialize , Clone ) ]
199
- struct Package {
200
- id : String ,
201
- name : String ,
202
- source : Option < String > ,
203
- manifest_path : String ,
204
- }
211
+ for pkg in pkgs {
212
+ go ( pkgs, & mut visited, & mut res, pkg) ;
213
+ }
205
214
206
- #[ derive( Deserialize ) ]
207
- struct Resolve {
208
- nodes : Vec < ResolveNode > ,
209
- }
215
+ return res;
210
216
211
- #[ derive( Deserialize ) ]
212
- struct ResolveNode {
213
- id : String ,
214
- dependencies : Vec < String > ,
217
+ fn go < ' a > (
218
+ pkgs : & [ & ' a Package ] ,
219
+ visited : & mut HashSet < String > ,
220
+ res : & mut Vec < & ' a Package > ,
221
+ source : & ' a Package ,
222
+ ) {
223
+ if !visited. insert ( source. name . clone ( ) ) {
224
+ return ;
225
+ }
226
+ for dep in source. dependencies . iter ( ) {
227
+ if let Some ( dep) = pkgs. iter ( ) . find ( |it| it. name == dep. name ) {
228
+ go ( pkgs, visited, res, dep)
229
+ }
230
+ }
231
+ res. push ( source)
232
+ }
215
233
}
216
-
217
- struct RustcApCrate < ' a > {
218
- name : & ' a str ,
219
- dir : & ' a str ,
234
+ # [ derive ( Clone ) ]
235
+ struct RustcApCrate {
236
+ name : String ,
237
+ dir : String ,
220
238
}
221
239
222
240
struct RustcPackageInfo {
0 commit comments