1
+ // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2
+ // file at the top-level directory of this distribution and at
3
+ // http://rust-lang.org/COPYRIGHT.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6
+ // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7
+ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
+ // option. This file may not be copied, modified, or distributed
9
+ // except according to those terms.
10
+
11
+ /// A version is either an exact revision,
12
+ /// or a semantic version
13
+
14
+ extern mod std;
15
+
16
+ use std:: semver;
17
+ use core:: prelude:: * ;
18
+ use core:: run;
19
+ use package_path:: RemotePath ;
20
+ use std:: tempfile:: mkdtemp;
21
+
22
+ pub enum Version {
23
+ ExactRevision ( float ) ,
24
+ SemVersion ( semver:: Version )
25
+ }
26
+
27
+
28
+ impl Ord for Version {
29
+ fn lt ( & self , other : & Version ) -> bool {
30
+ match ( self , other) {
31
+ ( & ExactRevision ( f1) , & ExactRevision ( f2) ) => f1 < f2,
32
+ ( & SemVersion ( ref v1) , & SemVersion ( ref v2) ) => v1 < v2,
33
+ _ => false // incomparable, really
34
+ }
35
+ }
36
+ fn le ( & self , other : & Version ) -> bool {
37
+ match ( self , other) {
38
+ ( & ExactRevision ( f1) , & ExactRevision ( f2) ) => f1 <= f2,
39
+ ( & SemVersion ( ref v1) , & SemVersion ( ref v2) ) => v1 <= v2,
40
+ _ => false // incomparable, really
41
+ }
42
+ }
43
+ fn ge ( & self , other : & Version ) -> bool {
44
+ match ( self , other) {
45
+ ( & ExactRevision ( f1) , & ExactRevision ( f2) ) => f1 > f2,
46
+ ( & SemVersion ( ref v1) , & SemVersion ( ref v2) ) => v1 > v2,
47
+ _ => false // incomparable, really
48
+ }
49
+ }
50
+ fn gt ( & self , other : & Version ) -> bool {
51
+ match ( self , other) {
52
+ ( & ExactRevision ( f1) , & ExactRevision ( f2) ) => f1 >= f2,
53
+ ( & SemVersion ( ref v1) , & SemVersion ( ref v2) ) => v1 >= v2,
54
+ _ => false // incomparable, really
55
+ }
56
+ }
57
+
58
+ }
59
+
60
+ impl ToStr for Version {
61
+ fn to_str ( & self ) -> ~str {
62
+ match * self {
63
+ ExactRevision ( ref n) => n. to_str ( ) ,
64
+ SemVersion ( ref v) => v. to_str ( )
65
+ }
66
+ }
67
+ }
68
+
69
+ pub fn parse_vers ( vers : ~str ) -> result:: Result < semver:: Version , ~str > {
70
+ match semver:: parse ( vers) {
71
+ Some ( vers) => result:: Ok ( vers) ,
72
+ None => result:: Err ( ~"could not parse version: invalid")
73
+ }
74
+ }
75
+
76
+
77
+ /// If `remote_path` refers to a git repo that can be downloaded,
78
+ /// and the most recent tag in that repo denotes a version, return it;
79
+ /// otherwise, `None`
80
+ pub fn try_getting_version ( remote_path : & RemotePath ) -> Option < Version > {
81
+ debug ! ( "try_getting_version: %s" , remote_path. to_str( ) ) ;
82
+ if is_url_like ( remote_path) {
83
+ debug ! ( "Trying to fetch its sources.." ) ;
84
+ let tmp_dir = mkdtemp ( & os:: tmpdir ( ) ,
85
+ "test" ) . expect ( "try_getting_version: couldn't create temp dir" ) ;
86
+ debug ! ( "executing {git clone https://%s %s}" , remote_path. to_str( ) , tmp_dir. to_str( ) ) ;
87
+ let outp = run:: process_output ( "git" , [ ~"clone", fmt ! ( "https://%s" , remote_path. to_str( ) ) ,
88
+ tmp_dir. to_str ( ) ] ) ;
89
+ if outp. status == 0 {
90
+ debug ! ( "Cloned it... ( %s, %s )" , str :: from_bytes( outp. output) , str :: from_bytes( outp. error) ) ;
91
+ let mut output = None ;
92
+ debug ! ( "executing {git --git-dir=%s tag -l}" , tmp_dir. push( ".git" ) . to_str( ) ) ;
93
+ let outp = run:: process_output ( "git" , [ fmt ! ( "--git-dir=%s" , tmp_dir. push( ".git" ) . to_str( ) ) ,
94
+ ~"tag", ~"-l"] ) ;
95
+ let output_text = str:: from_bytes ( outp. output ) ;
96
+ debug ! ( "Full output: ( %s ) [%?]" , output_text, outp. status) ;
97
+ for output_text. each_split_char( '\n' ) |l| {
98
+ debug ! ( "A line of output: %s" , l) ;
99
+ if !l. is_whitespace ( ) {
100
+ output = Some ( l) ;
101
+ }
102
+ }
103
+
104
+ output. chain ( try_parsing_version)
105
+ }
106
+ else {
107
+ None
108
+ }
109
+ }
110
+ else {
111
+ None
112
+ }
113
+ }
114
+
115
+ fn try_parsing_version ( s : & str ) -> Option < Version > {
116
+ let s = s. trim ( ) ;
117
+ debug ! ( "Attempting to parse: %s" , s) ;
118
+ match float:: from_str ( s) {
119
+ Some ( f) => {
120
+ debug ! ( "%s -> %f" , s, f) ;
121
+ Some ( ExactRevision ( f) ) // semver not handled yet
122
+ }
123
+ None => {
124
+ debug ! ( "None!!" ) ;
125
+ None
126
+ }
127
+ }
128
+ }
129
+
130
+ /// Placeholder
131
+ pub fn default_version ( ) -> Version { ExactRevision ( 0.1 ) }
132
+
133
+ /// Just an approximation
134
+ fn is_url_like ( p : & RemotePath ) -> bool {
135
+ let mut n = 0 ;
136
+ for p. to_str( ) . each_split_char( '/' ) |_| {
137
+ n += 1 ;
138
+ }
139
+ n > 2
140
+ }
0 commit comments