blob: f16d6e3d4fd7691faa97554615d30a2dda8922c1 [file] [log] [blame]
# Copyright 2022 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Ensure all modules have OWNERS files."""
import logging
from pathlib import Path
from typing import Callable, Optional, Tuple
from pw_presubmit import (
PresubmitContext,
PresubmitFailure,
presubmit,
)
_LOG: logging.Logger = logging.getLogger(__name__)
def upstream_pigweed_applicability(
ctx: PresubmitContext,
path: Path,
) -> Optional[Path]:
"""Return a parent of path required to have an OWNERS file, or None."""
parts: Tuple[str, ...] = path.relative_to(ctx.root).parts
if len(parts) >= 2 and parts[0].startswith('pw_'):
return ctx.root / parts[0]
if len(parts) >= 3 and parts[0] in ('targets', 'third_party'):
return ctx.root / parts[0] / parts[1]
return None
ApplicabilityFunc = Callable[[PresubmitContext, Path], Optional[Path]]
def presubmit_check(
applicability: ApplicabilityFunc = upstream_pigweed_applicability,
) -> presubmit.Check:
"""Create a presubmit check for the presence of OWNERS files."""
@presubmit.check(name='module_owners')
def check(ctx: PresubmitContext) -> None:
"""Presubmit check that ensures all modules have OWNERS files."""
modules_to_check = set()
for path in ctx.paths:
result = applicability(ctx, path)
if result:
modules_to_check.add(result)
errors = 0
for module in sorted(modules_to_check):
_LOG.debug('Checking module %s', module)
owners_path = module / 'OWNERS'
if not owners_path.is_file():
_LOG.error('%s is missing an OWNERS file', module)
errors += 1
continue
with owners_path.open() as ins:
contents = [x.strip() for x in ins.read().strip().splitlines()]
wo_comments = [x for x in contents if not x.startswith('#')]
owners = [x for x in wo_comments if 'per-file' not in x]
if len(owners) < 1:
_LOG.error('%s is too short: add owners', owners_path)
if errors:
raise PresubmitFailure
return check