Skip to content

bundle init from the workspace UI creates an extra empty directory at the Git folder root #6142

Description

@peloyeje

Summary

Running bundle init on a custom template from the Databricks workspace UI
creates an extra, empty directory named after project_name at the root of the
Git folder
, in addition to correctly scaffolding the bundle at its intended
nested path. The UI then redirects to the stray directory rather than to the
generated bundle.

Reproduced on CLI v1.9.0 (the version the workspace UI runs).

Steps to reproduce

  1. Create a Git folder in the workspace from a repo containing a custom bundle
    template. The template's output path is nested and derived from prompt values:
    projects/{{.group}}/{{.project_name}}/.
  2. From the workspace UI, run the bundle-init wizard against that template.
  3. Answer the prompts, e.g. group=alpha, project_name=my_bundle.

Expected

Only the nested bundle is created:

<git folder>/
  projects/alpha/my_bundle/
    databricks.yml
    src/my_bundle            (NOTEBOOK)

Actual

The nested bundle is created correctly, plus an empty directory at the Git
folder root:

<git folder>/
  my_bundle/                            <-- stray
  projects/alpha/my_bundle/
    databricks.yml
    src/my_bundle            (NOTEBOOK)

The UI redirects to
the stray directory, not to the generated bundle.

Notes on scope

  • Reproduces with two different variants of the template — one whose preamble
    skips a directory, and one that skips no directory at all. The stray directory
    appears either way, so it is not caused by {{skip}} of a directory.
  • The template uses template_dir in its schema to share a template tree between
    two variant schemas. I have not tested whether template_dir is required to
    trigger this.
  • The stray directory is harmless in itself (empty, Git-ignored), but the wizard
    redirecting to it is misleading - it looks like the bundle failed to generate.

Claude investigation

persistToDisk creates every visited directory even when all its files were
skipped, which is intentional (added in #3885, libs/template/renderer.go:358-385
at v1.9.0):

for _, dir := range r.visitedDirs {
    if dir == "." { continue }
    _, err := out.Stat(ctx, dir)
    ...
    err = out.Mkdir(ctx, dir)
}

visitedDirs entries are template-rendered relative paths
(renderer.go:263), so the intended behaviour is for the filer to resolve them
against the output directory. Something in that resolution appears to produce a
root-level directory named only after the leaf path segment.

I could not reproduce it outside the
workspace: constructOutputFiler (libs/template/writer.go:63) selects
WorkspaceFilesExtensionsClient only when the output path starts with
/Workspace/ and dbr.RunsOnRuntime(ctx) is true. Off-DBR, a /Workspace/...
--output-dir is treated as a local path, so the workspace filer path is
unreachable from a laptop. Every local bundle init with the same template and
the same inputs produces a clean tree with no stray directory.

Given the UI redirect also points at the stray path, it may be the wizard passing
an unexpected --output-dir rather than the renderer mishandling a correct one.
I can't distinguish those two from outside.

Minimal template shape

The relevant structure, with no project-specific content:

templates/
  base/
    library/constants.tmpl
    template/
      __preamble.tmpl
      projects/{{.group}}/{{.project_name}}/
        databricks.yml.tmpl
        src/{{.project_name}}.py.tmpl
        {{.project_name}}.sql.tmpl
  variant-python/databricks_template_schema.json    # template_dir: ../base, language=python
  variant-sql/databricks_template_schema.json       # template_dir: ../base, language=sql

__preamble.tmpl skips the surface the selected language does not use:

{{skip "__preamble"}}
{{if eq .language "python"}}
  {{skip "projects/{{.group}}/{{.project_name}}/{{.project_name}}.sql"}}
{{else}}
  {{skip "projects/{{.group}}/{{.project_name}}/src"}}
{{end}}

The stray directory appears for both variants, including the Python one, which
skips no directory.

Environment

  • CLI v1.9.0 (workspace UI)
  • Custom template with template_dir, output path projects/{{.group}}/{{.project_name}}/
  • Workspace on AWS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions