@@ -15,39 +15,43 @@ use core::{os, str};
15
15
use core:: option:: * ;
16
16
use util:: PkgId ;
17
17
18
- /// Returns the output directory to use.
19
- /// Right now is always the default, should
20
- /// support changing it.
21
- pub fn dest_dir ( pkgid : PkgId ) -> Path {
22
- default_dest_dir ( & pkgid. path )
18
+ #[ deriving( Eq ) ]
19
+ pub enum OutputType { Main , Lib , Bench , Test }
20
+
21
+ /// Returns the value of RUST_PATH, as a list
22
+ /// of Paths. In general this should be read from the
23
+ /// environment; for now, it's hard-wired to just be "."
24
+ pub fn rust_path ( ) -> ~[ Path ] {
25
+ ~[ Path ( "." ) ]
23
26
}
24
27
25
- /// Returns the default output directory for compilation.
26
- /// Creates that directory if it doesn't exist.
27
- pub fn default_dest_dir ( pkg_dir : & Path ) -> Path {
28
+ /// Creates a directory that is readable, writeable,
29
+ /// and executable by the user. Returns true iff creation
30
+ /// succeeded.
31
+ pub fn make_dir_rwx ( p : & Path ) -> bool {
28
32
use core:: libc:: consts:: os:: posix88:: { S_IRUSR , S_IWUSR , S_IXUSR } ;
29
- use conditions:: bad_path:: cond;
30
33
31
- // For now: assumes that pkg_dir exists and is relative
32
- // to the CWD. Change this later when we do path searching.
33
- let rslt = pkg_dir. push ( "build" ) ;
34
- let is_dir = os:: path_is_dir ( & rslt) ;
35
- if os:: path_exists ( & rslt) {
36
- if is_dir {
37
- rslt
38
- }
39
- else {
40
- cond. raise ( ( rslt, ~"Path names a file that isn' t a directory") )
41
- }
34
+ os:: make_dir ( p, ( S_IRUSR | S_IWUSR | S_IXUSR ) as i32 )
35
+ }
36
+
37
+ /// Creates a directory that is readable, writeable,
38
+ /// and executable by the user. Returns true iff creation
39
+ /// succeeded. Also creates all intermediate subdirectories
40
+ /// if they don't already exist.
41
+ pub fn mkdir_recursive ( p : & Path ) -> bool {
42
+ if os:: path_is_dir ( p) {
43
+ return true ;
44
+ }
45
+ let parent = p. dir_path ( ) ;
46
+ debug ! ( "mkdir_recursive: parent = %s" ,
47
+ parent. to_str( ) ) ;
48
+ if parent. to_str ( ) == ~". "
49
+ || parent. to_str ( ) == ~"/" { // !!!
50
+ // No parent directories to create
51
+ os:: path_is_dir ( & parent) && make_dir_rwx ( p)
42
52
}
43
53
else {
44
- // Create it
45
- if os:: make_dir ( & rslt, ( S_IRUSR | S_IWUSR | S_IXUSR ) as i32 ) {
46
- rslt
47
- }
48
- else {
49
- cond. raise ( ( rslt, ~"Could not create directory") )
50
- }
54
+ mkdir_recursive ( & parent) && make_dir_rwx ( p)
51
55
}
52
56
}
53
57
@@ -69,34 +73,94 @@ pub fn normalize(p: ~Path) -> ~Path {
69
73
}
70
74
}
71
75
76
+ // n.b. So far this only handles local workspaces
77
+ // n.b. The next three functions ignore the package version right
78
+ // now. Should fix that.
79
+
80
+ /// True if there's a directory in <workspace> with
81
+ /// pkgid's short name
82
+ pub fn workspace_contains_package_id ( pkgid : PkgId , workspace : & Path ) -> bool {
83
+ let pkgpath = workspace. push ( "src" ) . push ( pkgid. path . to_str ( ) ) ;
84
+ os:: path_is_dir ( & pkgpath)
85
+ }
86
+
87
+ /// Return the directory for <pkgid>'s source files in <workspace>.
88
+ /// Doesn't check that it exists.
89
+ pub fn pkgid_src_in_workspace ( pkgid : PkgId , workspace : & Path ) -> Path {
90
+ let result = workspace. push ( "src" ) ;
91
+ result. push ( pkgid. path . to_str ( ) )
92
+ }
93
+
94
+ /// Returns the executable that would be installed for <pkgid>
95
+ /// in <workspace>
96
+ pub fn target_executable_in_workspace ( pkgid : PkgId , workspace : & Path ) -> Path {
97
+ let result = workspace. push ( "bin" ) ;
98
+ // should use a target-specific subdirectory
99
+ mk_output_path ( Main , pkgid. path . to_str ( ) , result)
100
+ }
101
+
102
+
103
+ /// Returns the executable that would be installed for <pkgid>
104
+ /// in <workspace>
105
+ pub fn target_library_in_workspace ( pkgid : PkgId , workspace : & Path ) -> Path {
106
+ let result = workspace. push ( "lib" ) ;
107
+ mk_output_path ( Lib , pkgid. path . to_str ( ) , result)
108
+ }
109
+
110
+ /// Returns the test executable that would be installed for <pkgid>
111
+ /// in <workspace>
112
+ pub fn target_test_in_workspace ( pkgid : PkgId , workspace : & Path ) -> Path {
113
+ let result = workspace. push ( "build" ) ;
114
+ mk_output_path ( Test , pkgid. path . to_str ( ) , result)
115
+ }
116
+
117
+ /// Returns the bench executable that would be installed for <pkgid>
118
+ /// in <workspace>
119
+ pub fn target_bench_in_workspace ( pkgid : PkgId , workspace : & Path ) -> Path {
120
+ let result = workspace. push ( "build" ) ;
121
+ mk_output_path ( Bench , pkgid. path . to_str ( ) , result)
122
+ }
123
+
124
+ /// Return the directory for <pkgid>'s build artifacts in <workspace>.
125
+ /// Creates it if it doesn't exist.
126
+ pub fn build_pkg_id_in_workspace ( pkgid : PkgId , workspace : & Path ) -> Path {
127
+ use conditions:: bad_path:: cond;
128
+
129
+ let mut result = workspace. push ( "build" ) ;
130
+ // n.b. Should actually use a target-specific
131
+ // subdirectory of build/
132
+ result = result. push ( normalize ( ~pkgid. path ) . to_str ( ) ) ;
133
+ if os:: path_exists ( & result) || mkdir_recursive ( & result) {
134
+ result
135
+ }
136
+ else {
137
+ cond. raise ( ( result, fmt ! ( "Could not create directory for package %s" , pkgid. to_str( ) ) ) )
138
+ }
139
+ }
140
+
141
+ /// Return the output file for a given directory name,
142
+ /// given whether we're building a library and whether we're building tests
143
+ pub fn mk_output_path( what : OutputType , short_name : ~str , dir : Path ) -> Path {
144
+ match what {
145
+ Lib => dir. push ( os:: dll_filename ( short_name) ) ,
146
+ _ => dir. push ( fmt!( "%s%s%s" , short_name,
147
+ if what == Test { ~"test" } else { ~" " },
148
+ os::EXE_SUFFIX))
149
+ }
150
+ }
151
+
72
152
#[cfg(test)]
73
153
mod test {
74
- use core:: { os, rand} ;
75
- use core:: path:: Path ;
76
- use path_util:: * ;
77
- use core:: rand:: RngUtil ;
78
-
79
- // Helper function to create a directory name that doesn't exist
80
- pub fn mk_nonexistent ( tmpdir : & Path , suffix : & str ) -> Path {
81
- let r = rand:: rng ( ) ;
82
- for 1000 . times {
83
- let p = tmpdir. push( r. gen_str( 16 ) + suffix) ;
84
- if !os:: path_exists ( & p) {
85
- return p;
86
- }
87
- }
88
- fail ! ( ~"Couldn ' t compute a non-existent path name; this is worrisome")
89
- }
154
+ use core::os;
90
155
91
156
#[test]
92
- fn default_dir_ok() {
93
- let the_path = os::tmpdir();
94
- let substitute_path = Path(" xyzzy");
95
- assert!(default_dest_dir(&the_path) == the_path.push(~" build"));
96
- let nonexistent_path = mk_nonexistent(&the_path, " quux" ) ;
97
- let bogus = do :: conditions:: bad_path:: cond. trap ( |_| {
98
- substitute_path
99
- } ) . in { default_dest_dir ( & nonexistent_path) } ;
100
- assert ! ( bogus == substitute_path) ;
157
+ fn recursive_mkdir_ok() {
158
+ let root = os::tmpdir();
159
+ let path = " xy/z/zy";
160
+ let nested = root.push(path);
161
+ assert!(super::mkdir_recursive(&nested));
162
+ assert!(os::path_is_dir(&root.push(" xy")));
163
+ assert!(os::path_is_dir(&root.push(" xy/z") ) ) ;
164
+ assert!( os:: path_is_dir( & nested) ) ;
101
165
}
102
166
}
0 commit comments