Skip to content

Commit b0953a1

Browse files
committed
cmk-dev-deploy: Resolve Bazel-generated files from bazel-bin
The config deployer copied omdlib/__init__.py from the repo source tree, deploying the raw placeholder with {CMK_VERSION}.{CMK_EDITION} instead of the Bazel-substituted file. The manifest had no way to distinguish source files from generated artifacts. Fix: expose is_source from Bazel's PackageFilesInfo in the Starlark cquery formatter, propagate it as a "generated" flag through the manifest and ConfigFileEntry, and resolve generated files from bazel-bin/ in the config deployer. Change-Id: I35959d3d6d1e7580b929172baccd53272d516da4
1 parent e71d91e commit b0953a1

4 files changed

Lines changed: 50 additions & 24 deletions

File tree

packages/cmk-dev-deploy/cmk/dev_deploy/deployers/config_deployer.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
ChangeSet,
2626
ConfigDeployResult,
2727
ConfigDeploySpec,
28+
ConfigFileEntry,
2829
DeployMethod,
2930
SiteInfo,
3031
)
@@ -69,6 +70,17 @@ def _resolve_mode(entry_mode: str, spec_mode: int | None, file_chmod: str | None
6970
return mode
7071

7172

73+
def _resolve_src(entry: ConfigFileEntry, repo_root: Path) -> Path:
74+
"""Resolve the source path for a config file entry.
75+
76+
Generated files (``file_from_flag``, etc.) live under ``bazel-bin/``
77+
rather than directly in the repo tree.
78+
"""
79+
if entry.generated:
80+
return repo_root / "bazel-bin" / entry.src
81+
return repo_root / entry.src
82+
83+
7284
def _copy_dir(source: Path, dest: Path, spec: ConfigDeploySpec, repo_root: Path) -> None:
7385
"""Copy a config/data directory to the site using the Bazel-derived file list.
7486
@@ -83,7 +95,7 @@ def _copy_dir(source: Path, dest: Path, spec: ConfigDeploySpec, repo_root: Path)
8395
expected_files: set[str] = set()
8496

8597
for entry in spec.files:
86-
src_path = repo_root / entry.src
98+
src_path = _resolve_src(entry, repo_root)
8799
if not src_path.is_file():
88100
continue
89101

@@ -150,7 +162,7 @@ def _install_files(source: Path, dest: Path, spec: ConfigDeploySpec, repo_root:
150162

151163
if spec.files:
152164
for entry in spec.files:
153-
src_path = repo_root / entry.src
165+
src_path = _resolve_src(entry, repo_root)
154166
if not src_path.is_file():
155167
continue
156168
dest_file = dest / src_path.name

packages/cmk-dev-deploy/cmk/dev_deploy/manifest/reader.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ def _parse_install_spec(raw: dict[str, Any]) -> InstallSpec:
8888
def _parse_config_spec(raw: dict[str, Any]) -> ConfigDeploySpec:
8989
"""Convert a manifest config_spec dict to a ConfigDeploySpec dataclass."""
9090
mode_raw = raw["mode"]
91-
files = tuple(ConfigFileEntry(src=f["src"], mode=f["mode"]) for f in raw.get("files", []))
91+
files = tuple(
92+
ConfigFileEntry(src=f["src"], mode=f["mode"], generated=f.get("generated", False))
93+
for f in raw.get("files", [])
94+
)
9295
services = tuple(_parse_service_pair(s) for s in raw.get("services", []))
9396
return ConfigDeploySpec(
9497
source_prefix=raw["source_prefix"],

packages/cmk-dev-deploy/cmk/dev_deploy/manifest/update.py

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,9 @@ def _discover_config_specs(
363363
if not entries:
364364
continue
365365

366-
src_paths = [src for _, _, src in entries]
367-
dest_paths = [dest for dest, _, _ in entries]
368-
modes = [mode for _, mode, _ in entries if mode]
366+
src_paths = [src for _, _, src, _ in entries]
367+
dest_paths = [dest for dest, _, _, _ in entries]
368+
modes = [mode for _, mode, _, _ in entries if mode]
369369

370370
# Derive source_prefix
371371
common_src = os.path.commonpath(src_paths) if src_paths else ""
@@ -411,9 +411,13 @@ def _discover_config_specs(
411411
# Auto-classify deploy method
412412
method = _classify_config_method(common_src, target_label)
413413

414-
# Build files list
415-
files = sorted(
416-
[{"src": src, "dest": dest, "mode": fmode} for dest, fmode, src in entries],
414+
# Build files list — mark generated files (is_source=False) so the
415+
# deployer knows to resolve them from bazel-bin instead of the repo.
416+
files: list[dict[str, Any]] = sorted(
417+
[
418+
{"src": src, "dest": dest, "mode": fmode, "generated": not is_source}
419+
for dest, fmode, src, is_source in entries
420+
],
417421
key=lambda f: f["src"],
418422
)
419423

@@ -539,17 +543,18 @@ def format(target):
539543
label = "//%s:%s" % (target.label.package, target.label.name)
540544
lines = []
541545
for dest, src in pfi.dest_src_map.items():
542-
lines.append("%s\\t%s\\t%s\\t%s" % (
546+
lines.append("%s\\t%s\\t%s\\t%s\\t%s" % (
543547
label,
544548
dest,
545549
mode,
546550
src.short_path,
551+
src.is_source,
547552
))
548553
return "\\n".join(lines)
549554
"""
550555

551-
# Type alias: label -> [(dest_path, mode_str, src_short_path)]
552-
PackagingTargetIndex = dict[str, list[tuple[str, str, str]]]
556+
# Type alias: label -> [(dest_path, mode_str, src_short_path, is_source)]
557+
PackagingTargetIndex = dict[str, list[tuple[str, str, str, bool]]]
553558

554559

555560
def _cquery_packaging_targets(
@@ -603,17 +608,17 @@ def _cquery_packaging_targets(
603608
f"{result.stderr.strip()}"
604609
)
605610

606-
# Parse output lines: LABEL\tDEST\tMODE\tSRC_SHORT_PATH
611+
# Parse output lines: LABEL\tDEST\tMODE\tSRC_SHORT_PATH\tIS_SOURCE
607612
grouped: PackagingTargetIndex = {}
608613
for line in result.stdout.strip().splitlines():
609614
line = line.strip()
610615
if not line or "\t" not in line:
611616
continue
612617
parts = line.split("\t")
613-
if len(parts) != 4:
618+
if len(parts) != 5:
614619
continue
615-
label, dest, mode, src_path = parts
616-
grouped.setdefault(label, []).append((dest, mode, src_path))
620+
label, dest, mode, src_path, is_source_str = parts
621+
grouped.setdefault(label, []).append((dest, mode, src_path, is_source_str == "True"))
617622

618623
return grouped
619624

@@ -735,9 +740,9 @@ def _enrich_config_specs(
735740
unresolved.append(spec)
736741
continue
737742

738-
src_paths = [src for _, _, src in entries]
739-
dest_paths = [dest for dest, _, _ in entries]
740-
modes = [mode for _, mode, _ in entries if mode]
743+
src_paths = [src for _, _, src, _ in entries]
744+
dest_paths = [dest for dest, _, _, _ in entries]
745+
modes = [mode for _, mode, _, _ in entries if mode]
741746

742747
# Derive source_prefix (if not explicitly set)
743748
if not spec.get("source_prefix"):
@@ -759,8 +764,12 @@ def _enrich_config_specs(
759764
spec["mode"] = int(modes[0], 8)
760765

761766
# Populate files list from PackageFilesInfo
767+
enriched_files: list[dict[str, Any]] = [
768+
{"src": src, "dest": dest, "mode": mode, "generated": not is_source}
769+
for dest, mode, src, is_source in entries
770+
]
762771
spec["files"] = sorted(
763-
[{"src": src, "dest": dest, "mode": mode} for dest, mode, src in entries],
772+
enriched_files,
764773
key=lambda f: f["src"],
765774
)
766775

@@ -858,11 +867,11 @@ def _enrich_install_specs(
858867
)
859868
continue
860869

861-
modes = [mode for _, mode, _ in entries if mode]
870+
modes = [mode for _, mode, _, _ in entries if mode]
862871

863872
if len(entries) == 1:
864873
# Single-file deploy: dest IS the full site_dest path
865-
dest_path, _, src_path = entries[0]
874+
dest_path, _, src_path, _ = entries[0]
866875
if not spec.get("site_dest"):
867876
spec["site_dest"] = dest_path
868877
if not spec.get("output_basename"):
@@ -871,7 +880,7 @@ def _enrich_install_specs(
871880
# Multi-file target: find matching entry by output_basename
872881
output_basename = spec.get("output_basename", "")
873882
if output_basename:
874-
for dest, _, src in entries:
883+
for dest, _, src, _ in entries:
875884
if (
876885
os.path.basename(dest) == output_basename
877886
or os.path.basename(src) == output_basename
@@ -881,7 +890,7 @@ def _enrich_install_specs(
881890
break
882891
elif not spec.get("site_dest"):
883892
# No output_basename hint: compute common dest prefix
884-
common = os.path.commonpath([d for d, _, _ in entries])
893+
common = os.path.commonpath([d for d, _, _, _ in entries])
885894
if not common.endswith("/"):
886895
common += "/"
887896
spec["site_dest"] = common

packages/cmk-dev-deploy/cmk/dev_deploy/types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ class ConfigFileEntry:
206206

207207
src: str
208208
mode: str
209+
generated: bool = False
210+
"""True when the file is a Bazel-generated artifact (``is_source=False``)."""
209211

210212

211213
class DeployMethod(StrEnum):

0 commit comments

Comments
 (0)