@@ -3,8 +3,8 @@ use std::collections::{HashMap, BTreeMap};
3
3
use regex:: Regex ;
4
4
use rustc_serialize:: { Encodable , Encoder , Decodable , Decoder } ;
5
5
6
- use core:: { PackageId , SourceId } ;
7
- use util:: { CargoResult , Graph } ;
6
+ use core:: { Package , PackageId , SourceId } ;
7
+ use util:: { CargoResult , Graph , Config } ;
8
8
9
9
use super :: Resolve ;
10
10
@@ -18,66 +18,113 @@ pub struct EncodableResolve {
18
18
pub type Metadata = BTreeMap < String , String > ;
19
19
20
20
impl EncodableResolve {
21
- pub fn to_resolve ( & self , default : & SourceId ) -> CargoResult < Resolve > {
21
+ pub fn to_resolve ( & self , root : & Package , config : & Config )
22
+ -> CargoResult < Resolve > {
23
+ let mut path_deps = HashMap :: new ( ) ;
24
+ try!( build_path_deps ( root, & mut path_deps, config) ) ;
25
+ let default = root. package_id ( ) . source_id ( ) ;
26
+
22
27
let mut g = Graph :: new ( ) ;
23
28
let mut tmp = HashMap :: new ( ) ;
24
29
25
30
let packages = Vec :: new ( ) ;
26
31
let packages = self . package . as_ref ( ) . unwrap_or ( & packages) ;
27
32
33
+ let root = try!( to_package_id ( & self . root . name ,
34
+ & self . root . version ,
35
+ self . root . source . as_ref ( ) ,
36
+ default, & path_deps) ) ;
37
+ let ids = try!( packages. iter ( ) . map ( |p| {
38
+ to_package_id ( & p. name , & p. version , p. source . as_ref ( ) ,
39
+ default, & path_deps)
40
+ } ) . collect :: < CargoResult < Vec < _ > > > ( ) ) ;
41
+
28
42
{
29
- let mut register_pkg = |pkg : & EncodableDependency |
30
- -> CargoResult < ( ) > {
31
- let pkgid = try!( pkg. to_package_id ( default) ) ;
43
+ let mut register_pkg = |pkgid : & PackageId | {
32
44
let precise = pkgid. source_id ( ) . precise ( )
33
45
. map ( |s| s. to_string ( ) ) ;
34
46
assert ! ( tmp. insert( pkgid. clone( ) , precise) . is_none( ) ,
35
47
"a package was referenced twice in the lockfile" ) ;
36
- g. add ( try!( pkg. to_package_id ( default) ) , & [ ] ) ;
37
- Ok ( ( ) )
48
+ g. add ( pkgid. clone ( ) , & [ ] ) ;
38
49
} ;
39
50
40
- try! ( register_pkg ( & self . root ) ) ;
41
- for pkg in packages . iter ( ) {
42
- try! ( register_pkg ( pkg ) ) ;
51
+ register_pkg ( & root) ;
52
+ for id in ids . iter ( ) {
53
+ register_pkg ( id ) ;
43
54
}
44
55
}
45
56
46
57
{
47
- let mut add_dependencies = |pkg : & EncodableDependency |
58
+ let mut add_dependencies = |id : & PackageId , pkg : & EncodableDependency |
48
59
-> CargoResult < ( ) > {
49
- let package_id = try!( pkg. to_package_id ( default) ) ;
50
-
51
60
let deps = match pkg. dependencies {
52
61
Some ( ref deps) => deps,
53
62
None => return Ok ( ( ) ) ,
54
63
} ;
55
64
for edge in deps. iter ( ) {
56
- let to_depend_on = try!( edge. to_package_id ( default) ) ;
65
+ let to_depend_on = try!( to_package_id ( & edge. name ,
66
+ & edge. version ,
67
+ edge. source . as_ref ( ) ,
68
+ default,
69
+ & path_deps) ) ;
57
70
let precise_pkgid =
58
71
tmp. get ( & to_depend_on)
59
72
. map ( |p| to_depend_on. with_precise ( p. clone ( ) ) )
60
73
. unwrap_or ( to_depend_on. clone ( ) ) ;
61
- g. link ( package_id . clone ( ) , precise_pkgid) ;
74
+ g. link ( id . clone ( ) , precise_pkgid) ;
62
75
}
63
76
Ok ( ( ) )
64
77
} ;
65
78
66
- try!( add_dependencies ( & self . root ) ) ;
67
- for pkg in packages . iter ( ) {
68
- try!( add_dependencies ( pkg) ) ;
79
+ try!( add_dependencies ( & root , & self . root ) ) ;
80
+ for ( id , pkg) in ids . iter ( ) . zip ( packages ) {
81
+ try!( add_dependencies ( id , pkg) ) ;
69
82
}
70
83
}
71
84
72
85
Ok ( Resolve {
73
86
graph : g,
74
- root : try! ( self . root . to_package_id ( default ) ) ,
87
+ root : root,
75
88
features : HashMap :: new ( ) ,
76
89
metadata : self . metadata . clone ( ) ,
77
90
} )
78
91
}
79
92
}
80
93
94
+ fn build_path_deps ( root : & Package ,
95
+ map : & mut HashMap < String , SourceId > ,
96
+ config : & Config )
97
+ -> CargoResult < ( ) > {
98
+ assert ! ( root. package_id( ) . source_id( ) . is_path( ) ) ;
99
+
100
+ let deps = root. dependencies ( )
101
+ . iter ( )
102
+ . map ( |d| d. source_id ( ) )
103
+ . filter ( |id| id. is_path ( ) )
104
+ . filter_map ( |id| id. url ( ) . to_file_path ( ) . ok ( ) )
105
+ . map ( |path| path. join ( "Cargo.toml" ) )
106
+ . filter_map ( |path| Package :: for_path ( & path, config) . ok ( ) ) ;
107
+ for pkg in deps {
108
+ let source_id = pkg. package_id ( ) . source_id ( ) ;
109
+ if map. insert ( pkg. name ( ) . to_string ( ) , source_id. clone ( ) ) . is_none ( ) {
110
+ try!( build_path_deps ( & pkg, map, config) ) ;
111
+ }
112
+ }
113
+
114
+ Ok ( ( ) )
115
+ }
116
+
117
+ fn to_package_id ( name : & str ,
118
+ version : & str ,
119
+ source : Option < & SourceId > ,
120
+ default_source : & SourceId ,
121
+ path_sources : & HashMap < String , SourceId > )
122
+ -> CargoResult < PackageId > {
123
+ let source = source. or ( path_sources. get ( name) ) . unwrap_or ( default_source) ;
124
+ PackageId :: new ( name, version, source)
125
+ }
126
+
127
+
81
128
#[ derive( RustcEncodable , RustcDecodable , Debug , PartialOrd , Ord , PartialEq , Eq ) ]
82
129
pub struct EncodableDependency {
83
130
name : String ,
@@ -86,15 +133,6 @@ pub struct EncodableDependency {
86
133
dependencies : Option < Vec < EncodablePackageId > >
87
134
}
88
135
89
- impl EncodableDependency {
90
- fn to_package_id ( & self , default_source : & SourceId ) -> CargoResult < PackageId > {
91
- PackageId :: new (
92
- & self . name ,
93
- & self . version ,
94
- self . source . as_ref ( ) . unwrap_or ( default_source) )
95
- }
96
- }
97
-
98
136
#[ derive( Debug , PartialOrd , Ord , PartialEq , Eq ) ]
99
137
pub struct EncodablePackageId {
100
138
name : String ,
@@ -134,15 +172,6 @@ impl Decodable for EncodablePackageId {
134
172
}
135
173
}
136
174
137
- impl EncodablePackageId {
138
- fn to_package_id ( & self , default_source : & SourceId ) -> CargoResult < PackageId > {
139
- PackageId :: new (
140
- & self . name ,
141
- & self . version ,
142
- self . source . as_ref ( ) . unwrap_or ( default_source) )
143
- }
144
- }
145
-
146
175
impl Encodable for Resolve {
147
176
fn encode < S : Encoder > ( & self , s : & mut S ) -> Result < ( ) , S :: Error > {
148
177
let mut ids: Vec < & PackageId > = self . graph . iter ( ) . collect ( ) ;
@@ -151,28 +180,26 @@ impl Encodable for Resolve {
151
180
let encodable = ids. iter ( ) . filter_map ( |& id| {
152
181
if self . root == * id { return None ; }
153
182
154
- Some ( encodable_resolve_node ( id, & self . root , & self . graph ) )
183
+ Some ( encodable_resolve_node ( id, & self . graph ) )
155
184
} ) . collect :: < Vec < EncodableDependency > > ( ) ;
156
185
157
186
EncodableResolve {
158
187
package : Some ( encodable) ,
159
- root : encodable_resolve_node ( & self . root , & self . root , & self . graph ) ,
188
+ root : encodable_resolve_node ( & self . root , & self . graph ) ,
160
189
metadata : self . metadata . clone ( ) ,
161
190
} . encode ( s)
162
191
}
163
192
}
164
193
165
- fn encodable_resolve_node ( id : & PackageId , root : & PackageId ,
166
- graph : & Graph < PackageId > ) -> EncodableDependency {
194
+ fn encodable_resolve_node ( id : & PackageId , graph : & Graph < PackageId > )
195
+ -> EncodableDependency {
167
196
let deps = graph. edges ( id) . map ( |edge| {
168
- let mut deps = edge. map ( |e| {
169
- encodable_package_id ( e, root)
170
- } ) . collect :: < Vec < EncodablePackageId > > ( ) ;
197
+ let mut deps = edge. map ( encodable_package_id) . collect :: < Vec < _ > > ( ) ;
171
198
deps. sort ( ) ;
172
199
deps
173
200
} ) ;
174
201
175
- let source = if id. source_id ( ) == root . source_id ( ) {
202
+ let source = if id. source_id ( ) . is_path ( ) {
176
203
None
177
204
} else {
178
205
Some ( id. source_id ( ) . clone ( ) )
@@ -186,8 +213,8 @@ fn encodable_resolve_node(id: &PackageId, root: &PackageId,
186
213
}
187
214
}
188
215
189
- fn encodable_package_id ( id : & PackageId , root : & PackageId ) -> EncodablePackageId {
190
- let source = if id. source_id ( ) == root . source_id ( ) {
216
+ fn encodable_package_id ( id : & PackageId ) -> EncodablePackageId {
217
+ let source = if id. source_id ( ) . is_path ( ) {
191
218
None
192
219
} else {
193
220
Some ( id. source_id ( ) . with_precise ( None ) )
0 commit comments