Skip to content

Commit 64fc091

Browse files
author
Rakshil Modi
committed
Updated s3 handler
Adding Warning handler for no_overwrite
1 parent 2493f8b commit 64fc091

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

awscli/customizations/s3/s3handler.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,38 @@ def _get_fileout(self, fileinfo):
438438
return fileinfo.dest
439439

440440
def _get_warning_handlers(self):
441-
return [self._warn_glacier, self._warn_parent_reference]
441+
return [
442+
self._warn_glacier,
443+
self._warn_parent_reference,
444+
self._warn_if_file_exists_with_no_overwrite,
445+
]
446+
447+
def _warn_if_file_exists_with_no_overwrite(self, fileinfo):
448+
"""
449+
Warning handler to skip downloads when no-overwrite is set and local file exists.
450+
451+
This method prevents overwriting existing local files during S3 download operations
452+
when the --no-overwrite flag is specified. It checks if the destination file already
453+
exists on the local filesystem and skips the download if found.
454+
455+
:type fileinfo: awscli.customizations.s3.fileinfo.FileInfo
456+
:param fileinfo: The FileInfo object containing source and destination details
457+
458+
:rtype: bool
459+
:returns: True if the file should be skipped (exists and no-overwrite is set),
460+
False if the download should proceed
461+
"""
462+
if not self._cli_params.get('no_overwrite'):
463+
return False
464+
fileout = self._get_fileout(fileinfo)
465+
if os.path.exists(fileout):
466+
LOGGER.debug(
467+
"Warning: Skipping file %s as it already exists on %s",
468+
fileinfo.src,
469+
fileinfo.dest,
470+
)
471+
return True
472+
return False
442473

443474
def _format_src_dest(self, fileinfo):
444475
src = self._format_s3_path(fileinfo.src)

tests/unit/customizations/s3/test_s3handler.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,39 @@ def test_submit_move_adds_delete_source_subscriber(self):
679679
for i, actual_subscriber in enumerate(actual_subscribers):
680680
self.assertIsInstance(actual_subscriber, ref_subscribers[i])
681681

682+
def test_submit_with_no_overwrite_flag_when_file_exists_at_destination(
683+
self,
684+
):
685+
# Setting up the CLI params with no_overwrite flag as True
686+
self.cli_params['no_overwrite'] = True
687+
fileinfo = self.create_file_info(self.key)
688+
# Mocking os.path.exists to simulate that file already exists
689+
with mock.patch('os.path.exists', return_value=True):
690+
# Submitting download request
691+
future = self.transfer_request_submitter.submit(fileinfo)
692+
# Asserting that the future is None, as the file already exists
693+
self.assertIsNone(future)
694+
# Asserting that no download happened
695+
self.assert_no_downloads_happened()
696+
697+
def test_submit_with_no_overwrite_flag_when_file_does_not_exist_at_destination(
698+
self,
699+
):
700+
# Setting up the CLI params with no_overwrite flag as True
701+
self.cli_params['no_overwrite'] = True
702+
fileinfo = self.create_file_info(self.key)
703+
# Mocking os.path.exists to return False, to simulate that file does not exist
704+
with mock.patch('os.path.exists', return_value=False):
705+
# Submitting download request
706+
future = self.transfer_request_submitter.submit(fileinfo)
707+
# Asserting that the future is the same object returned by transfer_manager.download
708+
# This confirms that download was actually initiated
709+
self.assertIs(self.transfer_manager.download.return_value, future)
710+
# Asserting that download happened
711+
self.assertEqual(
712+
len(self.transfer_manager.download.call_args_list), 1
713+
)
714+
682715

683716
class TestCopyRequestSubmitter(BaseTransferRequestSubmitterTest):
684717
def setUp(self):

0 commit comments

Comments
 (0)