Skip to content

Commit cfcf59f

Browse files
committed
Added --[no]-follow-symlinks options.
1 parent 0bb6273 commit cfcf59f

5 files changed

Lines changed: 45 additions & 13 deletions

File tree

awscli/customizations/s3/description.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,17 @@ def add_param_descriptions(params_dict):
6565
params_dict['delete']['documents'] = "Files that exist in the " \
6666
"destination but not in the source are deleted during sync."
6767

68-
params_dict['follow-symlinks']['documents'] = "Symbolic links " \
69-
"are followed only when uploading locally to S3. Note that S3 " \
70-
"does not support symbolic links so contents of linked files are " \
71-
"uploaded under name of symbolic file."
68+
params_dict['follow-symlinks']['documents'] = "Symbolic links are " \
69+
"followed only when uploading to S3 from the local filesystem. Note" \
70+
" that S3 does not support symbolic links, so the contents of the link" \
71+
" target are uploaded under the name of the link. When neither " \
72+
"``--follow-symlinks`` nor ``--no-follow-symlinks`` is specifed, " \
73+
" the default is to follow symlinks."
74+
75+
params_dict['no-follow-symlinks']['documents'] = "Symbolic links are " \
76+
"ignored when uploading to S3 from the local filesystem. When neither " \
77+
"``--follow-symlinks`` nor ``--no-follow-symlinks`` is specifed, " \
78+
" the default is to follow symlinks."
7279

7380
params_dict['exclude']['documents'] = "Exclude all files or objects" \
7481
" from the command that matches the specified pattern."

awscli/customizations/s3/filegenerator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def check_ignore_file(self, path):
160160
"""
161161
if not os.path.exists(path):
162162
return True
163-
follow_symlinks = self.parameters.get('follow_symlinks', False)
163+
follow_symlinks = self.parameters.get('follow_symlinks', True)
164164
if not follow_symlinks:
165165
if os.path.isdir(path):
166166
# Trailing slash must be removed to check if it is a symlink.

awscli/customizations/s3/s3.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,6 @@ def run(self):
607607
's3_handler': [s3handler]}
608608

609609
files = command_dict['setup']
610-
611610
while self.instructions:
612611
instruction = self.instructions.pop(0)
613612
file_list = []
@@ -794,7 +793,7 @@ def add_verify_ssl(self, parsed_globals):
794793
CMD_DICT = {'cp': {'options': {'nargs': 2},
795794
'params': ['dryrun', 'quiet', 'recursive',
796795
'include', 'exclude', 'acl', 'follow-symlinks',
797-
'no-guess-mime-type',
796+
'no-follow-symlinks', 'no-guess-mime-type',
798797
'sse', 'storage-class', 'grants',
799798
'website-redirect', 'content-type',
800799
'cache-control', 'content-disposition',
@@ -803,6 +802,7 @@ def add_verify_ssl(self, parsed_globals):
803802
'mv': {'options': {'nargs': 2},
804803
'params': ['dryrun', 'quiet', 'recursive',
805804
'include', 'exclude', 'acl', 'follow-symlinks',
805+
'no-follow-symlinks',
806806
'sse', 'storage-class', 'grants',
807807
'website-redirect', 'content-type',
808808
'cache-control', 'content-disposition',
@@ -815,6 +815,7 @@ def add_verify_ssl(self, parsed_globals):
815815
'params': ['dryrun', 'delete', 'exclude',
816816
'include', 'quiet', 'acl', 'grants',
817817
'no-guess-mime-type', 'follow-symlinks',
818+
'no-follow-symlinks',
818819
'sse', 'storage-class', 'content-type',
819820
'cache-control', 'content-disposition',
820821
'content-encoding', 'content-language',
@@ -841,7 +842,11 @@ def add_verify_ssl(self, parsed_globals):
841842
'delete': {'options': {'action': 'store_true'}},
842843
'quiet': {'options': {'action': 'store_true'}},
843844
'force': {'options': {'action': 'store_true'}},
844-
'follow-symlinks': {'options': {'action': 'store_true'}},
845+
'follow-symlinks': {'options': {'action': 'store_true',
846+
'default': True}},
847+
'no-follow-symlinks': {'options': {'action': 'store_false',
848+
'dest': 'follow_symlinks',
849+
'default': True}},
845850
'no-guess-mime-type': {'options': {'action': 'store_false',
846851
'dest': 'guess_mime_type',
847852
'default': True}},

tests/integration/customizations/s3/test_plugin.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,8 @@ def extra_setup(self):
571571
'c-goodsymlink'))
572572

573573
def test_no_follow_symlinks(self):
574-
p = aws('s3 sync %s s3://%s/' % (self.files.rootdir,
575-
self.bucket_name))
574+
p = aws('s3 sync %s s3://%s/ --no-follow-symlinks' % (self.files.rootdir,
575+
self.bucket_name))
576576
self.assert_no_errors(p)
577577
self.assertTrue(not self.key_exists(self.bucket_name,
578578
'a-goodsymlink'))
@@ -601,6 +601,24 @@ def test_follow_symlinks(self):
601601
key_name='realfiles/foo.txt'),
602602
'foo.txt contents')
603603

604+
def test_follow_symlinks_default(self):
605+
p = aws('s3 sync %s s3://%s/' %
606+
(self.files.rootdir, self.bucket_name))
607+
self.assert_no_errors(p)
608+
self.assertEqual(self.get_key_contents(self.bucket_name,
609+
key_name='a-goodsymlink'),
610+
'foo.txt contents')
611+
self.assertTrue(not self.key_exists(self.bucket_name,
612+
'b-badsymlink'))
613+
self.assertEqual(
614+
self.get_key_contents(self.bucket_name,
615+
key_name='c-goodsymlink/foo.txt'),
616+
'foo.txt contents')
617+
self.assertEqual(self.get_key_contents(self.bucket_name,
618+
key_name='realfiles/foo.txt'),
619+
'foo.txt contents')
620+
621+
604622

605623
class TestUnicode(BaseS3CLICommand):
606624
"""
@@ -723,7 +741,9 @@ def extra_setup(self):
723741
def test_mb_rb(self):
724742
p = aws('s3 mb s3://%s' % self.bucket_name)
725743
self.assert_no_errors(p)
726-
744+
745+
# Give the bucket time to form.
746+
time.sleep(1)
727747
response = self.list_buckets()
728748
self.assertIn(self.bucket_name, [b['Name'] for b in response])
729749

tests/unit/test_completer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@
6969
'--recursive', '--website-redirect',
7070
'--quiet', '--acl', '--storage-class',
7171
'--sse', '--exclude', '--include',
72-
'--follow-symlinks',
72+
'--follow-symlinks', '--no-follow-symlinks',
7373
'--cache-control', '--content-type',
7474
'--content-disposition',
7575
'--content-encoding', '--content-language',
7676
'--expires', '--grants'] + GLOBALOPTS)),
7777
('aws s3 cp --quiet -', -1, set(['--no-guess-mime-type', '--dryrun',
7878
'--recursive', '--content-type',
79-
'--follow-symlinks',
79+
'--follow-symlinks', '--no-follow-symlinks',
8080
'--content-disposition', '--cache-control',
8181
'--content-encoding', '--content-language',
8282
'--expires', '--website-redirect', '--acl',

0 commit comments

Comments
 (0)