@@ -121,6 +121,11 @@ impl ClobberRegistry {
121
121
122
122
// if we find an entry, we have a clobbering path!
123
123
if let Some ( e) = self . paths_registry . get ( & path) {
124
+ if e == & name_idx {
125
+ // A name cannot appear twice in an environment.
126
+ // We get into this case if a package is updated (removed and installed again with a new version)
127
+ continue ;
128
+ }
124
129
let new_path = Self :: clobber_name ( & path, & self . package_names [ name_idx] ) ;
125
130
self . clobbers
126
131
. entry ( path. clone ( ) )
@@ -475,6 +480,14 @@ mod tests {
475
480
]
476
481
}
477
482
483
+ fn test_operations_update ( ) -> Vec < RepoDataRecord > {
484
+ let repodata_record_1 = get_repodata_record ( "clobber/clobber-1-0.2.0-h4616a5c_0.tar.bz2" ) ;
485
+ let repodata_record_2 = get_repodata_record ( "clobber/clobber-2-0.2.0-h4616a5c_0.tar.bz2" ) ;
486
+ let repodata_record_3 = get_repodata_record ( "clobber/clobber-3-0.2.0-h4616a5c_0.tar.bz2" ) ;
487
+
488
+ vec ! [ repodata_record_1, repodata_record_2, repodata_record_3]
489
+ }
490
+
478
491
fn assert_check_files ( target_prefix : & Path , expected_files : & [ & str ] ) {
479
492
let files = std:: fs:: read_dir ( target_prefix) . unwrap ( ) ;
480
493
let files = files
@@ -763,4 +776,177 @@ mod tests {
763
776
) ;
764
777
}
765
778
}
779
+
780
+ #[ tokio:: test]
781
+ async fn test_clobber_update ( ) {
782
+ // Create a transaction
783
+ let operations = test_operations ( ) ;
784
+
785
+ let transaction = transaction:: Transaction :: < PrefixRecord , RepoDataRecord > {
786
+ operations,
787
+ python_info : None ,
788
+ current_python_info : None ,
789
+ platform : Platform :: current ( ) ,
790
+ } ;
791
+
792
+ // execute transaction
793
+ let target_prefix = tempfile:: tempdir ( ) . unwrap ( ) ;
794
+
795
+ let packages_dir = tempfile:: tempdir ( ) . unwrap ( ) ;
796
+ let cache = PackageCache :: new ( packages_dir. path ( ) ) ;
797
+
798
+ execute_transaction (
799
+ transaction,
800
+ target_prefix. path ( ) ,
801
+ & reqwest_middleware:: ClientWithMiddleware :: from ( reqwest:: Client :: new ( ) ) ,
802
+ & cache,
803
+ & InstallDriver :: default ( ) ,
804
+ & InstallOptions :: default ( ) ,
805
+ )
806
+ . await ;
807
+
808
+ // check that the files are there
809
+ assert_check_files (
810
+ target_prefix. path ( ) ,
811
+ & [
812
+ "clobber.txt" ,
813
+ "clobber.txt__clobber-from-clobber-2" ,
814
+ "clobber.txt__clobber-from-clobber-3" ,
815
+ ] ,
816
+ ) ;
817
+
818
+ let mut prefix_records = PrefixRecord :: collect_from_prefix ( target_prefix. path ( ) ) . unwrap ( ) ;
819
+ prefix_records. sort_by ( |a, b| {
820
+ a. repodata_record
821
+ . package_record
822
+ . name
823
+ . as_normalized ( )
824
+ . cmp ( & b. repodata_record . package_record . name . as_normalized ( ) )
825
+ } ) ;
826
+
827
+ let update_ops = test_operations_update ( ) ;
828
+
829
+ // remove one of the clobbering files
830
+ let transaction = transaction:: Transaction :: < PrefixRecord , RepoDataRecord > {
831
+ operations : vec ! [ TransactionOperation :: Change {
832
+ old: prefix_records[ 0 ] . clone( ) ,
833
+ new: update_ops[ 0 ] . clone( ) ,
834
+ } ] ,
835
+ python_info : None ,
836
+ current_python_info : None ,
837
+ platform : Platform :: current ( ) ,
838
+ } ;
839
+
840
+ let install_driver = InstallDriver :: new ( 100 , Some ( & prefix_records) ) ;
841
+
842
+ execute_transaction (
843
+ transaction,
844
+ target_prefix. path ( ) ,
845
+ & reqwest_middleware:: ClientWithMiddleware :: from ( reqwest:: Client :: new ( ) ) ,
846
+ & cache,
847
+ & install_driver,
848
+ & InstallOptions :: default ( ) ,
849
+ )
850
+ . await ;
851
+
852
+ assert_check_files (
853
+ target_prefix. path ( ) ,
854
+ & [
855
+ "clobber.txt" ,
856
+ "clobber.txt__clobber-from-clobber-2" ,
857
+ "clobber.txt__clobber-from-clobber-3" ,
858
+ ] ,
859
+ ) ;
860
+
861
+ // content of clobber.txt
862
+ assert_eq ! (
863
+ fs:: read_to_string( target_prefix. path( ) . join( "clobber.txt" ) ) . unwrap( ) ,
864
+ "clobber-1 v2\n "
865
+ ) ;
866
+ }
867
+
868
+ #[ tokio:: test]
869
+ async fn test_clobber_update_and_remove ( ) {
870
+ // Create a transaction
871
+ let operations = test_operations ( ) ;
872
+
873
+ let transaction = transaction:: Transaction :: < PrefixRecord , RepoDataRecord > {
874
+ operations,
875
+ python_info : None ,
876
+ current_python_info : None ,
877
+ platform : Platform :: current ( ) ,
878
+ } ;
879
+
880
+ // execute transaction
881
+ let target_prefix = tempfile:: tempdir ( ) . unwrap ( ) ;
882
+
883
+ let packages_dir = tempfile:: tempdir ( ) . unwrap ( ) ;
884
+ let cache = PackageCache :: new ( packages_dir. path ( ) ) ;
885
+
886
+ execute_transaction (
887
+ transaction,
888
+ target_prefix. path ( ) ,
889
+ & reqwest_middleware:: ClientWithMiddleware :: from ( reqwest:: Client :: new ( ) ) ,
890
+ & cache,
891
+ & InstallDriver :: default ( ) ,
892
+ & InstallOptions :: default ( ) ,
893
+ )
894
+ . await ;
895
+
896
+ // check that the files are there
897
+ assert_check_files (
898
+ target_prefix. path ( ) ,
899
+ & [
900
+ "clobber.txt" ,
901
+ "clobber.txt__clobber-from-clobber-2" ,
902
+ "clobber.txt__clobber-from-clobber-3" ,
903
+ ] ,
904
+ ) ;
905
+
906
+ let mut prefix_records = PrefixRecord :: collect_from_prefix ( target_prefix. path ( ) ) . unwrap ( ) ;
907
+ prefix_records. sort_by ( |a, b| {
908
+ a. repodata_record
909
+ . package_record
910
+ . name
911
+ . as_normalized ( )
912
+ . cmp ( & b. repodata_record . package_record . name . as_normalized ( ) )
913
+ } ) ;
914
+
915
+ let update_ops = test_operations_update ( ) ;
916
+
917
+ // remove one of the clobbering files
918
+ let transaction = transaction:: Transaction :: < PrefixRecord , RepoDataRecord > {
919
+ operations : vec ! [
920
+ TransactionOperation :: Change {
921
+ old: prefix_records[ 2 ] . clone( ) ,
922
+ new: update_ops[ 2 ] . clone( ) ,
923
+ } ,
924
+ TransactionOperation :: Remove ( prefix_records[ 0 ] . clone( ) ) ,
925
+ TransactionOperation :: Remove ( prefix_records[ 1 ] . clone( ) ) ,
926
+ ] ,
927
+ python_info : None ,
928
+ current_python_info : None ,
929
+ platform : Platform :: current ( ) ,
930
+ } ;
931
+
932
+ let install_driver = InstallDriver :: new ( 100 , Some ( & prefix_records) ) ;
933
+
934
+ execute_transaction (
935
+ transaction,
936
+ target_prefix. path ( ) ,
937
+ & reqwest_middleware:: ClientWithMiddleware :: from ( reqwest:: Client :: new ( ) ) ,
938
+ & cache,
939
+ & install_driver,
940
+ & InstallOptions :: default ( ) ,
941
+ )
942
+ . await ;
943
+
944
+ assert_check_files ( target_prefix. path ( ) , & [ "clobber.txt" ] ) ;
945
+
946
+ // content of clobber.txt
947
+ assert_eq ! (
948
+ fs:: read_to_string( target_prefix. path( ) . join( "clobber.txt" ) ) . unwrap( ) ,
949
+ "clobber-3 v2\n "
950
+ ) ;
951
+ }
766
952
}
0 commit comments