diff --git a/requirements/base.txt b/requirements/base.txt index e351d186eb6a..4fe8481b6f11 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -11,4 +11,4 @@ docker>=3.3.0 dateparser~=0.7 python-dateutil~=2.6 pathlib2~=2.3.2; python_version<"3.4" -aws_lambda_builders==0.0.2-dev +aws_lambda_builders==0.0.2 diff --git a/samcli/cli/main.py b/samcli/cli/main.py index 58b6a91aac94..66127aa8b951 100644 --- a/samcli/cli/main.py +++ b/samcli/cli/main.py @@ -3,6 +3,7 @@ """ import logging +import json import click from samcli import __version__ @@ -36,9 +37,21 @@ def aws_creds_options(f): return f +def print_info(ctx, param, value): + if not value or ctx.resilient_parsing: + return + + click.echo(json.dumps({ + "version": __version__ + }, indent=2)) + + ctx.exit() + + @click.command(cls=BaseCommand) @common_options @click.version_option(version=__version__, prog_name="SAM CLI") +@click.option("--info", is_flag=True, is_eager=True, callback=print_info, expose_value=False) @pass_context def cli(ctx): """ diff --git a/samcli/commands/build/command.py b/samcli/commands/build/command.py index c0577c5274ab..eb9eb80bd2ec 100644 --- a/samcli/commands/build/command.py +++ b/samcli/commands/build/command.py @@ -17,9 +17,11 @@ LOG = logging.getLogger(__name__) +DEFAULT_BUILD_DIR = os.path.join(".aws-sam", "build") HELP_TEXT = """ -Use this command to build your AWS Lambda Functions source code to generate artifacts that can run on AWS Lambda.\n +Use this command to build your AWS Lambda Functions source code to generate artifacts that target AWS Lambda's +execution environment.\n \b Supported Resource Types ------------------------ @@ -31,10 +33,10 @@ 1. Python2.7\n 2. Python3.6\n \b -Usage ------ -In your SAM template, specify the path to your function's source code -in the resource's Code or CodeUri property. +Examples +-------- +To use this command, update your SAM template to specify the path +to your function's source code in the resource's Code or CodeUri property. \b To build on your workstation, run this command in folder containing SAM template. Built artifacts will be written to .aws-sam/build folder @@ -47,24 +49,25 @@ $ sam build && sam local invoke \b To build and package for deployment -$ sam build && sam package +$ sam build && sam package --s3-bucket """ @click.command("build", help=HELP_TEXT, short_help="Build your Lambda function code") @click.option('--build-dir', '-b', - default=os.path.join(".aws-sam", "build"), + default=DEFAULT_BUILD_DIR, type=click.Path(file_okay=False, dir_okay=True, writable=True), # Must be a directory help="Path to a folder where the built artifacts will be stored") @click.option("--base-dir", "-s", default=None, type=click.Path(dir_okay=True, file_okay=False), # Must be a directory help="Resolve relative paths to function's source code with respect to this folder. Use this if " - "SAM template and your source code are not in same enclosing folder. By default, relative paths to" + "SAM template and your source code are not in same enclosing folder. By default, relative paths " "are resolved with respect to the SAM template's location") -@click.option("--use-container", +@click.option("--use-container", "-u", is_flag=True, - help="Run the builds inside a Docker container that simulates an AWS Lambda like environment") + help="If your functions depend on packages that have natively compiled dependencies, use this flag " + "to build your function inside an AWS Lambda-like Docker container") @click.option("--manifest", "-m", default=None, type=click.Path(), @@ -133,19 +136,39 @@ def do_cli(template, # pylint: disable=too-many-locals with open(ctx.output_template_path, "w") as fp: fp.write(yaml_dump(modified_template)) - msg = """\nBuild Artifacts Available At: {artifacts_dir} - -Next Steps -========== -[*] Invoke Function: sam local invoke -t {template} -[*] Package: sam package --template-file {template} - """.format(artifacts_dir=os.path.relpath(ctx.build_dir), - template=os.path.relpath(ctx.output_template_path)) - click.secho("\nBuild Succeeded", fg="green") + msg = gen_success_msg(os.path.relpath(ctx.build_dir), + os.path.relpath(ctx.output_template_path), + os.path.abspath(ctx.build_dir) == os.path.abspath(DEFAULT_BUILD_DIR)) + click.secho(msg, fg="yellow") except (UnsupportedRuntimeException, BuildError, UnsupportedBuilderLibraryVersionError) as ex: click.secho("Build Failed", fg="red") raise UserException(str(ex)) + + +def gen_success_msg(artifacts_dir, output_template_path, is_default_build_dir): + + invoke_cmd = "sam local invoke" + if not is_default_build_dir: + invoke_cmd += " -t {}".format(output_template_path) + + package_cmd = "sam package --s3-bucket " + if not is_default_build_dir: + package_cmd += " --template-file {}".format(output_template_path) + + msg = """\nBuilt Artifacts : {artifacts_dir} +Built Template : {template} + +Commands you can use next +========================= +[*] Invoke Function: {invokecmd} +[*] Package: {packagecmd} + """.format(invokecmd=invoke_cmd, + packagecmd=package_cmd, + artifacts_dir=artifacts_dir, + template=output_template_path) + + return msg diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index ee90d9b6000b..8b15cef8ec23 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -16,18 +16,18 @@ class TestBuildCommand_PythonFunctions(BuildIntegBase): EXPECTED_FILES_GLOBAL_MANIFEST = set() - EXPECTED_FILES_PROJECT_MANIFEST = {'__init__.py', 'main.py', 'numpy', 'cryptography', "jinja2", + EXPECTED_FILES_PROJECT_MANIFEST = {'__init__.py', 'main.py', 'numpy', + # 'cryptography', + "jinja2", 'requirements.txt'} FUNCTION_LOGICAL_ID = "PythonFunction" @parameterized.expand([ ("python2.7", False), - ("python3.6", False) - - # FIXME: Turning off Container build tests until official Docker Container is published - # ("python2.7", "use_container"), - # ("python3.6", "use_container"), + ("python3.6", False), + ("python2.7", "use_container"), + ("python3.6", "use_container"), ]) def test_with_default_requirements(self, runtime, use_container): diff --git a/tests/integration/testdata/buildcmd/Python/main.py b/tests/integration/testdata/buildcmd/Python/main.py index 3800cf819a8f..fe02bd097ebb 100644 --- a/tests/integration/testdata/buildcmd/Python/main.py +++ b/tests/integration/testdata/buildcmd/Python/main.py @@ -1,12 +1,12 @@ import numpy -from cryptography.fernet import Fernet +# from cryptography.fernet import Fernet from jinja2 import Template def handler(event, context): # Try using some of the modules to make sure they work & don't crash the process - print(Fernet.generate_key()) + # print(Fernet.generate_key()) template = Template('Hello {{ name }}') diff --git a/tests/integration/testdata/buildcmd/Python/requirements.txt b/tests/integration/testdata/buildcmd/Python/requirements.txt index ffa4678cc53f..74a5095ee35d 100644 --- a/tests/integration/testdata/buildcmd/Python/requirements.txt +++ b/tests/integration/testdata/buildcmd/Python/requirements.txt @@ -1,5 +1,7 @@ # These are some hard packages to build. Using them here helps us verify that building works on various platforms numpy~=1.15 -cryptography~=2.4 +# `cryptography` has a dependency on `pycparser` which, for some reason doesn't build inside a Docker container. +# Turning this off until we resolve this issue: https://github.com/awslabs/aws-lambda-builders/issues/29 +# cryptography~=2.4 Jinja2~=2.10