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 ## Table of Content
- [ansible-later](#ansible-later)
- [Table of Content](#table-of-content)
- [Setup](#setup) - [Setup](#setup)
- [Using pip](#using-pip) - [Using pip](#using-pip)
- [From source](#from-source) - [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. comes with a couple of built-in checks explained in the following table.
| Rule | ID | Description | Parameter | | 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_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_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} | | 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_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_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_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_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_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_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_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 ### 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. which contains some meta informations and is an instance of one of following object types.
| Object type | Description | | Object type | Description |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------- | |-------------|------------------------------------------------------------------------------------------------------------------------------|
| Task | all files within the parent dir `tasks` | | Task | all files within the parent dir `tasks` |
| Handler | all files within the parent dir `handler` | | Handler | all files within the parent dir `handler` |
| RoleVars | all files within the parent dir `vars` or `default` | | 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_compare_to_literal_bool
from ansiblelater.rules.ansiblefiles import check_literal_bool_format from ansiblelater.rules.ansiblefiles import check_literal_bool_format
from ansiblelater.rules.ansiblefiles import check_become_user from ansiblelater.rules.ansiblefiles import check_become_user
from ansiblelater.rules.ansiblefiles import check_filter_separation
tasks_should_be_separated = Standard(dict( 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", name="Literal bools should start with a capital letter",
check=check_literal_bool_format, check=check_literal_bool_format,
version="0.1", version="0.1",
types=[["playbook", "task", "handler", "rolevars", types=["playbook", "task", "handler", "rolevars",
"hostvars", "groupvars"]] "hostvars", "groupvars"]
)) ))
use_become_with_become_user = Standard(dict( use_become_with_become_user = Standard(dict(
@ -145,6 +146,15 @@ use_become_with_become_user = Standard(dict(
types=["playbook", "task", "handler"] 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( files_should_not_contain_unnecessarily_empty_lines = Standard(dict(
id="LINT0001", id="LINT0001",
name="YAML should not contain unnecessarily empty lines", name="YAML should not contain unnecessarily empty lines",
@ -236,6 +246,7 @@ standards = [
dont_compare_to_literal_bool, dont_compare_to_literal_bool,
literal_bool_should_be_formatted, literal_bool_should_be_formatted,
use_become_with_become_user, use_become_with_become_user,
use_spaces_around_filters,
# Lint # Lint
files_should_not_contain_unnecessarily_empty_lines, files_should_not_contain_unnecessarily_empty_lines,
files_should_be_indented, files_should_be_indented,

View File

@ -231,3 +231,24 @@ def check_become_user(candidate, settings):
errors.append(Error(task["__line__"], description)) errors.append(Error(task["__line__"], description))
return Result(candidate.path, errors) 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)