@@ -1072,6 +1072,9 @@ pub async fn debug_recipe(
10721072) -> miette:: Result < ( ) > {
10731073 let recipe_path = get_recipe_path ( & debug_data. recipe_path ) ?;
10741074
1075+ let is_test_mode = debug_data. test_mode ;
1076+ let test_index = debug_data. test_index ; // None means run all tests, Some(n) means run test n
1077+
10751078 let build_data = BuildData {
10761079 build_platform : debug_data. build_platform ,
10771080 target_platform : debug_data. target_platform ,
@@ -1177,22 +1180,147 @@ pub async fn debug_recipe(
11771180 }
11781181 }
11791182
1180- tracing:: info!( "\n To run the actual build, use:" ) ;
1181- tracing:: info!(
1182- "rattler-build build --recipe {}" ,
1183- output. build_configuration. directories. recipe_path. display( )
1184- ) ;
1185- tracing:: info!( "Or run the build script directly with:" ) ;
1186- if cfg ! ( windows) {
1187- tracing:: info!(
1188- "cd {} && ./conda_build.bat" ,
1189- output. build_configuration. directories. work_dir. display( )
1190- ) ;
1183+ if is_test_mode {
1184+ // Test mode: setup test environment and run test(s)
1185+ let tests = & output. recipe . tests ;
1186+
1187+ if tests. is_empty ( ) {
1188+ return Err ( miette:: miette!( "No tests found in recipe." ) ) ;
1189+ }
1190+
1191+ // Determine which tests to run
1192+ let tests_to_run: Vec < usize > = match test_index {
1193+ Some ( idx) => {
1194+ if idx >= tests. len ( ) {
1195+ return Err ( miette:: miette!(
1196+ "Test index {} out of range. Recipe has {} test(s)." ,
1197+ idx,
1198+ tests. len( )
1199+ ) ) ;
1200+ }
1201+ vec ! [ idx]
1202+ }
1203+ None => ( 0 ..tests. len ( ) ) . collect ( ) ,
1204+ } ;
1205+
1206+ tracing:: info!( "\n === Test Debug Mode ===" ) ;
1207+ if test_index. is_some ( ) {
1208+ tracing:: info!( "Running test {} of {}" , tests_to_run[ 0 ] , tests. len( ) ) ;
1209+ } else {
1210+ tracing:: info!( "Running all {} tests" , tests. len( ) ) ;
1211+ }
1212+ tracing:: info!( "Available tests:" ) ;
1213+ for ( idx, test) in tests. iter ( ) . enumerate ( ) {
1214+ let test_type = match test {
1215+ crate :: recipe:: parser:: TestType :: Python { .. } => "Python" ,
1216+ crate :: recipe:: parser:: TestType :: Perl { .. } => "Perl" ,
1217+ crate :: recipe:: parser:: TestType :: R { .. } => "R" ,
1218+ crate :: recipe:: parser:: TestType :: Ruby { .. } => "Ruby" ,
1219+ crate :: recipe:: parser:: TestType :: Command ( _) => "Command" ,
1220+ crate :: recipe:: parser:: TestType :: Downstream ( _) => "Downstream" ,
1221+ crate :: recipe:: parser:: TestType :: PackageContents { .. } => "PackageContents" ,
1222+ } ;
1223+ let marker = if tests_to_run. contains ( & idx) {
1224+ ">>>"
1225+ } else {
1226+ " "
1227+ } ;
1228+ tracing:: info!( "{} Test {}: {}" , marker, idx, test_type) ;
1229+ }
1230+
1231+ // Build the package first to be able to run tests
1232+ tracing:: info!( "\n Note: Tests require a built package. Building package first..." ) ;
1233+
1234+ // Create a modified output with debug mode disabled for the actual build
1235+ let mut build_output = output. clone ( ) ;
1236+ build_output. build_configuration . debug = crate :: types:: Debug :: new ( false ) ;
1237+
1238+ let ( built_output, archive_path) = run_build (
1239+ build_output,
1240+ & tool_config,
1241+ WorkingDirectoryBehavior :: Cleanup ,
1242+ )
1243+ . await ?;
1244+
1245+ tracing:: info!( "Package built successfully: {}" , archive_path. display( ) ) ;
1246+
1247+ // Run the test(s) with environment preservation for debugging
1248+ let config = & built_output. build_configuration ;
1249+
1250+ for current_test_index in tests_to_run {
1251+ // Skip PackageContents tests as they run at build time
1252+ if matches ! (
1253+ tests[ current_test_index] ,
1254+ crate :: recipe:: parser:: TestType :: PackageContents { .. }
1255+ ) {
1256+ tracing:: info!(
1257+ "\n Skipping test {} (PackageContents tests run at build time)" ,
1258+ current_test_index
1259+ ) ;
1260+ continue ;
1261+ }
1262+
1263+ // Calculate the package test index (excluding PackageContents tests before this one)
1264+ let package_test_index = tests[ ..=current_test_index]
1265+ . iter ( )
1266+ . filter ( |t| {
1267+ !matches ! ( t, crate :: recipe:: parser:: TestType :: PackageContents { .. } )
1268+ } )
1269+ . count ( )
1270+ - 1 ;
1271+
1272+ let test_config = TestConfiguration {
1273+ test_prefix : config
1274+ . directories
1275+ . output_dir
1276+ . join ( format ! ( "test_debug_{}" , current_test_index) ) ,
1277+ target_platform : Some ( config. target_platform ) ,
1278+ host_platform : Some ( config. host_platform . clone ( ) ) ,
1279+ current_platform : config. build_platform . clone ( ) ,
1280+ keep_test_prefix : true ,
1281+ test_index : Some ( package_test_index) ,
1282+ channels : config. channels . clone ( ) ,
1283+ channel_priority : tool_config. channel_priority ,
1284+ solve_strategy : SolveStrategy :: Highest ,
1285+ tool_configuration : tool_config. clone ( ) ,
1286+ output_dir : config. directories . output_dir . clone ( ) ,
1287+ debug : crate :: types:: Debug :: new ( false ) ,
1288+ exclude_newer : config. exclude_newer ,
1289+ } ;
1290+
1291+ tracing:: info!(
1292+ "\n Running test {} with environment preservation...\n " ,
1293+ current_test_index
1294+ ) ;
1295+
1296+ match package_test:: run_test ( & archive_path, & test_config, None ) . await {
1297+ Ok ( _) => {
1298+ tracing:: info!( "\n Test {} passed!" , current_test_index) ;
1299+ }
1300+ Err ( e) => {
1301+ return Err ( miette:: miette!( "Test {} failed: {}" , current_test_index, e) ) ;
1302+ }
1303+ }
1304+ }
11911305 } else {
1306+ // Build mode: provide instructions to run the build script
1307+ tracing:: info!( "\n To run the actual build, use:" ) ;
11921308 tracing:: info!(
1193- "cd {} && ./conda_build.sh " ,
1194- output. build_configuration. directories. work_dir . display( )
1309+ "rattler-build build --recipe {} " ,
1310+ output. build_configuration. directories. recipe_path . display( )
11951311 ) ;
1312+ tracing:: info!( "Or run the build script directly with:" ) ;
1313+ if cfg ! ( windows) {
1314+ tracing:: info!(
1315+ "cd {} && ./conda_build.bat" ,
1316+ output. build_configuration. directories. work_dir. display( )
1317+ ) ;
1318+ } else {
1319+ tracing:: info!(
1320+ "cd {} && ./conda_build.sh" ,
1321+ output. build_configuration. directories. work_dir. display( )
1322+ ) ;
1323+ }
11961324 }
11971325 }
11981326
0 commit comments