Skip to content

Commit e2ac815

Browse files
committed
fix(cfn-lint): backwards compatible support for cfn-lint 1.x
1 parent 2f5de08 commit e2ac815

File tree

2 files changed

+50
-16
lines changed

2 files changed

+50
-16
lines changed

taskcat/_cfn_lint.py

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,26 @@
22
import re
33
import textwrap
44

5+
import cfnlint.config
56
import cfnlint.core
67
import cfnlint.helpers
8+
import cfnlint.version
79
from cfnlint.config import ConfigMixIn as CfnLintConfig
810
from jsonschema.exceptions import ValidationError
911
from taskcat._common_utils import neglect_submodule_templates
1012
from taskcat._config import Config
1113
from taskcat._dataclasses import Templates
1214

15+
# Ignoring linting errors here as pylint doesn't seem to handle the conditional nature
16+
if cfnlint.version.__version__.startswith("0."):
17+
from cfnlint.core import ( # pylint:disable=no-name-in-module, ungrouped-imports
18+
CfnLintExitException,
19+
)
20+
else:
21+
from cfnlint.runner import ( # pylint:disable=no-name-in-module, ungrouped-imports
22+
CfnLintExitException,
23+
)
24+
1325
LOG = logging.getLogger(__name__)
1426

1527

@@ -32,8 +44,24 @@ def __init__(self, config: Config, templates: Templates, strict: bool = False):
3244
except ValidationError as e:
3345
LOG.error("Error parsing cfn-lint config file: %s", str(e))
3446
raise
47+
48+
# There is a change in the way that the cfn lint config class functions between the 0.x and 1.x versions.
49+
# In 1.x, the append_rules property getter includes the default rule set along with the loaded configuration
50+
# https://github.com/aws-cloudformation/cfn-lint/blob/23ee527fadb43e4fd54238eeea5bc3a169175c91/src/cfnlint/config.py#L773
51+
# In 0.x, it only returned the loaded configuration.
52+
# https://github.com/aws-cloudformation/cfn-lint/blob/f006cb5d8c7056923f3f21b31c14edfeed3804b5/src/cfnlint/config.py#L730
53+
#
54+
# This causes issues for us as the get_rules method combines the supplied value with the default rule list,
55+
# resulting in a duplicate rule error. get_rules has always behaved this way though, so not sure if we have just missed something
56+
# in the intended approach to calling this.
57+
if cfnlint.version.__version__.startswith("0."):
58+
append_rules = self._cfnlint_config.append_rules
59+
else:
60+
append_rules = self._cfnlint_config.append_rules
61+
append_rules.remove(cfnlint.config._DEFAULT_RULESDIR)
62+
3563
self._rules = cfnlint.core.get_rules(
36-
self._cfnlint_config.append_rules,
64+
append_rules,
3765
self._cfnlint_config.ignore_checks,
3866
self._cfnlint_config.include_checks,
3967
self._cfnlint_config.configure_rules,
@@ -91,17 +119,11 @@ def _run_checks(self, template, name, lint_errors, lints):
91119
tpath = str(template.template_path)
92120
results = []
93121
try:
94-
(_, rules, template_matches) = cfnlint.core.get_template_rules(
95-
tpath, self._cfnlint_config
122+
results = cfnlint.core.run_checks(
123+
tpath, template.template, self._rules, lints[name]["regions"]
96124
)
97-
if template_matches:
98-
results = template_matches
99-
else:
100-
results = cfnlint.core.run_checks(
101-
tpath, template.template, rules, lints[name]["regions"]
102-
)
103125
lints[name]["results"][tpath] = results
104-
except cfnlint.core.CfnLintExitException as e:
126+
except CfnLintExitException as e:
105127
lint_errors.add(str(e))
106128
lints[name]["results"][tpath] = results
107129

tests/test_cfn_lint.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import yaml
88

9+
import cfnlint.version
910
from taskcat._cfn_lint import Lint
1011
from taskcat._config import Config
1112

@@ -30,6 +31,22 @@ def __init__(self):
3031
"(This code may only work with `package` cli command as the property"
3132
"(Resources/Name/Properties/TemplateURL) is a string) matched /private/tmp/lint_test/test-config-three/templates/taskcat_test_template_test1:1"
3233
)
34+
if cfnlint.version.__version__.startswith("0."):
35+
invalid_type_error = [
36+
f"[E3001: Basic CloudFormation Resource Check] (Invalid or "
37+
f"unsupported Type AWS::Not::Exist for resource Name in "
38+
f"eu-west-1) matched "
39+
f"{test_two_path}:1"
40+
]
41+
else:
42+
# The format of this message seems to change in 1.3.0 onwards
43+
# (prior 1.x versions were pre-releases so not supporting them)
44+
invalid_type_error = [
45+
f"[E3006: Validate the CloudFormation resource type] (Resource "
46+
f"type 'AWS::Not::Exist' does not exist in "
47+
f"'eu-west-1') matched "
48+
f"{test_two_path}:1"
49+
]
3350
test_cases = [
3451
{
3552
"config": {
@@ -71,12 +88,7 @@ def __init__(self):
7188
"/tmp/lint_test/test-config-two/templates/taskcat_test_"
7289
"template_test1"
7390
).resolve()
74-
): [
75-
f"[E3001: Basic CloudFormation Resource Check] (Invalid or "
76-
f"unsupported Type AWS::Not::Exist for resource Name in "
77-
f"eu-west-1) matched "
78-
f"{test_two_path}:1"
79-
]
91+
): invalid_type_error
8092
},
8193
"template": Path(
8294
"/tmp/lint_test/test-config-two/templates/taskcat_test_template"

0 commit comments

Comments
 (0)