Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions cmd/mdatagen/internal/cfggen/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,10 @@ func (r *Ref) String() string {
func (r *Ref) CacheKey() string {
return r.String()
}

func LocalizeRef(refPath, importRootPath string) string {
if importRootPath == "" || !strings.HasPrefix(refPath, importRootPath+"/") {
return refPath
}
return strings.TrimPrefix(refPath, importRootPath)
}
28 changes: 28 additions & 0 deletions cmd/mdatagen/internal/cfggen/namespace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,31 @@ func TestNamespaceOf_NoSlash(t *testing.T) {
result := namespaceOf("noslash")
require.Empty(t, result)
}

func TestLocalizeRef(t *testing.T) {
tests := []struct {
name string
refPath string
importRootPath string
expected string
}{
{
name: "same root collector ref becomes local absolute",
refPath: "go.opentelemetry.io/collector/filter.config",
importRootPath: "go.opentelemetry.io/collector",
expected: "/filter.config",
},
{
name: "different root ref stays external",
refPath: "go.opentelemetry.io/collector/filter.config",
importRootPath: "github.com/open-telemetry/opentelemetry-collector-contrib",
expected: "go.opentelemetry.io/collector/filter.config",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.expected, LocalizeRef(tt.refPath, tt.importRootPath))
})
}
}
41 changes: 24 additions & 17 deletions cmd/mdatagen/internal/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ func run(ymlPath string) error {

ymlDir := filepath.Dir(ymlPath)
packageName := filepath.Base(ymlDir)
importRootPath, err := helpers.RootPackage(ymlDir)
if err != nil {
return fmt.Errorf("unable to determine import root path: %w", err)
}

raw, readErr := os.ReadFile(filepath.Clean(ymlPath))
if readErr != nil {
Expand All @@ -104,7 +108,7 @@ func run(ymlPath string) error {
if !slices.Contains(nonComponents, md.Status.Class) {
toGenerate[filepath.Join(tmplDir, "status.go.tmpl")] = filepath.Join(codeDir, "generated_status.go")
err = generateFile(filepath.Join(tmplDir, "component_test.go.tmpl"),
filepath.Join(ymlDir, "generated_component_test.go"), md, packageName)
filepath.Join(ymlDir, "generated_component_test.go"), md, packageName, importRootPath)
if err != nil {
return err
}
Expand All @@ -124,7 +128,7 @@ func run(ymlPath string) error {
}

err = generateFile(filepath.Join(tmplDir, "package_test.go.tmpl"),
filepath.Join(ymlDir, "generated_package_test.go"), md, packageName)
filepath.Join(ymlDir, "generated_package_test.go"), md, packageName, importRootPath)
if err != nil {
return err
}
Expand All @@ -133,7 +137,7 @@ func run(ymlPath string) error {
err = inlineReplace(
filepath.Join(tmplDir, "readme.md.tmpl"),
filepath.Join(ymlDir, "README.md"),
md, statusStart, statusEnd, md.GeneratedPackageName)
md, statusStart, statusEnd, md.GeneratedPackageName, importRootPath)
if err != nil {
return err
}
Expand Down Expand Up @@ -225,19 +229,19 @@ func run(ymlPath string) error {
}

for tmpl, dst := range toGenerate {
if err := generateFile(tmpl, dst, md, md.GeneratedPackageName); err != nil {
if err := generateFile(tmpl, dst, md, md.GeneratedPackageName, importRootPath); err != nil {
return err
}
}

if err := generateConfigFiles(md, ymlDir); err != nil {
if err := generateConfigFiles(md, ymlDir, importRootPath); err != nil {
return fmt.Errorf("failed to generate config files: %w", err)
}

return nil
}

func getTemplateFuncMap(md Metadata) template.FuncMap {
func getTemplateFuncMap(md Metadata, importRootPath string) template.FuncMap {
return template.FuncMap{
"publicVar": func(s string) (string, error) {
return helpers.FormatIdentifier(s, true)
Expand Down Expand Up @@ -344,6 +348,9 @@ func getTemplateFuncMap(md Metadata) template.FuncMap {
"toLowerCamelCase": func(s string) string {
return joinCamelCase(strings.Split(s, "_"), false)
},
"schemaRef": func(ref string) string {
return cfggen.LocalizeRef(ref, importRootPath)
},
"inc": func(i int) int { return i + 1 },
"distroURL": distroURL,
"isExporter": func() bool {
Expand Down Expand Up @@ -406,21 +413,21 @@ func templatize(tmplFile string, funcMap template.FuncMap) *template.Template {
ParseFS(TemplateFS, "templates/helper.tmpl", strings.ReplaceAll(tmplFile, "\\", "/")))
}

func executeTemplate(tmplFile string, md Metadata, goPackage string, fns template.FuncMap) ([]byte, error) {
func executeTemplate(tmplFile string, md Metadata, goPackage, importRootPath string, fns template.FuncMap) ([]byte, error) {
tmpl := templatize(tmplFile, fns)
buf := bytes.Buffer{}

if err := tmpl.Execute(&buf, TemplateContext{Metadata: md, Package: goPackage}); err != nil {
if err := tmpl.Execute(&buf, TemplateContext{Metadata: md, Package: goPackage, ImportRootPath: importRootPath}); err != nil {
return []byte{}, fmt.Errorf("failed executing template: %w", err)
}
return buf.Bytes(), nil
}

func generateFile(tmplFile, outputFile string, md Metadata, goPackage string) error {
return generateFileWithFns(tmplFile, outputFile, md, goPackage, getTemplateFuncMap(md))
func generateFile(tmplFile, outputFile string, md Metadata, goPackage, importRootPath string) error {
return generateFileWithFns(tmplFile, outputFile, md, goPackage, importRootPath, getTemplateFuncMap(md, importRootPath))
}

func inlineReplace(tmplFile, outputFile string, md Metadata, start, end, goPackage string) error {
func inlineReplace(tmplFile, outputFile string, md Metadata, start, end, goPackage, importRootPath string) error {
var readmeContents []byte
var err error
if readmeContents, err = os.ReadFile(filepath.Clean(outputFile)); err != nil {
Expand All @@ -436,7 +443,7 @@ func inlineReplace(tmplFile, outputFile string, md Metadata, start, end, goPacka
md.GithubProject = "open-telemetry/opentelemetry-collector-contrib"
}

buf, err := executeTemplate(tmplFile, md, goPackage, getTemplateFuncMap(md))
buf, err := executeTemplate(tmplFile, md, goPackage, importRootPath, getTemplateFuncMap(md, importRootPath))
if err != nil {
return err
}
Expand All @@ -449,12 +456,12 @@ func inlineReplace(tmplFile, outputFile string, md Metadata, start, end, goPacka
return nil
}

func generateFileWithFns(tmplFile, outputFile string, md Metadata, goPackage string, fns template.FuncMap) error {
func generateFileWithFns(tmplFile, outputFile string, md Metadata, goPackage, importRootPath string, fns template.FuncMap) error {
if err := os.Remove(outputFile); err != nil && !errors.Is(err, fs.ErrNotExist) {
return fmt.Errorf("unable to remove generated file %q: %w", outputFile, err)
}

result, err := executeTemplate(tmplFile, md, goPackage, fns)
result, err := executeTemplate(tmplFile, md, goPackage, importRootPath, fns)
if err != nil {
return err
}
Expand Down Expand Up @@ -534,7 +541,7 @@ func validateYAMLKeyOrder(raw []byte) error {
return nil
}

func generateConfigFiles(md Metadata, mdDir string) error {
func generateConfigFiles(md Metadata, mdDir, _ string) error {
if md.Config != nil {
resolver := cfggen.NewResolver(md.PackageName, md.Status.Class, md.Type, mdDir)
resolvedSchema, err := resolver.ResolveSchema(md.Config)
Expand Down Expand Up @@ -564,8 +571,8 @@ func generateConfigGoStruct(md Metadata, outputDir string) error {
tmplFile := filepath.Join("templates", "config_from_cfggen.go.tmpl")
dstFile := filepath.Join(outputDir, "generated_config.go")

fns := cfggen.WithCfgFns(getTemplateFuncMap(md), rootPkg, md.PackageName)
return generateFileWithFns(tmplFile, dstFile, md, packageName, fns)
fns := cfggen.WithCfgFns(getTemplateFuncMap(md, rootPkg), rootPkg, md.PackageName)
return generateFileWithFns(tmplFile, dstFile, md, packageName, rootPkg, fns)
}

func joinCamelCase(parts []string, exported bool) string {
Expand Down
44 changes: 38 additions & 6 deletions cmd/mdatagen/internal/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ func TestGenerateConfigFiles(t *testing.T) {

gitInit(t, root)
require.NoError(t, os.WriteFile(filepath.Join(root, "go.mod"), []byte("module testmodule\n"), 0o600))
err := generateConfigFiles(tt.md, tmpdir)
err := generateConfigFiles(tt.md, tmpdir, "testmodule")
if tt.wantErr {
require.Error(t, err)
return
Expand Down Expand Up @@ -564,7 +564,7 @@ func TestGenerateConfigFiles_GoStructError(t *testing.T) {
Status: &Status{Class: "receiver"},
Config: &cfggen.ConfigMetadata{Type: "object"},
}
err := generateConfigFiles(md, t.TempDir())
err := generateConfigFiles(md, t.TempDir(), "testmodule")
require.Error(t, err)
require.Contains(t, err.Error(), "failed to generate config Go struct")
}
Expand All @@ -580,7 +580,7 @@ func TestGenerateConfigFiles_WriteError(t *testing.T) {
Type: "object",
},
}
err := generateConfigFiles(md, "/nonexistent/path/that/does/not/exist")
err := generateConfigFiles(md, "/nonexistent/path/that/does/not/exist", "testmodule")
require.Error(t, err)
require.Contains(t, err.Error(), "failed to write config schema")
}
Expand Down Expand Up @@ -855,7 +855,7 @@ Some info about a component
readmeFile := filepath.Join(tmpdir, "README.md")
require.NoError(t, os.WriteFile(readmeFile, []byte(tt.markdown), 0o600))

err := inlineReplace("templates/readme.md.tmpl", readmeFile, md, statusStart, statusEnd, "metadata")
err := inlineReplace("templates/readme.md.tmpl", readmeFile, md, statusStart, statusEnd, "metadata", "go.opentelemetry.io/collector")
require.NoError(t, err)

require.FileExists(t, filepath.Join(tmpdir, "README.md"))
Expand Down Expand Up @@ -977,7 +977,7 @@ const (
t.Run(tt.name, func(t *testing.T) {
tmpdir := t.TempDir()
err := generateFile("templates/status.go.tmpl",
filepath.Join(tmpdir, "generated_status.go"), tt.md, "metadata")
filepath.Join(tmpdir, "generated_status.go"), tt.md, "metadata", "go.opentelemetry.io/collector")
require.NoError(t, err)
actual, err := os.ReadFile(filepath.Clean(filepath.Join(tmpdir, "generated_status.go")))
require.NoError(t, err)
Expand Down Expand Up @@ -1063,7 +1063,7 @@ func Tracer(settings component.TelemetrySettings) trace.Tracer {
t.Run(tt.name, func(t *testing.T) {
tmpdir := t.TempDir()
err := generateFile("templates/telemetry.go.tmpl",
filepath.Join(tmpdir, "generated_telemetry.go"), tt.md, "metadata")
filepath.Join(tmpdir, "generated_telemetry.go"), tt.md, "metadata", "go.opentelemetry.io/collector")
require.NoError(t, err)
actual, err := os.ReadFile(filepath.Clean(filepath.Join(tmpdir, "generated_telemetry.go")))
require.NoError(t, err)
Expand All @@ -1072,6 +1072,38 @@ func Tracer(settings component.TelemetrySettings) trace.Tracer {
}
}

func TestGenerateConfigSchema_LocalizesSameRootRefs(t *testing.T) {
enabled := true
md := Metadata{
Type: "foo",
ResourceAttributes: map[AttributeName]Attribute{
"resource.attr": {
Description: "resource attr",
EnabledPtr: &enabled,
FullName: "resource.attr",
},
},
Events: map[EventName]Event{
"default.event": {
Signal: Signal{
Enabled: true,
Description: "event description",
},
},
},
}

tmpdir := t.TempDir()
outputFile := filepath.Join(tmpdir, "config.schema.yaml")
err := generateFile("templates/config.schema.yaml.tmpl", outputFile, md, "metadata", "go.opentelemetry.io/collector")
require.NoError(t, err)

actual, err := os.ReadFile(filepath.Clean(outputFile))
require.NoError(t, err)
require.Contains(t, string(actual), "$ref: /filter.config")
require.NotContains(t, string(actual), "$ref: go.opentelemetry.io/collector/filter.config")
}

func gitInit(t *testing.T, dir string) {
t.Helper()
cmd := exec.Command("git", "init")
Expand Down
2 changes: 2 additions & 0 deletions cmd/mdatagen/internal/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type TemplateContext struct {
Metadata
// Package name for generated code.
Package string
// ImportRootPath is the repo-local import prefix used to localize same-tree schema references.
ImportRootPath string
}

func LoadMetadata(filePath string) (Metadata, error) {
Expand Down
Loading
Loading