
from ansiblelint import AnsibleLintRule
import re


class VariableHasSpacesRule(AnsibleLintRule):
    id = '206'
    shortdesc = 'Variables should have spaces before and after: {{ var_name }}'
    description = 'Variables should have spaces before and after: ``{{ var_name }}``'
    severity = 'LOW'
    tags = ['formatting']
    version_added = 'v4.0.0'

    variable_syntax = re.compile(r"{{.*}}")
    bracket_regex = re.compile(r"{{[^{' -]|[^ '}-]}}")

    def match(self, file, line):
        if not self.variable_syntax.search(line):
            return
        return self.bracket_regex.search(line)


from ansiblelint import AnsibleLintRule
import re


class VariableHasSpacesRule(AnsibleLintRule):
    id = '206'
    shortdesc = 'Variables should have spaces before and after: {{ var_name }}'
    description = 'Variables should have spaces before and after: ``{{ var_name }}``'
    severity = 'LOW'
    tags = ['formatting']
    version_added = 'v4.0.0'

    variable_syntax = re.compile(r"{{.*}}")
    bracket_regex = re.compile(r"{{[^{' -]|[^ '}-]}}")

    def match(self, file, line):
        if not self.variable_syntax.search(line):
            return
        line_exclude_json = re.sub(r"[^{]{'\w+': ?[^{]{.*?}}", "", line)
        return self.bracket_regex.search(line_exclude_json)

Fix nested JSON obj false positive
var-space-rule: Fix nested JSON obj false positive

When using compact form nested JSON object within a
Jinja2 context as shown in the following example:
  set_fact:"{{ {'test': {'subtest': variable}} }}"

'variable}}' will raise a false positive [206] error.

This commit adds an intermediate step within 206
(VariableHasSpacesRule.py) rule to exclude nested
JSON object before matching for an actual error.

Fixes: #665

Signed-off-by: Simon Kheng <765fd267c62104898c4dfafd2f027edd838d8b13@gmail.com>

  
  from ansiblelint import AnsibleLintRule
  import re
  
  
  class VariableHasSpacesRule(AnsibleLintRule):
      id = '206'
      shortdesc = 'Variables should have spaces before and after: {{ var_name }}'
      description = 'Variables should have spaces before and after: ``{{ var_name }}``'
      severity = 'LOW'
      tags = ['formatting']
      version_added = 'v4.0.0'
  
      variable_syntax = re.compile(r"{{.*}}")
      bracket_regex = re.compile(r"{{[^{' -]|[^ '}-]}}")
  
      def match(self, file, line):
          if not self.variable_syntax.search(line):
              return
+         line_exclude_json = re.sub(r"[^{]{'\w+': ?[^{]{.*?}}", "", line)
-         return self.bracket_regex.search(line)
+         return self.bracket_regex.search(line_exclude_json)
  
Fix nested JSON obj false positive
## Code Before:

from ansiblelint import AnsibleLintRule
import re


class VariableHasSpacesRule(AnsibleLintRule):
    id = '206'
    shortdesc = 'Variables should have spaces before and after: {{ var_name }}'
    description = 'Variables should have spaces before and after: ``{{ var_name }}``'
    severity = 'LOW'
    tags = ['formatting']
    version_added = 'v4.0.0'

    variable_syntax = re.compile(r"{{.*}}")
    bracket_regex = re.compile(r"{{[^{' -]|[^ '}-]}}")

    def match(self, file, line):
        if not self.variable_syntax.search(line):
            return
        return self.bracket_regex.search(line)

## Instruction:
Fix nested JSON obj false positive
## Code After:

from ansiblelint import AnsibleLintRule
import re


class VariableHasSpacesRule(AnsibleLintRule):
    id = '206'
    shortdesc = 'Variables should have spaces before and after: {{ var_name }}'
    description = 'Variables should have spaces before and after: ``{{ var_name }}``'
    severity = 'LOW'
    tags = ['formatting']
    version_added = 'v4.0.0'

    variable_syntax = re.compile(r"{{.*}}")
    bracket_regex = re.compile(r"{{[^{' -]|[^ '}-]}}")

    def match(self, file, line):
        if not self.variable_syntax.search(line):
            return
        line_exclude_json = re.sub(r"[^{]{'\w+': ?[^{]{.*?}}", "", line)
        return self.bracket_regex.search(line_exclude_json)
