Skip to content

Commit 6fb50e7

Browse files
committed
Tighten vendored ExternalData smoke coverage
1 parent bd7b23f commit 6fb50e7

4 files changed

Lines changed: 29 additions & 7 deletions

File tree

.github/workflows/smoke.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,5 @@ jobs:
6161
python smoke/ci/verify_materialization.py `
6262
--build-dir $env:SMOKE_BUILD_DIR `
6363
--cache-root $env:NAM_CACHE_ROOT `
64-
--expected-mode ${{ matrix.link_mode }}
64+
--expected-mode ${{ matrix.link_mode }} `
65+
--forbid-tree .nam/media/assets

cmake/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ consumer to verify:
206206
- Windows and Linux runners
207207
- explicit `symlink`, `hardlink`, and `copy` modes
208208
- shared cache reuse via `${{ github.workspace }}/.nam-cache`
209+
- absence of the legacy vendored payload staging tree under `.nam/<target>/assets`
209210
- post-build size and materialization statistics
210211

211212
Typical local smoke runs are:

cmake/vendor/ExternalData-NAM.cmake

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
22
# file LICENSE.rst or https://cmake.org/licensing for details.
3-
#
4-
# Vendored by Nabla Asset Manifests from CMake 4.2 `ExternalData.cmake`.
5-
# NAM patch scope is intentionally narrow:
6-
# - on Windows prefer hardlinks, then symlinks, then copies when exposing
7-
# objects from the content-addressed store
83

94
#[=======================================================================[.rst:
105
ExternalData
@@ -184,12 +179,16 @@ calling any of the functions provided by this module.
184179
host. The default order is ``hardlink -> symlink -> copy`` on Windows and
185180
``symlink -> hardlink -> copy`` elsewhere.
186181
182+
When ``ExternalData_NO_SYMLINKS`` is set, the ``symlink`` mode is removed
183+
from automatic selection and cannot be requested explicitly.
184+
187185
.. variable:: ExternalData_STATE_ROOT
188186
189187
The ``ExternalData_STATE_ROOT`` variable may be set to place module-managed
190188
metadata outside ``ExternalData_BINARY_ROOT``. When set, ``ExternalData``
191189
stores its hash records and build driver stamps under this directory while
192190
still materializing real data files under ``ExternalData_BINARY_ROOT``.
191+
By default, these files continue to be placed next to the materialized data.
193192
194193
.. variable:: ExternalData_OBJECT_STORES
195194
@@ -576,7 +575,8 @@ function(ExternalData_add_target target)
576575
# Users care about the data file, so hide the hash/timestamp file.
577576
COMMENT "Generating ${file}"
578577
# Use a dedicated build stamp as the primary output so IDE
579-
# generators keep an explicit build step for each materialized file.
578+
# generators keep an explicit build step for each materialized file
579+
# even when metadata is redirected outside the data tree.
580580
# List the hash record and real file as secondary outputs.
581581
# The files must be listed in this order so CMake can hide from the
582582
# make tool that a symlink target may not be newer than the input.

smoke/ci/verify_materialization.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ def parse_args() -> argparse.Namespace:
1414
parser.add_argument("--build-dir", required=True)
1515
parser.add_argument("--cache-root", required=True)
1616
parser.add_argument("--expected-mode", required=True, choices=("symlink", "hardlink", "copy"))
17+
parser.add_argument(
18+
"--forbid-tree",
19+
action="append",
20+
default=[],
21+
help="Path relative to --build-dir that must not exist after materialization.",
22+
)
1723
return parser.parse_args()
1824

1925

@@ -57,6 +63,19 @@ def main() -> int:
5763
if not media_root.exists():
5864
raise SystemExit(f"Missing materialized tree: {media_root}")
5965

66+
forbidden_trees: list[str] = []
67+
for relative_path in args.forbid_tree:
68+
forbidden_path = (build_dir / relative_path).resolve()
69+
if forbidden_path.exists():
70+
forbidden_trees.append(str(forbidden_path))
71+
72+
if forbidden_trees:
73+
preview = ", ".join(forbidden_trees[:5])
74+
raise SystemExit(
75+
f"Expected the following paths to stay absent after materialization, "
76+
f"but found {len(forbidden_trees)} present. First entries: {preview}"
77+
)
78+
6079
files = sorted(iter_files(media_root))
6180
if not files:
6281
raise SystemExit(f"No files found under {media_root}")
@@ -110,6 +129,7 @@ def main() -> int:
110129
"build_dir": str(build_dir),
111130
"cache_root": str(cache_root),
112131
"expected_mode": args.expected_mode,
132+
"forbid_tree": args.forbid_tree,
113133
"file_count": len(files),
114134
"counts": counts,
115135
"logical_size_bytes": logical_size,

0 commit comments

Comments
 (0)