blob: e224595caed1a78ae316103a42d12d4423572b82 [file] [log] [blame]
# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Provides utility for linting OWNERS."""
import logging
import os
from pathlib import Path
import re
from typing import Union
from chromite.lint.linters import whitespace
# Cross-repository includes take the form:
# include [server/path[:branch]:]/path/to/file
INCLUDE_RE = re.compile(
r"^include +((?P<repo>[^:]*):((?P<branch>[^:]*):)?)?(?P<path>[^\s]*)"
)
# Current version of our owners repo.
SHARED_OWNERS_BRANCH = "v1"
def lint_data(path: Union[str, os.PathLike], data: str) -> bool:
"""Run basic checks on |data|.
Args:
path: The name of the file (for diagnostics).
data: The file content to lint.
Returns:
True if everything passed.
"""
ret = whitespace.LintData(path, data)
lines = data.splitlines()
if not lines:
ret = False
logging.error("%s: empty owners file not allowed", path)
for i, line in enumerate(lines):
if "\t" in line:
ret = False
logging.error('%s:%i: no tabs allowed: "%s"', path, i, line)
lstrip = line.lstrip()
if lstrip != line:
ret = False
logging.error(
'%s:%i: no leading whitespace allowed: "%s"', path, i, line
)
m = INCLUDE_RE.match(lstrip)
if m:
if m.group("repo") in ("chromiumos/owners", "chromeos/owners"):
if m.group("branch") != SHARED_OWNERS_BRANCH:
ret = False
logging.error(
'%s:%i: shared owners must use branch "%s", not "%s"',
path,
i,
SHARED_OWNERS_BRANCH,
m.group("branch"),
)
p = m.group("path")
if not p.startswith("/"):
ret = False
logging.error(
'%s:%i: shared owners files use absolute paths: "%s"',
path,
i,
line,
)
if p.split("/")[-1] == "OWNERS":
ret = False
logging.error(
"%s:%i: shared owners files may not include plain "
'"OWNERS": "%s"',
path,
i,
line,
)
return ret
def lint_path(path: Union[str, os.PathLike]) -> bool:
"""Run basic checks on |path|.
Args:
path: The name of the file.
Returns:
True if everything passed.
"""
path = Path(path)
if path.exists():
return lint_data(path, path.read_text(encoding="utf-8"))
else:
return True