add new rule check_filter_separation

This commit is contained in:
Robert Kaussow 2019-01-30 00:27:30 +01:00
parent 86ffffd8e1
commit 098366fcf8
3 changed files with 77 additions and 42 deletions

View File

@ -18,6 +18,8 @@ The project name is an acronym for **L**ovely **A**utomation **TE**sting f**R**m
## Table of Content
- [ansible-later](#ansible-later)
- [Table of Content](#table-of-content)
- [Setup](#setup)
- [Using pip](#using-pip)
- [From source](#from-source)
@ -131,7 +133,7 @@ Reviews are nothing without some rules or standards against which to review. ans
comes with a couple of built-in checks explained in the following table.
| Rule | ID | Description | Parameter |
| ------------------------------- | ----------- | ---------------------------------------------------------------- | -------------------------------------------------------------------- |
|---------------------------------|-------------|-------------------------------------------------------------------|----------------------------------------------------------------------|
| check_yaml_empty_lines | LINT0001 | YAML should not contain unnecessarily empty lines. | {max: 1, max-start: 0, max-end: 0} |
| check_yaml_indent | LINT0002 | YAML should be correctly indented. | {spaces: 2, check-multi-line-strings: false, indent-sequences: true} |
| check_yaml_hyphens | LINT0003 | YAML should use consitent number of spaces after hyphens (-). | {max-spaces-after: 1} |
@ -151,10 +153,11 @@ comes with a couple of built-in checks explained in the following table.
| check_install_use_latest | ANSIBLE0009 | Package managers should not install with state=latest. | |
| check_shell_instead_command | ANSIBLE0010 | Use Shell only when piping, redirecting or chaining commands. | |
| check_command_has_changes | ANSIBLE0011 | Commands should be idempotent and only used with some checks. | |
| check_empty_string_compare | ANSIBLE0012 | Don't compare to "" - use `when: var` or `when: not var` | |
| check_compare_to_literal_bool | ANSIBLE0013 | Don't compare to True/False - use `when: var` or `when: not var` | |
| check_literal_bool_format | ANSIBLE0014 | Literal bools should be written as `True/False` or `yes/no` | forbidden values are `true false TRUE FALSE Yes No YES NO` |
| check_become_user | ANSIBLE0015 | `become` should be always used combined with `become_user` | |
| check_empty_string_compare | ANSIBLE0012 | Don't compare to "" - use `when: var` or `when: not var`. | |
| check_compare_to_literal_bool | ANSIBLE0013 | Don't compare to True/False - use `when: var` or `when: not var`. | |
| check_literal_bool_format | ANSIBLE0014 | Literal bools should be written as `True/False` or `yes/no`. | forbidden values are `true false TRUE FALSE Yes No YES NO` |
| check_become_user | ANSIBLE0015 | `become` should be always used combined with `become_user`. | |
| check_filter_separation | ANSIBLE0016 | Jinja2 filters should be separated with spaces. | |
### Build your own
@ -217,7 +220,7 @@ Each file passed to `ansible-later` will be classified. The result is a `Candida
which contains some meta informations and is an instance of one of following object types.
| Object type | Description |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------- |
|-------------|------------------------------------------------------------------------------------------------------------------------------|
| Task | all files within the parent dir `tasks` |
| Handler | all files within the parent dir `handler` |
| RoleVars | all files within the parent dir `vars` or `default` |

View File

@ -23,6 +23,7 @@ from ansiblelater.rules.ansiblefiles import check_empty_string_compare
from ansiblelater.rules.ansiblefiles import check_compare_to_literal_bool
from ansiblelater.rules.ansiblefiles import check_literal_bool_format
from ansiblelater.rules.ansiblefiles import check_become_user
from ansiblelater.rules.ansiblefiles import check_filter_separation
tasks_should_be_separated = Standard(dict(
@ -133,8 +134,8 @@ literal_bool_should_be_formatted = Standard(dict(
name="Literal bools should start with a capital letter",
check=check_literal_bool_format,
version="0.1",
types=[["playbook", "task", "handler", "rolevars",
"hostvars", "groupvars"]]
types=["playbook", "task", "handler", "rolevars",
"hostvars", "groupvars"]
))
use_become_with_become_user = Standard(dict(
@ -145,6 +146,15 @@ use_become_with_become_user = Standard(dict(
types=["playbook", "task", "handler"]
))
use_spaces_around_filters = Standard(dict(
id="ANSIBLE0016",
name="jinja2 filters should be separated with spaces",
check=check_filter_separation,
version="0.1",
types=["playbook", "task", "handler", "rolevars",
"hostvars", "groupvars"]
))
files_should_not_contain_unnecessarily_empty_lines = Standard(dict(
id="LINT0001",
name="YAML should not contain unnecessarily empty lines",
@ -236,6 +246,7 @@ standards = [
dont_compare_to_literal_bool,
literal_bool_should_be_formatted,
use_become_with_become_user,
use_spaces_around_filters,
# Lint
files_should_not_contain_unnecessarily_empty_lines,
files_should_be_indented,

View File

@ -231,3 +231,24 @@ def check_become_user(candidate, settings):
errors.append(Error(task["__line__"], description))
return Result(candidate.path, errors)
def check_filter_separation(candidate, settings):
yamllines, errors = get_normalized_yaml(candidate, settings)
description = "no suitable numbers of spaces (required: 1)"
matches = []
braces = re.compile("{{(.*?)}}")
filters = re.compile(r"(?<=\|)([\s]{2,}[^\s}]+|[^\s]+)|([^\s{]+[\s]{2,}|[^\s]+)(?=\|)")
if not errors:
for i, line in yamllines:
match = braces.findall(line)
if match:
for item in match:
matches.append((i, item))
for i, line in matches:
if filters.findall(line):
errors.append(Error(i, description))
return Result(candidate.path, errors)