Skip to content

Commit 82b62c4

Browse files
Use a shared AGENTS.md file for templates (#6017)
## Changes Stacked on #5996. The four standalone templates (`default`, `default-scala`, `default-sql`, `dbt-sql`) carried byte-identical `AGENTS.md`/`CLAUDE.md` files. This moves the content into one shared library (`templates/common/library`) that `newRenderer` parses into every template's namespace, and reduces each template's files to one-line `{{template}}` stubs. - [x] target branch must be set to `main` before merging ## Tests Template and pipelines acceptance goldens are unchanged; `task test-update-templates` passes with no diff.
1 parent b327a7f commit 82b62c4

14 files changed

Lines changed: 114 additions & 166 deletions

File tree

libs/template/builtin.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import (
88
//go:embed all:templates
99
var builtinTemplates embed.FS
1010

11+
// sharedLibraryDir holds definitions shared across templates; it has no schema, so builtin() excludes it.
12+
const sharedLibraryDir = "common"
13+
14+
// sharedLibraryFS is parsed into every template's namespace by newRenderer.
15+
var sharedLibraryFS, _ = fs.Sub(builtinTemplates, "templates/"+sharedLibraryDir+"/"+libraryDirName)
16+
1117
// builtinTemplate represents a template that is built into the CLI.
1218
type builtinTemplate struct {
1319
Name string
@@ -32,6 +38,11 @@ func builtin() ([]builtinTemplate, error) {
3238
continue
3339
}
3440

41+
// The shared library dir is not a template; skip it.
42+
if entry.Name() == sharedLibraryDir {
43+
continue
44+
}
45+
3546
templateFS, err := fs.Sub(templates, entry.Name())
3647
if err != nil {
3748
return nil, err

libs/template/renderer.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,16 @@ func newRenderer(
7575
// Initialize new template, with helper functions loaded
7676
tmpl := template.New("").Funcs(helpers)
7777

78-
// Find user-defined templates in the library directory
79-
matches, err := fs.Glob(templateFS, path.Join(libraryDir, "*"))
78+
// Parse the shared library before the template's own, so a same-named
79+
// definition in the template's library takes precedence.
80+
tmpl, err := parseLibrary(tmpl, sharedLibraryFS, "*")
8081
if err != nil {
8182
return nil, err
8283
}
8384

84-
// Parse user-defined templates.
85-
// Note: we do not call [ParseFS] with the glob directly because
86-
// it returns an error if no files match the pattern.
87-
if len(matches) != 0 {
88-
tmpl, err = tmpl.ParseFS(templateFS, matches...)
89-
if err != nil {
90-
return nil, err
91-
}
85+
tmpl, err = parseLibrary(tmpl, templateFS, path.Join(libraryDir, "*"))
86+
if err != nil {
87+
return nil, err
9288
}
9389

9490
srcFS, err := fs.Sub(templateFS, path.Clean(templateDir))
@@ -109,6 +105,19 @@ func newRenderer(
109105
}, nil
110106
}
111107

108+
// parseLibrary parses files in fsys matching pattern into tmpl, tolerating no matches
109+
// (unlike [template.Template.ParseFS], which errors when nothing matches).
110+
func parseLibrary(tmpl *template.Template, fsys fs.FS, pattern string) (*template.Template, error) {
111+
matches, err := fs.Glob(fsys, pattern)
112+
if err != nil {
113+
return nil, err
114+
}
115+
if len(matches) == 0 {
116+
return tmpl, nil
117+
}
118+
return tmpl.ParseFS(fsys, matches...)
119+
}
120+
112121
// Executes the template by applying config on it. Returns the materialized template
113122
// as a string
114123
func (r *renderer) executeTemplate(templateDefinition string) (string, error) {

libs/template/renderer_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,34 @@ func TestRendererWithAssociatedTemplateInLibrary(t *testing.T) {
155155
assert.Equal(t, "shreyas.goenka@databricks.com", strings.Trim(string(b), "\n\r"))
156156
}
157157

158+
func TestRendererSharedLibraryAndOverride(t *testing.T) {
159+
tmpDir := t.TempDir()
160+
161+
ctx := t.Context()
162+
ctx = cmdctx.SetWorkspaceClient(ctx, nil)
163+
helpers := loadHelpers(ctx)
164+
r, err := newRenderer(ctx, nil, helpers, os.DirFS("."), "./testdata/library-override/template", "./testdata/library-override/library")
165+
require.NoError(t, err)
166+
167+
err = r.walk()
168+
require.NoError(t, err)
169+
out, err := filer.NewLocalClient(tmpDir)
170+
require.NoError(t, err)
171+
err = r.persistToDisk(ctx, out)
172+
require.NoError(t, err)
173+
174+
b, err := os.ReadFile(filepath.Join(tmpDir, "out"))
175+
require.NoError(t, err)
176+
got := string(b)
177+
178+
// agents_md is defined only in the shared library, so rendering it (a heading)
179+
// without error proves the shared library is parsed into the template's namespace.
180+
assert.Contains(t, got, "shared: #")
181+
// claude_md is defined in both the shared library and this template's own
182+
// library; the template's own definition must take precedence.
183+
assert.Contains(t, got, "own: OWN WINS")
184+
}
185+
158186
func TestRendererExecuteTemplate(t *testing.T) {
159187
templateText := `"{{.count}} items are made of {{.Material}}".
160188
{{if eq .Animal "sheep" }}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{{- /*
2+
* Template for the AGENTS.md / CLAUDE.md files created in new projects.
3+
*
4+
* Goal for this file is to point agents to Databricks AI Tools for guidance.
5+
* A secondary goal is to offer a placeholder to users to extend with their own instructions.
6+
* It is a non-goal to inline all instructions.
7+
*
8+
*/ -}}
9+
10+
{{- define "agents_md" -}}
11+
# Declarative Automation Bundles Project
12+
13+
This project uses Declarative Automation Bundles (DABs) for deployment. Add project-specific instructions below.
14+
15+
## For AI Agents: Use Databricks AI Tools
16+
17+
**BEFORE any other action, read the `databricks-core` skill.**
18+
19+
It sets you up to work with this project reliably: CLI authentication, profile
20+
selection, data discovery, and the bundle deployment workflow. Without it,
21+
results are often slower and less accurate.
22+
23+
If this skill is not available (Databricks AI Tools are not installed), you can install them for your coding agent in seconds:
24+
25+
```bash
26+
databricks aitools install
27+
```
28+
29+
If the CLI is not installed, see: https://docs.databricks.com/dev-tools/cli/install
30+
31+
---
32+
33+
## Project Instructions
34+
35+
<!-- Add your project-specific instructions, coding conventions, or notes here -->
36+
{{- end -}}
37+
38+
{{- define "claude_md" -}}
39+
# CLAUDE.md
40+
41+
Project guidance for AI agents lives in AGENTS.md.
42+
Claude Code loads it via the import below.
43+
44+
@AGENTS.md
45+
{{- end -}}
Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1 @@
1-
{{- /*
2-
* Template for the AGENTS.md / CLAUDE.md files created in new projects.
3-
*
4-
* Goal for this file is to point agents to Databricks AI Tools for guidance.
5-
* A secondary goal is to offer a placeholder to users to extend with their own instructions.
6-
* It is a non-goal to inline all instructions.
7-
*
8-
*/ -}}
9-
# Declarative Automation Bundles Project
10-
11-
This project uses Declarative Automation Bundles (DABs) for deployment. Add project-specific instructions below.
12-
13-
## For AI Agents: Use Databricks AI Tools
14-
15-
**BEFORE any other action, read the `databricks-core` skill.**
16-
17-
It sets you up to work with this project reliably: CLI authentication, profile
18-
selection, data discovery, and the bundle deployment workflow. Without it,
19-
results are often slower and less accurate.
20-
21-
If this skill is not available (Databricks AI Tools are not installed), you can install them for your coding agent in seconds:
22-
23-
```bash
24-
databricks aitools install
25-
```
26-
27-
If the CLI is not installed, see: https://docs.databricks.com/dev-tools/cli/install
28-
29-
---
30-
31-
## Project Instructions
32-
33-
<!-- Add your project-specific instructions, coding conventions, or notes here -->
1+
{{template "agents_md" .}}
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1 @@
1-
# CLAUDE.md
2-
3-
Project guidance for AI agents lives in AGENTS.md.
4-
Claude Code loads it via the import below.
5-
6-
@AGENTS.md
1+
{{template "claude_md" .}}
Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1 @@
1-
{{- /*
2-
* Template for the AGENTS.md / CLAUDE.md files created in new projects.
3-
*
4-
* Goal for this file is to point agents to Databricks AI Tools for guidance.
5-
* A secondary goal is to offer a placeholder to users to extend with their own instructions.
6-
* It is a non-goal to inline all instructions.
7-
*
8-
*/ -}}
9-
# Declarative Automation Bundles Project
10-
11-
This project uses Declarative Automation Bundles (DABs) for deployment. Add project-specific instructions below.
12-
13-
## For AI Agents: Use Databricks AI Tools
14-
15-
**BEFORE any other action, read the `databricks-core` skill.**
16-
17-
It sets you up to work with this project reliably: CLI authentication, profile
18-
selection, data discovery, and the bundle deployment workflow. Without it,
19-
results are often slower and less accurate.
20-
21-
If this skill is not available (Databricks AI Tools are not installed), you can install them for your coding agent in seconds:
22-
23-
```bash
24-
databricks aitools install
25-
```
26-
27-
If the CLI is not installed, see: https://docs.databricks.com/dev-tools/cli/install
28-
29-
---
30-
31-
## Project Instructions
32-
33-
<!-- Add your project-specific instructions, coding conventions, or notes here -->
1+
{{template "agents_md" .}}
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1 @@
1-
# CLAUDE.md
2-
3-
Project guidance for AI agents lives in AGENTS.md.
4-
Claude Code loads it via the import below.
5-
6-
@AGENTS.md
1+
{{template "claude_md" .}}
Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1 @@
1-
{{- /*
2-
* Template for the AGENTS.md / CLAUDE.md files created in new projects.
3-
*
4-
* Goal for this file is to point agents to Databricks AI Tools for guidance.
5-
* A secondary goal is to offer a placeholder to users to extend with their own instructions.
6-
* It is a non-goal to inline all instructions.
7-
*
8-
*/ -}}
9-
# Declarative Automation Bundles Project
10-
11-
This project uses Declarative Automation Bundles (DABs) for deployment. Add project-specific instructions below.
12-
13-
## For AI Agents: Use Databricks AI Tools
14-
15-
**BEFORE any other action, read the `databricks-core` skill.**
16-
17-
It sets you up to work with this project reliably: CLI authentication, profile
18-
selection, data discovery, and the bundle deployment workflow. Without it,
19-
results are often slower and less accurate.
20-
21-
If this skill is not available (Databricks AI Tools are not installed), you can install them for your coding agent in seconds:
22-
23-
```bash
24-
databricks aitools install
25-
```
26-
27-
If the CLI is not installed, see: https://docs.databricks.com/dev-tools/cli/install
28-
29-
---
30-
31-
## Project Instructions
32-
33-
<!-- Add your project-specific instructions, coding conventions, or notes here -->
1+
{{template "agents_md" .}}
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1 @@
1-
# CLAUDE.md
2-
3-
Project guidance for AI agents lives in AGENTS.md.
4-
Claude Code loads it via the import below.
5-
6-
@AGENTS.md
1+
{{template "claude_md" .}}

0 commit comments

Comments
 (0)