Skip to content
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

Added a method to provide plugin information that is included in artifact zip #166

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ repos:
- id: bandit
files: ^(src|python)/
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.711
rev: v0.790
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upgraded mypy because of python/mypy#9916.

hooks:
- id: mypy
files: ^src/
Expand Down
36 changes: 36 additions & 0 deletions python/rpdk/python/codegen.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import os
import re
import shutil
import zipfile
from pathlib import PurePosixPath
Expand All @@ -15,6 +16,7 @@
from rpdk.core.jsonutils.resolver import ContainerType, resolve_models
from rpdk.core.plugin_base import LanguagePlugin

from . import __version__
from .resolver import contains_model, translate_type

LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -169,6 +171,9 @@ def generate(self, project):

LOG.debug("Generate complete")

def get_plugin_information(self, project):
return self._get_plugin_information(project)

def _pre_package(self, build_path):
f = TemporaryFile("w+b") # pylint: disable=R1732

Expand Down Expand Up @@ -233,6 +238,37 @@ def _make_pip_command(base_path):
str(base_path / "build"),
]

@staticmethod
def _get_plugin_information(project):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plz follow repo coding style - annotations are required, method description would be useful as well

requirements_file = project.root / "requirements.txt"
plugin_version = None

with open(requirements_file) as f:
line = f.readline()
while line:
line = line.strip()
if line.startswith(SUPPORT_LIB_NAME):
line_without_prefix = line[len(SUPPORT_LIB_NAME) :]

semi_colon = ";"
if semi_colon in line_without_prefix:
index = line_without_prefix.index(semi_colon)
line_without_prefix = line_without_prefix[0:index].strip()

plugin_version = re.split("=\\s*", line_without_prefix.strip())[-1]
break

line = f.readline()

plugin_info = {
"plugin-tool-version": __version__,
"plugin-name": "python",
}
if plugin_version and plugin_version is not None:
plugin_info["plugin-version"] = plugin_version

return plugin_info
Comment on lines +243 to +270
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not pick the version from requirements file, as we statically specify >=2.1.3

I don't think lib version can be available during the boiler plate setup. The lib is pulled from PyPi after the repo is setup


@classmethod
def _docker_build(cls, external_path):
internal_path = PurePosixPath("/project")
Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ exclude =
max-complexity = 10
max-line-length = 88
select = C,E,F,W,B,B950
# C812, C815, W503 clash with black, F723 false positive
ignore = E501,C812,C815,C816,W503,F723
# C812, C815, E203, W503 clash with black, F723 false positive
ignore = E203,E501,C812,C815,C816,W503,F723
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this because of line 251 in codegen.py

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why? can u remove whitespace instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

black add space here and flake8 complains.


[isort]
line_length = 88
Expand Down
8 changes: 4 additions & 4 deletions src/cloudformation_cli_python_lib/recast.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def recast_object(
if not isinstance(json_data, dict):
raise InvalidRequest(f"Can only parse dict items, not {type(json_data)}")
# if type is Any, we leave it as is
if cls == typing.Any:
if cls is typing.Any:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this change because of pylint error,
W0143: Comparing against a callable, did you omit the parenthesis? (comparison-with-callable)

return
for k, v in json_data.items():
if isinstance(v, dict):
Expand All @@ -35,7 +35,7 @@ def recast_object(

def _recast_lists(cls: Any, k: str, v: List[Any], classes: Dict[str, Any]) -> List[Any]:
# Leave as is if type is Any
if cls == typing.Any:
if cls is typing.Any:
return v
if "__dataclass_fields__" not in dir(cls):
pass
Expand Down Expand Up @@ -64,7 +64,7 @@ def cast_sequence_item(cls: Any, k: str, item: Any, classes: Dict[str, Any]) ->


def _recast_primitive(cls: Any, k: str, v: Any) -> Any:
if cls == typing.Any:
if cls is typing.Any:
# If the type is Any, we cannot guess what the original type was, so we leave
# it as a string
return v
Expand Down Expand Up @@ -127,5 +127,5 @@ def get_forward_ref_type() -> Any:
# introspection is valid:
# https://docs.python.org/3/library/typing.html#typing.ForwardRef
if "ForwardRef" in dir(typing):
return typing.ForwardRef # type: ignore
return typing.ForwardRef
return typing._ForwardRef # type: ignore
2 changes: 1 addition & 1 deletion tests/lib/resource_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def resource():

def patch_and_raise(resource, str_to_patch, exc_cls, entrypoint):
with patch.object(resource, str_to_patch) as mock_parse:
mock_parse.side_effect = exc_cls("hahaha")
mock_parse.side_effect = exc_cls("exception")
# "un-apply" decorator
event = entrypoint.__wrapped__(resource, {}, None) # pylint: disable=no-member
return event
Expand Down
63 changes: 63 additions & 0 deletions tests/plugin/codegen_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from requests.exceptions import ConnectionError as RequestsConnectionError
from rpdk.core.exceptions import DownstreamError
from rpdk.core.project import Project
from rpdk.python.__init__ import __version__
from rpdk.python.codegen import (
SUPPORT_LIB_NAME,
SUPPORT_LIB_PKG,
Expand Down Expand Up @@ -289,6 +290,68 @@ def test__docker_build_good_path(plugin, tmp_path):
)


def test_get_plugin_information_format1(project):
plugin_information = project._plugin.get_plugin_information(project)

assert plugin_information["plugin-tool-version"] == __version__
assert plugin_information["plugin-name"] == "python"
assert plugin_information["plugin-version"] == "2.1.3"


def test_get_plugin_information_format2(project):
existing_content = ""
with open(project.root / "requirements.txt", "r+") as f:
existing_content = f.read()
f.seek(0)
f.write("cloudformation-cli-python-lib>=2.1.3; python_version < '3.8'")
f.truncate()

plugin_information = project._plugin.get_plugin_information(project)

with open(project.root / "requirements.txt", "w") as f:
f.write(existing_content)

assert plugin_information["plugin-tool-version"] == __version__
assert plugin_information["plugin-name"] == "python"
assert plugin_information["plugin-version"] == "2.1.3"


def test_get_plugin_information_format3(project):
existing_content = ""
with open(project.root / "requirements.txt", "r+") as f:
existing_content = f.read()
f.seek(0)
f.write("dummy_line\ncloudformation-cli-python-lib; python_version < '3.8'")
f.truncate()

plugin_information = project._plugin.get_plugin_information(project)

with open(project.root / "requirements.txt", "w") as f:
f.write(existing_content)

assert plugin_information["plugin-tool-version"] == __version__
assert plugin_information["plugin-name"] == "python"
assert "plugin-version" not in plugin_information


def test_get_plugin_information_no_support_lib(project):
existing_content = ""
with open(project.root / "requirements.txt", "r+") as f:
existing_content = f.read()
f.seek(0)
f.write("dummy_line1\ndummy_line2")
f.truncate()

plugin_information = project._plugin.get_plugin_information(project)

with open(project.root / "requirements.txt", "w") as f:
f.write(existing_content)

assert plugin_information["plugin-tool-version"] == __version__
assert plugin_information["plugin-name"] == "python"
assert "plugin-version" not in plugin_information


@pytest.mark.parametrize(
"exception",
[
Expand Down