Skip to content

Commit e4b1c05

Browse files
committed
feat: helm chart directory can be configured
Per default, helm-charts will get generated under dist/ directory. Via the newly introduced --directory flag it's now possible to define an alternative directory (e.g.: chart) fixes #4320 Signed-off-by: Mario Constanti <[email protected]>
1 parent 202a630 commit e4b1c05

File tree

22 files changed

+209
-94
lines changed

22 files changed

+209
-94
lines changed

.golangci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ linters:
1313
- goconst
1414
- gocyclo
1515
- govet
16+
- importas
1617
- ineffassign
1718
- lll
1819
- misspell
@@ -27,6 +28,10 @@ linters:
2728
- wrapcheck
2829
- whitespace
2930
settings:
31+
importas:
32+
alias:
33+
- pkg: sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha
34+
alias: helmv1alpha
3035
ginkgolinter:
3136
forbid-focus-container: true
3237
forbid-spec-pollution: true

cmd/cmd.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
deployimagev1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/deploy-image/v1alpha1"
2929
golangv4 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/v4"
3030
grafanav1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha"
31-
helmv1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha"
31+
helmv1alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha"
3232
)
3333

3434
func init() {
@@ -62,7 +62,7 @@ func Run() {
6262
&kustomizecommonv2.Plugin{},
6363
&deployimagev1alpha1.Plugin{},
6464
&grafanav1alpha1.Plugin{},
65-
&helmv1alpha1.Plugin{},
65+
&helmv1alpha.Plugin{},
6666
),
6767
cli.WithPlugins(externalPlugins...),
6868
cli.WithDefaultPlugins(cfgv3.Version, gov4Bundle),

pkg/cli/alpha/internal/generate.go

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ import (
3434
"sigs.k8s.io/kubebuilder/v4/pkg/plugin"
3535
"sigs.k8s.io/kubebuilder/v4/pkg/plugin/util"
3636
"sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/deploy-image/v1alpha1"
37-
"sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha"
38-
hemlv1alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha"
37+
grafanav1alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha"
38+
helmv1alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha"
3939
)
4040

4141
// Generate store the required info for the command
@@ -110,8 +110,8 @@ func (opts *Generate) Generate() error {
110110
}
111111

112112
if hasHelmPlugin(projectConfig) {
113-
if err = kubebuilderHelmEdit(); err != nil {
114-
return fmt.Errorf("error editing Helm plugin: %w", err)
113+
if err = migrateHelmPlugin(projectConfig); err != nil {
114+
return fmt.Errorf("error migrating Helm plugin: %w", err)
115115
}
116116
}
117117

@@ -226,7 +226,7 @@ func kubebuilderCreate(s store.Store) error {
226226
// Migrates the Grafana plugin.
227227
func migrateGrafanaPlugin(s store.Store, src, des string) error {
228228
var grafanaPlugin struct{}
229-
err := s.Config().DecodePluginConfig(plugin.KeyFor(v1alpha.Plugin{}), grafanaPlugin)
229+
err := s.Config().DecodePluginConfig(plugin.KeyFor(grafanav1alpha.Plugin{}), grafanaPlugin)
230230
if errors.As(err, &config.PluginKeyNotFoundError{}) {
231231
log.Info("Grafana plugin not found, skipping migration")
232232
return nil
@@ -481,28 +481,58 @@ func grafanaConfigMigrate(src, des string) error {
481481

482482
// Edits the project to include the Grafana plugin.
483483
func kubebuilderGrafanaEdit() error {
484-
args := []string{"edit", "--plugins", plugin.KeyFor(v1alpha.Plugin{})}
484+
args := []string{"edit", "--plugins", plugin.KeyFor(grafanav1alpha.Plugin{})}
485485
if err := util.RunCmd("kubebuilder edit", "kubebuilder", args...); err != nil {
486486
return fmt.Errorf("failed to run edit subcommand for Grafana plugin: %w", err)
487487
}
488488
return nil
489489
}
490490

491+
// Migrates the Helm plugin.
492+
func migrateHelmPlugin(s store.Store) error {
493+
var helmPlugin helmv1alpha.PluginConfig
494+
495+
err := s.Config().DecodePluginConfig(plugin.KeyFor(helmv1alpha.Plugin{}), &helmPlugin)
496+
if errors.As(err, &config.PluginKeyNotFoundError{}) {
497+
log.Info("Helm plugin not found, skipping migration")
498+
return nil
499+
} else if err != nil {
500+
return fmt.Errorf("failed to decode Helm plugin config: %w", err)
501+
}
502+
503+
return kubebuilderHelmEdit(helmPlugin)
504+
}
505+
491506
// Edits the project to include the Helm plugin.
492-
func kubebuilderHelmEdit() error {
493-
args := []string{"edit", "--plugins", plugin.KeyFor(hemlv1alpha.Plugin{})}
507+
func kubebuilderHelmEdit(resourceData helmv1alpha.PluginConfig) error {
508+
args := []string{"edit", "--plugins", plugin.KeyFor(helmv1alpha.Plugin{})}
509+
args = append(args, getHelmOptions(resourceData)...)
494510
if err := util.RunCmd("kubebuilder edit", "kubebuilder", args...); err != nil {
495511
return fmt.Errorf("failed to run edit subcommand for Helm plugin: %w", err)
496512
}
497513
return nil
498514
}
499515

516+
// Gets the options for Helm resource.
517+
// If the directory is not the default, it sets the directory option.
518+
// otherwise, it returns an empty slice which then use the default value from the edit/init subcommand.
519+
func getHelmOptions(resourceData helmv1alpha.PluginConfig) []string {
520+
var args []string
521+
522+
if resourceData.Options.Directory != helmv1alpha.HelmDefaultTargetDirectory {
523+
log.Info("setting directory for Helm chart")
524+
args = append(args, fmt.Sprintf("--directory=%s", resourceData.Options.Directory))
525+
}
526+
527+
return args
528+
}
529+
500530
// hasHelmPlugin checks if the Helm plugin is present by inspecting the plugin chain or configuration.
501531
func hasHelmPlugin(cfg store.Store) bool {
502532
var pluginConfig map[string]interface{}
503533

504534
// Decode the Helm plugin configuration to check if it's present
505-
err := cfg.Config().DecodePluginConfig(plugin.KeyFor(hemlv1alpha.Plugin{}), &pluginConfig)
535+
err := cfg.Config().DecodePluginConfig(plugin.KeyFor(helmv1alpha.Plugin{}), &pluginConfig)
506536
if err != nil {
507537
// If the Helm plugin is not found, return false
508538
if errors.As(err, &config.PluginKeyNotFoundError{}) {

pkg/plugins/optional/helm/v1alpha/commons.go

Lines changed: 0 additions & 38 deletions
This file was deleted.

pkg/plugins/optional/helm/v1alpha/edit.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package v1alpha
1818

1919
import (
20+
"errors"
2021
"fmt"
2122

2223
"github.com/spf13/pflag"
@@ -29,8 +30,9 @@ import (
2930
var _ plugin.EditSubcommand = &editSubcommand{}
3031

3132
type editSubcommand struct {
32-
config config.Config
33-
force bool
33+
config config.Config
34+
force bool
35+
directory string
3436
}
3537

3638
//nolint:lll
@@ -66,6 +68,7 @@ manifests in the chart align with the latest changes.
6668

6769
func (p *editSubcommand) BindFlags(fs *pflag.FlagSet) {
6870
fs.BoolVar(&p.force, "force", false, "if true, regenerates all the files")
71+
fs.StringVar(&p.directory, "directory", HelmDefaultTargetDirectory, "domain for groups")
6972
}
7073

7174
func (p *editSubcommand) InjectConfig(c config.Config) error {
@@ -74,13 +77,30 @@ func (p *editSubcommand) InjectConfig(c config.Config) error {
7477
}
7578

7679
func (p *editSubcommand) Scaffold(fs machinery.Filesystem) error {
77-
scaffolder := scaffolds.NewInitHelmScaffolder(p.config, p.force)
80+
scaffolder := scaffolds.NewInitHelmScaffolder(p.config, p.force, p.directory)
7881
scaffolder.InjectFS(fs)
7982
err := scaffolder.Scaffold()
8083
if err != nil {
8184
return fmt.Errorf("error scaffolding Helm chart: %w", err)
8285
}
8386

8487
// Track the resources following a declarative approach
85-
return insertPluginMetaToConfig(p.config, pluginConfig{})
88+
cfg := PluginConfig{}
89+
if err = p.config.DecodePluginConfig(pluginKey, &cfg); errors.As(err, &config.UnsupportedFieldError{}) {
90+
// Skip tracking as the config doesn't support per-plugin configuration
91+
return nil
92+
} else if err != nil && !errors.As(err, &config.PluginKeyNotFoundError{}) {
93+
// Fail unless the key wasn't found, which just means it is the first resource tracked
94+
return fmt.Errorf("error decoding plugin configuration: %w", err)
95+
}
96+
97+
cfg.Options = options{
98+
Directory: p.directory,
99+
}
100+
101+
if err = p.config.EncodePluginConfig(pluginKey, cfg); err != nil {
102+
return fmt.Errorf("error encoding plugin configuration: %w", err)
103+
}
104+
105+
return nil
86106
}

pkg/plugins/optional/helm/v1alpha/init.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ limitations under the License.
1717
package v1alpha
1818

1919
import (
20+
"errors"
2021
"fmt"
2122

23+
"github.com/spf13/pflag"
2224
"sigs.k8s.io/kubebuilder/v4/pkg/config"
2325
"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
2426
"sigs.k8s.io/kubebuilder/v4/pkg/plugin"
@@ -29,6 +31,9 @@ var _ plugin.InitSubcommand = &initSubcommand{}
2931

3032
type initSubcommand struct {
3133
config config.Config
34+
35+
// config options
36+
directory string
3237
}
3338

3439
func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) {
@@ -41,19 +46,40 @@ func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *
4146
`, cliMeta.CommandName, plugin.KeyFor(Plugin{}))
4247
}
4348

49+
func (p *initSubcommand) BindFlags(fs *pflag.FlagSet) {
50+
fs.StringVar(&p.directory, "directory", HelmDefaultTargetDirectory, "domain for groups")
51+
}
52+
4453
func (p *initSubcommand) InjectConfig(c config.Config) error {
4554
p.config = c
4655
return nil
4756
}
4857

4958
func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error {
50-
scaffolder := scaffolds.NewInitHelmScaffolder(p.config, false)
59+
scaffolder := scaffolds.NewInitHelmScaffolder(p.config, false, p.directory)
5160
scaffolder.InjectFS(fs)
5261
err := scaffolder.Scaffold()
5362
if err != nil {
5463
return fmt.Errorf("error scaffolding helm chart: %w", err)
5564
}
5665

5766
// Track the resources following a declarative approach
58-
return insertPluginMetaToConfig(p.config, pluginConfig{})
67+
cfg := PluginConfig{}
68+
if err = p.config.DecodePluginConfig(pluginKey, &cfg); errors.As(err, &config.UnsupportedFieldError{}) {
69+
// Skip tracking as the config doesn't support per-plugin configuration
70+
return nil
71+
} else if err != nil && !errors.As(err, &config.PluginKeyNotFoundError{}) {
72+
// Fail unless the key wasn't found, which just means it is the first resource tracked
73+
return fmt.Errorf("error decoding plugin configuration: %w", err)
74+
}
75+
76+
cfg.Options = options{
77+
Directory: p.directory,
78+
}
79+
80+
if err = p.config.EncodePluginConfig(pluginKey, cfg); err != nil {
81+
return fmt.Errorf("error encoding plugin configuration: %w", err)
82+
}
83+
84+
return nil
5985
}

pkg/plugins/optional/helm/v1alpha/plugin.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,15 @@ import (
2424
"sigs.k8s.io/kubebuilder/v4/pkg/plugins"
2525
)
2626

27-
const pluginName = "helm." + plugins.DefaultNameQualifier
27+
const (
28+
pluginName = "helm." + plugins.DefaultNameQualifier
29+
30+
// HelmDefaultTargetDirectory is the default directory where the Helm chart will be scaffolded
31+
// This is used in the init subcommand to scaffold the Helm chart.
32+
// It is also used in the edit subcommand to add or edit a Helm chart.
33+
// It is set to "dist" to match the default target directory for other plugins.
34+
HelmDefaultTargetDirectory = "dist"
35+
)
2836

2937
var (
3038
pluginVersion = plugin.Version{Number: 1, Stage: stage.Alpha}
@@ -43,7 +51,15 @@ var (
4351
_ plugin.Edit = Plugin{}
4452
)
4553

46-
type pluginConfig struct{}
54+
type PluginConfig struct {
55+
// Options contains the options for the Helm plugin
56+
Options options `json:"options,omitempty"`
57+
}
58+
59+
type options struct {
60+
// Directory is the directory where the Helm chart will be scaffolded
61+
Directory string `json:"directory,omitempty"`
62+
}
4763

4864
// Name returns the name of the plugin
4965
func (Plugin) Name() string { return pluginName }

0 commit comments

Comments
 (0)