blob: 5648574e632a5d41ecd9f3da0016caf5ed6c8d20 [file] [log] [blame] [edit]
# Copyright 2022 The Chromium OS Authors. All rights reserved.
# 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