Skip to content

Commit

Permalink
Merge branch 'main' into create-pull-request/maintenance-v1
Browse files Browse the repository at this point in the history
  • Loading branch information
kddejong authored Dec 10, 2024
2 parents a5000d6 + c6e3878 commit 7c88b8d
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 7 deletions.
8 changes: 4 additions & 4 deletions src/cfnlint/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,10 +796,10 @@ def _glob_filenames(self, filenames: Sequence[str]) -> list[str]:
for filename in filenames:
add_filenames = glob.glob(filename, recursive=True)

if isinstance(add_filenames, list):
all_filenames.extend(add_filenames)
else:
LOGGER.error(f"{filename} could not be processed by glob.glob")
if not add_filenames and not self.ignore_bad_template:
raise ValueError(f"{filename} could not be processed by glob.glob")

all_filenames.extend(add_filenames)

return sorted(list(map(str, map(Path, all_filenames))))

Expand Down
4 changes: 4 additions & 0 deletions src/cfnlint/data/CfnLintCli/config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@
"description": "custom rule file to use",
"type": "string"
},
"ignore_bad_template": {
"description": "Ignore bad templates",
"type": "boolean"
},
"ignore_checks": {
"description": "List of checks to ignore",
"items": {
Expand Down
1 change: 1 addition & 0 deletions src/cfnlint/rules/errors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
SPDX-License-Identifier: MIT-0
"""

from cfnlint.rules.errors.config import ConfigError
from cfnlint.rules.errors.parse import ParseError
from cfnlint.rules.errors.rule import RuleError
from cfnlint.rules.errors.transform import TransformError
15 changes: 15 additions & 0 deletions src/cfnlint/rules/errors/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""

from cfnlint.rules._rule import CloudFormationLintRule


class ConfigError(CloudFormationLintRule):

id = "E0003"
shortdesc = "Error with cfn-lint configuration"
description = "Error as a result of the cfn-lint configuration"
source_url = "https://github.com/aws-cloudformation/cfn-lint"
tags = ["base", "rule"]
7 changes: 5 additions & 2 deletions src/cfnlint/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from cfnlint.decode.decode import decode
from cfnlint.helpers import REGIONS
from cfnlint.rules import Match, Rules
from cfnlint.rules.errors import ParseError, TransformError
from cfnlint.rules.errors import ConfigError, ParseError, TransformError
from cfnlint.schema import PROVIDER_SCHEMA_MANAGER
from cfnlint.template.template import Template

Expand Down Expand Up @@ -223,10 +223,13 @@ def __init__(self, config: ConfigMixIn) -> None:
settings for the template scan.
"""
self.config = config
self.config.templates
self.formatter = get_formatter(self.config)
self.rules: Rules = Rules()
self._get_rules()
try:
self.config.templates
except ValueError as e:
self._cli_output([Match(str(e), ConfigError(), None)])
# load registry schemas before patching
if self.config.registry_schemas:
for path in self.config.registry_schemas:
Expand Down
5 changes: 4 additions & 1 deletion src/cfnlint/template/transforms/_language_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,12 @@ def value(

if mapping:
try:
return mapping.get(t_map[1].value(cfn, params, only_params), {}).get(
value = mapping.get(t_map[1].value(cfn, params, only_params), {}).get(
t_map[2].value(cfn, params, only_params)
)
if value is None:
raise _ResolveError("Can't resolve Fn::FindInMap", self._obj)
return value
except _ResolveError as e:
if len(self._map) == 4 and default_on_resolver_failure:
return self._map[3].value(cfn, params, only_params)
Expand Down
14 changes: 14 additions & 0 deletions test/unit/module/config/test_config_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,20 @@ def test_config_expand_paths_nomatch(self, yaml_mock):
]
config = cfnlint.config.ConfigMixIn([])

with self.assertRaises(ValueError):
self.assertEqual(len(config.templates), 1)

@patch("cfnlint.config.ConfigFileArgs._read_config", create=True)
def test_config_expand_paths_nomatch_ignore_bad_template(self, yaml_mock):
"""Test precedence in"""

filename = "test/fixtures/templates/nonexistant/*.yaml"
yaml_mock.side_effect = [
{"templates": [filename], "ignore_bad_template": True},
{},
]
config = cfnlint.config.ConfigMixIn([])

# test defaults
self.assertEqual(config.templates, [])

Expand Down
8 changes: 8 additions & 0 deletions test/unit/module/maintenance/test_update_documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ def test_update_docs(self):
" [Source](https://github.com/aws-cloudformation/cfn-lint) |"
" `base`,`rule` |\n"
),
call(
'| [E0003<a name="E0003"></a>]'
"(../src/cfnlint/rules/errors/config.py) | "
"Error with cfn-lint configuration | "
"Error as a result of the cfn-lint configuration | | "
"[Source](https://github.com/aws-cloudformation/cfn-lint) "
"| `base`,`rule` |\n"
),
call("\n\\* experimental rules\n"),
]
mock_builtin_open.return_value.write.assert_has_calls(expected_calls)
Expand Down
16 changes: 16 additions & 0 deletions test/unit/module/runner/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
SPDX-License-Identifier: MIT-0
"""

from io import StringIO
from unittest.mock import patch

import pytest
Expand Down Expand Up @@ -93,3 +94,18 @@ def test_init_schemas(name, registry_path, patch_path, expected):

PROVIDER_SCHEMA_MANAGER._registry_schemas = {}
PROVIDER_SCHEMA_MANAGER.reset()


def test_no_templates():
params = ["--template", "does-not-exist.yaml"]

config = ConfigMixIn(params)
with patch("sys.exit") as exit:
with patch("sys.stdout", new=StringIO()) as out:
exit.assert_not_called()
Runner(config)
assert out.getvalue().strip() == (
"E0003 does-not-exist.yaml could not "
"be processed by glob.glob\nNone:1:1"
)
exit.assert_called_once_with(2)
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,14 @@ def test_find_in_map_values_with_default(self):
with self.assertRaises(_ResolveError):
map.value(self.cfn, None, False, False)

def test_find_in_map_values_not_found_with_default(self):
map = _ForEachValueFnFindInMap(
"a", ["Bucket", "Production", "DNE", {"DefaultValue": "bar"}]
)

self.assertEqual(map.value(self.cfn, None, False, True), "bar")
self.assertEqual(map.value(self.cfn, None, False, False), ["foo", "bar"])

def test_find_in_map_values_without_default(self):
map = _ForEachValueFnFindInMap("a", ["Bucket", {"Ref": "Foo"}, "Key"])

Expand Down

0 comments on commit 7c88b8d

Please sign in to comment.