From cdcf86e7c70833abd34c7d5c09f7f09514957642 Mon Sep 17 00:00:00 2001 From: Drew Minnear Date: Mon, 29 Jun 2026 14:04:05 -0400 Subject: [PATCH] embed resources and skills directory in binary --- Containerfile | 13 --- README.md | 2 +- src/cmd/cmd_suite_test.go | 15 +--- src/cmd/init.go | 28 ++----- src/cmd/upgrade.go | 24 ++---- src/internal/embedded/embedded.go | 9 +++ .../internal/embedded/resources}/Makefile | 0 .../embedded/resources}/Makefile-common | 0 .../internal/embedded/resources}/ansible.cfg | 0 .../internal/embedded/resources}/pattern.sh | 0 .../resources}/values-secret.yaml.template | 0 .../embedded/skills}/pattern-author/SKILL.md | 0 .../skills}/pattern-author/reference.md | 0 src/internal/fileutils/fileutils.go | 47 ++++++----- src/internal/fileutils/fileutils_test.go | 81 +++++++++---------- src/internal/fileutils/skills.go | 16 ++-- src/main_test.go | 23 ------ 17 files changed, 98 insertions(+), 160 deletions(-) create mode 100644 src/internal/embedded/embedded.go rename {resources => src/internal/embedded/resources}/Makefile (100%) rename {resources => src/internal/embedded/resources}/Makefile-common (100%) rename {resources => src/internal/embedded/resources}/ansible.cfg (100%) rename {resources => src/internal/embedded/resources}/pattern.sh (100%) rename {resources => src/internal/embedded/resources}/values-secret.yaml.template (100%) rename {skills => src/internal/embedded/skills}/pattern-author/SKILL.md (100%) rename {skills => src/internal/embedded/skills}/pattern-author/reference.md (100%) diff --git a/Containerfile b/Containerfile index 59bbbff..7ac44de 100644 --- a/Containerfile +++ b/Containerfile @@ -17,18 +17,5 @@ FROM registry.access.redhat.com/ubi10/ubi-minimal:10.0 COPY --from=builder /build/patternizer /usr/local/bin/patternizer -ARG PATTERNIZER_RESOURCES_DIR=/tmp/resources -WORKDIR ${PATTERNIZER_RESOURCES_DIR} - -COPY resources/* . - -ARG PATTERNIZER_SKILLS_DIR=/tmp/skills -WORKDIR ${PATTERNIZER_SKILLS_DIR} - -COPY skills/ . - -ENV PATTERNIZER_RESOURCES_DIR=${PATTERNIZER_RESOURCES_DIR} -ENV PATTERNIZER_SKILLS_DIR=${PATTERNIZER_SKILLS_DIR} - ENTRYPOINT ["patternizer"] CMD ["help"] diff --git a/README.md b/README.md index 33f33f9..46610c0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Patternizer -![Version: 1.3.1](https://img.shields.io/badge/Version-1.3.1-informational?style=flat-square) +![Version: 2.0.0](https://img.shields.io/badge/Version-2.0.0-informational?style=flat-square) [![Quay Repository](https://img.shields.io/badge/Quay.io-patternizer-blue?logo=quay)](https://quay.io/repository/validatedpatterns/patternizer) [![CI Pipeline](https://github.com/validatedpatterns/patternizer/actions/workflows/build-push.yaml/badge.svg?branch=main)](https://github.com/validatedpatterns/patternizer/actions/workflows/build-push.yaml) diff --git a/src/cmd/cmd_suite_test.go b/src/cmd/cmd_suite_test.go index 76e35f6..d45d1d2 100644 --- a/src/cmd/cmd_suite_test.go +++ b/src/cmd/cmd_suite_test.go @@ -20,7 +20,6 @@ var ( binaryPath string resourcesPath string skillsPath string - projectRoot string ) func TestCmd(t *testing.T) { @@ -33,18 +32,16 @@ var _ = BeforeSuite(func() { wd, err := os.Getwd() Expect(err).NotTo(HaveOccurred()) - projectRoot, err = filepath.Abs(filepath.Join(wd, "..", "..")) + srcRoot, err := filepath.Abs(filepath.Join(wd, "..")) Expect(err).NotTo(HaveOccurred()) - resourcesPath = filepath.Join(projectRoot, "resources") + resourcesPath = filepath.Join(srcRoot, "internal", "embedded", "resources") Expect(resourcesPath).To(BeADirectory(), "Could not find resources directory") - os.Setenv("PATTERNIZER_RESOURCES_DIR", resourcesPath) - skillsPath = filepath.Join(projectRoot, "skills") + skillsPath = filepath.Join(srcRoot, "internal", "embedded", "skills") Expect(skillsPath).To(BeADirectory(), "Could not find skills directory") - os.Setenv("PATTERNIZER_SKILLS_DIR", skillsPath) - binaryPath, err = gexec.Build(filepath.Join(projectRoot, "src")) + binaryPath, err = gexec.Build(srcRoot) Expect(err).NotTo(HaveOccurred()) }) @@ -135,10 +132,6 @@ func createTestDir() string { func runCLI(dir string, args ...string) *gexec.Session { cmd := exec.Command(binaryPath, args...) cmd.Dir = dir - cmd.Env = append(os.Environ(), - "PATTERNIZER_RESOURCES_DIR="+resourcesPath, - "PATTERNIZER_SKILLS_DIR="+skillsPath, - ) session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) diff --git a/src/cmd/init.go b/src/cmd/init.go index 218d2fd..a8f8bcd 100644 --- a/src/cmd/init.go +++ b/src/cmd/init.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" + "github.com/validatedpatterns/patternizer/internal/embedded" "github.com/validatedpatterns/patternizer/internal/fileutils" "github.com/validatedpatterns/patternizer/internal/helm" "github.com/validatedpatterns/patternizer/internal/pattern" @@ -35,44 +36,27 @@ func runInit(withSecrets bool) error { return fmt.Errorf("error processing cluster group values: %w", err) } - // Copy pattern.sh and Makefile from resources - resourcesDir, err := fileutils.GetResourcesPath() - if err != nil { - return fmt.Errorf("error getting resource path: %w", err) - } - - patternShSrc := filepath.Join(resourcesDir, "pattern.sh") - patternShDst := filepath.Join(repoRoot, "pattern.sh") - if err := fileutils.CopyFile(patternShSrc, patternShDst); err != nil { + if err := fileutils.WriteEmbeddedFile(embedded.Resources, "resources/pattern.sh", filepath.Join(repoRoot, "pattern.sh"), 0o755); err != nil { return fmt.Errorf("error copying pattern.sh: %w", err) } - // Always copy ansible.cfg to the pattern repo - ansibleCfgSrc := filepath.Join(resourcesDir, "ansible.cfg") - ansibleCfgDst := filepath.Join(repoRoot, "ansible.cfg") - if err := fileutils.CopyFile(ansibleCfgSrc, ansibleCfgDst); err != nil { + if err := fileutils.WriteEmbeddedFile(embedded.Resources, "resources/ansible.cfg", filepath.Join(repoRoot, "ansible.cfg"), 0o644); err != nil { return fmt.Errorf("error copying ansible.cfg: %w", err) } - // Always copy Makefile-common to the pattern repo - makefilePatternSrc := filepath.Join(resourcesDir, "Makefile-common") - makefilePatternDst := filepath.Join(repoRoot, "Makefile-common") - if err := fileutils.CopyFile(makefilePatternSrc, makefilePatternDst); err != nil { + if err := fileutils.WriteEmbeddedFile(embedded.Resources, "resources/Makefile-common", filepath.Join(repoRoot, "Makefile-common"), 0o644); err != nil { return fmt.Errorf("error copying Makefile-common: %w", err) } - // Create a simple Makefile that includes Makefile-common (only if it doesn't exist) - makefileSrc := filepath.Join(resourcesDir, "Makefile") makefileDst := filepath.Join(repoRoot, "Makefile") if _, err := os.Stat(makefileDst); os.IsNotExist(err) { - if err := fileutils.CopyFile(makefileSrc, makefileDst); err != nil { + if err := fileutils.WriteEmbeddedFile(embedded.Resources, "resources/Makefile", makefileDst, 0o644); err != nil { return fmt.Errorf("error copying Makefile: %w", err) } } - // Handle secrets setup if requested if withSecrets { - if err := fileutils.HandleSecretsSetup(resourcesDir, repoRoot); err != nil { + if err := fileutils.HandleSecretsSetup(embedded.Resources, repoRoot); err != nil { return fmt.Errorf("error setting up secrets: %w", err) } } diff --git a/src/cmd/upgrade.go b/src/cmd/upgrade.go index 46bbf54..7a5821d 100644 --- a/src/cmd/upgrade.go +++ b/src/cmd/upgrade.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" + "github.com/validatedpatterns/patternizer/internal/embedded" "github.com/validatedpatterns/patternizer/internal/fileutils" "github.com/validatedpatterns/patternizer/internal/pattern" ) @@ -31,43 +32,30 @@ func runUpgrade(replaceMakefile bool) error { return fmt.Errorf("error removing pattern.sh: %w", err) } - // Copy resources into repo root - resourcesDir, err := fileutils.GetResourcesPath() - if err != nil { - return fmt.Errorf("error getting resource path: %w", err) - } - - // Copy pattern.sh - if err := fileutils.CopyFile(filepath.Join(resourcesDir, "pattern.sh"), patternShPath); err != nil { + if err := fileutils.WriteEmbeddedFile(embedded.Resources, "resources/pattern.sh", patternShPath, 0o755); err != nil { return fmt.Errorf("error copying pattern.sh: %w", err) } - // Copy Makefile-common - if err := fileutils.CopyFile(filepath.Join(resourcesDir, "Makefile-common"), filepath.Join(repoRoot, "Makefile-common")); err != nil { + if err := fileutils.WriteEmbeddedFile(embedded.Resources, "resources/Makefile-common", filepath.Join(repoRoot, "Makefile-common"), 0o644); err != nil { return fmt.Errorf("error copying Makefile-common: %w", err) } - // Copy ansible.cfg - if err := fileutils.CopyFile(filepath.Join(resourcesDir, "ansible.cfg"), filepath.Join(repoRoot, "ansible.cfg")); err != nil { + if err := fileutils.WriteEmbeddedFile(embedded.Resources, "resources/ansible.cfg", filepath.Join(repoRoot, "ansible.cfg"), 0o644); err != nil { return fmt.Errorf("error copying ansible.cfg: %w", err) } - // Makefile handling - makefileSrc := filepath.Join(resourcesDir, "Makefile") makefileDst := filepath.Join(repoRoot, "Makefile") if replaceMakefile { - if err := fileutils.CopyFile(makefileSrc, makefileDst); err != nil { + if err := fileutils.WriteEmbeddedFile(embedded.Resources, "resources/Makefile", makefileDst, 0o644); err != nil { return fmt.Errorf("error replacing Makefile: %w", err) } } else { - // If Makefile doesn't exist, copy it if _, err := os.Stat(makefileDst); os.IsNotExist(err) { - if err := fileutils.CopyFile(makefileSrc, makefileDst); err != nil { + if err := fileutils.WriteEmbeddedFile(embedded.Resources, "resources/Makefile", makefileDst, 0o644); err != nil { return fmt.Errorf("error copying Makefile: %w", err) } } else if err == nil { - // If Makefile exists, check for include and prepend if missing hasInclude, err := fileutils.FileContainsIncludeMakefileCommon(makefileDst) if err != nil { return fmt.Errorf("error checking Makefile for include: %w", err) diff --git a/src/internal/embedded/embedded.go b/src/internal/embedded/embedded.go new file mode 100644 index 0000000..e6f6fab --- /dev/null +++ b/src/internal/embedded/embedded.go @@ -0,0 +1,9 @@ +package embedded + +import "embed" + +//go:embed resources/* +var Resources embed.FS + +//go:embed all:skills +var Skills embed.FS diff --git a/resources/Makefile b/src/internal/embedded/resources/Makefile similarity index 100% rename from resources/Makefile rename to src/internal/embedded/resources/Makefile diff --git a/resources/Makefile-common b/src/internal/embedded/resources/Makefile-common similarity index 100% rename from resources/Makefile-common rename to src/internal/embedded/resources/Makefile-common diff --git a/resources/ansible.cfg b/src/internal/embedded/resources/ansible.cfg similarity index 100% rename from resources/ansible.cfg rename to src/internal/embedded/resources/ansible.cfg diff --git a/resources/pattern.sh b/src/internal/embedded/resources/pattern.sh similarity index 100% rename from resources/pattern.sh rename to src/internal/embedded/resources/pattern.sh diff --git a/resources/values-secret.yaml.template b/src/internal/embedded/resources/values-secret.yaml.template similarity index 100% rename from resources/values-secret.yaml.template rename to src/internal/embedded/resources/values-secret.yaml.template diff --git a/skills/pattern-author/SKILL.md b/src/internal/embedded/skills/pattern-author/SKILL.md similarity index 100% rename from skills/pattern-author/SKILL.md rename to src/internal/embedded/skills/pattern-author/SKILL.md diff --git a/skills/pattern-author/reference.md b/src/internal/embedded/skills/pattern-author/reference.md similarity index 100% rename from skills/pattern-author/reference.md rename to src/internal/embedded/skills/pattern-author/reference.md diff --git a/src/internal/fileutils/fileutils.go b/src/internal/fileutils/fileutils.go index a989cdf..1379129 100644 --- a/src/internal/fileutils/fileutils.go +++ b/src/internal/fileutils/fileutils.go @@ -3,6 +3,7 @@ package fileutils import ( "fmt" "io" + "io/fs" "os" "path/filepath" "strings" @@ -49,13 +50,11 @@ func CopyFile(src, dst string) error { } // HandleSecretsSetup handles the setup for secrets usage by copying the secrets template. -func HandleSecretsSetup(resourcesDir, repoRoot string) (err error) { - // Copy the values-secret.yaml.template file to the pattern root only if it doesn't already exist - secretsTemplateSrc := filepath.Join(resourcesDir, "values-secret.yaml.template") +func HandleSecretsSetup(fsys fs.FS, repoRoot string) error { secretsTemplateDst := filepath.Join(repoRoot, "values-secret.yaml.template") if _, err := os.Stat(secretsTemplateDst); os.IsNotExist(err) { - if err = CopyFile(secretsTemplateSrc, secretsTemplateDst); err != nil { + if err = WriteEmbeddedFile(fsys, "resources/values-secret.yaml.template", secretsTemplateDst, 0o644); err != nil { return fmt.Errorf("error copying secrets template: %w", err) } } @@ -63,25 +62,35 @@ func HandleSecretsSetup(resourcesDir, repoRoot string) (err error) { return nil } -// GetResourcesPath returns the path to the resources directory. -// It checks the PATTERNIZER_RESOURCES_DIR environment variable first, -// and falls back to the current working directory. -func GetResourcesPath() (path string, err error) { - path = os.Getenv("PATTERNIZER_RESOURCES_DIR") - if path != "" { - return path, nil +// WriteEmbeddedFile reads a file from an embedded FS and writes it to disk with the given mode. +func WriteEmbeddedFile(fsys fs.FS, srcPath, dstPath string, mode os.FileMode) error { + data, err := fs.ReadFile(fsys, srcPath) + if err != nil { + return fmt.Errorf("reading embedded file %s: %w", srcPath, err) } - - return "", fmt.Errorf("PATTERNIZER_RESOURCES_DIR environment variable is not set") + if err := os.WriteFile(dstPath, data, mode); err != nil { + return err + } + return os.Chmod(dstPath, mode) } -func GetSkillsPath() (string, error) { - path := os.Getenv("PATTERNIZER_SKILLS_DIR") - if path != "" { - return path, nil - } +// WriteEmbeddedDir recursively copies an embedded directory tree to disk. +func WriteEmbeddedDir(fsys fs.FS, srcDir, dstDir string) error { + return fs.WalkDir(fsys, srcDir, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + relPath, err := filepath.Rel(srcDir, path) + if err != nil { + return err + } + target := filepath.Join(dstDir, relPath) - return "", fmt.Errorf("PATTERNIZER_SKILLS_DIR environment variable is not set") + if d.IsDir() { + return os.MkdirAll(target, 0o755) + } + return WriteEmbeddedFile(fsys, path, target, 0o644) + }) } // CopyDir recursively copies the contents of src into dst. diff --git a/src/internal/fileutils/fileutils_test.go b/src/internal/fileutils/fileutils_test.go index c494e66..3f1dbef 100644 --- a/src/internal/fileutils/fileutils_test.go +++ b/src/internal/fileutils/fileutils_test.go @@ -5,6 +5,7 @@ import ( "path/filepath" "runtime" "strings" + "testing/fstest" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -40,70 +41,64 @@ var _ = Describe("CopyFile", func() { var _ = Describe("HandleSecretsSetup", func() { It("should copy template when missing and not overwrite when present", func() { - resources := GinkgoT().TempDir() repoRoot := GinkgoT().TempDir() - templatePath := filepath.Join(resources, "values-secret.yaml.template") - originalContent := "foo: bar\n" - Expect(os.WriteFile(templatePath, []byte(originalContent), 0o644)).To(Succeed()) + fsys := fstest.MapFS{ + "resources/values-secret.yaml.template": &fstest.MapFile{Data: []byte("foo: bar\n")}, + } - // First call should copy - Expect(HandleSecretsSetup(resources, repoRoot)).To(Succeed()) + Expect(HandleSecretsSetup(fsys, repoRoot)).To(Succeed()) copied := filepath.Join(repoRoot, "values-secret.yaml.template") data, err := os.ReadFile(copied) Expect(err).NotTo(HaveOccurred()) - Expect(string(data)).To(Equal(originalContent)) + Expect(string(data)).To(Equal("foo: bar\n")) - // Change the source and call again; destination should remain unchanged - Expect(os.WriteFile(templatePath, []byte("baz: qux\n"), 0o644)).To(Succeed()) - Expect(HandleSecretsSetup(resources, repoRoot)).To(Succeed()) + Expect(HandleSecretsSetup(fsys, repoRoot)).To(Succeed()) data2, err := os.ReadFile(copied) Expect(err).NotTo(HaveOccurred()) - Expect(string(data2)).To(Equal(originalContent)) + Expect(string(data2)).To(Equal("foo: bar\n")) }) }) -var _ = Describe("GetResourcesPath", func() { - It("should return the path when the environment variable is set", func() { - old := os.Getenv("PATTERNIZER_RESOURCES_DIR") - DeferCleanup(func() { os.Setenv("PATTERNIZER_RESOURCES_DIR", old) }) +var _ = Describe("WriteEmbeddedFile", func() { + It("should write file contents with the specified mode", func() { + dir := GinkgoT().TempDir() + dst := filepath.Join(dir, "out.txt") - tmp := GinkgoT().TempDir() - Expect(os.Setenv("PATTERNIZER_RESOURCES_DIR", tmp)).To(Succeed()) - got, err := GetResourcesPath() - Expect(err).NotTo(HaveOccurred()) - Expect(got).To(Equal(tmp)) - }) + fsys := fstest.MapFS{ + "resources/test.txt": &fstest.MapFile{Data: []byte("hello embedded")}, + } - It("should return an error when the environment variable is unset", func() { - old := os.Getenv("PATTERNIZER_RESOURCES_DIR") - DeferCleanup(func() { os.Setenv("PATTERNIZER_RESOURCES_DIR", old) }) + Expect(WriteEmbeddedFile(fsys, "resources/test.txt", dst, 0o755)).To(Succeed()) - Expect(os.Unsetenv("PATTERNIZER_RESOURCES_DIR")).To(Succeed()) - _, err := GetResourcesPath() - Expect(err).To(HaveOccurred()) + data, err := os.ReadFile(dst) + Expect(err).NotTo(HaveOccurred()) + Expect(string(data)).To(Equal("hello embedded")) + + info, err := os.Stat(dst) + Expect(err).NotTo(HaveOccurred()) + Expect(info.Mode().Perm()).To(Equal(os.FileMode(0o755).Perm())) }) }) -var _ = Describe("GetSkillsPath", func() { - It("should return the path when the environment variable is set", func() { - old := os.Getenv("PATTERNIZER_SKILLS_DIR") - DeferCleanup(func() { os.Setenv("PATTERNIZER_SKILLS_DIR", old) }) +var _ = Describe("WriteEmbeddedDir", func() { + It("should recursively write an embedded directory tree", func() { + dst := filepath.Join(GinkgoT().TempDir(), "output") - tmp := GinkgoT().TempDir() - Expect(os.Setenv("PATTERNIZER_SKILLS_DIR", tmp)).To(Succeed()) - got, err := GetSkillsPath() - Expect(err).NotTo(HaveOccurred()) - Expect(got).To(Equal(tmp)) - }) + fsys := fstest.MapFS{ + "skills/myskill/SKILL.md": &fstest.MapFile{Data: []byte("skill content")}, + "skills/myskill/reference.md": &fstest.MapFile{Data: []byte("ref content")}, + } - It("should return an error when the environment variable is unset", func() { - old := os.Getenv("PATTERNIZER_SKILLS_DIR") - DeferCleanup(func() { os.Setenv("PATTERNIZER_SKILLS_DIR", old) }) + Expect(WriteEmbeddedDir(fsys, "skills/myskill", dst)).To(Succeed()) - Expect(os.Unsetenv("PATTERNIZER_SKILLS_DIR")).To(Succeed()) - _, err := GetSkillsPath() - Expect(err).To(HaveOccurred()) + got1, err := os.ReadFile(filepath.Join(dst, "SKILL.md")) + Expect(err).NotTo(HaveOccurred()) + Expect(string(got1)).To(Equal("skill content")) + + got2, err := os.ReadFile(filepath.Join(dst, "reference.md")) + Expect(err).NotTo(HaveOccurred()) + Expect(string(got2)).To(Equal("ref content")) }) }) diff --git a/src/internal/fileutils/skills.go b/src/internal/fileutils/skills.go index b3256a2..f1a3264 100644 --- a/src/internal/fileutils/skills.go +++ b/src/internal/fileutils/skills.go @@ -2,21 +2,18 @@ package fileutils import ( "fmt" - "os" + "io/fs" "path/filepath" + + "github.com/validatedpatterns/patternizer/internal/embedded" ) var skillTargets = []string{".claude", ".cursor"} func InstallSkills(repoRoot string) error { - skillsDir, err := GetSkillsPath() - if err != nil { - return fmt.Errorf("error getting skills path: %w", err) - } - - entries, err := os.ReadDir(skillsDir) + entries, err := fs.ReadDir(embedded.Skills, "skills") if err != nil { - return fmt.Errorf("error reading skills directory: %w", err) + return fmt.Errorf("error reading embedded skills: %w", err) } for _, entry := range entries { @@ -25,11 +22,10 @@ func InstallSkills(repoRoot string) error { } skillName := entry.Name() - skillSrc := filepath.Join(skillsDir, skillName) for _, target := range skillTargets { skillDst := filepath.Join(repoRoot, target, "skills", skillName) - if err := CopyDir(skillSrc, skillDst); err != nil { + if err := WriteEmbeddedDir(embedded.Skills, "skills/"+skillName, skillDst); err != nil { return fmt.Errorf("error installing skill %s to %s: %w", skillName, target, err) } } diff --git a/src/main_test.go b/src/main_test.go index 823a49f..4f4e49f 100644 --- a/src/main_test.go +++ b/src/main_test.go @@ -1,35 +1,12 @@ package main import ( - "os" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/validatedpatterns/patternizer/internal/fileutils" "github.com/validatedpatterns/patternizer/internal/types" ) -var _ = Describe("GetResourcePath", func() { - AfterEach(func() { - os.Unsetenv("PATTERNIZER_RESOURCES_DIR") - }) - - It("should return the path when the environment variable is set", func() { - os.Setenv("PATTERNIZER_RESOURCES_DIR", "/tmp/test") - path, err := fileutils.GetResourcesPath() - Expect(err).NotTo(HaveOccurred()) - Expect(path).To(Equal("/tmp/test")) - }) - - It("should return an error when the environment variable is unset", func() { - os.Unsetenv("PATTERNIZER_RESOURCES_DIR") - path, err := fileutils.GetResourcesPath() - Expect(err).To(HaveOccurred()) - Expect(path).To(BeEmpty()) - }) -}) - var _ = Describe("NewDefaultValuesGlobal", func() { It("should create default global values with expected defaults", func() { values := types.NewDefaultValuesGlobal()