Skip to content
7 changes: 7 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
version: "2"

run:
# Tests behind the compilegate tag shell out to the Go toolchain to build the
# generated models module, so they can't run in the hermetic Nix sandbox that
# runs our unit tests. Lint them anyway, so they don't rot.
build-tags:
- compilegate

output:
formats:
text:
Expand Down
8 changes: 8 additions & 0 deletions cmd/crossplane/config/help/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,11 @@ Enable alpha commands:
```shell
crossplane config set features.enableAlpha true
```

Generate `runtime.Object` methods and per-package `AddToScheme` helpers on
generated Go models (off by default), so you can register generated types with a
`runtime.Scheme`:

```shell
crossplane config set features.generateGoRuntimeObjects true
```
5 changes: 3 additions & 2 deletions cmd/crossplane/config/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ type boolSetter func(c *config.Config, v bool)
//
//nolint:gochecknoglobals // This is a constant.
var boolKeys = map[string]boolSetter{
"features.enableAlpha": func(c *config.Config, v bool) { c.Features.EnableAlpha = v },
"features.disableBeta": func(c *config.Config, v bool) { c.Features.DisableBeta = v },
"features.enableAlpha": func(c *config.Config, v bool) { c.Features.EnableAlpha = v },
"features.disableBeta": func(c *config.Config, v bool) { c.Features.DisableBeta = v },
"features.generateGoRuntimeObjects": func(c *config.Config, v bool) { c.Features.GenerateGoRuntimeObjects = v },
}

func (c *setCmd) AfterApply() error {
Expand Down
8 changes: 6 additions & 2 deletions cmd/crossplane/function/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/crossplane/crossplane-runtime/v2/pkg/xpkg"

v1alpha1 "github.com/crossplane/cli/v2/apis/dev/v1alpha1"
"github.com/crossplane/cli/v2/internal/config"
"github.com/crossplane/cli/v2/internal/filesystem"
"github.com/crossplane/cli/v2/internal/kcl"
"github.com/crossplane/cli/v2/internal/project/projectfile"
Expand Down Expand Up @@ -144,7 +145,7 @@ func functionSchemaLanguage(functionLang string) string {
}

// Run generates a function scaffold.
func (c *generateCmd) Run(sp terminal.SpinnerPrinter) error {
func (c *generateCmd) Run(sp terminal.SpinnerPrinter, cfg *config.Config) error {
if err := c.validatePaths(); err != nil {
return err
}
Expand All @@ -156,7 +157,10 @@ func (c *generateCmd) Run(sp terminal.SpinnerPrinter) error {
}
schemaMgr := manager.New(
c.schemasFS,
generator.Filter(generator.AllLanguages(), c.proj.Spec.Schemas.GetLanguages()),
generator.Filter(
generator.AllLanguages(generator.WithGoRuntimeObjects(cfg.Features.GenerateGoRuntimeObjects)),
c.proj.Spec.Schemas.GetLanguages(),
),
runner.NewRealSchemaRunner(runner.WithImageConfig(c.proj.Spec.ImageConfigs)),
)

Expand Down
24 changes: 23 additions & 1 deletion cmd/crossplane/function/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
apiextv1 "github.com/crossplane/crossplane/apis/v2/apiextensions/v1"

v1alpha1 "github.com/crossplane/cli/v2/apis/dev/v1alpha1"
"github.com/crossplane/cli/v2/internal/config"
"github.com/crossplane/cli/v2/internal/terminal"
)

Expand Down Expand Up @@ -292,6 +293,7 @@ func TestRunErrors(t *testing.T) {
name string
language string
seedFunctionsFS map[string][]byte
cfg *config.Config
stage string // "afterApply" or "run"
wantErrSubstring string
}{
Expand All @@ -309,6 +311,22 @@ func TestRunErrors(t *testing.T) {
stage: "run",
wantErrSubstring: "already exists and is not empty",
},
"DirectoryNotEmptyWithGoRuntimeObjects": {
// Run reads the feature flag out of the config it's handed, so
// exercise the flag-on path too. Asserting on the generated
// artifacts isn't possible here: that needs the real schema
// runner, which runs a container.
name: "my-func",
language: "go-templating",
seedFunctionsFS: map[string][]byte{
"my-func/existing.txt": []byte("data"),
},
cfg: &config.Config{
Features: config.Features{GenerateGoRuntimeObjects: true},
},
stage: "run",
wantErrSubstring: "already exists and is not empty",
},
}

for name, tc := range cases {
Expand All @@ -319,12 +337,16 @@ func TestRunErrors(t *testing.T) {
functionsFS: seedFS(t, tc.seedFunctionsFS),
projFS: afero.NewMemMapFs(),
}
cfg := tc.cfg
if cfg == nil {
cfg = &config.Config{}
}
var err error
switch tc.stage {
case "afterApply":
err = c.AfterApply()
case "run":
err = c.Run(terminal.NewSpinnerPrinter(io.Discard, false))
err = c.Run(terminal.NewSpinnerPrinter(io.Discard, false), cfg)
}
if err == nil {
t.Fatalf("expected error containing %q, got nil", tc.wantErrSubstring)
Expand Down
2 changes: 2 additions & 0 deletions cmd/crossplane/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ func main() {
// at runtime.
kong.BindTo(logger, (*logging.Logger)(nil)),
kong.BindTo(configcmd.ConfigPath(cfgPath), (*configcmd.ConfigPath)(nil)),
// Bind the loaded config so commands can read feature flags at runtime.
kong.Bind(cfg),
kong.Help(helpPrinter),
kong.UsageOnError())

Expand Down
5 changes: 3 additions & 2 deletions cmd/crossplane/project/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (

devv1alpha1 "github.com/crossplane/cli/v2/apis/dev/v1alpha1"
"github.com/crossplane/cli/v2/internal/async"
"github.com/crossplane/cli/v2/internal/config"
"github.com/crossplane/cli/v2/internal/dependency"
"github.com/crossplane/cli/v2/internal/project"
"github.com/crossplane/cli/v2/internal/project/functions"
Expand Down Expand Up @@ -83,7 +84,7 @@ func (c *buildCmd) AfterApply() error {
}

// Run executes the build command.
func (c *buildCmd) Run(logger logging.Logger, sp terminal.SpinnerPrinter) error {
func (c *buildCmd) Run(logger logging.Logger, sp terminal.SpinnerPrinter, cfg *config.Config) error {
ctx := context.Background()

if c.Repository != "" {
Expand All @@ -97,7 +98,7 @@ func (c *buildCmd) Run(logger logging.Logger, sp terminal.SpinnerPrinter) error
concurrency := max(1, c.MaxConcurrency)

schemasFS := afero.NewBasePathFs(c.projFS, c.proj.Spec.Paths.Schemas)
generators := generator.Filter(generator.AllLanguages(), c.proj.Spec.Schemas.GetLanguages())
generators := generator.Filter(generator.AllLanguages(generator.WithGoRuntimeObjects(cfg.Features.GenerateGoRuntimeObjects)), c.proj.Spec.Schemas.GetLanguages())
schemaRunner := runner.NewRealSchemaRunner(runner.WithImageConfig(c.proj.Spec.ImageConfigs))
schemaMgr := manager.New(schemasFS, generators, schemaRunner)
cacheDir := c.CacheDir
Expand Down
5 changes: 3 additions & 2 deletions cmd/crossplane/project/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
devv1alpha1 "github.com/crossplane/cli/v2/apis/dev/v1alpha1"
"github.com/crossplane/cli/v2/cmd/crossplane/render"
"github.com/crossplane/cli/v2/internal/async"
"github.com/crossplane/cli/v2/internal/config"
"github.com/crossplane/cli/v2/internal/dependency"
"github.com/crossplane/cli/v2/internal/project"
"github.com/crossplane/cli/v2/internal/project/controlplane"
Expand Down Expand Up @@ -132,7 +133,7 @@ func (c *runCmd) AfterApply() error {
}

// Run executes the run command.
func (c *runCmd) Run(logger logging.Logger, sp terminal.SpinnerPrinter) error { //nolint:gocyclo // Main command orchestration.
func (c *runCmd) Run(logger logging.Logger, sp terminal.SpinnerPrinter, cfg *config.Config) error { //nolint:gocyclo // Main command orchestration.
ctx := context.Background()

if c.Repository != "" {
Expand All @@ -150,7 +151,7 @@ func (c *runCmd) Run(logger logging.Logger, sp terminal.SpinnerPrinter) error {
concurrency := max(1, c.MaxConcurrency)

schemasFS := afero.NewBasePathFs(c.projFS, c.proj.Spec.Paths.Schemas)
generators := generator.Filter(generator.AllLanguages(), c.proj.Spec.Schemas.GetLanguages())
generators := generator.Filter(generator.AllLanguages(generator.WithGoRuntimeObjects(cfg.Features.GenerateGoRuntimeObjects)), c.proj.Spec.Schemas.GetLanguages())
schemaRunner := runner.NewRealSchemaRunner(runner.WithImageConfig(c.proj.Spec.ImageConfigs))
schemaMgr := manager.New(schemasFS, generators, schemaRunner)
cacheDir := c.CacheDir
Expand Down
5 changes: 5 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ type Config struct {
type Features struct {
EnableAlpha bool `json:"enableAlpha,omitempty"`
DisableBeta bool `json:"disableBeta,omitempty"`

// GenerateGoRuntimeObjects enables generation of runtime.Object methods and
// per-package AddToScheme helpers on generated Go models. Disabled by
// default; opt in to register generated types with a runtime.Scheme.
GenerateGoRuntimeObjects bool `json:"generateGoRuntimeObjects,omitempty"`
}

// Load reads a Config from path. A missing file is not an error; the zero
Expand Down
Loading
Loading