Skip to content

Commit 7de1605

Browse files
refactor: introduce RuntimeFiles (#376)
Signed-off-by: Dmitry Bochkarev <[email protected]>
1 parent 77130d2 commit 7de1605

4 files changed

Lines changed: 113 additions & 7 deletions

File tree

pkg/chart/chart.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ type Chart struct {
5353
// Files are miscellaneous files in a chart archive,
5454
// e.g. README, LICENSE, etc.
5555
Files []*File `json:"files"`
56+
// Files that are used at runtime, but should not be saved to secret/configmap.
57+
RuntimeFiles []*File `json:"-"`
58+
// Dependencies for RuntimeFiles that are used at runtime, but should not be saved to secret/configmap and not added to packaged chart.
59+
RuntimeDepsFiles []*File `json:"-"`
5660

5761
parent *Chart
5862
dependencies []*Chart

pkg/chart/loader/load.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ func LoadFiles(files []*BufferedFile, opts helmopts.HelmOptions) (*chart.Chart,
173173
fname := strings.TrimPrefix(f.Name, "charts/")
174174
cname := strings.SplitN(fname, "/", 2)[0]
175175
subcharts[cname] = append(subcharts[cname], &BufferedFile{Name: fname, Data: f.Data})
176+
case strings.HasPrefix(f.Name, "ts/node_modules/"):
177+
c.RuntimeDepsFiles = append(c.RuntimeDepsFiles, &chart.File{Name: f.Name, Data: f.Data})
178+
case strings.HasPrefix(f.Name, "ts/"):
179+
c.RuntimeFiles = append(c.RuntimeFiles, &chart.File{Name: f.Name, Data: f.Data})
176180
default:
177181
c.Files = append(c.Files, &chart.File{Name: f.Name, Data: f.Data})
178182
}

pkg/chart/loader/load_test.go

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,12 @@ import (
3030
"time"
3131

3232
"github.com/werf/3p-helm/pkg/chart"
33+
"github.com/werf/3p-helm/pkg/werf/helmopts"
3334
)
3435

36+
// GlobalLoadOptions is a default set of options for testing
37+
var GlobalLoadOptions = &helmopts.HelmOptions{}
38+
3539
func TestLoadDir(t *testing.T) {
3640
l, err := Loader("testdata/frobnitz")
3741
if err != nil {
@@ -379,7 +383,7 @@ icon: https://example.com/64x64.png
379383
// Packaging the chart on a Windows machine will produce an
380384
// archive that has \\ as delimiters. Test that we support these archives
381385
func TestLoadFileBackslash(t *testing.T) {
382-
c, err := Load("testdata/frobnitz_backslash-1.2.3.tgz")
386+
c, err := Load("testdata/frobnitz_backslash-1.2.3.tgz", *GlobalLoadOptions)
383387
if err != nil {
384388
t.Fatalf("Failed to load testdata: %s", err)
385389
}
@@ -454,7 +458,7 @@ func TestLoadInvalidArchive(t *testing.T) {
454458
} {
455459
illegalChart := filepath.Join(tmpdir, tt.chartname)
456460
writeTar(illegalChart, tt.internal, []byte("hello: world"))
457-
_, err := Load(illegalChart)
461+
_, err := Load(illegalChart, *GlobalLoadOptions)
458462
if err == nil {
459463
t.Fatal("expected error when unpacking illegal files")
460464
}
@@ -466,23 +470,23 @@ func TestLoadInvalidArchive(t *testing.T) {
466470
// Make sure that absolute path gets interpreted as relative
467471
illegalChart := filepath.Join(tmpdir, "abs-path.tgz")
468472
writeTar(illegalChart, "/Chart.yaml", []byte("hello: world"))
469-
_, err := Load(illegalChart)
473+
_, err := Load(illegalChart, *GlobalLoadOptions)
470474
if err.Error() != "validation: chart.metadata.name is required" {
471475
t.Error(err)
472476
}
473477

474478
// And just to validate that the above was not spurious
475479
illegalChart = filepath.Join(tmpdir, "abs-path2.tgz")
476480
writeTar(illegalChart, "files/whatever.yaml", []byte("hello: world"))
477-
_, err = Load(illegalChart)
481+
_, err = Load(illegalChart, *GlobalLoadOptions)
478482
if err.Error() != "Chart.yaml file is missing" {
479483
t.Errorf("Unexpected error message: %s", err)
480484
}
481485

482486
// Finally, test that drive letter gets stripped off on Windows
483487
illegalChart = filepath.Join(tmpdir, "abs-winpath.tgz")
484488
writeTar(illegalChart, "c:\\Chart.yaml", []byte("hello: world"))
485-
_, err = Load(illegalChart)
489+
_, err = Load(illegalChart, *GlobalLoadOptions)
486490
if err.Error() != "validation: chart.metadata.name is required" {
487491
t.Error(err)
488492
}
@@ -646,3 +650,89 @@ func verifyBomStripped(t *testing.T, files []*chart.File) {
646650
}
647651
}
648652
}
653+
654+
func TestLoadFilesRuntimeFiles(t *testing.T) {
655+
files := []*BufferedFile{
656+
{
657+
Name: "Chart.yaml",
658+
Data: []byte(`apiVersion: v2
659+
name: test-chart
660+
version: "1.0.0"
661+
`),
662+
},
663+
{
664+
Name: "ts/runtime.ts",
665+
Data: []byte("console.log('runtime');"),
666+
},
667+
{
668+
Name: "ts/utils/helper.ts",
669+
Data: []byte("export function helper() {}"),
670+
},
671+
{
672+
Name: "templates/deployment.yaml",
673+
Data: []byte("some deployment"),
674+
},
675+
{
676+
Name: "values.yaml",
677+
Data: []byte("key: value"),
678+
},
679+
}
680+
681+
c, err := LoadFiles(files, *GlobalLoadOptions)
682+
if err != nil {
683+
t.Fatalf("Expected files to be loaded, got %v", err)
684+
}
685+
686+
// Verify RuntimeFiles are loaded correctly
687+
if len(c.RuntimeFiles) != 2 {
688+
t.Errorf("Expected 2 runtime files, got %d", len(c.RuntimeFiles))
689+
}
690+
691+
expectedRuntimeFiles := map[string][]byte{
692+
"ts/runtime.ts": []byte("console.log('runtime');"),
693+
"ts/utils/helper.ts": []byte("export function helper() {}"),
694+
}
695+
696+
for _, rf := range c.RuntimeFiles {
697+
expected, ok := expectedRuntimeFiles[rf.Name]
698+
if !ok {
699+
t.Errorf("Unexpected runtime file: %s", rf.Name)
700+
continue
701+
}
702+
if !bytes.Equal(rf.Data, expected) {
703+
t.Errorf("Runtime file %s has unexpected content", rf.Name)
704+
}
705+
}
706+
707+
// Verify runtime files are NOT in Files collection
708+
for _, f := range c.Files {
709+
if strings.HasPrefix(f.Name, "ts/") {
710+
t.Errorf("Runtime file %s should not be in Files collection", f.Name)
711+
}
712+
}
713+
714+
// Verify runtime files are NOT in Templates collection
715+
for _, f := range c.Templates {
716+
if strings.HasPrefix(f.Name, "ts/") {
717+
t.Errorf("Runtime file %s should not be in Templates collection", f.Name)
718+
}
719+
}
720+
721+
// Verify other files are loaded correctly
722+
// Note: default ChartTypeChart adds _werf_helpers.tpl template, so we expect 2 templates
723+
if len(c.Templates) != 2 {
724+
t.Errorf("Expected 2 templates, got %d", len(c.Templates))
725+
}
726+
727+
// Verify the user template is present
728+
foundDeployment := false
729+
for _, tmpl := range c.Templates {
730+
if tmpl.Name == "templates/deployment.yaml" {
731+
foundDeployment = true
732+
break
733+
}
734+
}
735+
if !foundDeployment {
736+
t.Error("Expected to find templates/deployment.yaml template")
737+
}
738+
}

pkg/chartutil/save.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ func SaveIntoDir(c *chart.Chart, dest string) error {
9191
}
9292
}
9393

94-
// Save templates and files
95-
for _, o := range [][]*chart.File{c.Templates, c.Files} {
94+
// Save templates, files, and runtime files (e.g., ts/ for TypeScript charts)
95+
for _, o := range [][]*chart.File{c.Templates, c.Files, c.RuntimeFiles} {
9696
for _, f := range o {
9797
n := filepath.Join(outdir, f.Name)
9898
if err := writeFile(n, f.Data); err != nil {
@@ -243,6 +243,14 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error {
243243
}
244244
}
245245

246+
// Save runtime files (e.g., ts/ directory for TypeScript charts)
247+
for _, f := range c.RuntimeFiles {
248+
n := filepath.Join(base, f.Name)
249+
if err := writeToTar(out, n, f.Data); err != nil {
250+
return err
251+
}
252+
}
253+
246254
// Save dependencies
247255
for _, dep := range c.Dependencies() {
248256
if err := writeTarContents(out, dep, filepath.Join(base, ChartsDir)); err != nil {

0 commit comments

Comments
 (0)