Skip to content

Commit

Permalink
Move file related models to pkg/model/file
Browse files Browse the repository at this point in the history
- Move model.File to its own subpackage
- Change input.File name to input.Template to avoid collisions with file.File
- Move pkg/scaffold/input into pkg/model/file
- Delete unused tests
- Resolve naming conflicts
- Stop injecting ProjectPath, BoilerplatePath and Version into templates
    BoilerplatePath is being used once in v1 and once in v2, and the rest are never being used, so injeceting them is not justified.
- Inject from universe instead of from scaffold
- Remove unused fields from Scaffold
- Remove validate function as was only used once and has 3 LoC
- Remove file.Options
- model.UniverseOptions and model.NewUniverse no longer return an error
  • Loading branch information
Adirio committed Jan 31, 2020
1 parent eace08d commit f3a1adc
Show file tree
Hide file tree
Showing 90 changed files with 599 additions and 853 deletions.
10 changes: 9 additions & 1 deletion cmd/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -202,6 +204,12 @@ func (o *apiOptions) validate(c *config.Config) error {
}

func (o *apiOptions) scaffolder(c *config.Config) (scaffold.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)
}

// Create the actual resource from the resource options
var res *resource.Resource
switch {
Expand All @@ -226,7 +234,7 @@ func (o *apiOptions) scaffolder(c *config.Config) (scaffold.Scaffolder, error) {
return nil, fmt.Errorf("unknown pattern %q", o.pattern)
}

return scaffold.NewAPIScaffolder(c, res, o.doResource, o.doController, plugins), nil
return scaffold.NewAPIScaffolder(c, string(bp), res, o.doResource, o.doController, plugins), nil
}

func (o *apiOptions) postScaffold(_ *config.Config) error {
Expand Down
20 changes: 17 additions & 3 deletions cmd/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ package main
import (
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"

"github.com/spf13/cobra"

Expand Down Expand Up @@ -110,7 +112,13 @@ func (o *webhookV1Options) validate(c *config.Config) error {
return nil
}

func (o *webhookV1Options) scaffolder(c *config.Config) (scaffold.Scaffolder, error) { // nolint:unparam
func (o *webhookV1Options) scaffolder(c *config.Config) (scaffold.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)
}

// Create the actual resource from the resource options
var res *resource.Resource
switch {
Expand All @@ -122,7 +130,7 @@ func (o *webhookV1Options) scaffolder(c *config.Config) (scaffold.Scaffolder, er
return nil, fmt.Errorf("unknown project version %v", c.Version)
}

return scaffold.NewV1WebhookScaffolder(&c.Config, res, o.server, o.webhookType, o.operations), nil
return scaffold.NewV1WebhookScaffolder(&c.Config, string(bp), res, o.server, o.webhookType, o.operations), nil
}

func (o *webhookV1Options) postScaffold(_ *config.Config) error {
Expand Down Expand Up @@ -213,6 +221,12 @@ func (o *webhookV2Options) validate(c *config.Config) error {
}

func (o *webhookV2Options) scaffolder(c *config.Config) (scaffold.Scaffolder, error) { // nolint:unparam
// 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)
}

// Create the actual resource from the resource options
var res *resource.Resource
switch {
Expand All @@ -224,7 +238,7 @@ func (o *webhookV2Options) scaffolder(c *config.Config) (scaffold.Scaffolder, er
return nil, fmt.Errorf("unknown project version %v", c.Version)
}

return scaffold.NewV2WebhookScaffolder(&c.Config, res, o.defaulting, o.validation, o.conversion), nil
return scaffold.NewV2WebhookScaffolder(&c.Config, string(bp), res, o.defaulting, o.validation, o.conversion), nil
}

func (o *webhookV2Options) postScaffold(_ *config.Config) error {
Expand Down
19 changes: 14 additions & 5 deletions pkg/model/file.go → pkg/model/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,20 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package model
package file

import (
"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
// IfExistsAction determines what to do if the scaffold file already exists
type IfExistsAction int

const (
// Skip skips the file and moves to the next one
Skip IfExistsAction = iota

// Error returns an error and stops processing
Error

// Overwrite truncates and overwrites the existing file
Overwrite
)

// File describes a file that will be written
Expand All @@ -28,7 +38,6 @@ type File struct {
// Contents is the generated output
Contents string `json:"contents,omitempty"`

// TODO: Move input.IfExistsAction into model
// IfExistsAction determines what to do if the file exists
IfExistsAction input.IfExistsAction `json:"ifExistsAction,omitempty"`
IfExistsAction IfExistsAction `json:"ifExistsAction,omitempty"`
}
79 changes: 4 additions & 75 deletions pkg/scaffold/input/input.go → pkg/model/file/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package input

// IfExistsAction determines what to do if the scaffold file already exists
type IfExistsAction int

const (
// Skip skips the file and moves to the next one
Skip IfExistsAction = iota

// Error returns an error and stops processing
Error

// Overwrite truncates and overwrites the existing file
Overwrite
)
package file

// Input is the input for scaffolding a file
type Input struct {
Expand All @@ -44,21 +30,12 @@ type Input struct {
// Boilerplate is the contents of a Boilerplate go header file
Boilerplate string

// BoilerplatePath is the path to a Boilerplate go header file
BoilerplatePath string

// Version is the project version
Version string

// Domain is the domain for the APIs
Domain string

// Repo is the go project package
Repo string

// ProjectPath is the relative path to the project root
ProjectPath string

// MultiGroup is the multi-group boolean from the PROJECT file
MultiGroup bool
}
Expand Down Expand Up @@ -102,32 +79,6 @@ func (i *Input) SetBoilerplate(b string) {
}
}

// BoilerplatePath allows boilerplate file path to be set on an object
type BoilerplatePath interface {
// SetBoilerplatePath sets the boilerplate file path
SetBoilerplatePath(string)
}

// SetBoilerplatePath sets the boilerplate file path
func (i *Input) SetBoilerplatePath(bp string) {
if i.BoilerplatePath == "" {
i.BoilerplatePath = bp
}
}

// Version allows the project version to be set on an object
type Version interface {
// SetVersion sets the project version
SetVersion(string)
}

// SetVersion sets the project version
func (i *Input) SetVersion(v string) {
if i.Version == "" {
i.Version = v
}
}

// MultiGroup allows the project version to be set on an object
type MultiGroup interface {
// SetVersion sets the project version
Expand All @@ -139,37 +90,15 @@ func (i *Input) SetMultiGroup(v bool) {
i.MultiGroup = v
}

// ProjecPath allows the project path to be set on an object
type ProjecPath interface {
// SetProjectPath sets the project file location
SetProjectPath(string)
}

// SetProjectPath sets the project path
func (i *Input) SetProjectPath(p string) {
if i.ProjectPath == "" {
i.ProjectPath = p
}
}

// File is a scaffoldable file
type File interface {
// Template is a scaffoldable file template
type Template interface {
// GetInput returns the Input for creating a scaffold file
GetInput() (Input, error)
}

// RequiresValidation is a file that requires validation
type RequiresValidation interface {
File
Template
// Validate returns true if the template has valid values
Validate() error
}

// Options are the options for executing scaffold templates
type Options struct {
// BoilerplatePath is the path to the boilerplate file
BoilerplatePath string

// Path is the path to the project
ProjectPath string
}
60 changes: 29 additions & 31 deletions pkg/model/universe.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ limitations under the License.
package model

import (
"io/ioutil"

"sigs.k8s.io/kubebuilder/pkg/model/config"
"sigs.k8s.io/kubebuilder/pkg/model/file"
"sigs.k8s.io/kubebuilder/pkg/model/resource"
)

Expand All @@ -35,66 +34,65 @@ type Universe struct {
Resource *resource.Resource `json:"resource,omitempty"`

// Files contains the model of the files that are being scaffolded
Files []*File `json:"files,omitempty"`
Files []*file.File `json:"files,omitempty"`
}

// NewUniverse creates a new Universe
func NewUniverse(options ...UniverseOption) (*Universe, error) {
func NewUniverse(options ...UniverseOption) *Universe {
universe := &Universe{}

// Apply options
for _, option := range options {
if err := option(universe); err != nil {
return nil, err
}
option(universe)
}

return universe, nil
return universe
}

// UniverseOption configure Universe
type UniverseOption func(*Universe) error
type UniverseOption func(*Universe)

// WithConfig stores the already loaded project configuration
func WithConfig(projectConfig *config.Config) UniverseOption {
return func(universe *Universe) error {
return func(universe *Universe) {
universe.Config = projectConfig
return nil
}
}

// WithBoilerplateFrom loads the boilerplate from the provided path
func WithBoilerplateFrom(path string) UniverseOption {
return func(universe *Universe) error {
boilerplate, err := ioutil.ReadFile(path)
if err != nil {
return err
}

universe.Boilerplate = string(boilerplate)
return nil
}
}

// WithBoilerplate stores the already loaded project configuration
func WithBoilerplate(boilerplate string) UniverseOption {
return func(universe *Universe) error {
return func(universe *Universe) {
universe.Boilerplate = boilerplate
return nil
}
}

// WithoutBoilerplate is used for files that do not require a boilerplate
func WithoutBoilerplate(universe *Universe) error {
universe.Boilerplate = "-"
return nil
func WithoutBoilerplate(universe *Universe) {
universe.Boilerplate = ""
}

// WithResource stores the provided resource
func WithResource(resource *resource.Resource) UniverseOption {
return func(universe *Universe) error {
return func(universe *Universe) {
universe.Resource = resource
}
}

return nil
func (u Universe) InjectInto(t file.Template) {
// Inject project configuration
if u.Config != nil {
if templateWithDomain, ok := t.(file.Domain); ok {
templateWithDomain.SetDomain(u.Config.Domain)
}
if templateWithRepository, ok := t.(file.Repo); ok {
templateWithRepository.SetRepo(u.Config.Repo)
}
if templateWithMultiGroup, ok := t.(file.MultiGroup); ok {
templateWithMultiGroup.SetMultiGroup(u.Config.MultiGroup)
}
}
// Inject boilerplate
if templateWithBoilerplate, ok := t.(file.Boilerplate); ok {
templateWithBoilerplate.SetBoilerplate(u.Boilerplate)
}
}
Loading

0 comments on commit f3a1adc

Please sign in to comment.