diff --git a/src/ansiblelint/app.py b/src/ansiblelint/app.py index 915c2b25bd..0d319cfa99 100644 --- a/src/ansiblelint/app.py +++ b/src/ansiblelint/app.py @@ -31,6 +31,7 @@ _logger = logging.getLogger(__package__) +_CACHED_APP = None class App: @@ -386,8 +387,19 @@ def _sanitize_list_options(tag_list: list[str]) -> list[str]: @lru_cache -def get_app(*, offline: bool | None = None) -> App: +def get_app(*, offline: bool | None = None, cached: bool = False) -> App: """Return the application instance, caching the return value.""" + # Avoids ever running the app initialization twice if cached argument + # is mentioned. + if cached: + if offline is not None: + msg = ( + "get_app should never be called with other arguments when cached=True." + ) + raise RuntimeError(msg) + if cached and _CACHED_APP is not None: + return _CACHED_APP + if offline is None: offline = default_options.offline diff --git a/src/ansiblelint/rules/__init__.py b/src/ansiblelint/rules/__init__.py index 037fa5f09a..ef507187ff 100644 --- a/src/ansiblelint/rules/__init__.py +++ b/src/ansiblelint/rules/__init__.py @@ -396,7 +396,7 @@ def __init__( # pylint: disable=too-many-arguments else: self.options = options self.profile = [] - self.app = app or get_app(offline=True) + self.app = app or get_app(cached=True) if profile_name: self.profile = PROFILES[profile_name] diff --git a/src/ansiblelint/rules/jinja.py b/src/ansiblelint/rules/jinja.py index 2241df52a7..b3edafa8be 100644 --- a/src/ansiblelint/rules/jinja.py +++ b/src/ansiblelint/rules/jinja.py @@ -389,6 +389,7 @@ def uncook(value: str, *, implicit: bool = False) -> str: except jinja2.exceptions.TemplateSyntaxError as exc: return "", str(exc.message), "invalid" + # pylint: disable=c-extension-no-member except (NotImplementedError, black.parsing.InvalidInput) as exc: # black is not able to recognize all valid jinja2 templates, so we # just ignore InvalidInput errors. diff --git a/src/ansiblelint/runner.py b/src/ansiblelint/runner.py index 07dedb486b..59cfe4713b 100644 --- a/src/ansiblelint/runner.py +++ b/src/ansiblelint/runner.py @@ -232,7 +232,7 @@ def _run(self) -> list[MatchError]: # -- phase 1 : syntax check in parallel -- if not self.skip_ansible_syntax_check: - app = get_app(offline=True) + app = get_app(cached=True) def worker(lintable: Lintable) -> list[MatchError]: return self._get_ansible_syntax_check_matches( diff --git a/src/ansiblelint/utils.py b/src/ansiblelint/utils.py index be1fbaec03..35c9a933c2 100644 --- a/src/ansiblelint/utils.py +++ b/src/ansiblelint/utils.py @@ -490,7 +490,7 @@ def _rolepath(basedir: str, role: str) -> str | None: path_dwim(basedir, os.path.join("..", role)), ] - for loc in get_app(offline=True).runtime.config.default_roles_path: + for loc in get_app(cached=True).runtime.config.default_roles_path: loc = os.path.expanduser(loc) possible_paths.append(path_dwim(loc, role))