Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to recognize base file types #1461

Merged
merged 1 commit into from Mar 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions examples/galaxy.yml
@@ -0,0 +1,14 @@
name: foo
namespace: bar
version: 1.2.3
authors:
- John
readme: ../README.md
description: ...
dependencies:
"other_namespace.collection1": ">=1.0.0"
"other_namespace.collection2": ">=2.0.0,<3.0.0"
"anderson55.my_collection": "*" # note: "*" selects the highest version available
license:
- GPL
- Apache
18 changes: 18 additions & 0 deletions src/ansiblelint/config.py
Expand Up @@ -14,6 +14,8 @@
DEFAULT_KINDS = [
# Do not sort this list, order matters.
{"requirements": "**/meta/requirements.yml"}, # v1 only
# https://docs.ansible.com/ansible/latest/dev_guide/collections_galaxy_meta.html
{"galaxy": "**/galaxy.yml"}, # Galaxy collection meta
{"reno": "**/releasenotes/*/*.{yaml,yml}"}, # reno release notes
{"playbook": "**/playbooks/*.{yml,yaml}"},
{"playbook": "**/*playbook*.{yml,yaml}"},
Expand All @@ -29,10 +31,26 @@
{"yaml": "**/molecule/*/{base,molecule}.{yaml,yml}"}, # molecule config
{"requirements": "**/requirements.yml"}, # v2 and v1
{"playbook": "**/molecule/*/*.{yaml,yml}"}, # molecule playbooks
{"yaml": "**/{.ansible-lint,.yamllint}"},
{"yaml": "**/*.{yaml,yml}"},
{"yaml": "**/.*.{yaml,yml}"},
]

BASE_KINDS = [
# These assignations are only for internal use and are only inspired by
# MIME/IANA model. Their purpose is to be able to process a file based on
# it type, including generic processing of text files using the prefix.
{"text/json": "**/*.json"}, # standardized
{"text/markdown": "**/*.md"}, # https://tools.ietf.org/html/rfc7763
{"text/rst": "**/*.rst"}, # https://en.wikipedia.org/wiki/ReStructuredText
{"text/ini": "**/*.ini"},
# YAML has no official IANA assignation
{"text/yaml": "**/{.ansible-lint,.yamllint}"},
{"text/yaml": "**/*.{yaml,yml}"},
{"text/yaml": "**/.*.{yaml,yml}"},
]


options = Namespace(
colored=True,
cwd=".",
Expand Down
21 changes: 17 additions & 4 deletions src/ansiblelint/file_utils.py
Expand Up @@ -13,7 +13,7 @@

import wcmatch.pathlib

from ansiblelint.config import options
from ansiblelint.config import BASE_KINDS, options
from ansiblelint.constants import FileType

if TYPE_CHECKING:
Expand Down Expand Up @@ -67,12 +67,17 @@ def expand_paths_vars(paths: List[str]) -> List[str]:
return paths


def kind_from_path(path: Path) -> str:
"""Determine the file kind based on its name."""
def kind_from_path(path: Path, base=False) -> str:
"""Determine the file kind based on its name.

When called with base=True, it will return the base file type instead
of the explicit one. That is expected to return 'yaml' for any yaml files.
"""
# pathlib.Path.match patterns are very limited, they do not support *a*.yml
# glob.glob supports **/foo.yml but not multiple extensions
pathex = wcmatch.pathlib.PurePath(path.absolute().resolve())
for entry in options.kinds:
kinds = options.kinds if not base else BASE_KINDS
for entry in kinds:
for k, v in entry.items():
if pathex.globmatch(
v,
Expand All @@ -83,6 +88,11 @@ def kind_from_path(path: Path) -> str:
),
):
return str(k)

if base:
# Unknown base file type is default
return ""

if path.is_dir():
return "role"

Expand Down Expand Up @@ -146,6 +156,9 @@ def __init__(
else:
self.dir = str(self.path.parent.resolve())

# determine base file kind (yaml, xml, ini, ...)
self.base_kind = kind_from_path(self.path, base=True)

def __getitem__(self, key: Any) -> Any:
"""Provide compatibility subscriptable support."""
if key == 'path':
Expand Down
2 changes: 1 addition & 1 deletion src/ansiblelint/rules/YamllintRule.py
Expand Up @@ -76,7 +76,7 @@ def matchyaml(self, file: Lintable) -> List["MatchError"]:
"""Return matches found for a specific YAML text."""
matches: List["MatchError"] = []
filtered_matches = []
if file.kind == 'role':
if file.base_kind != 'text/yaml':
return matches

if YamllintRule.config:
Expand Down
1 change: 1 addition & 0 deletions test/TestUtils.py
Expand Up @@ -364,6 +364,7 @@ def test_is_playbook():
"../roles/geerlingguy.mysql/tasks/configure.yml",
"tasks",
), # relative path involved
("galaxy.yml", "galaxy"),
),
)
def test_default_kinds(monkeypatch, path: str, kind: FileType) -> None:
Expand Down