@@ -10,10 +10,13 @@ use std::str;
1010use std:: thread;
1111use std:: time:: Duration ;
1212
13+ use cargo_metadata:: { Metadata , Package } ;
14+
1315const PREFIX : & str = "ra-ap" ;
1416
1517fn 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 ) ;
1720 let commit = latest_master_commit ( & token) ;
1821 println ! ( "latest commit: {}" , commit) ;
1922
@@ -27,48 +30,50 @@ fn main() {
2730
2831 let target_crates = vec ! [
2932 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( ) ,
4435 } ,
4536 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 ( ) ,
4839 } ,
4940 RustcApCrate {
50- name: "rustc_abi" ,
51- dir: "compiler/rustc_abi" ,
41+ name: "rustc_abi" . to_owned ( ) ,
42+ dir: "compiler/rustc_abi" . to_owned ( ) ,
5243 } ,
5344 ] ;
5445
5546 println ! ( "learning about the dependency graph" ) ;
5647 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+ ) ;
5755 let mut crates = Vec :: new ( ) ;
5856 let mut seen = HashSet :: new ( ) ;
5957
6058 for RustcPackageInfo { package, metadata } in rustc_packages. iter ( ) {
6159 fill ( & metadata, & package, & mut crates, & mut seen) ;
6260 }
61+ let crates = crates_in_topological_order ( & crates) ;
6362
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) ;
6670
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) ;
6973
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+ }
7277 }
7378}
7479
@@ -134,31 +139,38 @@ fn download_src(dst: &Path, commit: &str) {
134139}
135140
136141fn get_rustc_packages ( target_crates : & [ RustcApCrate ] , dst : & Path ) -> Vec < RustcPackageInfo > {
142+ let mut work = target_crates. to_vec ( ) ;
137143 let mut packages = Vec :: new ( ) ;
138144
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 ;
148151 }
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 ( ) ;
151155
152- let rustc_package = output
156+ let rustc_package = metadata
153157 . packages
154158 . iter ( )
155159 . find ( |p| p. name == * name)
156160 . expect ( & format ! ( "failed to find {}" , & name) )
157161 . 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+ }
158170
159171 packages. push ( RustcPackageInfo {
160172 package : rustc_package,
161- metadata : output ,
173+ metadata,
162174 } )
163175 }
164176
@@ -176,6 +188,8 @@ fn fill<'a>(
176188 }
177189 let node = output
178190 . resolve
191+ . as_ref ( )
192+ . unwrap ( )
179193 . nodes
180194 . iter ( )
181195 . find ( |n| n. id == pkg. id )
@@ -189,34 +203,38 @@ fn fill<'a>(
189203 pkgs. push ( pkg) ;
190204}
191205
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 ( ) ;
197210
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+ }
205214
206- #[ derive( Deserialize ) ]
207- struct Resolve {
208- nodes : Vec < ResolveNode > ,
209- }
215+ return res;
210216
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+ }
215233}
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 ,
220238}
221239
222240struct RustcPackageInfo {
0 commit comments