@@ -62,8 +62,7 @@ async fn test_develop_dependencies_basic() {
6262 setup_tracing ( ) ;
6363
6464 // Create a package database with common dependencies
65- let mut package_database = create_test_package_database ( ) ;
66- package_database. add_package ( Package :: build ( "empty-backend" , "0.1.0" ) . finish ( ) ) ;
65+ let package_database = create_test_package_database ( ) ;
6766
6867 // Convert to channel
6968 let channel = package_database. into_channel ( ) . await . unwrap ( ) ;
@@ -156,8 +155,7 @@ async fn test_develop_dependencies_with_source_dependencies() {
156155 setup_tracing ( ) ;
157156
158157 // Create a package database
159- let mut package_database = create_test_package_database ( ) ;
160- package_database. add_package ( Package :: build ( "empty-backend" , "0.1.0" ) . finish ( ) ) ;
158+ let package_database = create_test_package_database ( ) ;
161159
162160 let channel = package_database. into_channel ( ) . await . unwrap ( ) ;
163161
@@ -273,8 +271,7 @@ package-a = {{ path = "./package-a" }}
273271async fn test_develop_dependencies_with_cross_references ( ) {
274272 setup_tracing ( ) ;
275273
276- let mut package_database = create_test_package_database ( ) ;
277- package_database. add_package ( Package :: build ( "empty-backend" , "0.1.0" ) . finish ( ) ) ;
274+ let package_database = create_test_package_database ( ) ;
278275
279276 let channel = package_database. into_channel ( ) . await . unwrap ( ) ;
280277
@@ -379,8 +376,7 @@ package-y = {{ path = "{}" }}
379376async fn test_develop_dependencies_in_features ( ) {
380377 setup_tracing ( ) ;
381378
382- let mut package_database = create_test_package_database ( ) ;
383- package_database. add_package ( Package :: build ( "empty-backend" , "0.1.0" ) . finish ( ) ) ;
379+ let package_database = create_test_package_database ( ) ;
384380
385381 let channel = package_database. into_channel ( ) . await . unwrap ( ) ;
386382
@@ -445,13 +441,127 @@ feature-package = {{ path = "./feature-package" }}
445441 ) ;
446442}
447443
444+ /// Test that a source package can be listed both in [develop] and in dependencies
445+ /// without causing conflicts (the package is essentially included twice, once as a develop dep
446+ /// and once as a regular source dep)
447+ #[ tokio:: test]
448+ async fn test_develop_and_regular_dependency_same_package ( ) {
449+ setup_tracing ( ) ;
450+
451+ let package_database = create_test_package_database ( ) ;
452+
453+ let channel = package_database. into_channel ( ) . await . unwrap ( ) ;
454+
455+ let backend_override = BackendOverride :: from_memory ( PassthroughBackend :: instantiator ( ) ) ;
456+ let pixi = PixiControl :: new ( )
457+ . unwrap ( )
458+ . with_backend_override ( backend_override) ;
459+
460+ // Create a shared package that will be both a develop dependency and a regular dependency
461+ let shared_package_path = create_source_package (
462+ pixi. workspace_path ( ) ,
463+ "shared-package" ,
464+ "1.0.0" ,
465+ r#"
466+ [package.host-dependencies]
467+ python = ">=3.8"
468+ "# ,
469+ ) ;
470+
471+ // Create another package that depends on shared-package as a regular source dependency
472+ let _dependent_package = create_source_package (
473+ pixi. workspace_path ( ) ,
474+ "dependent-package" ,
475+ "1.0.0" ,
476+ & format ! (
477+ r#"
478+ [package.run-dependencies]
479+ shared-package = {{ path = "{}" }}
480+ numpy = ">=1.0"
481+ "# ,
482+ shared_package_path. to_string_lossy( ) . replace( '\\' , "\\ \\ " )
483+ ) ,
484+ ) ;
485+
486+ // Create a manifest that:
487+ // 1. Lists shared-package as a develop dependency
488+ // 2. Lists dependent-package as a regular source dependency
489+ // This means shared-package appears both as a develop dep and as a transitive source dep
490+ let manifest_content = format ! (
491+ r#"
492+ [workspace]
493+ channels = ["{}"]
494+ platforms = ["{}"]
495+ preview = ["pixi-build"]
496+
497+ [dependencies]
498+ dependent-package = {{ path = "./dependent-package" }}
499+
500+ [develop]
501+ shared-package = {{ path = "{}" }}
502+ "# ,
503+ channel. url( ) ,
504+ Platform :: current( ) ,
505+ shared_package_path. to_string_lossy( ) . replace( '\\' , "\\ \\ " )
506+ ) ;
507+
508+ fs:: write ( pixi. manifest_path ( ) , manifest_content) . unwrap ( ) ;
509+
510+ // Update the lock-file - this should work without conflicts
511+ let lock_file = pixi. update_lock_file ( ) . await . unwrap ( ) ;
512+
513+ // Verify that python is in the lock-file (from shared-package's dependencies)
514+ assert ! (
515+ lock_file. contains_conda_package(
516+ consts:: DEFAULT_ENVIRONMENT_NAME ,
517+ Platform :: current( ) ,
518+ "python" ,
519+ ) ,
520+ "python should be in the lock-file (run dependency of shared-package)"
521+ ) ;
522+
523+ // Verify that numpy is in the lock-file (from dependent-package's dependencies)
524+ assert ! (
525+ lock_file. contains_conda_package(
526+ consts:: DEFAULT_ENVIRONMENT_NAME ,
527+ Platform :: current( ) ,
528+ "numpy" ,
529+ ) ,
530+ "numpy should be in the lock-file (run dependency of dependent-package)"
531+ ) ;
532+
533+ // Verify that dependent-package IS in the lock-file (it's a regular source dependency)
534+ assert ! (
535+ lock_file. contains_conda_package(
536+ consts:: DEFAULT_ENVIRONMENT_NAME ,
537+ Platform :: current( ) ,
538+ "dependent-package" ,
539+ ) ,
540+ "dependent-package SHOULD be in the lock-file (it's a regular source dependency)"
541+ ) ;
542+
543+ // Key assertion: shared-package WILL appear in the lock-file as a built package
544+ // because it's a source dependency of dependent-package.
545+ // The fact that it's also in [develop] doesn't prevent it from being built when
546+ // it's needed as a dependency of another package.
547+ // This is correct behavior - [develop] means "install my dependencies without building me",
548+ // but if another package needs it built, it will be built.
549+ assert ! (
550+ lock_file. contains_conda_package(
551+ consts:: DEFAULT_ENVIRONMENT_NAME ,
552+ Platform :: current( ) ,
553+ "shared-package" ,
554+ ) ,
555+ "shared-package SHOULD be in the lock-file (it's built as a source dependency of dependent-package)"
556+ ) ;
557+ }
558+
448559/// Test that platform-specific develop dependencies work correctly
449560#[ tokio:: test]
450561async fn test_develop_dependencies_platform_specific ( ) {
451562 setup_tracing ( ) ;
452563
453- let mut package_database = create_test_package_database ( ) ;
454- package_database. add_package ( Package :: build ( "empty-backend" , "0.1.0" ) . finish ( ) ) ;
564+ let package_database = create_test_package_database ( ) ;
455565
456566 let channel = package_database. into_channel ( ) . await . unwrap ( ) ;
457567
0 commit comments