Skip to content

Commit

Permalink
Merge branch 'release-1.29.48'
Browse files Browse the repository at this point in the history
* release-1.29.48:
  Bumping version to 1.29.48
  Update changelog based on model updates
  Improve error messages for codeartifact login
  • Loading branch information
aws-sdk-python-automation committed Sep 14, 2023
2 parents d8240ed + f233a39 commit 017235a
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 64 deletions.
27 changes: 27 additions & 0 deletions .changes/1.29.48.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[
{
"category": "``codeartifact login``",
"description": "Include stderr output from underlying login tool when subprocess fails",
"type": "enhancement"
},
{
"category": "``appstream``",
"description": "This release introduces multi-session fleets, allowing customers to provision more than one user session on a single fleet instance.",
"type": "api-change"
},
{
"category": "``cloudformation``",
"description": "Documentation updates for AWS CloudFormation",
"type": "api-change"
},
{
"category": "``entityresolution``",
"description": "Changed \"ResolutionTechniques\" and \"MappedInputFields\" in workflow and schema mapping operations to be required fields.",
"type": "api-change"
},
{
"category": "``lookoutequipment``",
"description": "This release adds APIs for the new scheduled retraining feature.",
"type": "api-change"
}
]
10 changes: 10 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
CHANGELOG
=========

1.29.48
=======

* enhancement:``codeartifact login``: Include stderr output from underlying login tool when subprocess fails
* api-change:``appstream``: This release introduces multi-session fleets, allowing customers to provision more than one user session on a single fleet instance.
* api-change:``cloudformation``: Documentation updates for AWS CloudFormation
* api-change:``entityresolution``: Changed "ResolutionTechniques" and "MappedInputFields" in workflow and schema mapping operations to be required fields.
* api-change:``lookoutequipment``: This release adds APIs for the new scheduled retraining feature.


1.29.47
=======

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.29.47'
__version__ = '1.29.48'

#
# Get our data path to be added to botocore's search path
Expand Down
7 changes: 7 additions & 0 deletions awscli/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,13 @@ def get_stderr_text_writer():
return _get_text_writer(sys.stderr, errors="replace")


def get_stderr_encoding():
encoding = getattr(sys.__stderr__, 'encoding', None)
if encoding is None:
encoding = 'utf-8'
return encoding


def compat_input(prompt):
"""
Cygwin's pty's are based on pipes. Therefore, when it interacts with a Win32
Expand Down
28 changes: 20 additions & 8 deletions awscli/customizations/codeartifact/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from dateutil.relativedelta import relativedelta
from botocore.utils import parse_timestamp

from awscli.compat import is_windows, urlparse, RawConfigParser, StringIO
from awscli.compat import is_windows, urlparse, RawConfigParser, StringIO, get_stderr_encoding
from awscli.customizations import utils as cli_utils
from awscli.customizations.commands import BasicCommand
from awscli.customizations.utils import uni_print
Expand All @@ -34,6 +34,17 @@ def get_relative_expiration_time(remaining):
return message


class CommandFailedError(Exception):
def __init__(self, called_process_error):
msg = str(called_process_error)
if called_process_error.stderr is not None:
msg +=(
f' Stderr from command:\n'
f'{called_process_error.stderr.decode(get_stderr_encoding())}'
)
Exception.__init__(self, msg)


class BaseLogin(object):
_TOOL_NOT_FOUND_MESSAGE = '%s was not found. Please verify installation.'

Expand Down Expand Up @@ -84,14 +95,14 @@ def _run_commands(self, tool, commands, dry_run=False):

def _run_command(self, tool, command, *, ignore_errors=False):
try:
self.subprocess_utils.check_call(
self.subprocess_utils.run(
command,
stdout=self.subprocess_utils.PIPE,
stderr=self.subprocess_utils.PIPE
capture_output=True,
check=True
)
except subprocess.CalledProcessError as ex:
if not ignore_errors:
raise ex
raise CommandFailedError(ex)
except OSError as ex:
if ex.errno == errno.ENOENT:
raise ValueError(
Expand Down Expand Up @@ -153,13 +164,14 @@ def login(self, dry_run=False):
return

try:
self.subprocess_utils.check_output(
self.subprocess_utils.run(
command,
stderr=self.subprocess_utils.PIPE
capture_output=True,
check=True
)
except subprocess.CalledProcessError as e:
uni_print('Failed to update the NuGet.Config\n')
raise e
raise CommandFailedError(e)

uni_print(source_configured_message % source_name)
self._write_success_message('nuget')
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.29.'
# The full version, including alpha/beta/rc tags.
release = '1.29.47'
release = '1.29.48'

# 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.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ universal = 0

[metadata]
requires_dist =
botocore==1.31.47
botocore==1.31.48
docutils>=0.10,<0.17
s3transfer>=0.6.0,<0.7.0
PyYAML>=3.10,<6.1
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def find_version(*file_paths):


install_requires = [
'botocore==1.31.47',
'botocore==1.31.48',
'docutils>=0.10,<0.17',
's3transfer>=0.6.0,<0.7.0',
'PyYAML>=3.10,<6.1',
Expand Down
25 changes: 13 additions & 12 deletions tests/functional/codeartifact/test_codeartifact_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def setUp(self):
self.pypi_rc_path_mock = self.pypi_rc_path_patch.start()
self.pypi_rc_path_mock.return_value = self.test_pypi_rc_path

self.subprocess_patch = mock.patch('subprocess.check_call')
self.subprocess_patch = mock.patch('subprocess.run')
self.subprocess_mock = self.subprocess_patch.start()
self.subprocess_check_output_patch = mock.patch(
'subprocess.check_output'
Expand All @@ -51,6 +51,7 @@ def setUp(self):

def tearDown(self):
self.pypi_rc_path_patch.stop()
self.subprocess_check_output_patch.stop()
self.subprocess_patch.stop()
self.file_creator.remove_all()

Expand Down Expand Up @@ -274,8 +275,8 @@ def _assert_subprocess_execution(self, commands):
expected_calls = [
mock.call(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
capture_output=True,
check=True
) for command in commands
]
self.subprocess_mock.assert_has_calls(
Expand Down Expand Up @@ -336,7 +337,7 @@ def test_nuget_login_without_domain_owner_without_duration_seconds(self):
self.assertEqual(result.rc, 0)
self._assert_operations_called(package_format='nuget', result=result)
self._assert_expiration_printed_to_stdout(result.stdout)
self._assert_subprocess_check_output_execution(
self._assert_subprocess_execution(
self._get_nuget_commands()
)

Expand All @@ -350,7 +351,7 @@ def test_nuget_login_with_domain_owner_without_duration_seconds(self):
result=result
)
self._assert_expiration_printed_to_stdout(result.stdout)
self._assert_subprocess_check_output_execution(
self._assert_subprocess_execution(
self._get_nuget_commands()
)

Expand All @@ -364,7 +365,7 @@ def test_nuget_login_without_domain_owner_with_duration_seconds(self):
result=result
)
self._assert_expiration_printed_to_stdout(result.stdout)
self._assert_subprocess_check_output_execution(
self._assert_subprocess_execution(
self._get_nuget_commands()
)

Expand All @@ -383,7 +384,7 @@ def test_nuget_login_with_domain_owner_duration_sections(self):
result=result
)
self._assert_expiration_printed_to_stdout(result.stdout)
self._assert_subprocess_check_output_execution(
self._assert_subprocess_execution(
self._get_nuget_commands()
)

Expand Down Expand Up @@ -454,7 +455,7 @@ def test_dotnet_login_without_domain_owner_without_duration_seconds(self):
self.assertEqual(result.rc, 0)
self._assert_operations_called(package_format='nuget', result=result)
self._assert_expiration_printed_to_stdout(result.stdout)
self._assert_subprocess_check_output_execution(
self._assert_subprocess_execution(
self._get_dotnet_commands()
)

Expand All @@ -469,7 +470,7 @@ def test_dotnet_login_with_domain_owner_without_duration_seconds(self):
result=result
)
self._assert_expiration_printed_to_stdout(result.stdout)
self._assert_subprocess_check_output_execution(
self._assert_subprocess_execution(
self._get_dotnet_commands()
)

Expand All @@ -484,7 +485,7 @@ def test_dotnet_login_without_domain_owner_with_duration_seconds(self):
result=result
)
self._assert_expiration_printed_to_stdout(result.stdout)
self._assert_subprocess_check_output_execution(
self._assert_subprocess_execution(
self._get_dotnet_commands()
)

Expand All @@ -504,7 +505,7 @@ def test_dotnet_login_with_domain_owner_duration_sections(self):
result=result
)
self._assert_expiration_printed_to_stdout(result.stdout)
self._assert_subprocess_check_output_execution(
self._assert_subprocess_execution(
self._get_dotnet_commands()
)

Expand Down Expand Up @@ -623,7 +624,7 @@ def test_npm_login_always_auth_error_ignored(self):
exit code. This is to make sure that login ignores that error and all
other commands executes successfully.
"""
def side_effect(command, stdout, stderr):
def side_effect(command, capture_output, check):
if any('always-auth' in arg for arg in command):
raise subprocess.CalledProcessError(
returncode=1,
Expand Down

0 comments on commit 017235a

Please sign in to comment.