Skip to content

feat: support CUE @embed via data attr on cue_instance and cue_module#26

Open
cgrindel wants to merge 2 commits intoseh:mainfrom
cgrindel:embed_support
Open

feat: support CUE @embed via data attr on cue_instance and cue_module#26
cgrindel wants to merge 2 commits intoseh:mainfrom
cgrindel:embed_support

Conversation

@cgrindel
Copy link
Copy Markdown

Summary

  • Add a data attribute (allow_files = True) to both cue_instance and cue_module so non-.cue files can be staged alongside a package's .cue files in the Bazel sandbox.
  • Motivation: CUE v0.12.0+ supports @embed(file=…) / @embed(glob=…) directives (activated per file with @extern(embed)), which resolve paths relative to the directory containing the referring .cue file. Today cue_instance.srcs is .cue-only (allow_files = [".cue"]), and the existing srcs / qualified_srcs on the output-producing rules are passed to CUE as CLI "packageless file" args (merged into evaluation, not staged as siblings). So @embed directives can't find their targets under Bazel.
  • The fix threads declared data files through CUEInstanceInfo.transitive_files and the module-runfiles depset. No changes to cue-run-from-runfiles: Bazel's runfiles tree already places the files at their workspace-relative paths, which mirror the CUE module layout, so CUE's embed interpreter resolves them naturally.
  • Module-boundary enforcement (no .. escapes, no symlink escapes) is deferred to CUE at evaluation time rather than duplicated in Starlark — avoids drift from CUE's canonical rules.

Changes

  • cue/cue.bzl:
    • CUEModuleInfo gains an external_data_files depset field.
    • cue_module and cue_instance both gain a data = attr.label_list(allow_files = True) attribute.
    • _cue_instance_impl includes ctx.files.data (and the module's external_data_files) in transitive_files.
    • _cue_module_runfiles_impl includes external_data_files in its runfiles depset so module-level data reaches consumers (e.g. cue_exported_files).

Test plan

  • `bazel test //...` — 17 / 17 tests pass (14 pre-existing + 3 new embed tests).
  • New golden-file integration tests under `test/testdata/embed/`, matching the existing `cue_test` pattern:
    • basic/ — single-file `@embed(file=default.conf.template, type=text)`
    • glob/ — multi-file `@embed(glob=payloads/*.json)` (exercises that the whole package dir is staged, not just one file)
    • transitive/ — `app` depends on `lib`; `lib` embeds a sibling `greeting.txt`. Verifies `data` on a transitive `cue_instance` flows through to the consumer's action inputs.
  • Buildifier check on touched files — no formatting changes needed.

Notes

  • Attribute naming: chose `data` over a CUE-specific name (e.g. `embed_files`) to match Bazel convention (`py_library`, `sh_library`, `filegroup`) — it's what users grep for, and it also covers any future non-`@embed` reason to co-locate sibling files.
  • No automated negative test for "file outside module root" — since enforcement is deferred to CUE, that path produces a CUE runtime error (not a Starlark one). The existing test suite has no `analysistest` usage; keeping it that way for this PR.

cgrindel and others added 2 commits April 24, 2026 00:55
CUE v0.12.0+ supports embedding sibling non-.cue files via @embed directives, resolved relative to the referring .cue file's directory. Under Bazel, this requires staging those sibling files in the same sandbox location as the .cue file. Previously cue_instance.srcs was .cue-only with no companion attribute, so @embed directives couldn't find their targets.

Add a data attribute (allow_files = True) to both cue_instance and cue_module, threading declared files through CUEInstanceInfo.transitive_files and the module runfiles depset. No changes to cue-run-from-runfiles: Bazel's runfiles tree already places data files at their workspace-relative paths, which mirror the CUE module layout, so CUE's embed interpreter resolves them naturally. Module-boundary enforcement is deferred to CUE at evaluation time.

Adds integration tests for three scenarios: single-file @embed(file=...), multi-file @embed(glob=...), and a transitive case where an instance's dep embeds its own siblings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds an embed_module_data test that registers a data file on cue_module.data (not on any cue_instance.data) and embeds it from a consuming instance, locking in CUEModuleInfo.external_data_files propagation. Also clarifies the data-attr docs to say runfile paths (workspace-relative within the containing repository) and fixes a pre-existing pacakge typo.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cgrindel cgrindel marked this pull request as ready for review April 24, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant