This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git


The following commit(s) were added to refs/heads/main by this push:
     new ba1e74f  Add path analysis for release candidate tags
ba1e74f is described below

commit ba1e74f7456c427920a90419fbae4ad00381e752
Author: Sean B. Palmer <[email protected]>
AuthorDate: Wed May 28 16:21:33 2025 +0100

    Add path analysis for release candidate tags
---
 atr/analysis.py | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/atr/analysis.py b/atr/analysis.py
index 8525f03..8620c73 100755
--- a/atr/analysis.py
+++ b/atr/analysis.py
@@ -133,6 +133,10 @@ VARIANT_PATTERNS: Final[list[str]] = [
     "src",
 ]
 
+_CANDIDATE_TAG: Final = r"(?: Candidate | candidate | RC | Rc | rc ) [.-]? 
[0-9]+"
+_CANDIDATE_PARTIAL: Final = re.compile(rf"(?x) - {_CANDIDATE_TAG}")
+_CANDIDATE_WHOLE: Final = re.compile(rf"(?x) ^ {_CANDIDATE_TAG} $")
+
 
 @dataclasses.dataclass
 class Analysis:
@@ -173,6 +177,20 @@ def architecture_pattern() -> str:
     return "(" + "|".join(architectures) + ")(?=[_.-])"
 
 
+def candidate_match(segment: str) -> re.Match[str] | None:
+    return _CANDIDATE_WHOLE.match(segment) or 
_CANDIDATE_PARTIAL.search(segment)
+
+
+def candidate_removed(path: pathlib.Path) -> pathlib.Path:
+    parts = []
+    for part in path.parts:
+        if _CANDIDATE_WHOLE.match(part):
+            continue
+        if part := _CANDIDATE_PARTIAL.sub("", part):
+            parts.append(part)
+    return pathlib.Path(*parts)
+
+
 def component_parse(i: int, component: str, size: int, elements: dict[str, str 
| None]) -> None:
     if i == 0:
         # CORE
@@ -293,6 +311,14 @@ def is_artifact(file_path: str | pathlib.Path) -> bool:
     return bool(search and search.group("artifact"))
 
 
+def is_candidate(path: pathlib.Path) -> bool:
+    return any(is_candidate_segment(part) for part in path.parts)
+
+
+def is_candidate_segment(segment: str) -> bool:
+    return bool(candidate_match(segment))
+
+
 def is_skippable(path: pathlib.Path) -> bool:
     if len(path.parts) < 2:
         return True


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to