-
Notifications
You must be signed in to change notification settings - Fork 166
Support CLI arguments for cfn init #574
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
Changes from 11 commits
affbc86
a82e90f
bd16519
9df29ad
250a5f8
08ecbd2
ff86042
ebceecf
f7f54e6
5d80586
906b630
f4381b5
90a5393
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,22 @@ | |
for entry_point in pkg_resources.iter_entry_points("rpdk.v1.languages") | ||
} | ||
|
||
PLUGIN_CHOICES = sorted(PLUGIN_REGISTRY.keys()) | ||
|
||
def get_plugin_choices(): | ||
plugin_choices = [ | ||
entry_point.name | ||
for entry_point in pkg_resources.iter_entry_points("rpdk.v1.languages") | ||
] | ||
Comment on lines
+10
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would use set if you dont rely on element position There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before my changes the list of plugins was already being sorted which converts the set back to a list. I f this is not required anymore I'll be ok with making it a set. |
||
return sorted(plugin_choices) | ||
|
||
|
||
def get_parsers(): | ||
parsers = { | ||
entry_point.name: entry_point.load | ||
for entry_point in pkg_resources.iter_entry_points("rpdk.v1.parsers") | ||
} | ||
|
||
return parsers | ||
|
||
|
||
def load_plugin(language): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,13 @@ | ||
from pathlib import Path | ||
from unittest.mock import ANY, Mock, PropertyMock, patch | ||
|
||
import pytest | ||
|
||
from rpdk.core.cli import main | ||
from rpdk.core.exceptions import WizardAbortError, WizardValidationError | ||
from rpdk.core.init import ( | ||
ValidatePluginChoice, | ||
check_for_existing_project, | ||
ignore_abort, | ||
init, | ||
input_language, | ||
input_typename, | ||
input_with_validation, | ||
|
@@ -17,62 +16,93 @@ | |
) | ||
from rpdk.core.project import Project | ||
|
||
from .utils import add_dummy_language_plugin, dummy_parser, get_args, get_mock_project | ||
|
||
PROMPT = "MECVGD" | ||
ERROR = "TUJFEL" | ||
|
||
|
||
def test_init_method_interactive_language(): | ||
def test_init_method_interactive(): | ||
type_name = object() | ||
language = object() | ||
|
||
args = Mock(spec_set=["force", "language"]) | ||
args.force = False | ||
args.language = None | ||
|
||
mock_project = Mock(spec=Project) | ||
mock_project.load_settings.side_effect = FileNotFoundError | ||
mock_project.settings_path = "" | ||
mock_project.root = Path(".") | ||
args = get_args(interactive=True) | ||
|
||
mock_project, patch_project = get_mock_project() | ||
|
||
patch_project = patch("rpdk.core.init.Project", return_value=mock_project) | ||
patch_tn = patch("rpdk.core.init.input_typename", return_value=type_name) | ||
patch_l = patch("rpdk.core.init.input_language", return_value=language) | ||
|
||
with patch_project, patch_tn as mock_tn, patch_l as mock_l: | ||
init(args) | ||
main(args_in=["init"]) | ||
|
||
mock_tn.assert_called_once_with() | ||
mock_l.assert_called_once_with() | ||
|
||
mock_project.load_settings.assert_called_once_with() | ||
mock_project.init.assert_called_once_with(type_name, language) | ||
mock_project.init.assert_called_once_with( | ||
type_name, | ||
language, | ||
args.settings, | ||
) | ||
mock_project.generate.assert_called_once_with() | ||
|
||
|
||
def test_init_method_noninteractive_language(): | ||
type_name = object() | ||
def test_init_method_noninteractive(): | ||
add_dummy_language_plugin() | ||
|
||
args = get_args() | ||
mock_project, patch_project = get_mock_project() | ||
|
||
patch_tn = patch("rpdk.core.init.input_typename") | ||
|
||
patch_l = patch("rpdk.core.init.input_language") | ||
|
||
patch_get_parser = patch( | ||
"rpdk.core.init.get_parsers", return_value={"dummy": dummy_parser} | ||
) | ||
|
||
# pylint: disable=C0301 | ||
with patch_project, patch_tn as mock_tn, patch_l as mock_l, patch_get_parser as mock_parser: # noqa: B950 | ||
main(args_in=["init", "--type-name", args.type_name, args.language, "--dummy"]) | ||
|
||
mock_tn.assert_not_called() | ||
mock_l.assert_not_called() | ||
mock_parser.assert_called_once() | ||
|
||
mock_project.load_settings.assert_called_once_with() | ||
mock_project.init.assert_called_once_with( | ||
args.type_name, | ||
args.language, | ||
args.settings, | ||
|
||
) | ||
mock_project.generate.assert_called_once_with() | ||
|
||
args = Mock(spec_set=["force", "language"]) | ||
args.force = False | ||
args.language = "rust1.39" | ||
|
||
mock_project = Mock(spec=Project) | ||
mock_project.load_settings.side_effect = FileNotFoundError | ||
mock_project.settings_path = "" | ||
mock_project.root = Path(".") | ||
def test_init_method_noninteractive_invalid_type_name(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. confused on this. how does init reach project init method if the typename is invalid? |
||
add_dummy_language_plugin() | ||
type_name = object() | ||
|
||
args = get_args(type_name=False) | ||
mock_project, patch_project = get_mock_project() | ||
|
||
patch_project = patch("rpdk.core.init.Project", return_value=mock_project) | ||
patch_tn = patch("rpdk.core.init.input_typename", return_value=type_name) | ||
patch_l = patch("rpdk.core.init.input_language") | ||
patch_get_parser = patch( | ||
"rpdk.core.init.get_parsers", return_value={"dummy": dummy_parser} | ||
) | ||
|
||
with patch_project, patch_tn as mock_tn, patch_l as mock_l: | ||
init(args) | ||
# pylint: disable=C0301 | ||
with patch_project, patch_tn as mock_tn, patch_l as mock_l, patch_get_parser as mock_parser: # noqa: B950 | ||
main(args_in=["init", "--type-name", args.type_name, args.language, "--dummy"]) | ||
|
||
mock_tn.assert_called_once_with() | ||
mock_l.assert_not_called() | ||
mock_parser.assert_called_once() | ||
|
||
mock_project.load_settings.assert_called_once_with() | ||
mock_project.init.assert_called_once_with(type_name, args.language) | ||
mock_project.init.assert_called_once_with( | ||
type_name, | ||
args.language, | ||
args.settings, | ||
) | ||
mock_project.generate.assert_called_once_with() | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,13 @@ | ||
import os | ||
from contextlib import contextmanager | ||
from io import BytesIO | ||
from pathlib import Path | ||
from random import sample | ||
from unittest.mock import Mock, patch | ||
|
||
import pkg_resources | ||
|
||
from rpdk.core.project import Project | ||
|
||
CONTENTS_UTF8 = "💣" | ||
|
||
|
@@ -67,6 +73,79 @@ def chdir(path): | |
os.chdir(old) | ||
|
||
|
||
def add_dummy_language_plugin(): | ||
distribution = pkg_resources.Distribution(__file__) | ||
entry_point = pkg_resources.EntryPoint.parse( | ||
"dummy = rpdk.dummy:DummyLanguagePlugin", dist=distribution | ||
) | ||
distribution._ep_map = { # pylint: disable=protected-access | ||
"rpdk.v1.languages": {"dummy": entry_point} | ||
} | ||
pkg_resources.working_set.add(distribution) | ||
|
||
|
||
def get_mock_project(): | ||
mock_project = Mock(spec=Project) | ||
mock_project.load_settings.side_effect = FileNotFoundError | ||
mock_project.settings_path = "" | ||
mock_project.root = Path(".") | ||
|
||
patch_project = patch("rpdk.core.init.Project", return_value=mock_project) | ||
|
||
return (mock_project, patch_project) | ||
|
||
|
||
def get_args(interactive=False, language=True, type_name=True): | ||
args = Mock( | ||
spec_set=[ | ||
"language", | ||
"type_name", | ||
"settings", | ||
] | ||
) | ||
|
||
args.language = ( | ||
None if interactive else ("dummy" if language else "invalid_language") | ||
|
||
) | ||
args.type_name = ( | ||
None if interactive else ("Test::Test::Test" if type_name else "Test") | ||
|
||
) | ||
args.settings = { | ||
"version": False, | ||
"subparser_name": None if interactive else ("dummy" if language else None), | ||
"verbose": 0, | ||
"force": False, | ||
"type_name": args.type_name, | ||
} | ||
|
||
if language and not interactive: | ||
args.settings["dummy"] = True | ||
args.settings["language"] = args.language | ||
|
||
return args | ||
|
||
|
||
def dummy_parser(): | ||
def dummy_subparser(subparsers, parents): | ||
parser = subparsers.add_parser( | ||
"dummy", | ||
description="""This sub command generates IDE and build | ||
files for the Dummy plugin""", | ||
parents=parents, | ||
) | ||
parser.set_defaults(language="dummy") | ||
|
||
parser.add_argument( | ||
"-d", | ||
"--dummy", | ||
action="store_true", | ||
help="Dummy boolean to test if parser is loaded correctly", | ||
) | ||
return parser | ||
|
||
return dummy_subparser | ||
|
||
|
||
class UnclosingBytesIO(BytesIO): | ||
_was_closed = False | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.