8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ extern mod extra;
12
+
11
13
use target:: * ;
12
14
use package_id:: PkgId ;
13
15
use std:: path:: Path ;
@@ -16,8 +18,9 @@ use context::*;
16
18
use crate :: Crate ;
17
19
use messages:: * ;
18
20
use source_control:: { git_clone, git_clone_general} ;
19
- use path_util:: pkgid_src_in_workspace;
21
+ use path_util:: { pkgid_src_in_workspace, find_dir_using_rust_path_hack , default_workspace } ;
20
22
use util:: compile_crate;
23
+ use workspace:: is_workspace;
21
24
22
25
// An enumeration of the unpacked source of a package workspace.
23
26
// This contains a list of files found in the source workspace.
@@ -48,7 +51,7 @@ impl PkgSrc {
48
51
}
49
52
50
53
51
- fn check_dir ( & self ) -> Path {
54
+ fn check_dir( & self , cx : & Ctx ) -> Path {
52
55
use conditions:: nonexistent_package:: cond;
53
56
54
57
debug ! ( "Pushing onto root: %s | %s" , self . id. path. to_str( ) , self . root. to_str( ) ) ;
@@ -59,12 +62,21 @@ impl PkgSrc {
59
62
60
63
let dir = match path {
61
64
Some ( d) => ( * d) . clone ( ) ,
62
- None => match self . fetch_git ( ) {
63
- Some ( d) => d,
64
- None => cond. raise ( ( self . id . clone ( ) , ~"supplied path for package dir does not \
65
- exist, and couldn' t interpret it as a URL fragment") )
65
+ None => {
66
+ match self . fetch_git ( ) {
67
+ Some ( d) => d,
68
+ None => {
69
+ match find_dir_using_rust_path_hack ( cx, & self . id ) {
70
+ Some ( d) => d,
71
+ None => cond. raise ( ( self . id . clone ( ) ,
72
+ ~"supplied path for package dir does not \
73
+ exist, and couldn' t interpret it as a URL fragment") )
74
+ }
75
+ }
76
+ }
66
77
}
67
78
} ;
79
+ debug ! ( "For package id %s, returning %s" , self . id. to_str( ) , dir. to_str( ) ) ;
68
80
if !os:: path_is_dir ( & dir) {
69
81
cond. raise ( ( self . id . clone ( ) , ~"supplied path for package dir is a \
70
82
non-directory") ) ;
@@ -79,11 +91,19 @@ impl PkgSrc {
79
91
/// refers to a git repo on the local version, also check it out.
80
92
/// (right now we only support git)
81
93
pub fn fetch_git( & self ) -> Option < Path > {
94
+ use conditions:: failed_to_create_temp_dir:: cond;
95
+
96
+ // We use a temporary directory because if the git clone fails,
97
+ // it creates the target directory anyway and doesn't delete it
98
+
99
+ let scratch_dir = extra:: tempfile:: mkdtemp ( & os:: tmpdir ( ) , "rustpkg" ) ;
100
+ let clone_target = match scratch_dir {
101
+ Some ( d) => d. push ( "rustpkg_temp" ) ,
102
+ None => cond. raise ( ~"Failed to create temporary directory for fetching git sources")
103
+ } ;
82
104
83
105
let mut local = self . root. push( "src" ) ;
84
106
local = local. push( self . id. to_str( ) ) ;
85
- // Git can't clone into a non-empty directory
86
- os:: remove_dir_recursive ( & local) ;
87
107
88
108
debug ! ( "Checking whether %s exists locally. Cwd = %s, does it? %?" ,
89
109
self . id. path. to_str( ) ,
@@ -93,15 +113,28 @@ impl PkgSrc {
93
113
if os:: path_exists ( & self . id . path ) {
94
114
debug ! ( "%s exists locally! Cloning it into %s" ,
95
115
self . id. path. to_str( ) , local. to_str( ) ) ;
116
+ // Ok to use local here; we know it will succeed
96
117
git_clone ( & self . id . path , & local, & self . id . version ) ;
97
118
return Some ( local) ;
98
119
}
99
120
121
+ if ( self . id . path . clone ( ) ) . components ( ) . len ( ) < 2 {
122
+ // If a non-URL, don't bother trying to fetch
123
+ return None ;
124
+ }
125
+
100
126
let url = fmt ! ( "https://%s" , self . id. path. to_str( ) ) ;
101
127
note ( fmt ! ( "Fetching package: git clone %s %s [version=%s]" ,
102
- url, local. to_str( ) , self . id. version. to_str( ) ) ) ;
103
- if git_clone_general ( url, & local, & self . id . version ) {
104
- Some ( local)
128
+ url, clone_target. to_str( ) , self . id. version. to_str( ) ) ) ;
129
+
130
+ if git_clone_general ( url, & clone_target, & self . id . version ) {
131
+ // since the operation succeeded, move clone_target to local
132
+ if !os:: rename_file ( & clone_target, & local) {
133
+ None
134
+ }
135
+ else {
136
+ Some ( local)
137
+ }
105
138
}
106
139
else {
107
140
None
@@ -138,10 +171,10 @@ impl PkgSrc {
138
171
139
172
/// Infers crates to build. Called only in the case where there
140
173
/// is no custom build logic
141
- pub fn find_crates ( & mut self ) {
174
+ pub fn find_crates ( & mut self , cx : & Ctx ) {
142
175
use conditions:: missing_pkg_files:: cond;
143
176
144
- let dir = self . check_dir ( ) ;
177
+ let dir = self . check_dir ( cx ) ;
145
178
debug ! ( "Called check_dir, I'm in %s" , dir. to_str( ) ) ;
146
179
let prefix = dir. components . len ( ) ;
147
180
debug ! ( "Matching against %?" , self . id. short_name) ;
@@ -183,6 +216,7 @@ impl PkgSrc {
183
216
fn build_crates ( & self ,
184
217
ctx : & Ctx ,
185
218
src_dir : & Path ,
219
+ destination_dir : & Path ,
186
220
crates : & [ Crate ] ,
187
221
cfgs : & [ ~str ] ,
188
222
what : OutputType ) {
@@ -194,8 +228,8 @@ impl PkgSrc {
194
228
let result = compile_crate ( ctx,
195
229
& self . id ,
196
230
path,
197
- // compile_crate wants the workspace
198
- & self . root ,
231
+ // compile_crate wants the destination workspace
232
+ destination_dir ,
199
233
crate . flags,
200
234
crate . cfgs + cfgs,
201
235
false ,
@@ -209,15 +243,39 @@ impl PkgSrc {
209
243
}
210
244
}
211
245
212
- pub fn build ( & self , ctx : & Ctx , cfgs : ~[ ~str ] ) {
213
- let dir = self . check_dir ( ) ;
214
- debug ! ( "Building libs in %s" , dir. to_str( ) ) ;
215
- self . build_crates ( ctx, & dir, self . libs , cfgs, Lib ) ;
246
+ pub fn build ( & self , ctx : & Ctx , cfgs : ~[ ~str ] ) -> Path {
247
+ use conditions:: not_a_workspace:: cond;
248
+
249
+ // Determine the destination workspace (which depends on whether
250
+ // we're using the rust_path_hack)
251
+ let destination_workspace = if is_workspace ( & self . root ) {
252
+ debug ! ( "%s is indeed a workspace" , self . root. to_str( ) ) ;
253
+ self . root . clone ( )
254
+ }
255
+ else {
256
+ // It would be nice to have only one place in the code that checks
257
+ // for the use_rust_path_hack flag...
258
+ if ctx. use_rust_path_hack {
259
+ let rs = default_workspace ( ) ;
260
+ debug ! ( "Using hack: %s" , rs. to_str( ) ) ;
261
+ rs
262
+ }
263
+ else {
264
+ cond. raise ( fmt ! ( "Package root %s is not a workspace; pass in --rust_path_hack \
265
+ if you want to treat it as a package source", self . root. to_str( ) ) )
266
+ }
267
+ } ;
268
+
269
+ let dir = self . check_dir ( ctx) ;
270
+ debug ! ( "Building libs in %s, destination = %s" , dir. to_str( ) ,
271
+ destination_workspace. to_str( ) ) ;
272
+ self . build_crates ( ctx, & dir, & destination_workspace, self . libs , cfgs, Lib ) ;
216
273
debug ! ( "Building mains" ) ;
217
- self . build_crates ( ctx, & dir, self . mains , cfgs, Main ) ;
274
+ self . build_crates ( ctx, & dir, & destination_workspace , self . mains , cfgs, Main ) ;
218
275
debug ! ( "Building tests" ) ;
219
- self . build_crates ( ctx, & dir, self . tests , cfgs, Test ) ;
276
+ self . build_crates ( ctx, & dir, & destination_workspace , self . tests , cfgs, Test ) ;
220
277
debug ! ( "Building benches" ) ;
221
- self . build_crates ( ctx, & dir, self . benchs , cfgs, Bench ) ;
278
+ self . build_crates ( ctx, & dir, & destination_workspace, self . benchs , cfgs, Bench ) ;
279
+ destination_workspace
222
280
}
223
281
}
0 commit comments