Skip to content

Commit

Permalink
Add a yaml linting subcommand (#1023)
Browse files Browse the repository at this point in the history
Co-authored-by: Andreas Kloeckner <[email protected]>
  • Loading branch information
a-alveyblanc and inducer authored Oct 11, 2023
1 parent 3c60b86 commit 3eee406
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 2 deletions.
31 changes: 30 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ types-PyYAML = "^0.1.5"
# tests for code questions use question code that has numpy
numpy = "^1.19"

yamllint = "^1.32.0"

# enable with "-E postgres"
[tool.poetry.extras]
postgres = ["psycopg2"]
Expand Down
51 changes: 50 additions & 1 deletion relate/bin/relate.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,49 @@ def expand_yaml(yml_file, repo_root):
# }}}


# {{{ code test
# {{{ lint YAML
def lint_yaml(args):
import os

from yamllint import linter
from yamllint.cli import show_problems
from yamllint.config import YamlLintConfig

conf = YamlLintConfig(file=args.config_file)

had_problems = False

def check_file(name):
nonlocal had_problems

# expanded yaml is missing a newline at the end of the
# file which causes the linter to complain, so we add a
# newline :)
expanded_yaml = expand_yaml(name, args.repo_root) + "\n"

problems = list(linter.run(expanded_yaml, conf))
show_problems(problems, name, "auto", None)

had_problems = had_problems or bool(problems)

for item in args.files:
if os.path.isdir(item):
for root, _, filenames in os.walk(item):
for f in filenames:
filepath = os.path.join(root, f)
if not conf.is_file_ignored(f) and conf.is_yaml_file(f):
check_file(filepath)
else:
check_file(item)

print(f"{had_problems=}")

return int(had_problems)

# }}}


# {{{ code test
def test_code_question(page_desc, repo_root) -> bool:
if page_desc.type not in [
"PythonCodeQuestion",
Expand Down Expand Up @@ -305,6 +346,14 @@ def main() -> None:
parser_expand_yaml.add_argument("YAML_FILE")
parser_expand_yaml.set_defaults(func=expand_yaml_ui)

parser_lint_yaml = subp.add_parser("lint-yaml")
parser_lint_yaml.add_argument("--repo-root", default=os.getcwd())
parser_lint_yaml.add_argument("--config-file", default="./.yamllint")
parser_lint_yaml.add_argument("files", metavar="FILES",
nargs="+",
help="List of directories or files to lint")
parser_lint_yaml.set_defaults(func=lint_yaml)

args = parser.parse_args()

if not hasattr(args, "func"):
Expand Down
11 changes: 11 additions & 0 deletions tests/test_lint_yaml/.yamllint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extends: default
rules:
line-length:
max: 200
level: warning
document-start: disable
indentation: disable
empty-lines: disable
commas: disable
hyphens: disable
comments: disable
Empty file.
6 changes: 6 additions & 0 deletions tests/test_lint_yaml/fail.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extends: default

rules:
line-length:
max: 200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
bad
11 changes: 11 additions & 0 deletions tests/test_lint_yaml/pass.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extends: default
rules:
line-length:
max: 200
level: warning
document-start: disable
indentation: disable
empty-lines: disable
commas: disable
hyphens: disable
comments: disable
20 changes: 20 additions & 0 deletions tests/test_lint_yaml/test_lint_yaml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import os
import sys

import pytest


@pytest.mark.parametrize("yaml_file", ["pass.yml", "fail.yml"])
def test_yaml_lint(yaml_file):
from subprocess import Popen
thisdir = os.path.dirname(os.path.realpath(__file__))
stream = Popen([sys.executable, "-m", "relate", "lint-yaml",
"--config-file",
os.path.join(thisdir, ".yamllint.yml"),
os.path.join(thisdir, yaml_file)])
stream.wait()

if stream.returncode and "pass" in yaml_file:
raise Exception("File that was supposed to pass did not pass")
elif stream.returncode == 0 and "fail" in yaml_file:
raise Exception("File that was supposed to fail did not fail")

0 comments on commit 3eee406

Please sign in to comment.