Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Inject filesystem from cli instead of creating several per command
Signed-off-by: Adrian Orive <[email protected]>
  • Loading branch information
Adirio committed Mar 2, 2021
commit e3efd1517c59a1c1fe9dae36e1786d34883c5d0f
2 changes: 1 addition & 1 deletion pkg/cli/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,6 @@ func (c cli) bindCreateAPI(ctx plugin.Context, cmd *cobra.Command) {
subcommand.UpdateContext(&ctx)
cmd.Long = ctx.Description
cmd.Example = ctx.Examples
cmd.RunE = runECmdFunc(cfg, subcommand,
cmd.RunE = runECmdFunc(c.fs, cfg, subcommand,
fmt.Sprintf("failed to create API with %q", plugin.KeyFor(createAPIPlugin)))
}
5 changes: 5 additions & 0 deletions pkg/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"os"
"strings"

"github.com/spf13/afero"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

Expand Down Expand Up @@ -96,6 +97,9 @@ type cli struct { //nolint:maligned

// Root command.
cmd *cobra.Command

// Underlying fs
fs afero.Fs
}

// New creates a new cli instance.
Expand Down Expand Up @@ -134,6 +138,7 @@ func newCLI(opts ...Option) (*cli, error) {
defaultProjectVersion: cfgv3.Version,
defaultPlugins: make(map[config.Version][]string),
plugins: make(map[string]plugin.Plugin),
fs: afero.NewOsFs(),
}

// Apply provided options.
Expand Down
6 changes: 4 additions & 2 deletions pkg/cli/cmd_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package cli
import (
"fmt"

"github.com/spf13/afero"
"github.com/spf13/cobra"

"sigs.k8s.io/kubebuilder/v3/pkg/cli/internal/config"
Expand Down Expand Up @@ -48,12 +49,13 @@ func errCmdFunc(err error) func(*cobra.Command, []string) error {
// runECmdFunc returns a cobra RunE function that runs subcommand and saves the
// config, which may have been modified by subcommand.
func runECmdFunc(
fs afero.Fs,
c *config.Config,
subcommand plugin.Subcommand, // nolint:interfacer
subcommand plugin.Subcommand,
msg string,
) func(*cobra.Command, []string) error {
return func(*cobra.Command, []string) error {
if err := subcommand.Run(); err != nil {
if err := subcommand.Run(fs); err != nil {
return fmt.Errorf("%s: %v", msg, err)
}
return c.Save()
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,6 @@ func (c cli) bindEdit(ctx plugin.Context, cmd *cobra.Command) {
subcommand.UpdateContext(&ctx)
cmd.Long = ctx.Description
cmd.Example = ctx.Examples
cmd.RunE = runECmdFunc(cfg, subcommand,
cmd.RunE = runECmdFunc(c.fs, cfg, subcommand,
fmt.Sprintf("failed to edit project with %q", plugin.KeyFor(editPlugin)))
}
2 changes: 1 addition & 1 deletion pkg/cli/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (c cli) bindInit(ctx plugin.Context, cmd *cobra.Command) {
if err == nil || os.IsExist(err) {
log.Fatal("config already initialized")
}
if err := subcommand.Run(); err != nil {
if err := subcommand.Run(c.fs); err != nil {
return fmt.Errorf("failed to initialize project with %q: %v", plugin.KeyFor(initPlugin), err)
}
return cfg.Save()
Expand Down
3 changes: 3 additions & 0 deletions pkg/cli/internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const (
DefaultPath = "PROJECT"
)

// TODO: use cli.fs instead of creating a new afero.Fs for each config. For this purpose, we may want to turn this
// package's functions into methods of cli.

func exists(fs afero.Fs, path string) (bool, error) {
// Look up the file
_, err := fs.Stat(path)
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,6 @@ func (c cli) bindCreateWebhook(ctx plugin.Context, cmd *cobra.Command) {
subcommand.UpdateContext(&ctx)
cmd.Long = ctx.Description
cmd.Example = ctx.Examples
cmd.RunE = runECmdFunc(cfg, subcommand,
cmd.RunE = runECmdFunc(c.fs, cfg, subcommand,
fmt.Sprintf("failed to create webhook with %q", plugin.KeyFor(createWebhookPlugin)))
}
3 changes: 2 additions & 1 deletion pkg/plugin/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package plugin

import (
"github.com/spf13/afero"
"github.com/spf13/pflag"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
Expand Down Expand Up @@ -53,7 +54,7 @@ type Subcommand interface {
// command line flags.
BindFlags(*pflag.FlagSet)
// Run runs the subcommand.
Run() error
Run(fs afero.Fs) error
// InjectConfig passes a config to a plugin. The plugin may modify the config.
// Initializing, loading, and saving the config is managed by the cli package.
InjectConfig(config.Config)
Expand Down
15 changes: 4 additions & 11 deletions pkg/plugins/golang/v2/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/spf13/afero"
"github.com/spf13/pflag"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
Expand Down Expand Up @@ -126,7 +125,7 @@ func (p *createAPISubcommand) InjectConfig(c config.Config) {
p.config = c
}

func (p *createAPISubcommand) Run() error {
func (p *createAPISubcommand) Run(fs afero.Fs) error {
// Ask for API and Controller if not specified
reader := bufio.NewReader(os.Stdin)
if !p.resourceFlag.Changed {
Expand All @@ -141,7 +140,7 @@ func (p *createAPISubcommand) Run() error {
// Create the resource from the options
p.resource = p.options.NewResource(p.config)

return cmdutil.Run(p)
return cmdutil.Run(p, fs)
}

func (p *createAPISubcommand) Validate() error {
Expand Down Expand Up @@ -171,12 +170,6 @@ func (p *createAPISubcommand) Validate() error {
}

func (p *createAPISubcommand) GetScaffolder() (cmdutil.Scaffolder, error) {
// Load the boilerplate
bp, err := ioutil.ReadFile(filepath.Join("hack", "boilerplate.go.txt")) // nolint:gosec
if err != nil {
return nil, fmt.Errorf("unable to load boilerplate: %v", err)
}

// Load the requested plugins
plugins := make([]model.Plugin, 0)
switch strings.ToLower(p.pattern) {
Expand All @@ -188,7 +181,7 @@ func (p *createAPISubcommand) GetScaffolder() (cmdutil.Scaffolder, error) {
return nil, fmt.Errorf("unknown pattern %q", p.pattern)
}

return scaffolds.NewAPIScaffolder(p.config, string(bp), p.resource, p.force, plugins), nil
return scaffolds.NewAPIScaffolder(p.config, p.resource, p.force, plugins), nil
}

func (p *createAPISubcommand) PostScaffold() error {
Expand Down
5 changes: 3 additions & 2 deletions pkg/plugins/golang/v2/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package v2
import (
"fmt"

"github.com/spf13/afero"
"github.com/spf13/pflag"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
Expand Down Expand Up @@ -57,8 +58,8 @@ func (p *editSubcommand) InjectConfig(c config.Config) {
p.config = c
}

func (p *editSubcommand) Run() error {
return cmdutil.Run(p)
func (p *editSubcommand) Run(fs afero.Fs) error {
return cmdutil.Run(p, fs)
}

func (p *editSubcommand) Validate() error {
Expand Down
5 changes: 3 additions & 2 deletions pkg/plugins/golang/v2/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"path/filepath"
"strings"

"github.com/spf13/afero"
"github.com/spf13/pflag"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
Expand Down Expand Up @@ -109,8 +110,8 @@ func (p *initSubcommand) InjectConfig(c config.Config) {
p.config = c
}

func (p *initSubcommand) Run() error {
return cmdutil.Run(p)
func (p *initSubcommand) Run(fs afero.Fs) error {
return cmdutil.Run(p, fs)
}

func (p *initSubcommand) Validate() error {
Expand Down
43 changes: 28 additions & 15 deletions pkg/plugins/golang/v2/scaffolds/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package scaffolds
import (
"fmt"

"github.com/spf13/afero"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2"
"sigs.k8s.io/kubebuilder/v3/pkg/model"
Expand All @@ -30,6 +32,7 @@ import (
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/config/rbac"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/config/samples"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/controllers"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds/internal/templates/hack"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/machinery"
)
Expand All @@ -47,6 +50,9 @@ type apiScaffolder struct {
boilerplate string
resource resource.Resource

// fs is the filesystem that will be used by the scaffolder
fs afero.Fs

// plugins is the list of plugins we should allow to transform our generated scaffolding
plugins []model.Plugin

Expand All @@ -57,24 +63,21 @@ type apiScaffolder struct {
// NewAPIScaffolder returns a new Scaffolder for API/controller creation operations
func NewAPIScaffolder(
config config.Config,
boilerplate string,
res resource.Resource,
force bool,
plugins []model.Plugin,
) cmdutil.Scaffolder {
return &apiScaffolder{
config: config,
boilerplate: boilerplate,
resource: res,
plugins: plugins,
force: force,
config: config,
resource: res,
plugins: plugins,
force: force,
}
}

// Scaffold implements Scaffolder
func (s *apiScaffolder) Scaffold() error {
fmt.Println("Writing scaffold for you to edit...")
return s.scaffold()
// InjectFS implements cmdutil.Scaffolder
func (s *apiScaffolder) InjectFS(fs afero.Fs) {
s.fs = fs
}

func (s *apiScaffolder) newUniverse() *model.Universe {
Expand All @@ -85,7 +88,17 @@ func (s *apiScaffolder) newUniverse() *model.Universe {
)
}

func (s *apiScaffolder) scaffold() error {
// Scaffold implements cmdutil.Scaffolder
func (s *apiScaffolder) Scaffold() error {
fmt.Println("Writing scaffold for you to edit...")

// Load the boilerplate
bp, err := afero.ReadFile(s.fs, hack.DefaultBoilerplatePath)
if err != nil {
return fmt.Errorf("error scaffolding API/controller: unable to load boilerplate: %w", err)
}
s.boilerplate = string(bp)

// Keep track of these values before the update
doAPI := s.resource.HasAPI()
doController := s.resource.HasController()
Expand All @@ -104,7 +117,7 @@ func (s *apiScaffolder) scaffold() error {

if doAPI {

if err := machinery.NewScaffold(s.plugins...).Execute(
if err := machinery.NewScaffold(s.fs, s.plugins...).Execute(
s.newUniverse(),
&api.Types{Force: s.force},
&api.Group{},
Expand All @@ -117,7 +130,7 @@ func (s *apiScaffolder) scaffold() error {
return fmt.Errorf("error scaffolding APIs: %w", err)
}

if err := machinery.NewScaffold().Execute(
if err := machinery.NewScaffold(s.fs).Execute(
s.newUniverse(),
&crd.Kustomization{},
&crd.KustomizeConfig{},
Expand All @@ -128,7 +141,7 @@ func (s *apiScaffolder) scaffold() error {
}

if doController {
if err := machinery.NewScaffold(s.plugins...).Execute(
if err := machinery.NewScaffold(s.fs, s.plugins...).Execute(
s.newUniverse(),
&controllers.SuiteTest{Force: s.force},
&controllers.Controller{ControllerRuntimeVersion: ControllerRuntimeVersion, Force: s.force},
Expand All @@ -137,7 +150,7 @@ func (s *apiScaffolder) scaffold() error {
}
}

if err := machinery.NewScaffold(s.plugins...).Execute(
if err := machinery.NewScaffold(s.fs, s.plugins...).Execute(
s.newUniverse(),
&templates.MainUpdater{WireResource: doAPI, WireController: doController},
); err != nil {
Expand Down
20 changes: 14 additions & 6 deletions pkg/plugins/golang/v2/scaffolds/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ package scaffolds

import (
"fmt"
"io/ioutil"
"strings"

"github.com/spf13/afero"

"sigs.k8s.io/kubebuilder/v3/pkg/config"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil"
)
Expand All @@ -30,6 +31,9 @@ var _ cmdutil.Scaffolder = &editScaffolder{}
type editScaffolder struct {
config config.Config
multigroup bool

// fs is the filesystem that will be used by the scaffolder
fs afero.Fs
}

// NewEditScaffolder returns a new Scaffolder for configuration edit operations
Expand All @@ -40,10 +44,15 @@ func NewEditScaffolder(config config.Config, multigroup bool) cmdutil.Scaffolder
}
}

// Scaffold implements Scaffolder
// InjectFS implements cmdutil.Scaffolder
func (s *editScaffolder) InjectFS(fs afero.Fs) {
s.fs = fs
}

// Scaffold implements cmdutil.Scaffolder
func (s *editScaffolder) Scaffold() error {
filename := "Dockerfile"
bs, err := ioutil.ReadFile(filename)
bs, err := afero.ReadFile(s.fs, filename)
if err != nil {
return err
}
Expand Down Expand Up @@ -76,9 +85,8 @@ func (s *editScaffolder) Scaffold() error {
// Check if the str is not empty, because when the file is already in desired format it will return empty string
// because there is nothing to replace.
if str != "" {
// false positive
// nolint:gosec
return ioutil.WriteFile(filename, []byte(str), 0644)
// TODO: instead of writing it directly, we should use the scaffolding machinery for consistency
return afero.WriteFile(s.fs, filename, []byte(str), 0644)
}

return nil
Expand Down
Loading