Skip to content

Commit

Permalink
🏃 move current scaffolding under v1 pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
droot committed Apr 12, 2019
1 parent e904181 commit f8dba2e
Show file tree
Hide file tree
Showing 53 changed files with 1,081 additions and 260 deletions.
134 changes: 38 additions & 96 deletions cmd/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,112 +21,74 @@ import (
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"strings"

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

"sigs.k8s.io/kubebuilder/cmd/util"
"sigs.k8s.io/kubebuilder/pkg/scaffold"
"sigs.k8s.io/kubebuilder/pkg/scaffold/controller"
"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
"sigs.k8s.io/kubebuilder/pkg/scaffold/resource"
"sigs.k8s.io/kubebuilder/pkg/scaffold/v1/resource"
)

type apiOptions struct {
r *resource.Resource
resourceFlag, controllerFlag *flag.Flag
doResource, doController, doMake bool
apiScaffolder scaffold.API
resourceFlag, controllerFlag *flag.Flag
}

// APICmd represents the resource command
func (o *apiOptions) bindCmdFlags(cmd *cobra.Command) {
cmd.Flags().BoolVar(&o.apiScaffolder.RunMake, "make", true,
"if true, run make after generating files")
cmd.Flags().BoolVar(&o.apiScaffolder.DoResource, "resource", true,
"if set, generate the resource without prompting the user")
o.resourceFlag = cmd.Flag("resource")
cmd.Flags().BoolVar(&o.apiScaffolder.DoController, "controller", true,
"if set, generate the controller without prompting the user")
o.controllerFlag = cmd.Flag("controller")
o.apiScaffolder.Resource = resourceForFlags(cmd.Flags())
}

// resourceForFlags registers flags for Resource fields and returns the Resource
func resourceForFlags(f *flag.FlagSet) *resource.Resource {
r := &resource.Resource{}
f.StringVar(&r.Kind, "kind", "", "resource Kind")
f.StringVar(&r.Group, "group", "", "resource Group")
f.StringVar(&r.Version, "version", "", "resource Version")
f.BoolVar(&r.Namespaced, "namespaced", true, "resource is namespaced")
f.BoolVar(&r.CreateExampleReconcileBody, "example", true,
"if true an example reconcile body should be written while scaffolding a resource.")
return r
}

// APICmd represents the resource command
func (o *apiOptions) runAddAPI() {
dieIfNoProject()

reader := bufio.NewReader(os.Stdin)
if !o.resourceFlag.Changed {
fmt.Println("Create Resource under pkg/apis [y/n]?")
o.doResource = util.Yesno(reader)
o.apiScaffolder.DoResource = util.Yesno(reader)
}

if !o.controllerFlag.Changed {
fmt.Println("Create Controller under pkg/controller [y/n]?")
o.doController = util.Yesno(reader)
o.apiScaffolder.DoController = util.Yesno(reader)
}

if o.r.Group == "" {
log.Fatalf("Must specify --group")
}
if o.r.Version == "" {
log.Fatalf("Must specify --version")
}
if o.r.Kind == "" {
log.Fatalf("Must specify --kind")
if err := o.apiScaffolder.Validate(); err != nil {
log.Fatalln(err)
}

fmt.Println("Writing scaffold for you to edit...")

r := o.r
if o.doResource {
fmt.Println(filepath.Join("pkg", "apis", r.Group, r.Version,
fmt.Sprintf("%s_types.go", strings.ToLower(r.Kind))))
fmt.Println(filepath.Join("pkg", "apis", r.Group, r.Version,
fmt.Sprintf("%s_types_test.go", strings.ToLower(r.Kind))))

err := (&scaffold.Scaffold{}).Execute(input.Options{},
&resource.Register{Resource: r},
&resource.Types{Resource: r},
&resource.VersionSuiteTest{Resource: r},
&resource.TypesTest{Resource: r},
&resource.Doc{Resource: r},
&resource.Group{Resource: r},
&resource.AddToScheme{Resource: r},
&resource.CRDSample{Resource: r},
)
if err != nil {
log.Fatal(err)
}
} else {
// disable generation of example reconcile body if not scaffolding resource
// because this could result in a fork-bomb of k8s resources where watching a
// deployment, replicaset etc. results in generating deployment which
// end up generating replicaset, pod etc recursively.
r.CreateExampleReconcileBody = false
}

if o.doController {
fmt.Println(filepath.Join("pkg", "controller", strings.ToLower(r.Kind),
fmt.Sprintf("%s_controller.go", strings.ToLower(r.Kind))))
fmt.Println(filepath.Join("pkg", "controller", strings.ToLower(r.Kind),
fmt.Sprintf("%s_controller_test.go", strings.ToLower(r.Kind))))

err := (&scaffold.Scaffold{}).Execute(input.Options{},
&controller.Controller{Resource: r},
&controller.AddController{Resource: r},
&controller.Test{Resource: r},
&controller.SuiteTest{Resource: r},
)
if err != nil {
log.Fatal(err)
}
}

if o.doMake {
fmt.Println("Running make...")
cm := exec.Command("make") // #nosec
cm.Stderr = os.Stderr
cm.Stdout = os.Stdout
if err := cm.Run(); err != nil {
log.Fatal(err)
}
if err := o.apiScaffolder.Scaffold(); err != nil {
log.Fatal(err)
}
}

func newAPICommand() *cobra.Command {
o := apiOptions{}
options := apiOptions{
apiScaffolder: scaffold.API{},
}

apiCmd := &cobra.Command{
Use: "create api",
Expand Down Expand Up @@ -158,19 +120,11 @@ After the scaffold is written, api will run make on the project.
make run
`,
Run: func(cmd *cobra.Command, args []string) {
o.runAddAPI()
options.runAddAPI()
},
}

apiCmd.Flags().BoolVar(&o.doMake, "make", true,
"if true, run make after generating files")
apiCmd.Flags().BoolVar(&o.doResource, "resource", true,
"if set, generate the resource without prompting the user")
o.resourceFlag = apiCmd.Flag("resource")
apiCmd.Flags().BoolVar(&o.doController, "controller", true,
"if set, generate the controller without prompting the user")
o.controllerFlag = apiCmd.Flag("controller")
o.r = ResourceForFlags(apiCmd.Flags())
options.bindCmdFlags(apiCmd)

return apiCmd
}
Expand All @@ -181,15 +135,3 @@ func dieIfNoProject() {
log.Fatalf("Command must be run from a directory containing %s", "PROJECT")
}
}

// ResourceForFlags registers flags for Resource fields and returns the Resource
func ResourceForFlags(f *flag.FlagSet) *resource.Resource {
r := &resource.Resource{}
f.StringVar(&r.Kind, "kind", "", "resource Kind")
f.StringVar(&r.Group, "group", "", "resource Group")
f.StringVar(&r.Version, "version", "", "resource Version")
f.BoolVar(&r.Namespaced, "namespaced", true, "resource is namespaced")
f.BoolVar(&r.CreateExampleReconcileBody, "example", true,
"if true an example reconcile body should be written while scaffolding a resource.")
return r
}
Loading

0 comments on commit f8dba2e

Please sign in to comment.