@@ -33,7 +33,7 @@ use extra::{getopts};
33
33
use syntax:: { ast, diagnostic} ;
34
34
use util:: * ;
35
35
use messages:: { error, warn, note} ;
36
- use path_util:: build_pkg_id_in_workspace;
36
+ use path_util:: { build_pkg_id_in_workspace, built_test_in_workspace } ;
37
37
use path_util:: { U_RWX , in_rust_path} ;
38
38
use path_util:: { built_executable_in_workspace, built_library_in_workspace, default_workspace} ;
39
39
use path_util:: { target_executable_in_workspace, target_library_in_workspace} ;
@@ -44,7 +44,7 @@ use context::{Context, BuildContext,
44
44
LLVMAssemble , LLVMCompileBitcode } ;
45
45
use package_id:: PkgId ;
46
46
use package_source:: PkgSrc ;
47
- use target:: { WhatToBuild , Everything , is_lib, is_main, is_test, is_bench} ;
47
+ use target:: { WhatToBuild , Everything , is_lib, is_main, is_test, is_bench, Tests } ;
48
48
// use workcache_support::{discover_outputs, digest_only_date};
49
49
use workcache_support:: digest_only_date;
50
50
use exit_codes:: COPY_FAILED_CODE ;
@@ -177,6 +177,8 @@ impl<'self> PkgScript<'self> {
177
177
pub trait CtxMethods {
178
178
fn run ( & self , cmd : & str , args : ~[ ~str ] ) ;
179
179
fn do_cmd ( & self , _cmd : & str , _pkgname : & str ) ;
180
+ /// Returns a pair of the selected package ID, and the destination workspace
181
+ fn build_args ( & self , args : ~[ ~str ] , what : & WhatToBuild ) -> Option < ( PkgId , Path ) > ;
180
182
/// Returns the destination workspace
181
183
fn build ( & self , pkg_src : & mut PkgSrc , what : & WhatToBuild ) -> Path ;
182
184
fn clean ( & self , workspace : & Path , id : & PkgId ) ;
@@ -190,43 +192,53 @@ pub trait CtxMethods {
190
192
target_workspace : & Path ,
191
193
id : & PkgId ) -> ~[ ~str ] ;
192
194
fn prefer ( & self , _id : & str , _vers : Option < ~str > ) ;
193
- fn test ( & self ) ;
195
+ fn test ( & self , id : & PkgId , workspace : & Path ) ;
194
196
fn uninstall ( & self , _id : & str , _vers : Option < ~str > ) ;
195
197
fn unprefer ( & self , _id : & str , _vers : Option < ~str > ) ;
196
198
fn init ( & self ) ;
197
199
}
198
200
199
201
impl CtxMethods for BuildContext {
202
+ fn build_args ( & self , args : ~[ ~str ] , what : & WhatToBuild ) -> Option < ( PkgId , Path ) > {
203
+ if args. len ( ) < 1 {
204
+ match cwd_to_workspace ( ) {
205
+ None if self . context . use_rust_path_hack => {
206
+ let cwd = os:: getcwd ( ) ;
207
+ let pkgid = PkgId :: new ( cwd. components [ cwd. components . len ( ) - 1 ] ) ;
208
+ let mut pkg_src = PkgSrc :: new ( cwd, true , pkgid) ;
209
+ let dest_ws = self . build ( & mut pkg_src, what) ;
210
+ Some ( ( pkg_src. id , dest_ws) )
211
+ }
212
+ None => { usage:: build ( ) ; None }
213
+ Some ( ( ws, pkgid) ) => {
214
+ let mut pkg_src = PkgSrc :: new ( ws, false , pkgid) ;
215
+ let dest_ws = self . build ( & mut pkg_src, what) ;
216
+ Some ( ( pkg_src. id , dest_ws) )
217
+ }
218
+ }
219
+ } else {
220
+ // The package id is presumed to be the first command-line
221
+ // argument
222
+ let pkgid = PkgId :: new ( args[ 0 ] . clone ( ) ) ;
223
+ let mut dest_ws = None ;
224
+ do each_pkg_parent_workspace ( & self . context , & pkgid) |workspace| {
225
+ debug ! ( "found pkg %s in workspace %s, trying to build" ,
226
+ pkgid. to_str( ) , workspace. to_str( ) ) ;
227
+ let mut pkg_src = PkgSrc :: new ( workspace. clone ( ) , false , pkgid. clone ( ) ) ;
228
+ dest_ws = Some ( self . build ( & mut pkg_src, what) ) ;
229
+ true
230
+ } ;
231
+ assert ! ( dest_ws. is_some( ) ) ;
232
+ // n.b. If this builds multiple packages, it only returns the workspace for
233
+ // the last one. The whole building-multiple-packages-with-the-same-ID is weird
234
+ // anyway and there are no tests for it, so maybe take it out
235
+ Some ( ( pkgid, dest_ws. unwrap ( ) ) )
236
+ }
237
+ }
200
238
fn run ( & self , cmd : & str , args : ~[ ~str ] ) {
201
239
match cmd {
202
240
"build" => {
203
- if args. len ( ) < 1 {
204
- match cwd_to_workspace ( ) {
205
- None if self . context . use_rust_path_hack => {
206
- let cwd = os:: getcwd ( ) ;
207
- let pkgid = PkgId :: new ( cwd. components [ cwd. components . len ( ) - 1 ] ) ;
208
- let mut pkg_src = PkgSrc :: new ( cwd, true , pkgid) ;
209
- self . build ( & mut pkg_src, & Everything ) ;
210
- }
211
- None => { usage:: build ( ) ; return ; }
212
- Some ( ( ws, pkgid) ) => {
213
- let mut pkg_src = PkgSrc :: new ( ws, false , pkgid) ;
214
- self . build ( & mut pkg_src, & Everything ) ;
215
- }
216
- }
217
- }
218
- else {
219
- // The package id is presumed to be the first command-line
220
- // argument
221
- let pkgid = PkgId :: new ( args[ 0 ] . clone ( ) ) ;
222
- do each_pkg_parent_workspace ( & self . context , & pkgid) |workspace| {
223
- debug ! ( "found pkg %s in workspace %s, trying to build" ,
224
- pkgid. to_str( ) , workspace. to_str( ) ) ;
225
- let mut pkg_src = PkgSrc :: new ( workspace. clone ( ) , false , pkgid. clone ( ) ) ;
226
- self . build ( & mut pkg_src, & Everything ) ;
227
- true
228
- } ;
229
- }
241
+ self . build_args ( args, & Everything ) ;
230
242
}
231
243
"clean" => {
232
244
if args. len ( ) < 1 {
@@ -310,7 +322,17 @@ impl CtxMethods for BuildContext {
310
322
self . prefer ( args[ 0 ] , None ) ;
311
323
}
312
324
"test" => {
313
- self . test ( ) ;
325
+ // Build the test executable
326
+ let maybe_id_and_workspace = self . build_args ( args, & Tests ) ;
327
+ match maybe_id_and_workspace {
328
+ Some ( ( pkg_id, workspace) ) => {
329
+ // Assuming it's built, run the tests
330
+ self . test ( & pkg_id, & workspace) ;
331
+ }
332
+ None => {
333
+ error ( "Testing failed because building the specified package failed." ) ;
334
+ }
335
+ }
314
336
}
315
337
"init" => {
316
338
if args. len ( ) != 0 {
@@ -425,6 +447,8 @@ impl CtxMethods for BuildContext {
425
447
match what_to_build {
426
448
// Find crates inside the workspace
427
449
& Everything => pkg_src. find_crates ( ) ,
450
+ // Find only tests
451
+ & Tests => pkg_src. find_crates_with_filter ( |s| { is_test ( & Path ( s) ) } ) ,
428
452
// Don't infer any crates -- just build the one that was requested
429
453
& JustOne ( ref p) => {
430
454
// We expect that p is relative to the package source's start directory,
@@ -592,9 +616,25 @@ impl CtxMethods for BuildContext {
592
616
fail ! ( "prefer not yet implemented" ) ;
593
617
}
594
618
595
- fn test ( & self ) {
596
- // stub
597
- fail ! ( "test not yet implemented" ) ;
619
+ fn test ( & self , pkgid : & PkgId , workspace : & Path ) {
620
+ match built_test_in_workspace ( pkgid, workspace) {
621
+ Some ( test_exec) => {
622
+ debug ! ( "test: test_exec = %s" , test_exec. to_str( ) ) ;
623
+ let p_output = run:: process_output ( test_exec. to_str ( ) , [ ~"--test"] ) ;
624
+ if p_output. status == 0 {
625
+ println ( str:: from_utf8 ( p_output. output ) ) ;
626
+ }
627
+ else {
628
+ println ( str:: from_utf8 ( p_output. error ) ) ;
629
+ }
630
+ os:: set_exit_status ( p_output. status ) ;
631
+ }
632
+ None => {
633
+ error ( fmt ! ( "Internal error: test executable for package ID %s in workspace %s \
634
+ wasn't built! Please report this as a bug.",
635
+ pkgid. to_str( ) , workspace. to_str( ) ) ) ;
636
+ }
637
+ }
598
638
}
599
639
600
640
fn init ( & self ) {
0 commit comments