Skip to content

Receive namespace and codegen_model flags from the cli #309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 40 additions & 21 deletions python/rpdk/java/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@
from xml.etree.ElementTree import ParseError # nosec

from rpdk.core.data_loaders import resource_stream
from rpdk.core.exceptions import InternalError, SysExitRecommendedError
from rpdk.core.init import input_with_validation
from rpdk.core.exceptions import (
InternalError,
SysExitRecommendedError,
WizardValidationError,
)
from rpdk.core.init import input_with_validation, print_error
from rpdk.core.jsonutils.resolver import resolve_models
from rpdk.core.plugin_base import LanguagePlugin

from .resolver import translate_type
from .utils import safe_reserved, validate_codegen_model, validate_namespace
from .utils import (
get_default_namespace,
safe_reserved,
validate_codegen_model,
validate_namespace,
)

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -76,7 +85,7 @@ def __init__(self):
self.env = self._setup_jinja_env(
trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True
)
self.codegen_template_path = None
self.codegen_model = None
self.env.filters["translate_type"] = translate_type
self.env.filters["safe_reserved"] = safe_reserved
self.namespace = None
Expand All @@ -95,42 +104,52 @@ def _namespace_from_project(self, project):
self.package_name = ".".join(self.namespace)

def _prompt_for_namespace(self, project):
if project.type_info[0] == "AWS":
namespace = ("software", "amazon") + project.type_info[1:]
else:
namespace = ("com",) + project.type_info

namespace = tuple(safe_reserved(s.lower()) for s in namespace)
default_namespace = get_default_namespace(project)
settings_namespace = project.settings.get("namespace")

prompt = "Enter a package name (empty for default '{}'): ".format(
".".join(namespace)
".".join(default_namespace)
)

self.namespace = input_with_validation(prompt, validate_namespace(namespace))
namespace_validator = validate_namespace(default_namespace)

if settings_namespace == "default":
self.namespace = default_namespace
elif settings_namespace:
try:
self.namespace = namespace_validator(settings_namespace)
except WizardValidationError as error:
print_error(error)
self.namespace = input_with_validation(prompt, namespace_validator)
else:
self.namespace = input_with_validation(prompt, namespace_validator)

project.settings["namespace"] = self.namespace
self.package_name = ".".join(self.namespace)

@staticmethod
def _prompt_for_codegen_model(project):
prompt = "Choose codegen model - 1 (default) or 2 (guided-aws): "
codegen_model = project.settings.get("codegen_model")
if not codegen_model:
prompt = "Choose codegen model - 1 (default) or 2 (guided-aws): "

codegen_model = input_with_validation(
prompt, validate_codegen_model(CODEGEN.default_code)
)
codegen_model_code = input_with_validation(
prompt, validate_codegen_model(CODEGEN.default_code)
)

project.settings["codegen_template_path"] = CODEGEN.default
project.settings["codegen_model"] = CODEGEN.default

if codegen_model == CODEGEN.guided_code:
project.settings["codegen_template_path"] = CODEGEN.guided
if codegen_model_code == CODEGEN.guided_code:
project.settings["codegen_model"] = CODEGEN.guided

def _get_template(self, project, stage, name):
return self.env.get_template(
stage + "/" + project.settings["codegen_template_path"] + "/" + name
stage + "/" + project.settings["codegen_model"] + "/" + name
)

@staticmethod
def _is_aws_guided(project: object) -> bool:
return project.settings["codegen_template_path"] == CODEGEN.guided
return project.settings["codegen_model"] == CODEGEN.guided

@logdebug
def _writing_component(
Expand Down
25 changes: 25 additions & 0 deletions python/rpdk/java/parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
def setup_subparser(subparsers, parents):
parser = subparsers.add_parser(
"java",
description="This sub command generates IDE and build files for Java",
parents=parents,
)
parser.set_defaults(language="java")

parser.add_argument(
"-n",
"--namespace",
nargs="?",
const="default",
help="""Select the name of the Java namespace.
Passing the flag without argument select the default namespace.""",
)

parser.add_argument(
"-c",
"--codegen-model",
choices=["default", "guided_aws"],
help="Select a codegen model.",
)

return parser
10 changes: 10 additions & 0 deletions python/rpdk/java/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ def safe_reserved(token):
return token


def get_default_namespace(project):
if project.type_info[0] == "AWS":
namespace = ("software", "amazon") + project.type_info[1:]
else:
namespace = ("com",) + project.type_info

namespace = tuple(safe_reserved(s.lower()) for s in namespace)
return namespace


def validate_namespace(default):
pattern = r"^[_a-z][_a-z0-9]+$"

Expand Down
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ def find_version(*file_paths):
zip_safe=True,
install_requires=["cloudformation-cli>=0.1.4,<0.2"],
python_requires=">=3.6",
entry_points={"rpdk.v1.languages": ["java = rpdk.java.codegen:JavaLanguagePlugin"]},
entry_points={
"rpdk.v1.languages": ["java = rpdk.java.codegen:JavaLanguagePlugin"],
"rpdk.v1.parsers": ["java = rpdk.java.parser:setup_subparser"],
},
license="Apache License 2.0",
classifiers=[
"Development Status :: 5 - Production/Stable",
Expand Down
96 changes: 85 additions & 11 deletions tests/test_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ def mock_input_with_validation(prompt, validate): # pylint: disable=unused-argu
{"test": lambda: JavaLanguagePlugin},
clear=True,
), patch("rpdk.java.codegen.input_with_validation", new=mock_cli):
project.init("AWS::Foo::{}".format(RESOURCE), "test")
project.init(
"AWS::Foo::{}".format(RESOURCE),
"test",
{"namespace": None, "codegen_model": None},
)
return project


Expand Down Expand Up @@ -201,7 +205,7 @@ def test_package(project):


def test__prompt_for_namespace_aws_default():
project = Mock(type_info=("AWS", "Clown", "Service"), settings={})
project = Mock(type_info=("AWS", "Clown", "Service"), settings={"namespace": None})
plugin = JavaLanguagePlugin()

with patch("rpdk.core.init.input", return_value="") as mock_input:
Expand All @@ -213,7 +217,7 @@ def test__prompt_for_namespace_aws_default():


def test__prompt_for_namespace_aws_overwritten():
project = Mock(type_info=("AWS", "Clown", "Service"), settings={})
project = Mock(type_info=("AWS", "Clown", "Service"), settings={"namespace": None})
plugin = JavaLanguagePlugin()

with patch(
Expand All @@ -227,7 +231,9 @@ def test__prompt_for_namespace_aws_overwritten():


def test__prompt_for_namespace_other_default():
project = Mock(type_info=("Balloon", "Clown", "Service"), settings={})
project = Mock(
type_info=("Balloon", "Clown", "Service"), settings={"namespace": None}
)
plugin = JavaLanguagePlugin()

with patch("rpdk.core.init.input", return_value="") as mock_input:
Expand All @@ -239,7 +245,55 @@ def test__prompt_for_namespace_other_default():


def test__prompt_for_namespace_other_overwritten():
project = Mock(type_info=("Balloon", "Clown", "Service"), settings={})
project = Mock(
type_info=("Balloon", "Clown", "Service"), settings={"namespace": None}
)
plugin = JavaLanguagePlugin()

with patch(
"rpdk.core.init.input", return_value="com.ball.clown.service"
) as mock_input:
plugin._prompt_for_namespace(project)

mock_input.assert_called_once()

assert project.settings == {"namespace": ("com", "ball", "clown", "service")}


def test__prompt_for_namespace_default_provided():
project = Mock(
type_info=("Balloon", "Clown", "Service"), settings={"namespace": "default"}
)
plugin = JavaLanguagePlugin()

with patch("rpdk.core.init.input") as mock_input:
plugin._prompt_for_namespace(project)

mock_input.assert_not_called()

assert project.settings == {"namespace": ("com", "balloon", "clown", "service")}


def test__prompt_for_namespace_valid_provided():
project = Mock(
type_info=("Balloon", "Clown", "Service"),
settings={"namespace": "com.valid.namespace"},
)
plugin = JavaLanguagePlugin()

with patch("rpdk.core.init.input") as mock_input:
plugin._prompt_for_namespace(project)

mock_input.assert_not_called()

assert project.settings == {"namespace": ("com", "valid", "namespace")}


def test__prompt_for_namespace_invalid_provided():
project = Mock(
type_info=("Balloon", "Clown", "Service"),
settings={"namespace": "com.Invalid.Namespace"},
)
plugin = JavaLanguagePlugin()

with patch(
Expand Down Expand Up @@ -271,40 +325,60 @@ def test__namespace_from_project_old_settings():
assert plugin.package_name == "com.balloon.clown.service"


def test__prompt_for_codegen_model_provided():
project = Mock(
type_info=("AWS", "Clown", "Service"), settings={"codegen_model": "default"}
)
plugin = JavaLanguagePlugin()

with patch("rpdk.core.init.input") as mock_input:
plugin._prompt_for_codegen_model(project)

mock_input.assert_not_called()

assert project.settings == {"codegen_model": "default"}


def test__prompt_for_codegen_model_no_selection():
project = Mock(type_info=("AWS", "Clown", "Service"), settings={})
project = Mock(
type_info=("AWS", "Clown", "Service"), settings={"codegen_model": None}
)
plugin = JavaLanguagePlugin()

with patch("rpdk.core.init.input", return_value="") as mock_input:
plugin._prompt_for_codegen_model(project)

mock_input.assert_called_once()

assert project.settings == {"codegen_template_path": "default"}
assert project.settings == {"codegen_model": "default"}


def test__prompt_for_codegen_model_default():
project = Mock(type_info=("AWS", "Clown", "Service"), settings={})
project = Mock(
type_info=("AWS", "Clown", "Service"), settings={"codegen_model": None}
)
plugin = JavaLanguagePlugin()

with patch("rpdk.core.init.input", return_value="1") as mock_input:
plugin._prompt_for_codegen_model(project)

mock_input.assert_called_once()

assert project.settings == {"codegen_template_path": "default"}
assert project.settings == {"codegen_model": "default"}


def test__prompt_for_codegen_model_guided_aws():
project = Mock(type_info=("AWS", "Clown", "Service"), settings={})
project = Mock(
type_info=("AWS", "Clown", "Service"), settings={"codegen_model": None}
)
plugin = JavaLanguagePlugin()

with patch("rpdk.core.init.input", return_value="2") as mock_input:
plugin._prompt_for_codegen_model(project)

mock_input.assert_called_once()

assert project.settings == {"codegen_template_path": "guided_aws"}
assert project.settings == {"codegen_model": "guided_aws"}


def test_generate_image_build_config(project):
Expand Down
16 changes: 16 additions & 0 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import argparse

from rpdk.java.parser import setup_subparser


def test_setup_subparser():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="subparser_name")

sub_parser = setup_subparser(subparsers, [])

args = sub_parser.parse_args(["--namespace", "com.foo.bar", "-c", "default"])

assert args.language == "java"
assert args.namespace == "com.foo.bar"
assert args.codegen_model == "default"