Source code for runway.tests.handlers.cfn_lint

"""cfn-list test runner."""

from __future__ import annotations

import locale
import logging
import runpy
import sys
from pathlib import Path
from typing import TYPE_CHECKING, Any, Dict, Union

import yaml

from ..._logging import PrefixAdaptor
from ...utils import argv
from .base import TestHandler

if TYPE_CHECKING:
    from ...config.components.runway.base import ConfigProperty

TYPE_NAME = "cfn-lint"
LOGGER = logging.getLogger(__name__)


[docs]class CfnLintHandler(TestHandler): """Lints CFN."""
[docs] @classmethod def handle(cls, name: str, args: Union[ConfigProperty, Dict[str, Any]]) -> None: """Perform the actual test. Relies on .cfnlintrc file to be located beside the Runway config file. """ logger = PrefixAdaptor(name, LOGGER) cfnlintrc = Path("./.cfnlintrc") if not cfnlintrc.is_file(): logger.error("file must exist to use this test: %s", cfnlintrc) sys.exit(1) # prevent duplicate log messages by not passing to the root logger logging.getLogger("cfnlint").propagate = False try: with argv(*["cfn-lint"] + args.get("cli_args", [])): runpy.run_module("cfnlint", run_name="__main__") except SystemExit as err: # this call will always result in SystemExit if err.code != 0: # ignore zero exit codes but re-raise for non-zero if not ( yaml.safe_load( cfnlintrc.read_text( encoding=locale.getpreferredencoding(do_setlocale=False) ) ) or {} ).get("templates"): logger.warning( 'cfnlintrc is missing a "templates" ' "section which is required by cfn-lint" ) raise