@@ -381,13 +381,15 @@ def parse_stderr(line: str):
381381 logger .warning (f"rsync stderr: { line !r} " )
382382
383383 # Generate list of relative filenames for this batch of transferred files
384+ # Relative filenames will be safe to use on both Windows and Unix
384385 relative_filenames : List [Path ] = []
385386 for f in files :
386387 try :
387388 relative_filenames .append (f .relative_to (self ._basepath ))
388389 except ValueError :
389390 raise ValueError (f"File '{ f } ' is outside of { self ._basepath } " ) from None
390391
392+ # Encode files to rsync as bytestring
391393 if self ._remove_files :
392394 if self ._required_substrings_for_removal :
393395 rsync_stdin_remove = b"\n " .join (
@@ -416,24 +418,36 @@ def parse_stderr(line: str):
416418 rsync_stdin = b"\n " .join (os .fsencode (f ) for f in relative_filenames )
417419
418420 # Create and run rsync subprocesses
419- # rsync commands to pass to subprocess
421+ # rsync default settings
420422 rsync_cmd = [
421423 "rsync" ,
422424 "-iiv" ,
423425 "--times" ,
424426 "--progress" ,
425427 "--outbuf=line" ,
426- "--files-from=-" ,
427- "-p" , # preserve permissions
428- "--chmod=D0750,F0750" , # 4: Read, 2: Write, 1: Execute | User, Group, Others
428+ "--files-from=-" , # '-' indicates reading from standard input
429+ # Needed as a pair to trigger permission modifications
430+ # Ref: https://serverfault.com/a/796341
431+ "-p" ,
432+ "--chmod=D0750,F0750" , # Use extended chmod format
429433 ]
434+ # Add file locations
430435 rsync_cmd .extend (["." , self ._remote ])
431- result : subprocess .CompletedProcess | None = None
436+
437+ # Transfer files to destination
438+ result : subprocess .CompletedProcess [bytes ] | None = None
432439 success = True
433440 if rsync_stdin :
441+ # Wrap rsync command in a bash command
442+ bash_cmd = [
443+ "bash" ,
444+ "-c" ,
445+ # rsync command passed in as a single string
446+ " " .join (rsync_cmd ),
447+ ]
434448 result = subprocess .run (
435- rsync_cmd ,
436- cwd = str ( self ._basepath ),
449+ bash_cmd ,
450+ cwd = self ._basepath , # As-is Path is fine
437451 capture_output = True ,
438452 input = rsync_stdin ,
439453 )
@@ -443,15 +457,24 @@ def parse_stderr(line: str):
443457 parse_stderr (stderr_line )
444458 success = result .returncode == 0
445459
460+ # Remove files from source
446461 if rsync_stdin_remove :
462+ # Insert flag file removal flag before locations
447463 rsync_cmd .insert (- 2 , "--remove-source-files" )
464+ # Wrap rsync command in a bash command
465+ bash_cmd = [
466+ "bash" ,
467+ "-c" ,
468+ # Pass rsync command as single string
469+ " " .join (rsync_cmd ),
470+ ]
448471 result = subprocess .run (
449472 rsync_cmd ,
450473 cwd = str (self ._basepath ),
474+ capture_output = True ,
451475 input = rsync_stdin_remove ,
452476 )
453- for stdout_line in result .stdout .decode ("utf8" , "replace" ).split ("\n " ):
454- parse_stdout (stdout_line )
477+ # Only error log should be needed for file removal rsync process
455478 for stderr_line in result .stderr .decode ("utf8" , "replace" ).split ("\n " ):
456479 parse_stderr (stderr_line )
457480
0 commit comments