Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions src/rapids_pre_commit_hooks/codeowners.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class CodeownersLine:


class CodeownersTransform(Protocol):
def __call__(self, *, project_prefix: str) -> str: ...
def __call__(self, *, org: str, project_prefix: str) -> str: ...


@dataclasses.dataclass
Expand All @@ -49,14 +49,15 @@ class RequiredCodeownersLine:
after: list[str] = dataclasses.field(default_factory=list)


def hard_coded_codeowners(owners: str) -> CodeownersTransform:
return lambda *, project_prefix: owners # noqa: ARG005
def hard_coded_codeowners(owners: dict[str, str]) -> CodeownersTransform:
return lambda *, org, project_prefix: f"@{org}/{owners[org]}" # noqa: ARG005


def project_codeowners(category: str) -> CodeownersTransform:
return (
lambda *,
project_prefix: f"@rapidsai/{project_prefix}-{category}-codeowners"
org,
project_prefix: f"@{org}/{project_prefix}-{category}-codeowners"
)


Expand All @@ -74,7 +75,11 @@ def required_codeowners_list(
"/.github/",
"/ci/",
],
[hard_coded_codeowners("@rapidsai/ci-codeowners")],
[
hard_coded_codeowners(
{"rapidsai": "ci-codeowners", "NVIDIA": "adi-ci-codeowners"}
)
],
)
REQUIRED_PACKAGING_CODEOWNERS_LINES = required_codeowners_list(
[
Expand All @@ -85,7 +90,14 @@ def required_codeowners_list(
"/.pre-commit-config.yaml",
"/.devcontainer/",
],
[hard_coded_codeowners("@rapidsai/packaging-codeowners")],
[
hard_coded_codeowners(
{
"rapidsai": "packaging-codeowners",
"NVIDIA": "adi-packaging-codeowners",
}
)
],
)
REQUIRED_CPP_CODEOWNERS_LINES = required_codeowners_list(
[
Expand Down Expand Up @@ -175,7 +187,9 @@ def check_codeowners_line(
for required_codeowners_line in required_codeowners_lines(args):
if required_codeowners_line.file == codeowners_line.file.filename:
required_owners = [
required_owner(project_prefix=args.project_prefix)
required_owner(
org=args.org, project_prefix=args.project_prefix
)
for required_owner in required_codeowners_line.owners
]

Expand Down Expand Up @@ -247,7 +261,7 @@ def check_codeowners(linter: Linter, args: argparse.Namespace) -> None:
lambda line: line[0].file, found_files
):
owners_text = " ".join(
owner(project_prefix=args.project_prefix)
owner(org=args.org, project_prefix=args.project_prefix)
for owner in required_codeowners_line.owners
)
new_text += (
Expand All @@ -274,6 +288,12 @@ def main() -> None:
help="project prefix to insert for project-specific team names",
required=True,
)
m.argparser.add_argument(
"--org",
metavar="<organization>",
help="name of organization the project nbelongs to",
default="rapidsai",
)
m.argparser.add_argument(
"--ci",
help="enforce rules for CI codeowners",
Expand Down
75 changes: 70 additions & 5 deletions tests/rapids_pre_commit_hooks/test_codeowners.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
codeowners.RequiredCodeownersLine(
file="pyproject.toml",
owners=[
codeowners.hard_coded_codeowners("@rapidsai/ci-codeowners"),
codeowners.hard_coded_codeowners(
{"rapidsai": "ci-codeowners", "NVIDIA": "adi-ci-codeowners"}
),
],
allow_extra=True,
after=["CMakeLists.txt"],
Expand Down Expand Up @@ -126,13 +128,14 @@ def test_parse_codeowners_line(content, skip):


@pytest.mark.parametrize(
["content", "warnings"],
["content", "org", "warnings"],
[
pytest.param(
"""\
> CMakeLists.txt @rapidsai/cudf-cmake-codeowners
: ~~~~~~~~~~~~~~filename
""",
"rapidsai",
[],
id="good",
),
Expand All @@ -144,6 +147,7 @@ def test_parse_codeowners_line(content, skip):
: ~~~~~~~~~~~~~~warnings.0.replacements.0
: ^warnings.0.replacements.1
""",
"rapidsai",
[
{
"replacements": [
Expand All @@ -161,6 +165,7 @@ def test_parse_codeowners_line(content, skip):
: ~~~~~~~~~~~~~~warnings.0.span
: ~~~~~~~~~~~~~~warnings.0.replacements.0
""",
"rapidsai",
[
{
"replacements": [
Expand All @@ -175,13 +180,68 @@ def test_parse_codeowners_line(content, skip):
> pyproject.toml @someone-else @rapidsai/ci-codeowners
: ~~~~~~~~~~~~~~filename
""",
"rapidsai",
[],
id="extraneous-owner-allow-extra",
),
pytest.param(
"""\
> CMakeLists.txt @NVIDIA/cudf-cmake-codeowners
: ~~~~~~~~~~~~~~filename
""",
"NVIDIA",
[],
id="nvidia-org-cmake",
),
pytest.param(
"""\
> CMakeLists.txt @rapidsai/cudf-cmake-codeowners
: ~~~~~~~~~~~~~~filename
: ~~~~~~~~~~~~~~warnings.0.span
: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~warnings.0.replacements.0
: ^warnings.0.replacements.1
""", # noqa: E501
"NVIDIA",
[
{
"replacements": [
"",
" @NVIDIA/cudf-cmake-codeowners",
],
},
],
id="nvidia-org-cmake-wrong-owner",
),
pytest.param(
"""\
> pyproject.toml @NVIDIA/adi-ci-codeowners
: ~~~~~~~~~~~~~~filename
""",
"NVIDIA",
[],
id="nvidia-org-ci",
),
pytest.param(
"""\
> pyproject.toml @rapidsai/ci-codeowners
: ~~~~~~~~~~~~~~filename
: ~~~~~~~~~~~~~~warnings.0.span
: ^warnings.0.replacements.0
""",
"NVIDIA",
[
{
"replacements": [
" @NVIDIA/adi-ci-codeowners",
],
},
],
id="nvidia-org-ci-wrong-owner",
),
],
)
@patch_required_codeowners_lines
def test_check_codeowners_line(content, warnings):
def test_check_codeowners_line(content, org, warnings):
content, spans = parse_named_spans(content)
warnings = [
LintWarning(
Expand All @@ -206,7 +266,10 @@ def test_check_codeowners_line(content, warnings):
linter = Linter(".github/CODEOWNERS", content, "verify-codeowners")
found_files = []
codeowners.check_codeowners_line(
linter, Mock(project_prefix="cudf"), codeowners_line, found_files
linter,
Mock(org=org, project_prefix="cudf"),
codeowners_line,
found_files,
)
assert linter.warnings == warnings
assert found_files == [
Expand Down Expand Up @@ -341,5 +404,7 @@ def test_check_codeowners(content, warnings):
]

linter = Linter(".github/CODEOWNERS", content, "verify-codeowners")
codeowners.check_codeowners(linter, Mock(project_prefix="cudf"))
codeowners.check_codeowners(
linter, Mock(org="rapidsai", project_prefix="cudf")
)
assert linter.warnings == warnings
Loading