Skip to content

Commit

Permalink
Merge branch 'master' into pb/ruff
Browse files Browse the repository at this point in the history
  • Loading branch information
pmpbaptista authored Nov 20, 2023
2 parents 1f2c81e + 66ffaba commit b52d38b
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 17 deletions.
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ target-version = "py38"
# Same as Black.
line-length = 88

[tool.ruff.per-file-ignores]
"tests/**/*.py" = ["S101"] # Use of assert detected.

[tool.ruff.mccabe]
# Implicit 10 is too low for our codebase, even black uses 18 as default.
max-complexity = 20
Expand Down
39 changes: 37 additions & 2 deletions tests/test_zuul_lint.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
"""Zuul Linter Tests."""
import pathlib
import subprocess
import tempfile

import pytest

from zuul_lint import __main__ as zuul_lint


def setup_tmp_list_of_files():
"""Create a temporary directory with a list of files.
Returns
-------
A Path object representing the temporary directory.
"""
tmp_path = pathlib.Path(tempfile.mkdtemp())
for i in range(2):
with pathlib.Path.open(tmp_path / f"file{i}.yaml", "w", encoding="utf-8") as f:
f.write("hello")
return tmp_path


def test_invalid():
"""Test that the linter correctly detects errors in an invalid Zuul YAML file.
Expand All @@ -29,7 +47,24 @@ def test_valid():
pytest.fail: If the linter fails unexpectedly.
"""
try:
subprocess.check_call(["python", "-m", "zuul_lint",
"tests/data/zuul-config-valid.yaml"])
subprocess.check_call(
["python", "-m", "zuul_lint", "tests/data/zuul-config-valid.yaml"],
)
except subprocess.CalledProcessError as e:
pytest.fail(e)


def test_get_zuul_yaml_files_find():
"""Test that get_zuul_yaml_files() finds files."""
tmp_path = setup_tmp_list_of_files()
default_len = 2
zuul_yaml_files = [file.name for file in zuul_lint.get_zuul_yaml_files(tmp_path)]
assert len(zuul_yaml_files) == default_len
assert "file0.yaml" in zuul_yaml_files
assert "file1.yaml" in zuul_yaml_files

tmp_path = tmp_path / "subdir"
tmp_path.mkdir()
assert len(zuul_lint.get_zuul_yaml_files(tmp_path)) == 0

assert len(zuul_lint.get_zuul_yaml_files(tmp_path / "invalid_path")) == 0
60 changes: 45 additions & 15 deletions zuul_lint/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
A linter for Zuul configuration files.
"""
import argparse
import importlib.metadata
import json
import pathlib
import sys

import pkg_resources
import yaml
from jsonschema import Draft7Validator

Expand Down Expand Up @@ -45,6 +45,28 @@ def zuul_schema():
return json.load(f)


def get_zuul_yaml_files(path):
"""Retrieve a list of Zuul YAML files from the specified path.
Args:
----
path (Path): The path to search for Zuul YAML files.
Returns:
-------
List[Path]: A list of Path objects representing the Zuul YAML files found.
"""
zuul_yaml_files = []
if path.is_file() and path.suffix == ".yaml":
zuul_yaml_files.append(path)
elif path.is_dir():
for p in path.iterdir():
zuul_yaml_files.extend(get_zuul_yaml_files(p))
else:
print(f"Skipping {path}")
return zuul_yaml_files


def lint(f, schema):
"""Validate a YAML file against a JSON schema.
Expand All @@ -63,16 +85,20 @@ def lint(f, schema):
# see https://github.com/Julian/jsonschema/issues/646
v = Draft7Validator(schema)

with pathlib.Path.open(pathlib.Path(f), encoding="utf-8") as yaml_in:
try:
obj = yaml.safe_load(yaml_in)
va_errors = v.iter_errors(obj)
for e in va_errors:
print(e, file=sys.stderr)
try:
with pathlib.Path.open(pathlib.Path(f), encoding="utf-8") as yaml_in:
try:
obj = yaml.safe_load(yaml_in)
va_errors = v.iter_errors(obj)
for e in va_errors:
print(e, file=sys.stderr)
errors += 1
except yaml.YAMLError as e:
print(e)
errors += 1
except yaml.YAMLError as e:
print(e)
errors += 1
except FileNotFoundError as e:
print(f"{e.filename} not found!\nExiting")
sys.exit(1)
return errors


Expand All @@ -87,16 +113,20 @@ def main():
parser.add_argument(
"--version",
action="version",
version=pkg_resources.get_distribution("zuul_lint").version,
version=importlib.metadata.version("zuul-lint"),
)
parser.add_argument("file", nargs="+", help="file(s) to lint")
parser.add_argument("file", nargs="+", help="file(s) or paths to lint")
args = parser.parse_args()
schema = zuul_schema()
errors = 0
zuul_yaml_files = []

for f in args.file:
errors += lint(f, schema=schema)
path = pathlib.Path(f)
zuul_yaml_files.extend(get_zuul_yaml_files(path))

print(f"Linting {len(zuul_yaml_files)} files")

if errors:
if errors := sum(lint(f, schema=schema) for f in zuul_yaml_files):
sys.stderr.flush()
print(f"Failed with {errors} errors.")
sys.exit(1)
Expand Down

0 comments on commit b52d38b

Please sign in to comment.