2
2
3
3
use std:: {
4
4
collections:: { HashMap , HashSet } ,
5
- fs,
6
5
path:: { Path , PathBuf } ,
7
6
} ;
8
7
9
- use rattler_conda_types:: { package:: PathsJson , PackageName , PrefixRecord } ;
8
+ use rattler_conda_types:: {
9
+ package:: { IndexJson , PathsEntry } ,
10
+ PackageName , PrefixRecord ,
11
+ } ;
10
12
13
+ use fs_err as fs;
11
14
/// A registry for clobbering files
12
15
/// The registry keeps track of all files that are installed by a package and
13
16
/// can be used to rename files that are already installed by another package.
@@ -88,10 +91,11 @@ impl ClobberRegistry {
88
91
/// will "unclobber" the files after all packages have been installed.
89
92
pub fn register_paths (
90
93
& mut self ,
91
- name : & PackageName ,
92
- paths_json : & PathsJson ,
94
+ index_json : & IndexJson ,
95
+ computed_paths : & Vec < ( PathsEntry , PathBuf ) > ,
93
96
) -> HashMap < PathBuf , PathBuf > {
94
97
let mut clobber_paths = HashMap :: new ( ) ;
98
+ let name = & index_json. name . clone ( ) ;
95
99
96
100
// check if we have the package name already registered
97
101
let name_idx = if let Some ( idx) = self . package_names . iter ( ) . position ( |n| n == name) {
@@ -101,32 +105,30 @@ impl ClobberRegistry {
101
105
self . package_names . len ( ) - 1
102
106
} ;
103
107
104
- for entry in paths_json. paths . iter ( ) {
105
- let path = entry. relative_path . clone ( ) ;
106
-
108
+ for ( _, path) in computed_paths {
107
109
// if we find an entry, we have a clobbering path!
108
- if let Some ( e) = self . paths_registry . get ( & path) {
110
+ if let Some ( e) = self . paths_registry . get ( path) {
109
111
if e == & name_idx {
110
112
// A name cannot appear twice in an environment.
111
113
// We get into this case if a package is updated (removed and installed again with a new version)
112
114
continue ;
113
115
}
114
- let new_path = Self :: clobber_name ( & path, & self . package_names [ name_idx] ) ;
116
+ let new_path = Self :: clobber_name ( path, & self . package_names [ name_idx] ) ;
115
117
self . clobbers
116
118
. entry ( path. clone ( ) )
117
119
. or_insert_with ( || vec ! [ * e] )
118
120
. push ( name_idx) ;
119
121
120
- clobber_paths. insert ( path, new_path) ;
122
+ // We insert the non-renamed path here
123
+ clobber_paths. insert ( path. clone ( ) , new_path) ;
121
124
} else {
122
- self . paths_registry . insert ( path, name_idx) ;
125
+ self . paths_registry . insert ( path. clone ( ) , name_idx) ;
123
126
}
124
127
}
125
128
126
129
clobber_paths
127
130
}
128
131
129
- /// Unclobber the paths after all installation steps have been completed.
130
132
/// Unclobber the paths after all installation steps have been completed.
131
133
pub fn unclobber (
132
134
& mut self ,
@@ -268,13 +270,14 @@ mod tests {
268
270
use std:: {
269
271
fs,
270
272
path:: { Path , PathBuf } ,
273
+ str:: FromStr ,
271
274
} ;
272
275
273
276
use futures:: TryFutureExt ;
274
277
use insta:: assert_yaml_snapshot;
275
278
use rand:: seq:: SliceRandom ;
276
279
use rattler_conda_types:: {
277
- package:: IndexJson , PackageRecord , Platform , PrefixRecord , RepoDataRecord ,
280
+ package:: IndexJson , PackageRecord , Platform , PrefixRecord , RepoDataRecord , Version ,
278
281
} ;
279
282
use rattler_digest:: { Md5 , Sha256 } ;
280
283
use rattler_networking:: retry_policies:: default_retry_policy;
@@ -283,12 +286,13 @@ mod tests {
283
286
284
287
use crate :: {
285
288
get_test_data_dir,
286
- install:: { transaction, unlink_package, InstallDriver , InstallOptions } ,
289
+ install:: { transaction, unlink_package, InstallDriver , InstallOptions , PythonInfo } ,
287
290
package_cache:: PackageCache ,
288
291
} ;
289
292
290
293
fn get_repodata_record ( filename : & str ) -> RepoDataRecord {
291
294
let path = fs:: canonicalize ( get_test_data_dir ( ) . join ( filename) ) . unwrap ( ) ;
295
+ print ! ( "{:?}" , path) ;
292
296
let index_json = read_package_file :: < IndexJson > ( & path) . unwrap ( ) ;
293
297
294
298
// find size and hash
@@ -458,6 +462,18 @@ mod tests {
458
462
]
459
463
}
460
464
465
+ fn test_python_noarch_operations ( ) -> Vec < TransactionOperation < PrefixRecord , RepoDataRecord > > {
466
+ let repodata_record_1 =
467
+ get_repodata_record ( "clobber/clobber-pynoarch-1-0.1.0-pyh4616a5c_0.tar.bz2" ) ;
468
+ let repodata_record_2 =
469
+ get_repodata_record ( "clobber/clobber-pynoarch-2-0.1.0-pyh4616a5c_0.tar.bz2" ) ;
470
+
471
+ vec ! [
472
+ TransactionOperation :: Install ( repodata_record_1) ,
473
+ TransactionOperation :: Install ( repodata_record_2) ,
474
+ ]
475
+ }
476
+
461
477
fn test_operations_nested ( ) -> Vec < TransactionOperation < PrefixRecord , RepoDataRecord > > {
462
478
let repodata_record_1 =
463
479
get_repodata_record ( "clobber/clobber-nested-1-0.1.0-h4616a5c_0.tar.bz2" ) ;
@@ -495,6 +511,8 @@ mod tests {
495
511
. collect :: < Vec < _ > > ( ) ;
496
512
println ! ( "Files: {:?}" , files) ;
497
513
assert_eq ! ( files. len( ) , expected_files. len( ) ) ;
514
+ println ! ( "{:?}" , files) ;
515
+
498
516
for file in files {
499
517
assert ! ( expected_files. contains( & file. file_name( ) . unwrap( ) . to_string_lossy( ) . as_ref( ) ) ) ;
500
518
}
@@ -961,6 +979,7 @@ mod tests {
961
979
platform : Platform :: current ( ) ,
962
980
} ;
963
981
982
+ let prefix_records = PrefixRecord :: collect_from_prefix ( target_prefix. path ( ) ) . unwrap ( ) ;
964
983
let install_driver = InstallDriver :: new ( 100 , Some ( & prefix_records) ) ;
965
984
966
985
execute_transaction (
@@ -980,5 +999,89 @@ mod tests {
980
999
fs:: read_to_string( target_prefix. path( ) . join( "clobber.txt" ) ) . unwrap( ) ,
981
1000
"clobber-3 v2\n "
982
1001
) ;
1002
+
1003
+ let update_ops = test_operations_update ( ) ;
1004
+
1005
+ // remove one of the clobbering files
1006
+ let transaction = transaction:: Transaction :: < PrefixRecord , RepoDataRecord > {
1007
+ operations : vec ! [ TransactionOperation :: Install ( update_ops[ 0 ] . clone( ) ) ] ,
1008
+ python_info : None ,
1009
+ current_python_info : None ,
1010
+ platform : Platform :: current ( ) ,
1011
+ } ;
1012
+
1013
+ let prefix_records = PrefixRecord :: collect_from_prefix ( target_prefix. path ( ) ) . unwrap ( ) ;
1014
+ let install_driver = InstallDriver :: new ( 100 , Some ( & prefix_records) ) ;
1015
+
1016
+ execute_transaction (
1017
+ transaction,
1018
+ target_prefix. path ( ) ,
1019
+ & reqwest_middleware:: ClientWithMiddleware :: from ( reqwest:: Client :: new ( ) ) ,
1020
+ & cache,
1021
+ & install_driver,
1022
+ & InstallOptions :: default ( ) ,
1023
+ )
1024
+ . await ;
1025
+
1026
+ assert_check_files (
1027
+ target_prefix. path ( ) ,
1028
+ & [ "clobber.txt" , "clobber.txt__clobber-from-clobber-3" ] ,
1029
+ ) ;
1030
+
1031
+ // content of clobber.txt
1032
+ assert_eq ! (
1033
+ fs:: read_to_string( target_prefix. path( ) . join( "clobber.txt" ) ) . unwrap( ) ,
1034
+ "clobber-1 v2\n "
1035
+ ) ;
1036
+ }
1037
+
1038
+ #[ tokio:: test]
1039
+ async fn test_clobber_python_noarch ( ) {
1040
+ // Create a transaction
1041
+ let operations = test_python_noarch_operations ( ) ;
1042
+
1043
+ let python_info =
1044
+ PythonInfo :: from_version ( & Version :: from_str ( "3.11.0" ) . unwrap ( ) , Platform :: current ( ) )
1045
+ . unwrap ( ) ;
1046
+ let transaction = transaction:: Transaction :: < PrefixRecord , RepoDataRecord > {
1047
+ operations,
1048
+ python_info : Some ( python_info. clone ( ) ) ,
1049
+ current_python_info : Some ( python_info. clone ( ) ) ,
1050
+ platform : Platform :: current ( ) ,
1051
+ } ;
1052
+
1053
+ // execute transaction
1054
+ let target_prefix = tempfile:: tempdir ( ) . unwrap ( ) ;
1055
+
1056
+ let packages_dir = tempfile:: tempdir ( ) . unwrap ( ) ;
1057
+ let cache = PackageCache :: new ( packages_dir. path ( ) ) ;
1058
+
1059
+ let mut install_options = InstallOptions :: default ( ) ;
1060
+ install_options. python_info = Some ( python_info. clone ( ) ) ;
1061
+
1062
+ execute_transaction (
1063
+ transaction,
1064
+ target_prefix. path ( ) ,
1065
+ & reqwest_middleware:: ClientWithMiddleware :: from ( reqwest:: Client :: new ( ) ) ,
1066
+ & cache,
1067
+ & InstallDriver :: default ( ) ,
1068
+ & install_options,
1069
+ )
1070
+ . await ;
1071
+
1072
+ // check that the files are there
1073
+ if cfg ! ( unix) {
1074
+ assert_check_files (
1075
+ & target_prefix
1076
+ . path ( )
1077
+ . join ( "lib/python3.11/site-packages/clobber" ) ,
1078
+ & [ "clobber.py" , "clobber.py__clobber-from-clobber-pynoarch-2" ] ,
1079
+ ) ;
1080
+ } else {
1081
+ assert_check_files (
1082
+ & target_prefix. path ( ) . join ( "Lib/site-packages/clobber" ) ,
1083
+ & [ "clobber.py" , "clobber.py__clobber-from-clobber-pynoarch-2" ] ,
1084
+ ) ;
1085
+ }
983
1086
}
984
1087
}
0 commit comments