Skip to content

Commit afce048

Browse files
authored
Merge pull request #882 from awslabs/develop
chore: Release v0.10.0
2 parents 7e08351 + f6f55bb commit afce048

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1281
-156
lines changed

requirements/base.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ docker>=3.3.0
1111
dateparser~=0.7
1212
python-dateutil~=2.6
1313
pathlib2~=2.3.2; python_version<"3.4"
14-
requests~=2.20.0
15-
aws_lambda_builders==0.0.4
14+
requests==2.20.1
15+
aws_lambda_builders==0.0.5
16+
serverlessrepo==0.1.5

requirements/dev.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ pylint==1.7.2
1010
pytest==3.0.7
1111
py==1.4.33
1212
mock==2.0.0
13-
requests==2.20.0
1413
parameterized==0.6.1
1514
pathlib2==2.3.2; python_version<"3.4"
1615
futures==3.2.0; python_version<"3.2.3"

samcli/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
SAM CLI version
33
"""
44

5-
__version__ = '0.9.0'
5+
__version__ = '0.10.0'

samcli/cli/command.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"samcli.commands.deploy",
1717
"samcli.commands.package",
1818
"samcli.commands.logs",
19-
"samcli.commands.build"
19+
"samcli.commands.build",
20+
"samcli.commands.publish"
2021
}
2122

2223

samcli/commands/local/cli_common/invoke_context.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os
88

99
import samcli.lib.utils.osutils as osutils
10+
from samcli.lib.utils.stream_writer import StreamWriter
1011
from samcli.commands.local.lib.local_lambda import LocalLambdaRunner
1112
from samcli.commands.local.lib.debug_context import DebugContext
1213
from samcli.local.lambdafn.runtime import LambdaRuntime
@@ -202,26 +203,28 @@ def local_lambda_runner(self):
202203
@property
203204
def stdout(self):
204205
"""
205-
Returns a stdout stream to output Lambda function logs to
206+
Returns stream writer for stdout to output Lambda function logs to
206207
207-
:return File like object: Stream where the output of the function is sent to
208+
Returns
209+
-------
210+
samcli.lib.utils.stream_writer.StreamWriter
211+
Stream writer for stdout
208212
"""
209-
if self._log_file_handle:
210-
return self._log_file_handle
211-
212-
return osutils.stdout()
213+
stream = self._log_file_handle if self._log_file_handle else osutils.stdout()
214+
return StreamWriter(stream, self._is_debugging)
213215

214216
@property
215217
def stderr(self):
216218
"""
217-
Returns stderr stream to output Lambda function errors to
219+
Returns stream writer for stderr to output Lambda function errors to
218220
219-
:return File like object: Stream where the stderr of the function is sent to
221+
Returns
222+
-------
223+
samcli.lib.utils.stream_writer.StreamWriter
224+
Stream writer for stderr
220225
"""
221-
if self._log_file_handle:
222-
return self._log_file_handle
223-
224-
return osutils.stderr()
226+
stream = self._log_file_handle if self._log_file_handle else osutils.stderr()
227+
return StreamWriter(stream, self._is_debugging)
225228

226229
@property
227230
def template(self):
@@ -256,6 +259,10 @@ def parameter_overrides(self):
256259

257260
return self._parameter_overrides
258261

262+
@property
263+
def _is_debugging(self):
264+
return bool(self._debug_context)
265+
259266
@staticmethod
260267
def _get_template_data(template_file):
261268
"""

samcli/commands/local/lib/debug_context.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""
22
Information and debug options for a specific runtime.
33
"""
4-
import os
54

65

76
class DebugContext(object):
@@ -14,8 +13,6 @@ def __init__(self,
1413
self.debug_port = debug_port
1514
self.debugger_path = debugger_path
1615
self.debug_args = debug_args
17-
if self.debug_port:
18-
os.environ["PYTHONUNBUFFERED"] = "1"
1916

2017
def __bool__(self):
2118
return bool(self.debug_port)

samcli/commands/local/lib/local_lambda.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,21 @@ def invoke(self, function_name, event, stdout=None, stderr=None):
5353
5454
This function will block until either the function completes or times out.
5555
56-
:param string function_name: Name of the Lambda function to invoke
57-
:param string event: Event data passed to the function. Must be a valid JSON String.
58-
:param io.BaseIO stdout: Stream to write the output of the Lambda function to.
59-
:param io.BaseIO stderr: Stream to write the Lambda runtime logs to.
60-
:raises FunctionNotfound: When we cannot find a function with the given name
56+
Parameters
57+
----------
58+
function_name str
59+
Name of the Lambda function to invoke
60+
event str
61+
Event data passed to the function. Must be a valid JSON String.
62+
stdout samcli.lib.utils.stream_writer.StreamWriter
63+
Stream writer to write the output of the Lambda function to.
64+
stderr samcli.lib.utils.stream_writer.StreamWriter
65+
Stream writer to write the Lambda runtime logs to.
66+
67+
Raises
68+
------
69+
FunctionNotfound
70+
When we cannot find a function with the given name
6171
"""
6272

6373
# Generate the correct configuration based on given inputs
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"""`sam publish` command."""
2+
3+
# Expose the cli object here
4+
from .command import cli # noqa

samcli/commands/publish/command.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
"""CLI command for "publish" command."""
2+
3+
import json
4+
5+
import click
6+
import boto3
7+
from botocore.exceptions import ClientError
8+
from serverlessrepo import publish_application
9+
from serverlessrepo.publish import CREATE_APPLICATION
10+
from serverlessrepo.exceptions import ServerlessRepoError
11+
12+
from samcli.cli.main import pass_context, common_options as cli_framework_options, aws_creds_options
13+
from samcli.commands._utils.options import template_common_option
14+
from samcli.commands._utils.template import get_template_data
15+
from samcli.commands.exceptions import UserException
16+
17+
HELP_TEXT = """
18+
Use this command to publish a packaged AWS SAM template to
19+
the AWS Serverless Application Repository to share within your team,
20+
across your organization, or with the community at large.\n
21+
\b
22+
This command expects the template's Metadata section to contain an
23+
AWS::ServerlessRepo::Application section with application metadata
24+
for publishing. For more details on this metadata section, see
25+
https://docs.aws.amazon.com/serverlessrepo/latest/devguide/serverless-app-publishing-applications.html
26+
\b
27+
Examples
28+
--------
29+
To publish an application
30+
$ sam publish -t packaged.yaml --region <region>
31+
"""
32+
SHORT_HELP = "Publish a packaged AWS SAM template to the AWS Serverless Application Repository."
33+
SERVERLESSREPO_CONSOLE_URL = "https://console.aws.amazon.com/serverlessrepo/home?region={}#/published-applications/{}"
34+
35+
36+
@click.command("publish", help=HELP_TEXT, short_help=SHORT_HELP)
37+
@template_common_option
38+
@aws_creds_options
39+
@cli_framework_options
40+
@pass_context
41+
def cli(ctx, template):
42+
# All logic must be implemented in the ``do_cli`` method. This helps with easy unit testing
43+
44+
do_cli(ctx, template) # pragma: no cover
45+
46+
47+
def do_cli(ctx, template):
48+
"""Publish the application based on command line inputs."""
49+
try:
50+
template_data = get_template_data(template)
51+
except ValueError as ex:
52+
click.secho("Publish Failed", fg='red')
53+
raise UserException(str(ex))
54+
55+
try:
56+
publish_output = publish_application(template_data)
57+
click.secho("Publish Succeeded", fg="green")
58+
click.secho(_gen_success_message(publish_output), fg="yellow")
59+
except ServerlessRepoError as ex:
60+
click.secho("Publish Failed", fg='red')
61+
raise UserException(str(ex))
62+
except ClientError as ex:
63+
click.secho("Publish Failed", fg='red')
64+
raise _wrap_s3_uri_exception(ex)
65+
66+
application_id = publish_output.get('application_id')
67+
_print_console_link(ctx.region, application_id)
68+
69+
70+
def _gen_success_message(publish_output):
71+
"""
72+
Generate detailed success message for published applications.
73+
74+
Parameters
75+
----------
76+
publish_output : dict
77+
Output from serverlessrepo publish_application
78+
79+
Returns
80+
-------
81+
str
82+
Detailed success message
83+
"""
84+
application_id = publish_output.get('application_id')
85+
details = json.dumps(publish_output.get('details'), indent=2)
86+
87+
if CREATE_APPLICATION in publish_output.get('actions'):
88+
return "Created new application with the following metadata:\n{}".format(details)
89+
90+
return 'The following metadata of application "{}" has been updated:\n{}'.format(application_id, details)
91+
92+
93+
def _print_console_link(region, application_id):
94+
"""
95+
Print link for the application in AWS Serverless Application Repository console.
96+
97+
Parameters
98+
----------
99+
region : str
100+
AWS region name
101+
application_id : str
102+
The Amazon Resource Name (ARN) of the application
103+
104+
"""
105+
if not region:
106+
region = boto3.Session().region_name
107+
108+
console_link = SERVERLESSREPO_CONSOLE_URL.format(region, application_id.replace('/', '~'))
109+
msg = "Click the link below to view your application in AWS console:\n{}".format(console_link)
110+
click.secho(msg, fg="yellow")
111+
112+
113+
def _wrap_s3_uri_exception(ex):
114+
"""
115+
Wrap invalid S3 URI exception with a better error message.
116+
117+
Parameters
118+
----------
119+
ex : ClientError
120+
boto3 exception
121+
122+
Returns
123+
-------
124+
Exception
125+
UserException if found invalid S3 URI or ClientError
126+
"""
127+
error_code = ex.response.get('Error').get('Code')
128+
message = ex.response.get('Error').get('Message')
129+
130+
if error_code == 'BadRequestException' and "Invalid S3 URI" in message:
131+
return UserException(
132+
"Your SAM template contains invalid S3 URIs. Please make sure that you have uploaded application "
133+
"artifacts to S3 by packaging the template: 'sam package --template-file <file-path>'.")
134+
135+
return ex

samcli/lib/build/app_builder.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ def _get_workflow_config(runtime):
5757
dependency_manager="npm",
5858
application_framework=None,
5959
manifest_name="package.json")
60+
elif runtime.startswith("ruby"):
61+
return config(
62+
language="ruby",
63+
dependency_manager="bundler",
64+
application_framework=None,
65+
manifest_name="Gemfile")
6066
else:
6167
raise UnsupportedRuntimeException("'{}' runtime is not supported".format(runtime))
6268

0 commit comments

Comments
 (0)