@@ -70,20 +70,36 @@ pub mod tools;
7070struct FileBuilder {
7171 path : PathBuf ,
7272 body : String ,
73+ executable : bool ,
7374}
7475
7576impl FileBuilder {
76- pub fn new ( path : PathBuf , body : & str ) -> FileBuilder {
77+ pub fn new ( path : PathBuf , body : & str , executable : bool ) -> FileBuilder {
7778 FileBuilder {
7879 path,
7980 body : body. to_string ( ) ,
81+ executable : executable,
8082 }
8183 }
8284
83- fn mk ( & self ) {
85+ fn mk ( & mut self ) {
86+ if self . executable {
87+ self . path . set_extension ( env:: consts:: EXE_EXTENSION ) ;
88+ }
89+
8490 self . dirname ( ) . mkdir_p ( ) ;
8591 fs:: write ( & self . path , & self . body )
8692 . unwrap_or_else ( |e| panic ! ( "could not create file {}: {}" , self . path. display( ) , e) ) ;
93+
94+ #[ cfg( unix) ]
95+ if self . executable {
96+ use std:: os:: unix:: fs:: PermissionsExt ;
97+
98+ let mut perms = fs:: metadata ( & self . path ) . unwrap ( ) . permissions ( ) ;
99+ let mode = perms. mode ( ) ;
100+ perms. set_mode ( mode | 0o111 ) ;
101+ fs:: set_permissions ( & self . path , perms) . unwrap ( ) ;
102+ }
87103 }
88104
89105 fn dirname ( & self ) -> & Path {
@@ -122,11 +138,16 @@ impl SymlinkBuilder {
122138 }
123139
124140 #[ cfg( windows) ]
125- fn mk ( & self ) {
141+ fn mk ( & mut self ) {
126142 self . dirname ( ) . mkdir_p ( ) ;
127143 if self . src_is_dir {
128144 t ! ( os:: windows:: fs:: symlink_dir( & self . dst, & self . src) ) ;
129145 } else {
146+ if let Some ( ext) = self . dst . extension ( ) {
147+ if ext == env:: consts:: EXE_EXTENSION {
148+ self . src . set_extension ( ext) ;
149+ }
150+ }
130151 t ! ( os:: windows:: fs:: symlink_file( & self . dst, & self . src) ) ;
131152 }
132153 }
@@ -177,13 +198,22 @@ impl ProjectBuilder {
177198
178199 /// Adds a file to the project.
179200 pub fn file < B : AsRef < Path > > ( mut self , path : B , body : & str ) -> Self {
180- self . _file ( path. as_ref ( ) , body) ;
201+ self . _file ( path. as_ref ( ) , body, false ) ;
181202 self
182203 }
183204
184- fn _file ( & mut self , path : & Path , body : & str ) {
185- self . files
186- . push ( FileBuilder :: new ( self . root . root ( ) . join ( path) , body) ) ;
205+ /// Adds an executable file to the project.
206+ pub fn executable < B : AsRef < Path > > ( mut self , path : B , body : & str ) -> Self {
207+ self . _file ( path. as_ref ( ) , body, true ) ;
208+ self
209+ }
210+
211+ fn _file ( & mut self , path : & Path , body : & str , executable : bool ) {
212+ self . files . push ( FileBuilder :: new (
213+ self . root . root ( ) . join ( path) ,
214+ body,
215+ executable,
216+ ) ) ;
187217 }
188218
189219 /// Adds a symlink to a file to the project.
@@ -219,13 +249,17 @@ impl ProjectBuilder {
219249
220250 let manifest_path = self . root . root ( ) . join ( "Cargo.toml" ) ;
221251 if !self . no_manifest && self . files . iter ( ) . all ( |fb| fb. path != manifest_path) {
222- self . _file ( Path :: new ( "Cargo.toml" ) , & basic_manifest ( "foo" , "0.0.1" ) )
252+ self . _file (
253+ Path :: new ( "Cargo.toml" ) ,
254+ & basic_manifest ( "foo" , "0.0.1" ) ,
255+ false ,
256+ )
223257 }
224258
225259 let past = time:: SystemTime :: now ( ) - Duration :: new ( 1 , 0 ) ;
226260 let ftime = filetime:: FileTime :: from_system_time ( past) ;
227261
228- for file in self . files . iter ( ) {
262+ for file in self . files . iter_mut ( ) {
229263 file. mk ( ) ;
230264 if is_coarse_mtime ( ) {
231265 // Place the entire project 1 second in the past to ensure
@@ -237,7 +271,7 @@ impl ProjectBuilder {
237271 }
238272 }
239273
240- for symlink in self . symlinks . iter ( ) {
274+ for symlink in self . symlinks . iter_mut ( ) {
241275 symlink. mk ( ) ;
242276 }
243277
@@ -316,7 +350,7 @@ impl Project {
316350
317351 /// Changes the contents of an existing file.
318352 pub fn change_file ( & self , path : & str , body : & str ) {
319- FileBuilder :: new ( self . root ( ) . join ( path) , body) . mk ( )
353+ FileBuilder :: new ( self . root ( ) . join ( path) , body, false ) . mk ( )
320354 }
321355
322356 /// Creates a `ProcessBuilder` to run a program in the project
0 commit comments