You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by ar...@apache.org on 2026/07/15 15:36:58 UTC
(tooling-trusted-releases) branch arm updated: Add suggestion to avoid double-prefixing files in dist
This is an automated email from the ASF dual-hosted git repository.
alitheg pushed a commit to branch arm
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/arm by this push:
new b65a7ab6 Add suggestion to avoid double-prefixing files in dist
b65a7ab6 is described below
commit b65a7ab666f1c413483f17486e92a6d6a4ad9b0a
Author: Alastair McFarlane <ar...@apache.org>
AuthorDate: Wed Jul 15 16:36:35 2026 +0100
Add suggestion to avoid double-prefixing files in dist
---
atr/render.py | 3 +++
atr/storage/datatypes.py | 1 +
atr/storage/readers/releases.py | 2 ++
atr/tasks/checks/paths.py | 58 +++++++++++++++++++++++++++++++++++++++--
4 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/atr/render.py b/atr/render.py
index 6be66210..4c70439b 100644
--- a/atr/render.py
+++ b/atr/render.py
@@ -324,6 +324,7 @@ def render_checks_summary(
and (not info.release_level_concerns)
and (not info.release_level_exceptions)
and (not info.release_level_blockers)
+ and (not info.release_level_suggestions)
):
return None
@@ -339,6 +340,8 @@ def render_checks_summary(
release_problems_by_checker.setdefault(result.checker, []).append(result)
for result in info.release_level_blockers:
release_problems_by_checker.setdefault(result.checker, []).append(result)
+ for result in info.release_level_suggestions:
+ release_problems_by_checker.setdefault(result.checker, []).append(result)
stats_by_checker = {stat.checker: stat for stat in info.checker_stats}
all_checkers = sorted(set(release_problems_by_checker) | {stat.checker for stat in info.checker_stats})
diff --git a/atr/storage/datatypes.py b/atr/storage/datatypes.py
index 52ada271..b42cfabc 100644
--- a/atr/storage/datatypes.py
+++ b/atr/storage/datatypes.py
@@ -78,6 +78,7 @@ class PathInfo(schema.Strict):
release_level_blockers: list[sql.CheckResult] = schema.factory(list)
release_level_concerns: list[sql.CheckResult] = schema.factory(list)
release_level_exceptions: list[sql.CheckResult] = schema.factory(list)
+ release_level_suggestions: list[sql.CheckResult] = schema.factory(list)
suggestions: dict[safe.RelPath, list[sql.CheckResult]] = schema.factory(dict)
diff --git a/atr/storage/readers/releases.py b/atr/storage/readers/releases.py
index 30a796fa..b3be32c2 100644
--- a/atr/storage/readers/releases.py
+++ b/atr/storage/readers/releases.py
@@ -185,3 +185,5 @@ class GeneralPublic:
continue
if path := suggestion.safe_primary_rel_path:
cs.info.suggestions.setdefault(path, []).append(suggestion)
+ else:
+ cs.info.release_level_suggestions.append(suggestion)
diff --git a/atr/tasks/checks/paths.py b/atr/tasks/checks/paths.py
index 96080f73..89312c85 100644
--- a/atr/tasks/checks/paths.py
+++ b/atr/tasks/checks/paths.py
@@ -25,6 +25,7 @@ import aiofiles.os
import atr.analysis as analysis
import atr.attestable as attestable
import atr.classify as classify
+import atr.construct as construct
import atr.db as db
import atr.log as log
import atr.models.results as results
@@ -41,9 +42,9 @@ _ALLOWED_TOP_LEVEL: Final = frozenset(
)
_DOC_TREE_MAX_FILES: Final = 512
# Release policy fields which this check relies on - used for result caching
-INPUT_POLICY_KEYS: Final[list[str]] = ["binary_artifact_paths", "source_artifact_paths"]
+INPUT_POLICY_KEYS: Final[list[str]] = ["binary_artifact_paths", "source_artifact_paths", "download_path_suffix"]
INPUT_EXTRA_ARGS: Final[list[str]] = ["is_podling", "all_files"]
-CHECK_VERSION: Final[str] = "5"
+CHECK_VERSION: Final[str] = "6"
async def check(args: checks.FunctionArguments) -> results.Results | None:
@@ -115,6 +116,7 @@ async def check(args: checks.FunctionArguments) -> results.Results | None:
await _check_source_artifact_present(args, recorder_problems, relative_paths, base_path)
await _check_documentation_tree(recorder_problems, relative_paths)
+ await _check_download_suffix_duplication(args, recorder_suggestions, relative_paths)
return None
@@ -170,6 +172,58 @@ async def _check_documentation_tree(
)
+async def _check_download_suffix_duplication(
+ args: checks.FunctionArguments,
+ recorder_suggestions: checks.Recorder,
+ relative_paths: list[safe.RelPath],
+) -> None:
+ # A file whose first path component repeats a component of the policy's resolved download path
+ # suffix doubles that component in the published path - the suffix maven-3/3.10.0-rc-1 plus a
+ # 3.10.0-rc-1/... rel path lands at .../3.10.0-rc-1/3.10.0-rc-1/... Warn so the redundant top
+ # directory (or the {{VERSION}} in the template) gets dropped before the release ships
+ async with db.session() as data:
+ release = await data.release(
+ key=str(sql.release_key(args.project_key, args.version_key)),
+ _committee=True,
+ _project_release_policy=True,
+ ).demand(RuntimeError(f"Release {args.project_key} {args.version_key} not found"))
+
+ committee = release.committee
+ suffix = construct.resolve_download_path_suffix(
+ template=release.project.policy_download_path_suffix,
+ project_key=release.project.key,
+ version=str(release.version),
+ is_top_level=(committee is not None) and (release.project.key == committee.key),
+ )
+ if suffix is None:
+ return
+
+ suffix_components = frozenset(suffix.as_path().parts)
+ clashes: dict[str, int] = {}
+ for relative_path in relative_paths:
+ parts = relative_path.as_path().parts
+ if parts and (parts[0] in suffix_components):
+ clashes[parts[0]] = clashes.get(parts[0], 0) + 1
+
+ for component in sorted(clashes):
+ await recorder_suggestions.suggestion(
+ f"{clashes[component]} file(s) start with '{component}/', which the download path suffix"
+ " already contains. Consider removing this prefix.",
+ {
+ "component": component,
+ "suffix": str(suffix),
+ "count": clashes[component],
+ "details": (
+ f"The published path would repeat '{component}': the suffix '{suffix}' plus a "
+ f"'{component}/...' file lands at '.../{component}/{component}/...'. Consider dropping the "
+ f"top-level '{component}/' directory from the release, or remove that component from the download "
+ "path suffix when publishing."
+ ),
+ },
+ primary_rel_path=None,
+ )
+
+
async def _check_metadata_rules(
_base_path: safe.StatePath,
relative_path: safe.RelPath,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org