Skip to content
Open
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: 7 additions & 1 deletion cmd/crossplane/composition/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ import (
pkgv1 "github.com/crossplane/crossplane/apis/v2/pkg/v1"

"github.com/crossplane/cli/v2/apis/dev/v1alpha1"
"github.com/crossplane/cli/v2/internal/config"
"github.com/crossplane/cli/v2/internal/dependency"
"github.com/crossplane/cli/v2/internal/project/projectfile"
"github.com/crossplane/cli/v2/internal/schemas/generator"
"github.com/crossplane/cli/v2/internal/terminal"
clixpkg "github.com/crossplane/cli/v2/internal/xpkg"

Expand Down Expand Up @@ -71,7 +73,7 @@ func (c *generateCmd) Help() string {
}

// AfterApply sets up the project filesystem.
func (c *generateCmd) AfterApply() error {
func (c *generateCmd) AfterApply(cfg *config.Config) error {
projFilePath, err := filepath.Abs(c.ProjectFile)
if err != nil {
return err
Expand Down Expand Up @@ -103,6 +105,10 @@ func (c *generateCmd) AfterApply() error {

c.depManager = dependency.NewManager(proj, c.projFS,
dependency.WithProjectFile(filepath.Base(c.ProjectFile)),
dependency.WithSchemaGenerators(generator.Filter(
generator.AllLanguages(generator.WithGoRuntimeObjects(cfg.Features.GenerateGoRuntimeObjects)),
proj.Spec.Schemas.GetLanguages(),
)),
dependency.WithXpkgClient(client),
dependency.WithResolver(resolver),
)
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: 7 additions & 1 deletion cmd/crossplane/dependency/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import (
"github.com/crossplane/crossplane-runtime/v2/pkg/logging"

"github.com/crossplane/cli/v2/apis/dev/v1alpha1"
"github.com/crossplane/cli/v2/internal/config"
"github.com/crossplane/cli/v2/internal/dependency"
"github.com/crossplane/cli/v2/internal/project/projectfile"
"github.com/crossplane/cli/v2/internal/schemas/generator"
"github.com/crossplane/cli/v2/internal/terminal"
clixpkg "github.com/crossplane/cli/v2/internal/xpkg"

Expand All @@ -56,7 +58,7 @@ func (c *addCmd) Help() string {
}

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

projFilePath, err := filepath.Abs(c.ProjectFile)
Expand Down Expand Up @@ -88,6 +90,10 @@ func (c *addCmd) Run(logger logging.Logger, sp terminal.SpinnerPrinter) error {

m := dependency.NewManager(proj, projFS,
dependency.WithProjectFile(c.ProjectFile),
dependency.WithSchemaGenerators(generator.Filter(
generator.AllLanguages(generator.WithGoRuntimeObjects(cfg.Features.GenerateGoRuntimeObjects)),
proj.Spec.Schemas.GetLanguages(),
)),
dependency.WithXpkgClient(client),
dependency.WithResolver(resolver),
)
Expand Down
8 changes: 6 additions & 2 deletions cmd/crossplane/dependency/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/crossplane/crossplane-runtime/v2/pkg/logging"

"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/projectfile"
"github.com/crossplane/cli/v2/internal/schemas/generator"
Expand All @@ -52,7 +53,7 @@ func (c *updateCacheCmd) Help() string {
}

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

projFilePath, err := filepath.Abs(c.ProjectFile)
Expand Down Expand Up @@ -84,7 +85,10 @@ func (c *updateCacheCmd) Run(logger logging.Logger, sp terminal.SpinnerPrinter)

opts := []dependency.ManagerOption{
dependency.WithProjectFile(c.ProjectFile),
dependency.WithSchemaGenerators(generator.Filter(generator.AllLanguages(), proj.Spec.Schemas.GetLanguages())),
dependency.WithSchemaGenerators(generator.Filter(
generator.AllLanguages(generator.WithGoRuntimeObjects(cfg.Features.GenerateGoRuntimeObjects)),
proj.Spec.Schemas.GetLanguages(),
)),
dependency.WithXpkgClient(client),
dependency.WithResolver(resolver),
}
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
15 changes: 11 additions & 4 deletions cmd/crossplane/render/op/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
"github.com/crossplane/cli/v2/cmd/crossplane/render"
"github.com/crossplane/cli/v2/cmd/crossplane/render/contextfn"
"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 @@ -101,7 +102,7 @@ func (c *Cmd) AfterApply() error {
}

// Run alpha render op.
func (c *Cmd) Run(k *kong.Context, log logging.Logger, sp terminal.SpinnerPrinter) error { //nolint:gocognit // Orchestration is inherently complex.
func (c *Cmd) Run(k *kong.Context, log logging.Logger, sp terminal.SpinnerPrinter, cfg *config.Config) error { //nolint:gocognit // Orchestration is inherently complex.
ctx, cancel := context.WithTimeout(context.Background(), c.Timeout)
defer cancel()

Expand Down Expand Up @@ -149,7 +150,7 @@ func (c *Cmd) Run(k *kong.Context, log logging.Logger, sp terminal.SpinnerPrinte
}

// Load functions
fns, err := c.loadFunctions(ctx, log, sp)
fns, err := c.loadFunctions(ctx, log, sp, cfg)
if err != nil {
return err
}
Expand Down Expand Up @@ -317,7 +318,7 @@ func (c *Cmd) Run(k *kong.Context, log logging.Logger, sp terminal.SpinnerPrinte
return nil
}

func (c *Cmd) loadFunctions(ctx context.Context, log logging.Logger, sp terminal.SpinnerPrinter) ([]pkgv1.Function, error) {
func (c *Cmd) loadFunctions(ctx context.Context, log logging.Logger, sp terminal.SpinnerPrinter, cfg *config.Config) ([]pkgv1.Function, error) {
if c.Functions != "" {
fns, err := render.LoadFunctions(c.fs, c.Functions)
if err != nil {
Expand Down Expand Up @@ -359,8 +360,15 @@ func (c *Cmd) loadFunctions(ctx context.Context, log logging.Logger, sp terminal
}
resolver := clixpkg.NewResolver(xpkgClient)

// Built here rather than alongside the schema manager below so the
// dependency manager generates dependency schemas the same way.
generators := generator.AllLanguages(
generator.WithGoRuntimeObjects(cfg.Features.GenerateGoRuntimeObjects),
)

depMgr := dependency.NewManager(proj, projFS,
dependency.WithProjectFile(filepath.Base(projFilePath)),
dependency.WithSchemaGenerators(generators),
dependency.WithXpkgClient(xpkgClient),
dependency.WithResolver(resolver),
)
Expand All @@ -376,7 +384,6 @@ func (c *Cmd) loadFunctions(ctx context.Context, log logging.Logger, sp terminal

if err := sp.WrapAsyncWithSuccessSpinners(func(ch async.EventChannel) error {
schemasFS := afero.NewBasePathFs(projFS, proj.Spec.Paths.Schemas)
generators := generator.AllLanguages()
schemaRunner := runner.NewRealSchemaRunner(runner.WithImageConfig(proj.Spec.ImageConfigs))
schemaMgr := manager.New(schemasFS, generators, schemaRunner)

Expand Down
3 changes: 2 additions & 1 deletion cmd/crossplane/render/op/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
pkgv1 "github.com/crossplane/crossplane/apis/v2/pkg/v1"

"github.com/crossplane/cli/v2/cmd/crossplane/render"
"github.com/crossplane/cli/v2/internal/config"
"github.com/crossplane/cli/v2/internal/terminal"
renderv1alpha1 "github.com/crossplane/cli/v2/proto/render/v1alpha1"

Expand Down Expand Up @@ -425,7 +426,7 @@ func TestCmdRun(t *testing.T) {
buf := &bytes.Buffer{}
kctx := &kong.Context{Kong: &kong.Kong{Stdout: buf, Stderr: io.Discard}}

err := tc.args.cmd.Run(kctx, logging.NewNopLogger(), terminal.NewSpinnerPrinter(io.Discard, false))
err := tc.args.cmd.Run(kctx, logging.NewNopLogger(), terminal.NewSpinnerPrinter(io.Discard, false), &config.Config{})
if diff := cmp.Diff(tc.want.err, err, cmpopts.EquateErrors()); diff != "" {
t.Errorf("\n%s\nRun(...): -want error, +got error:\n%s", tc.reason, diff)
}
Expand Down
Loading