diff --git a/ansiblelater/candidate.py b/ansiblelater/candidate.py index f78fb9e..4ae896c 100644 --- a/ansiblelater/candidate.py +++ b/ansiblelater/candidate.py @@ -28,7 +28,6 @@ class Candidate(object): self.binary = False self.vault = False self.filetype = type(self).__name__.lower() - self.expected_version = True self.faulty = False self.config = settings.config self.settings = settings @@ -69,21 +68,7 @@ class Candidate(object): if match: version = match.group(1) - if not version: - version = utils.standards_latest(self.standards) - if self.expected_version: - if isinstance(self, RoleFile): - LOG.warning( - f"{name} {path} is in a role that contains a " - "meta/main.yml without a declared standards version. " - f"Using latest standards version {version}" - ) - else: - LOG.warning( - f"{name} {path} does not present standards version. " - f"Using latest standards version {version}" - ) - else: + if version: LOG.info(f"{name} {path} declares standards version {version}") return version @@ -105,7 +90,8 @@ class Candidate(object): def review(self, lines=None): errors = 0 self.standards = SingleStandards(self.config["rules"]["standards"]).rules - self.version = self._get_version() + self.version_config = self._get_version() + self.version = self.version_config or utils.standards_latest(self.standards) for standard in self._filter_standards(): if type(self).__name__.lower() not in standard.types: diff --git a/ansiblelater/rules/CheckVersion.py b/ansiblelater/rules/CheckVersion.py new file mode 100644 index 0000000..1ec80b3 --- /dev/null +++ b/ansiblelater/rules/CheckVersion.py @@ -0,0 +1,17 @@ +from ansiblelater.standard import StandardBase + + +class CheckVersion(StandardBase): + + sid = "ANSIBLE9998" + description = "Standards version should be pinned" + helptext = "Standards version not set. Using latest standards version {version}" + types = ["playbook", "task", "handler"] + + def check(self, candidate, settings): + errors = [] + + if not candidate.version_config: + errors.append(self.Error(None, self.helptext.format(version=candidate.version))) + + return self.Result(candidate.path, errors) diff --git a/ansiblelater/settings.py b/ansiblelater/settings.py index 3b8a192..d3304ad 100644 --- a/ansiblelater/settings.py +++ b/ansiblelater/settings.py @@ -120,7 +120,10 @@ class Settings(object): "standards": [], "filter": [], "exclude_filter": [], - "warning_filter": ["ANSIBLE9999"], + "warning_filter": [ + "ANSIBLE9999", + "ANSIBLE9998", + ], "ignore_dotfiles": True, "exclude_files": [], "version": "" diff --git a/docs/content/configuration/defaults.md b/docs/content/configuration/defaults.md index cc6302f..e2fe6ab 100644 --- a/docs/content/configuration/defaults.md +++ b/docs/content/configuration/defaults.md @@ -79,6 +79,7 @@ rules: # This list allows to degrade errors to warnings for each rule. warning_filter: - "ANSIBLE9999" + - "ANSIBLE9998" # All dotfiles (including hidden folders) are excluded by default. # You can disable this setting and handle dotfiles by yourself with `exclude_files`. diff --git a/docs/content/included_rules/_index.md b/docs/content/included_rules/_index.md index f0c8857..ffaf110 100644 --- a/docs/content/included_rules/_index.md +++ b/docs/content/included_rules/_index.md @@ -41,4 +41,5 @@ Reviews are useless without some rules or standards to check against. ansible-la | CheckLocalAction | ANSIBLE0024 | Don't use local_action. | | | CheckRelativeRolePaths | ANSIBLE0025 | Don't use a relative path in a role. | | | CheckChangedInWhen | ANSIBLE0026 | Use handlers instead of `when: changed`. | | +| CheckVersion | ANSIBLE9998 | Standards version should be pinned. | | | CheckDeprecated | ANSIBLE9999 | Deprecated features of `ansible-later` should not be used. | |