@@ -267,15 +267,6 @@ def movedircontent(root_src_dir, root_dst_dir):
267267 shutil .rmtree (root_src_dir )
268268
269269
270- def _rsync_directory (source : pathlib .Path , destination : pathlib .Path , exclude : tuple ) -> None :
271- """Copy source to destination using rsync, honouring the given exclude patterns."""
272- cmd = ['rsync' , '-a' ]
273- for pattern in exclude :
274- cmd += ['--exclude' , pattern ]
275- cmd += [str (source ) + '/' , str (destination )]
276- subprocess .run (cmd , check = True , capture_output = True )
277-
278-
279270def merge_configuration_directories (source : Union [str , pathlib .Path ], destination : Union [str , pathlib .Path ], envs = (), exclude = EXCLUDE_PATHS ) -> None :
280271 source_path , destination_path = pathlib .Path (source ), pathlib .Path (destination )
281272
@@ -289,31 +280,25 @@ def merge_configuration_directories(source: Union[str, pathlib.Path], destinatio
289280 merge_roots = ('deploy' , 'deployment' )
290281 spec = pathspec .PathSpec .from_lines ('gitwildmatch' , exclude )
291282 copy_single_files = False
292- try :
293- logging .info (f'Copying directory { source_path } to { destination_path } using rsync' )
294- _rsync_directory (source_path , destination_path , tuple (exclude ) + (merge_roots if destination_path .exists () else ()))
295- except (FileNotFoundError , subprocess .CalledProcessError ) as e :
296- if not destination_path .exists ():
297- logging .debug ("rsync failed (%s), falling back to shutil.copytree" , e )
298- merge_roots_set = set (merge_roots )
299-
300- def _ignore (directory , contents ):
301- rel_dir = pathlib .Path (directory ).relative_to (source_path )
302- ignored = []
303- for c in contents :
304- if str (rel_dir ) == '.' and c in merge_roots_set :
305- ignored .append (c )
306- elif spec .match_file (str (rel_dir / c )) or spec .match_file (str (rel_dir / c ) + '/' ):
307- ignored .append (c )
308- return ignored
309- shutil .copytree (source_path , destination_path , ignore = _ignore )
310- else :
311- copy_single_files = True
312-
283+
313284 if not destination_path .exists ():
314-
285+ logging .info ("Creating merged directory %s from %s" , destination , source )
286+ merge_roots_set = set (merge_roots )
287+
288+ def _ignore (directory , contents ):
289+ rel_dir = pathlib .Path (directory ).relative_to (source_path )
290+ ignored = []
291+ for c in contents :
292+ if str (rel_dir ) == '.' and c in merge_roots_set :
293+ ignored .append (c )
294+ elif spec .match_file (str (rel_dir / c )) or spec .match_file (str (rel_dir / c ) + '/' ):
295+ ignored .append (c )
296+ return ignored
297+ shutil .copytree (source_path , destination_path , ignore = _ignore )
315298 if not envs :
316299 return
300+ else :
301+ copy_single_files = True
317302
318303 for source_directory , dirs , files in os .walk (source_path ): # source_path.walk() from Python 3.12
319304 _merge_configuration_directory (
@@ -339,7 +324,7 @@ def _merge_configuration_directory(
339324
340325 destination_directory = destination / source_directory .relative_to (source )
341326 merge_roots = {'deploy' , 'deployment' }
342- if source != destination and not any (destination_directory .is_relative_to (destination / m ) for m in merge_roots ):
327+ if source != destination and not copy_single_files and not any (destination_directory .is_relative_to (destination / m ) for m in merge_roots ):
343328 return
344329 destination_directory .mkdir (exist_ok = True )
345330
0 commit comments