@@ -42,16 +42,23 @@ pub trait Source: Registry {
42
42
fn fingerprint ( & self , pkg : & Package ) -> CargoResult < String > ;
43
43
}
44
44
45
- #[ deriving( RustcEncodable , RustcDecodable , Show , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
45
+ #[ deriving( Show , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
46
46
enum Kind {
47
47
/// Kind::Git(<git reference>) represents a git repository
48
- Git ( String ) ,
48
+ Git ( GitReference ) ,
49
49
/// represents a local path
50
50
Path ,
51
51
/// represents the central registry
52
52
Registry ,
53
53
}
54
54
55
+ #[ deriving( Show , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
56
+ pub enum GitReference {
57
+ Tag ( String ) ,
58
+ Branch ( String ) ,
59
+ Rev ( String ) ,
60
+ }
61
+
55
62
type Error = Box < CargoError + Send > ;
56
63
57
64
/// Unique identifier for a source of packages.
@@ -97,16 +104,22 @@ impl SourceId {
97
104
match kind {
98
105
"git" => {
99
106
let mut url = url. to_url ( ) . unwrap ( ) ;
100
- let mut reference = "master" . to_string ( ) ;
107
+ let mut reference = GitReference :: Branch ( "master" . to_string ( ) ) ;
101
108
let pairs = url. query_pairs ( ) . unwrap_or ( Vec :: new ( ) ) ;
102
109
for & ( ref k, ref v) in pairs. iter ( ) {
103
- if k. as_slice ( ) == "ref" {
104
- reference = v. clone ( ) ;
110
+ match k. as_slice ( ) {
111
+ // map older 'ref' to branch
112
+ "branch" |
113
+ "ref" => reference = GitReference :: Branch ( v. clone ( ) ) ,
114
+
115
+ "rev" => reference = GitReference :: Rev ( v. clone ( ) ) ,
116
+ "tag" => reference = GitReference :: Tag ( v. clone ( ) ) ,
117
+ _ => { }
105
118
}
106
119
}
107
120
url. query = None ;
108
121
let precise = mem:: replace ( & mut url. fragment , None ) ;
109
- SourceId :: for_git ( & url, reference. as_slice ( ) )
122
+ SourceId :: for_git ( & url, reference)
110
123
. with_precise ( precise)
111
124
} ,
112
125
"registry" => {
@@ -128,11 +141,7 @@ impl SourceId {
128
141
SourceIdInner {
129
142
kind : Kind :: Git ( ref reference) , ref url, ref precise, ..
130
143
} => {
131
- let ref_str = if reference. as_slice ( ) != "master" {
132
- format ! ( "?ref={}" , reference)
133
- } else {
134
- "" . to_string ( )
135
- } ;
144
+ let ref_str = url_ref ( reference) ;
136
145
137
146
let precise_str = if precise. is_some ( ) {
138
147
format ! ( "#{}" , precise. as_ref( ) . unwrap( ) )
@@ -154,8 +163,8 @@ impl SourceId {
154
163
Ok ( SourceId :: new ( Kind :: Path , url) )
155
164
}
156
165
157
- pub fn for_git ( url : & Url , reference : & str ) -> SourceId {
158
- SourceId :: new ( Kind :: Git ( reference. to_string ( ) ) , url. clone ( ) )
166
+ pub fn for_git ( url : & Url , reference : GitReference ) -> SourceId {
167
+ SourceId :: new ( Kind :: Git ( reference) , url. clone ( ) )
159
168
}
160
169
161
170
pub fn for_registry ( url : & Url ) -> SourceId {
@@ -203,9 +212,9 @@ impl SourceId {
203
212
self . inner . precise . as_ref ( ) . map ( |s| s. as_slice ( ) )
204
213
}
205
214
206
- pub fn git_reference ( & self ) -> Option < & str > {
215
+ pub fn git_reference ( & self ) -> Option < & GitReference > {
207
216
match self . inner . kind {
208
- Kind :: Git ( ref s) => Some ( s. as_slice ( ) ) ,
217
+ Kind :: Git ( ref s) => Some ( s) ,
209
218
_ => None ,
210
219
}
211
220
}
@@ -269,10 +278,7 @@ impl Show for SourceId {
269
278
SourceIdInner { kind : Kind :: Path , ref url, .. } => url. fmt ( f) ,
270
279
SourceIdInner { kind : Kind :: Git ( ref reference) , ref url,
271
280
ref precise, .. } => {
272
- try!( write ! ( f, "{}" , url) ) ;
273
- if reference. as_slice ( ) != "master" {
274
- try!( write ! ( f, "?ref={}" , reference) ) ;
275
- }
281
+ try!( write ! ( f, "{}{}" , url, url_ref( reference) ) ) ;
276
282
277
283
match * precise {
278
284
Some ( ref s) => {
@@ -319,6 +325,29 @@ impl<S: hash::Writer> hash::Hash<S> for SourceId {
319
325
}
320
326
}
321
327
328
+ fn url_ref ( r : & GitReference ) -> String {
329
+ match r. to_ref_string ( ) {
330
+ None => "" . to_string ( ) ,
331
+ Some ( s) => format ! ( "?{}" , s) ,
332
+ }
333
+ }
334
+
335
+ impl GitReference {
336
+ pub fn to_ref_string ( & self ) -> Option < String > {
337
+ match * self {
338
+ GitReference :: Branch ( ref s) => {
339
+ if s. as_slice ( ) == "master" {
340
+ None
341
+ } else {
342
+ Some ( format ! ( "branch={}" , s) )
343
+ }
344
+ }
345
+ GitReference :: Tag ( ref s) => Some ( format ! ( "tag={}" , s) ) ,
346
+ GitReference :: Rev ( ref s) => Some ( format ! ( "rev={}" , s) ) ,
347
+ }
348
+ }
349
+ }
350
+
322
351
pub struct SourceMap < ' src > {
323
352
map : HashMap < SourceId , Box < Source +' src > >
324
353
}
@@ -446,20 +475,22 @@ impl<'src> Source for SourceSet<'src> {
446
475
447
476
#[ cfg( test) ]
448
477
mod tests {
449
- use super :: { SourceId , Kind } ;
478
+ use super :: { SourceId , Kind , GitReference } ;
450
479
use util:: ToUrl ;
451
480
452
481
#[ test]
453
482
fn github_sources_equal ( ) {
454
483
let loc = "https://github.com/foo/bar" . to_url ( ) . unwrap ( ) ;
455
- let s1 = SourceId :: new ( Kind :: Git ( "master" . to_string ( ) ) , loc) ;
484
+ let master = Kind :: Git ( GitReference :: Branch ( "master" . to_string ( ) ) ) ;
485
+ let s1 = SourceId :: new ( master. clone ( ) , loc) ;
456
486
457
487
let loc = "git://github.com/foo/bar" . to_url ( ) . unwrap ( ) ;
458
- let s2 = SourceId :: new ( Kind :: Git ( " master" . to_string ( ) ) , loc. clone ( ) ) ;
488
+ let s2 = SourceId :: new ( master, loc. clone ( ) ) ;
459
489
460
490
assert_eq ! ( s1, s2) ;
461
491
462
- let s3 = SourceId :: new ( Kind :: Git ( "foo" . to_string ( ) ) , loc) ;
492
+ let foo = Kind :: Git ( GitReference :: Branch ( "foo" . to_string ( ) ) ) ;
493
+ let s3 = SourceId :: new ( foo, loc) ;
463
494
assert ! ( s1 != s3) ;
464
495
}
465
496
}
0 commit comments