@@ -15,39 +15,43 @@ use core::{os, str};
1515use core:: option:: * ;
1616use util:: PkgId ;
1717
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 ( "." ) ]
2326}
2427
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 {
2832 use core:: libc:: consts:: os:: posix88:: { S_IRUSR , S_IWUSR , S_IXUSR } ;
29- use conditions:: bad_path:: cond;
3033
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)
4252 }
4353 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)
5155 }
5256}
5357
@@ -69,34 +73,94 @@ pub fn normalize(p: ~Path) -> ~Path {
6973 }
7074}
7175
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+
72152#[cfg(test)]
73153mod 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;
90155
91156 #[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) ) ;
101165 }
102166}
0 commit comments