Skip to content
Open
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
5 changes: 3 additions & 2 deletions conformance/scripts/check_conformance_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ def split_patterns(value: str) -> list[str]:

def path_matches(path: str, pattern: str) -> bool:
normalized = path.strip("/")
is_dir_pattern = pattern.endswith("/")
normalized_pattern = pattern.strip("/")
if not normalized_pattern:
return False
if normalized_pattern.endswith("/**"):
prefix = normalized_pattern[:-3].rstrip("/")
return normalized == prefix or normalized.startswith(prefix + "/")
if normalized_pattern.endswith("/"):
return normalized.startswith(normalized_pattern)
if is_dir_pattern:
return normalized.startswith(normalized_pattern + "/")
return fnmatchcase(normalized, normalized_pattern)


Expand Down
7 changes: 5 additions & 2 deletions conformance/scripts/select_ci_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,15 @@

def path_matches(path: str, pattern: str) -> bool:
normalized = path.strip("/")
is_dir_pattern = pattern.endswith("/")
normalized_pattern = pattern.strip("/")
if not normalized_pattern:
return False
if normalized_pattern.endswith("/**"):
prefix = normalized_pattern[:-3].rstrip("/")
return normalized == prefix or normalized.startswith(prefix + "/")
if normalized_pattern.endswith("/"):
return normalized.startswith(normalized_pattern)
if is_dir_pattern:
return normalized.startswith(normalized_pattern + "/")
return fnmatchcase(normalized, normalized_pattern)


Expand Down
49 changes: 49 additions & 0 deletions conformance/scripts/test_check_conformance_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from __future__ import annotations

import importlib
import json
import os
import subprocess
Expand All @@ -14,6 +15,54 @@

SCRIPT = Path(__file__).with_name("check_conformance_policy.py")

# Modules that each carry a copy of path_matches and must stay in sync.
PATH_MATCH_MODULES = [
"check_conformance_policy",
"validate_conformance_pr",
"select_ci_adapters",
]


class PathMatchesTest(unittest.TestCase):
def each_path_matches(self):
sys.path.insert(0, str(SCRIPT.parent))
try:
for module_name in PATH_MATCH_MODULES:
module = importlib.import_module(module_name)
yield module_name, module.path_matches
finally:
sys.path.remove(str(SCRIPT.parent))

def test_directory_pattern_matches_files_under_directory(self) -> None:
for module_name, path_matches in self.each_path_matches():
with self.subTest(module=module_name):
self.assertTrue(path_matches("src/proto/wire.go", "src/proto/"))
self.assertTrue(path_matches("src/proto/nested/deep.rs", "src/proto/"))
self.assertTrue(path_matches("/src/proto/wire.go", "src/proto/"))

def test_directory_pattern_does_not_overmatch(self) -> None:
for module_name, path_matches in self.each_path_matches():
with self.subTest(module=module_name):
self.assertFalse(path_matches("src/protocol/wire.go", "src/proto/"))
self.assertFalse(path_matches("src/proto", "src/proto/"))
self.assertFalse(path_matches("other/src/proto/wire.go", "src/proto/"))

def test_recursive_glob_pattern_still_matches(self) -> None:
for module_name, path_matches in self.each_path_matches():
with self.subTest(module=module_name):
self.assertTrue(path_matches("conformance/vectors/receipt.json", "conformance/vectors/**"))
self.assertTrue(path_matches("conformance/vectors", "conformance/vectors/**"))
self.assertFalse(path_matches("conformance/schemas/x.json", "conformance/vectors/**"))

def test_exact_and_glob_patterns_still_match(self) -> None:
for module_name, path_matches in self.each_path_matches():
with self.subTest(module=module_name):
self.assertTrue(path_matches("conformance/operations.json", "conformance/operations.json"))
self.assertTrue(path_matches("pkg/parse.go", "pkg/*.go"))
self.assertFalse(path_matches("pkg/readme.md", "pkg/*.go"))
self.assertFalse(path_matches("pkg/parse.go", ""))
self.assertFalse(path_matches("pkg/parse.go", "/"))


class CheckConformancePolicyTest(unittest.TestCase):
def run_policy(
Expand Down
7 changes: 5 additions & 2 deletions conformance/scripts/validate_conformance_pr.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ def split_patterns(value: str) -> list[str]:

def path_matches(path: str, pattern: str) -> bool:
normalized = path.strip("/")
is_dir_pattern = pattern.endswith("/")
normalized_pattern = pattern.strip("/")
if not normalized_pattern:
return False
if normalized_pattern.endswith("/**"):
prefix = normalized_pattern[:-3].rstrip("/")
return normalized == prefix or normalized.startswith(prefix + "/")
if normalized_pattern.endswith("/"):
return normalized.startswith(normalized_pattern)
if is_dir_pattern:
return normalized.startswith(normalized_pattern + "/")
return fnmatchcase(normalized, normalized_pattern)


Expand Down