Skip to content

Add JSON output to bundle init reporting where the template materialized - #6161

Draft
pavloKozlov wants to merge 3 commits into
mainfrom
bundle-init-report-bundle-roots
Draft

Add JSON output to bundle init reporting where the template materialized#6161
pavloKozlov wants to merge 3 commits into
mainfrom
bundle-init-report-bundle-roots

Conversation

@pavloKozlov

@pavloKozlov pavloKozlov commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

bundle init gives callers no machine-readable indication of where it wrote the template, so a caller that passes --output-dir has to assume the bundle root is named after the project. That holds for the built-in templates, which output {{.project_name}}/, but not for a custom template whose output path is nested: with output path projects/{{.group}}/{{.project_name}}/ the bundle lands at <output-dir>/projects/alpha/yz/, and a caller looking for <output-dir>/yz/ misses it.

Related: #6142.

Adds an InitResult rendered by bundle init -o json:

{
  "template_name": "custom",
  "output_dir": "/path/to/output",
  "bundle_roots": ["projects/alpha/yz"]
}

bundle_roots are the directories that received a bundle configuration file, relative to the resolved output_dir, slash-separated and sorted (a root that is output_dir itself is "."). They come from the files persistToDisk actually persisted, so a file removed by a {{skip}} directive is not reported, and all four names in bundle/config.FileNames are recognised. Paths use path rather than filepath and stay relative, so the contract is identical for the local and workspace filers. Configure now resolves --output-dir with filepath.Abs and retains it, so a relative value such as .. can be joined with a bundle root.

A template can emit several bundle configuration files, in which case each root is an independent bundle, so this is a list; callers expecting one root should handle len != 1 explicitly. Field names are part of the JSON contract — new fields should be additive.

Compatibility. Default text output is unchanged: rendering is gated on flags.OutputJSON, and the success message is still printed by Materialize. No existing golden files change, and Materialize's signature is untouched, so cmd/pipelines/init.go is unaffected.

Tests. Unit coverage of the root derivation (nested, multiple sorted, ".", all four file names, de-duplication, and a {{skip}}-removed file driven through persistToDisk), plus two acceptance cases: a nested-output custom template asserting ["projects/alpha/yz"] and no stray top-level yz/, and a built-in template pinning the standard shape. Both scripts redirect stderr so the goldens pin only the JSON.

…lized

`bundle init` gave callers no machine-readable indication of where it wrote
the template. The success message is the template's own rendered text, so a
caller that passes `--output-dir` could not learn which subdirectory under it
became the bundle root, and had to assume it is named after the project. That
assumption holds for the built-in templates, which output `{{.project_name}}/`,
but not for a custom template whose output path is nested.

Add an `InitResult` reported by `bundle init -o json`:

    {
      "template_name": "custom",
      "output_dir": "/path/to/output",
      "bundle_roots": ["projects/alpha/yz"]
    }

`bundle_roots` are the directories that received a bundle configuration file,
relative to the resolved output directory, slash-separated and sorted. They are
derived from the files `persistToDisk` actually persisted, so a configuration
file removed by a `{{skip}}` directive is not reported. Paths stay relative and
slash-based so the contract is identical for the local and workspace filers.

A template may emit more than one bundle configuration file, in which case each
root is an independent bundle, so this is a list; callers that expect exactly
one should handle len != 1 explicitly.

The default text output is unchanged: rendering is gated on JSON output, and
the success message is still printed by `Materialize`. `Configure` now resolves
the output directory with `filepath.Abs` and retains it, so a relative
`--output-dir` such as `..` can be joined with a bundle root by the caller.
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 01ee4b0

Run: 30912193150

Env 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
💚​ aws linux 4 4 306 1072 5:23
💚​ aws windows 4 4 308 1070 8:03
💚​ azure linux 4 4 305 1072 5:13
💚​ azure windows 4 4 307 1070 8:07
💚​ gcp linux 1 5 306 1072 5:25
💚​ gcp windows 1 5 308 1070 8:07
8 interesting tests: 4 RECOVERED, 4 SKIP
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo 💚​R 💚​R 💚​R 💚​R 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo/root 💚​R 💚​R 💚​R 💚​R
💚​ TestFetchRepositoryInfoAPI_FromRepo/subdir 💚​R 💚​R 💚​R 💚​R
Top 6 slowest tests (at least 2 minutes):
duration env testname
7:31 azure windows TestAccept
7:12 gcp windows TestAccept
7:05 aws windows TestAccept
2:56 azure linux TestAccept
2:50 aws linux TestAccept
2:50 gcp linux TestAccept

The two new acceptance tests compared `output_dir` verbatim, but it is an OS
path, so Windows rendered it backslash-separated and the golden files only
matched on Unix. Pipe the JSON through sed to normalize the separators, keeping
a single golden per case. `bundle_roots` are always slash-separated, so they are
unaffected.

Also drop the unit cases that the acceptance tests already cover end to end
(nested root, a root at the output directory, and the empty input). The
remaining rows cover what the acceptance tests cannot reach without a template
fixture each: the four configuration file names, ordering, de-duplication, and
files merely named like a configuration file.
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.

2 participants