Skip to content

Commit

Permalink
Merge branch 'release-1.3.21'
Browse files Browse the repository at this point in the history
* release-1.3.21:
  Bumping version to 1.3.21
  Add changelog entry for #829
  Add unittests for #829
  Update changelog with opsworks update
  Update changelog
  Fix single item shorthand list parsing bug
  bugfix: convert ints to strings before write
  Update changelog with issue 828
  Don't validate --endpoint-url for help subcommand
  • Loading branch information
jamesls committed Jul 1, 2014
2 parents d6c4980 + 69fbea5 commit 3f48075
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 16 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@
CHANGELOG
=========

1.3.21
======

* feature:``aws opsworks``: Update the ``aws opsworks`` command
to the latest version
* bugfix:Shorthand JSON: Fix bug where shorthand lists with
a single item (e.g. ``--arg Param=[item]``) were not parsed
correctly.
(`issue 830 <https://github.com/aws/aws-cli/pull/830>`__)
* bugfix:Text output: Fix bug when rendering only
scalars that are numbers in text output
(`issue 829 <https://github.com/aws/aws-cli/pull/829>`__)
* bugfix:``aws cloudsearchdomain``: Fix bug where
``--endpoint-url`` is required even for ``help`` subcommands
(`issue 828 <https://github.com/aws/aws-cli/pull/828>`__)


1.3.20
======

Expand Down
2 changes: 1 addition & 1 deletion awscli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""
import os

__version__ = '1.3.20'
__version__ = '1.3.21'

#
# Get our data path to be added to botocore's search path
Expand Down
8 changes: 4 additions & 4 deletions awscli/customizations/cloudsearchdomain.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
"""

def register_cloudsearchdomain(cli):
cli.register('top-level-args-parsed', validate_endpoint_url)
cli.register('operation-args-parsed.cloudsearchdomain',
validate_endpoint_url)


def validate_endpoint_url(parsed_args, **kwargs):
if parsed_args.command == 'cloudsearchdomain' and \
parsed_args.endpoint_url is None:
def validate_endpoint_url(parsed_globals, **kwargs):
if parsed_globals.endpoint_url is None:
raise ValueError(
"--endpoint-url is required for cloudsearchdomain commands")
2 changes: 1 addition & 1 deletion awscli/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def _exists_on_path(self, name):
# Since we're only dealing with POSIX systems, we can
# ignore things like PATHEXT.
return any([os.path.exists(os.path.join(p, name))
for p in os.environ.get('PATH', []).split(os.pathsep)])
for p in os.environ.get('PATH', '').split(os.pathsep)])

def _popen(self, *args, **kwargs):
return Popen(*args, **kwargs)
Expand Down
2 changes: 1 addition & 1 deletion awscli/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def _format_text(item, stream, identifier=None, scalar_keys=None):
else:
# If it's not a list or a dict, we just write the scalar
# value out directly.
stream.write(item)
stream.write(six.text_type(item))
stream.write('\n')


Expand Down
6 changes: 5 additions & 1 deletion awscli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ def _split_with_quotes(value):
if list_start >= 0 and value.find(']') != -1 and \
(quote_char is None or part.find(quote_char) > list_start):
# This is a list, eat all the items until the end
new_chunk = _eat_items(value, iter_parts, part, ']')
if ']' in part:
# Short circuit for only one item
new_chunk = part
else:
new_chunk = _eat_items(value, iter_parts, part, ']')
list_items = _split_with_quotes(new_chunk[list_start + 2:-1])
new_chunk = new_chunk[:list_start + 1] + ','.join(list_items)
new_parts.append(new_chunk)
Expand Down
2 changes: 1 addition & 1 deletion doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
# The short X.Y version.
version = '1.3.'
# The full version, including alpha/beta/rc tags.
release = '1.3.20'
release = '1.3.21'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import awscli


requires = ['botocore>=0.54.0,<0.55.0',
requires = ['botocore>=0.55.0,<0.56.0',
'bcdoc>=0.12.0,<0.13.0',
'six>=1.1.0',
'colorama==0.2.5',
Expand Down
17 changes: 17 additions & 0 deletions tests/integration/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ def test_operation_help_with_required_arg(self):
self.assertEqual(p.rc, 1, p.stderr)
self.assertIn('get-object', p.stdout)

def test_service_help_with_required_option(self):
# In cloudsearchdomain, the --endpoint-url is required.
# We want to make sure if you're just getting help tex
# that we don't trigger that validation.
p = aws('cloudsearchdomain help')
self.assertEqual(p.rc, 1, p.stderr)
self.assertIn('cloudsearchdomain', p.stdout)
# And nothing on stderr about missing options.
self.assertEqual(p.stderr, '')

def test_operation_help_with_required_option(self):
p = aws('cloudsearchdomain search help')
self.assertEqual(p.rc, 1, p.stderr)
self.assertIn('search', p.stdout)
# And nothing on stderr about missing options.
self.assertEqual(p.stderr, '')

def test_help_with_warning_blocks(self):
p = aws('elastictranscoder create-pipeline help')
self.assertEqual(p.rc, 1, p.stderr)
Expand Down
19 changes: 15 additions & 4 deletions tests/unit/customizations/test_cloudsearchdomain.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# language governing permissions and limitations under the License.
from awscli.testutils import unittest
from awscli.testutils import BaseAWSCommandParamsTest
from awscli.help import HelpRenderer
from awscli.customizations.cloudsearchdomain import validate_endpoint_url

import mock
Expand Down Expand Up @@ -48,14 +49,24 @@ def test_endpoint_is_required(self):
stderr = self.run_cmd(cmd, expected_rc=255)[1]
self.assertIn('--endpoint-url is required', stderr)

def test_endpoint_not_required_for_help(self):
cmd = self.prefix + 'help'
with mock.patch('awscli.help.get_renderer') as get_renderer:
mock_render = mock.Mock(spec=HelpRenderer)
get_renderer.return_value = mock_render
stdout, stderr, rc = self.run_cmd(cmd, expected_rc=None)
# If we get this far we've succeeded, but we can do
# a quick sanity check and make sure the service name is
# in the stdout help text.
self.assertIn(stdout, 'cloudsearchdomain')


class TestCloudsearchDomainHandler(unittest.TestCase):
def test_validate_endpoint_url_is_none(self):
parsed_args = mock.Mock()
parsed_args.endpoint_url = None
parsed_args.command = 'cloudsearchdomain'
parsed_globals = mock.Mock()
parsed_globals.endpoint_url = None
with self.assertRaises(ValueError):
validate_endpoint_url(parsed_args)
validate_endpoint_url(parsed_globals)


if __name__ == "__main__":
Expand Down
10 changes: 8 additions & 2 deletions tests/unit/test_argprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,18 @@ def test_list_structure_list_scalar_3(self):
{"Name": "foo",
"Args": ["a", "k1=v1", "b"]},
{"Name": "bar",
"Args": ["baz"]}
"Args": ["baz"]},
{"Name": "single_kv",
"Args": ["key=value"]},
{"Name": "single_v",
"Args": ["value"]}
]

simplified = self.simplify(p, [
"Name=foo,Args=[a,k1=v1,b]",
"Name=bar,Args=baz"
"Name=bar,Args=baz",
"Name=single_kv,Args=[key=value]",
"Name=single_v,Args=[value]"
])

self.assertEqual(simplified, expected)
Expand Down
9 changes: 9 additions & 0 deletions tests/unit/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ def test_multiple_list_of_dicts(self):
'ZOO\t0\t1\t2\n'
)

def test_single_scalar_number(self):
self.assert_text_renders_to(10, '10\n')

def test_list_of_single_number(self):
self.assert_text_renders_to([10], '10\n')

def test_list_of_multiple_numbers(self):
self.assert_text_renders_to([10, 10, 10], '10\t10\t10\n')

def test_different_keys_in_sublists(self):
self.assert_text_renders_to(
# missing "b" adds "d"
Expand Down

0 comments on commit 3f48075

Please sign in to comment.