Skip to content

Commit

Permalink
fix: remove resolve-image-repos error message from the commands it is…
Browse files Browse the repository at this point in the history
… not supported (#5596)

* fix: remove resolve-image-repos error message from the commands it is not supported

* formatting
  • Loading branch information
mndeveci authored Jul 22, 2023
1 parent 02df321 commit 3cee812
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 79 deletions.
2 changes: 1 addition & 1 deletion samcli/commands/deploy/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
@capabilities_option
@aws_creds_options
@common_options
@image_repository_validation
@image_repository_validation()
@pass_context
@track_command
@check_newer_version
Expand Down
2 changes: 1 addition & 1 deletion samcli/commands/package/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def resources_and_properties_help_string():
@no_progressbar_option
@common_options
@aws_creds_options
@image_repository_validation
@image_repository_validation(support_resolve_image_repos=False)
@pass_context
@track_command
@check_newer_version
Expand Down
2 changes: 1 addition & 1 deletion samcli/commands/sync/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
@pass_context
@track_command
@track_long_event("SyncUsed", "Start", "SyncUsed", "End")
@image_repository_validation
@image_repository_validation(support_resolve_image_repos=False)
@track_template_warnings([CodeDeployWarning.__name__, CodeDeployConditionWarning.__name__])
@check_newer_version
@print_cmdline_args
Expand Down
152 changes: 86 additions & 66 deletions samcli/lib/cli_validation/image_repository_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,83 +15,103 @@
from samcli.lib.utils.packagetype import IMAGE


def image_repository_validation(func):
def image_repository_validation(support_resolve_image_repos=True):
"""
Wrapper Validation function that will run last after the all cli parmaters have been loaded
to check for conditions surrounding `--image-repository`, `--image-repositories`, and `--resolve-image-repos`. The
reason they are done last instead of in callback functions, is because the options depend
on each other, and this breaks cyclic dependencies.
:param func: Click command function
:return: Click command function after validation
Parameters
----------
support_resolve_image_repos: bool
If it is True, it will be adding `--resolve-image-repos` related error messages below. Default is True.
"""

def wrapped(*args, **kwargs):
ctx = click.get_current_context()
guided = ctx.params.get("guided", False) or ctx.params.get("g", False)
image_repository = ctx.params.get("image_repository", False)
image_repositories = ctx.params.get("image_repositories", False) or {}
resolve_image_repos = ctx.params.get("resolve_image_repos", False)
parameters_overrides = ctx.params.get("parameters_overrides", {})
template_file = (
ctx.params.get("t", False) or ctx.params.get("template_file", False) or ctx.params.get("template", False)
)

# Check if `--image-repository`, `--image-repositories`, or `--resolve-image-repos` are required by
# looking for resources that have an IMAGE based packagetype.

required = any(
[
_template_artifact == IMAGE
for _template_artifact in get_template_artifacts_format(template_file=template_file)
]
)

validators = [
Validator(
validation_function=lambda: bool(image_repository)
+ bool(image_repositories)
+ bool(resolve_image_repos)
> 1,
exception=click.BadOptionUsage(
option_name="--image-repositories",
ctx=ctx,
message="Only one of the following can be provided: '--image-repositories', "
"'--image-repository', or '--resolve-image-repos'. "
"Do you have multiple specified in the command or in a configuration file?",
),
),
Validator(
validation_function=lambda: not guided
and not (image_repository or image_repositories or resolve_image_repos)
and required,
exception=click.BadOptionUsage(
option_name="--image-repositories",
ctx=ctx,
message="Missing option '--image-repository', '--image-repositories', or '--resolve-image-repos'",
def decorator(func):
"""
Actual decorator implementation for the validation functionality
:param func: Click command function
:return: Click command function after validation
"""

def wrapped(*args, **kwargs):
ctx = click.get_current_context()
guided = ctx.params.get("guided", False) or ctx.params.get("g", False)
image_repository = ctx.params.get("image_repository", False)
image_repositories = ctx.params.get("image_repositories", False) or {}
resolve_image_repos = ctx.params.get("resolve_image_repos", False)
parameters_overrides = ctx.params.get("parameters_overrides", {})
template_file = (
ctx.params.get("t", False)
or ctx.params.get("template_file", False)
or ctx.params.get("template", False)
)

# Check if `--image-repository`, `--image-repositories`, or `--resolve-image-repos` are required by
# looking for resources that have an IMAGE based packagetype.

required = any(
[
_template_artifact == IMAGE
for _template_artifact in get_template_artifacts_format(template_file=template_file)
]
)

available_options = "'--image-repositories', '--image-repository'"
if support_resolve_image_repos:
available_options += ", '--resolve-image-repos'"

image_repos_error_msg = "Incomplete list of function logical ids specified for '--image-repositories'."
if support_resolve_image_repos:
image_repos_error_msg += (
"You can also add --resolve-image-repos to automatically create missing " "repositories."
)

validators = [
Validator(
validation_function=lambda: bool(image_repository)
+ bool(image_repositories)
+ bool(resolve_image_repos)
> 1,
exception=click.BadOptionUsage(
option_name="--image-repositories",
ctx=ctx,
message=f"Only one of the following can be provided: {available_options}. "
"Do you have multiple specified in the command or in a configuration file?",
),
),
),
Validator(
validation_function=lambda: not guided
and (
image_repositories
and not resolve_image_repos
and not _is_all_image_funcs_provided(template_file, image_repositories, parameters_overrides)
Validator(
validation_function=lambda: not guided
and not (image_repository or image_repositories or resolve_image_repos)
and required,
exception=click.BadOptionUsage(
option_name="--image-repositories",
ctx=ctx,
message=f"Missing option {available_options}",
),
),
exception=click.BadOptionUsage(
option_name="--image-repositories",
ctx=ctx,
message="Incomplete list of function logical ids specified for '--image-repositories'. "
"You can also add --resolve-image-repos to automatically create missing repositories.",
Validator(
validation_function=lambda: not guided
and (
image_repositories
and not resolve_image_repos
and not _is_all_image_funcs_provided(template_file, image_repositories, parameters_overrides)
),
exception=click.BadOptionUsage(
option_name="--image-repositories", ctx=ctx, message=image_repos_error_msg
),
),
),
]
for validator in validators:
validator.validate()
# Call Original function after validation.
return func(*args, **kwargs)

return wrapped
]
for validator in validators:
validator.validate()
# Call Original function after validation.
return func(*args, **kwargs)

return wrapped

return decorator


def _is_all_image_funcs_provided(template_file, image_repositories, parameters_overrides):
Expand Down
41 changes: 31 additions & 10 deletions tests/unit/lib/cli_validation/test_image_repository_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import click
import posixpath
from parameterized import parameterized
from parameterized import parameterized, parameterized_class

from samcli.lib.cli_validation.image_repository_validation import (
image_repository_validation,
Expand All @@ -14,9 +14,18 @@
from samcli.lib.utils.packagetype import ZIP, IMAGE


@parameterized_class(
("support_resolve_image_repos"),
[
(True,),
(False,),
],
)
class TestImageRepositoryValidation(TestCase):
support_resolve_image_repos = False

def setUp(self):
@image_repository_validation
@image_repository_validation(self.support_resolve_image_repos)
def foo():
pass

Expand Down Expand Up @@ -102,10 +111,16 @@ def test_image_repository_validation_failure_IMAGE_image_repositories_and_image_

with self.assertRaises(click.BadOptionUsage) as ex:
self.foobar()
self.assertIn(
"Only one of the following can be provided: '--image-repositories', '--image-repository', or '--resolve-image-repos'. ",
ex.exception.message,
)
if self.support_resolve_image_repos:
self.assertIn(
"Only one of the following can be provided: '--image-repositories', '--image-repository', '--resolve-image-repos'.",
ex.exception.message,
)
else:
self.assertIn(
"Only one of the following can be provided: '--image-repositories', '--image-repository'.",
ex.exception.message,
)

@patch("samcli.lib.cli_validation.image_repository_validation.click")
@patch("samcli.lib.cli_validation.image_repository_validation._is_all_image_funcs_provided")
Expand Down Expand Up @@ -147,10 +162,16 @@ def test_image_repository_validation_failure_IMAGE_missing_image_repositories(

with self.assertRaises(click.BadOptionUsage) as ex:
self.foobar()
self.assertIn(
"Missing option '--image-repository', '--image-repositories', or '--resolve-image-repos'",
ex.exception.message,
)
if self.support_resolve_image_repos:
self.assertIn(
"Missing option '--image-repositories', '--image-repository', '--resolve-image-repos'",
ex.exception.message,
)
else:
self.assertIn(
"Missing option '--image-repositories', '--image-repository'",
ex.exception.message,
)

@patch("samcli.lib.cli_validation.image_repository_validation.click")
@patch("samcli.lib.cli_validation.image_repository_validation._is_all_image_funcs_provided")
Expand Down

0 comments on commit 3cee812

Please sign in to comment.