From 883ca641f035713a8cbd5495e3b86617430f6f2d Mon Sep 17 00:00:00 2001 From: Sunil Arora Date: Thu, 27 Sep 2018 15:14:48 -0700 Subject: [PATCH] drop support for legacy (v0) projects This is a first in the series of PRs for cleaning up the technical debt. --- .travis.yml | 2 - cmd/kubebuilder/initproject/init.go | 191 ++++++++++++++----------- cmd/kubebuilder/initproject/project.go | 169 ---------------------- cmd/kubebuilder/main.go | 12 +- 4 files changed, 117 insertions(+), 257 deletions(-) delete mode 100644 cmd/kubebuilder/initproject/project.go diff --git a/.travis.yml b/.travis.yml index 43dce6b7847..4b320213035 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,8 +22,6 @@ install: - script: -- TRACE=1 ./testv0.sh -- ./test_existing_projects.sh - TRACE=1 ./testv1.sh # TBD. Suppressing for now. diff --git a/cmd/kubebuilder/initproject/init.go b/cmd/kubebuilder/initproject/init.go index 0cc30d4c9d3..6d88ab1b83d 100644 --- a/cmd/kubebuilder/initproject/init.go +++ b/cmd/kubebuilder/initproject/init.go @@ -17,52 +17,51 @@ limitations under the License. package initproject import ( + "bufio" "fmt" "log" "os" "os/exec" "path/filepath" - "strconv" "strings" "github.com/Masterminds/semver" "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" "github.com/spf13/cobra" + flag "github.com/spf13/pflag" + "sigs.k8s.io/controller-tools/pkg/scaffold" + "sigs.k8s.io/controller-tools/pkg/scaffold/input" "sigs.k8s.io/controller-tools/pkg/scaffold/manager" "sigs.k8s.io/controller-tools/pkg/scaffold/project" ) -type initOptions struct { - domain string - copyright string - bazel bool - controllerOnly bool - projectVersion string - projectOptions -} - func AddInit(cmd *cobra.Command) { - o := initOptions{} + o := projectOptions{} initCmd := &cobra.Command{ Use: "init", Short: "Initialize a new project", - Long: `Initialize a new project including vendor/ directory and Go package directories.`, - Example: `# Initialize project structure -kubebuilder init --domain mydomain + Long: `Initialize a new project including vendor/ directory and Go package directories. + +Writes the following files: +- a boilerplate license file +- a PROJECT file with the domain and repo +- a Makefile to build the project +- a Gopkg.toml with project dependencies +- a Kustomization.yaml for customizating manifests +- a Patch file for customizing image for manager manifests +- a cmd/manager/main.go to run + +project will prompt the user to run 'dep ensure' after writing the project files. +`, + Example: `# Scaffold a project using the apache2 license with "The Kubernetes authors" as owners +kubebuilder init --domain example.org --license apache2 --owner "The Kubernetes authors" `, Run: func(cmd *cobra.Command, args []string) { - o.runInitRepo() + o.RunInit() }, } - v0comment := "Works only with project-version v0, " - initCmd.Flags().StringVar(&o.domain, "domain", "", "domain for the API groups") - initCmd.Flags().StringVar(&o.copyright, "copyright", filepath.Join("hack", "boilerplate.go.txt"), v0comment+"Location of copyright boilerplate file.") - initCmd.Flags().BoolVar(&o.bazel, "bazel", false, v0comment+"if true, setup Bazel workspace artifacts") - initCmd.Flags().BoolVar(&o.controllerOnly, "controller-only", false, v0comment+"if true, setup controller only") - initCmd.Flags().StringVar(&o.projectVersion, "project-version", "v1", "if set to v0, init project with kubebuilder legacy version") - initCmd.Flags().BoolVar( &o.dep, "dep", true, "if specified, determines whether dep will be used.") o.depFlag = initCmd.Flag("dep") @@ -76,56 +75,114 @@ kubebuilder init --domain mydomain cmd.AddCommand(initCmd) } -func (o *initOptions) runInitRepo() { +type projectOptions struct { + prj *project.Project + bp *project.Boilerplate + gopkg *project.GopkgToml + mgr *manager.Cmd + dkr *manager.Dockerfile + dep bool + depFlag *flag.Flag +} + +func (o *projectOptions) RunInit() { checkGoVersion() if !depExists() { log.Fatalf("Dep is not installed. Follow steps at: https://golang.github.io/dep/docs/installation.html") } - if o.projectVersion == "v1" { - if len(o.domain) != 0 { - o.prj.Domain = o.domain - } - o.RunInit() + if util.ProjectExist() { + fmt.Println("Failed to initialize project bacause project is already initialized") return } + // project and boilerplate must come before main so the boilerplate exists + s := &scaffold.Scaffold{ + BoilerplateOptional: true, + ProjectOptional: true, + } - if len(o.domain) == 0 { - log.Fatal("Must specify --domain") + p, err := o.prj.GetInput() + if err != nil { + log.Fatal(err) } - cr := util.GetCopyright(o.copyright) - fmt.Printf("Initializing project structure...\n") - if o.bazel { - createBazelWorkspace() + b, err := o.bp.GetInput() + if err != nil { + log.Fatal(err) } - createControllerManager(cr) - //createInstaller(cr) - createAPIs(cr, o.domain) - //runCreateApiserver(cr) - - pkgs := []string{ - filepath.Join("hack"), - filepath.Join("pkg"), - filepath.Join("pkg", "controller"), - filepath.Join("pkg", "inject"), - //filepath.Join("pkg", "openapi"), + + err = s.Execute(input.Options{ProjectPath: p.Path, BoilerplatePath: b.Path}, o.prj, o.bp) + if err != nil { + log.Fatal(err) } - fmt.Printf("\t%s/\n", filepath.Join("pkg", "controller")) - for _, p := range pkgs { - createPackage(cr, p) + // default controller manager image name + imgName := "controller:latest" + + s = &scaffold.Scaffold{} + err = s.Execute(input.Options{ProjectPath: p.Path, BoilerplatePath: b.Path}, + o.gopkg, + o.mgr, + &project.Makefile{Image: imgName}, + o.dkr, + &manager.APIs{}, + &manager.Controller{}, + &manager.Config{Image: imgName}, + &project.GitIgnore{}, + &project.Kustomize{}, + &project.KustomizeImagePatch{}) + if err != nil { + log.Fatal(err) + } + + if !o.depFlag.Changed { + reader := bufio.NewReader(os.Stdin) + fmt.Println("Run `dep ensure` to fetch dependencies (Recommended) [y/n]?") + o.dep = util.Yesno(reader) + } + if o.dep { + c := exec.Command("dep", "ensure") // #nosec + c.Stderr = os.Stderr + c.Stdout = os.Stdout + fmt.Println(strings.Join(c.Args, " ")) + if err := c.Run(); err != nil { + log.Fatal(err) + } + + fmt.Println("Running make...") + c = exec.Command("make") // #nosec + c.Stderr = os.Stderr + c.Stdout = os.Stdout + fmt.Println(strings.Join(c.Args, " ")) + if err := c.Run(); err != nil { + log.Fatal(err) + } + } else { + fmt.Println("Skipping `dep ensure`. Dependencies will not be fetched.") } - doDockerfile() - doInject(cr) - doArgs(cr, o.controllerOnly) - RunVendorInstall(nil, []string{o.copyright}) - createBoilerplate() fmt.Printf("Next: Define a resource with:\n" + - "$ kubebuilder create resource\n") + "$ kubebuilder create api\n") +} + +// projectForFlags registers flags for Project fields and returns the Project +func projectForFlags(f *flag.FlagSet) *project.Project { + p := &project.Project{} + f.StringVar(&p.Repo, "repo", "", "name of the github repo. "+ + "defaults to the go package of the current working directory.") + f.StringVar(&p.Domain, "domain", "k8s.io", "domain for groups") + f.StringVar(&p.Version, "project-version", "1", "project version") + return p } +// boilerplateForFlags registers flags for Boilerplate fields and returns the Boilerplate +func boilerplateForFlags(f *flag.FlagSet) *project.Boilerplate { + b := &project.Boilerplate{} + f.StringVar(&b.Path, "path", "", "path for boilerplate") + f.StringVar(&b.License, "license", "apache2", "license to use to boilerplate. Maybe one of apache2,none") + f.StringVar(&b.Owner, "owner", "", "Owner to add to the copyright") + return b +} func checkGoVersion() { cmd := exec.Command("go", "version") out, err := cmd.Output() @@ -165,29 +222,3 @@ type templateArgs struct { Repo string ControllerOnly bool } - -func versionCmp(v1 string, v2 string) int { - v1s := strings.Split(strings.Replace(v1, "go", "", 1), ".") - v2s := strings.Split(strings.Replace(v2, "go", "", 1), ".") - for i := 0; i < len(v1s) && i < len(v2s); i++ { - mv1, err1 := strconv.Atoi(v1s[i]) - mv2, err2 := strconv.Atoi(v2s[i]) - if err1 == nil && err2 == nil { - cmp := mv1 - mv2 - if cmp > 0 { - return 1 - } else if cmp < 0 { - return -1 - } - } else { - log.Fatalf("Unexpected error comparing %v with %v", v1, v2) - } - } - if len(v1s) == len(v2s) { - return 0 - } else if len(v1s) > len(v2s) { - return 1 - } else { - return -1 - } -} diff --git a/cmd/kubebuilder/initproject/project.go b/cmd/kubebuilder/initproject/project.go deleted file mode 100644 index e535e0c340d..00000000000 --- a/cmd/kubebuilder/initproject/project.go +++ /dev/null @@ -1,169 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "bufio" - "fmt" - "log" - "os" - "os/exec" - "strings" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "github.com/spf13/cobra" - flag "github.com/spf13/pflag" - "sigs.k8s.io/controller-tools/pkg/scaffold" - "sigs.k8s.io/controller-tools/pkg/scaffold/input" - "sigs.k8s.io/controller-tools/pkg/scaffold/manager" - "sigs.k8s.io/controller-tools/pkg/scaffold/project" -) - -type projectOptions struct { - prj *project.Project - bp *project.Boilerplate - gopkg *project.GopkgToml - mgr *manager.Cmd - dkr *manager.Dockerfile - dep bool - depFlag *flag.Flag -} - -func (o *projectOptions) RunInit() { - if util.ProjectExist() { - fmt.Println("Failed to initialize project bacause project is already initialized") - return - } - // project and boilerplate must come before main so the boilerplate exists - s := &scaffold.Scaffold{ - BoilerplateOptional: true, - ProjectOptional: true, - } - - p, _ := o.prj.GetInput() - b, _ := o.bp.GetInput() - err := s.Execute(input.Options{ProjectPath: p.Path, BoilerplatePath: b.Path}, o.prj, o.bp) - if err != nil { - log.Fatal(err) - } - - // default controller manager image name - imgName := "controller:latest" - - s = &scaffold.Scaffold{} - err = s.Execute(input.Options{ProjectPath: p.Path, BoilerplatePath: b.Path}, - o.gopkg, - o.mgr, - &project.Makefile{Image: imgName}, - o.dkr, - &manager.APIs{}, - &manager.Controller{}, - &manager.Config{Image: imgName}, - &project.GitIgnore{}, - &project.Kustomize{}, - &project.KustomizeImagePatch{}) - if err != nil { - log.Fatal(err) - } - - if !o.depFlag.Changed { - reader := bufio.NewReader(os.Stdin) - fmt.Println("Run `dep ensure` to fetch dependencies (Recommended) [y/n]?") - o.dep = util.Yesno(reader) - } - if o.dep { - c := exec.Command("dep", "ensure") // #nosec - c.Stderr = os.Stderr - c.Stdout = os.Stdout - fmt.Println(strings.Join(c.Args, " ")) - if err := c.Run(); err != nil { - log.Fatal(err) - } - - fmt.Println("Running make...") - c = exec.Command("make") // #nosec - c.Stderr = os.Stderr - c.Stdout = os.Stdout - fmt.Println(strings.Join(c.Args, " ")) - if err := c.Run(); err != nil { - log.Fatal(err) - } - } else { - fmt.Println("Skipping `dep ensure`. Dependencies will not be fetched.") - } - fmt.Printf("Next: Define a resource with:\n" + - "$ kubebuilder create api\n") -} - -func AddProjectCommand(cmd *cobra.Command) { - o := projectOptions{} - - projectCmd := &cobra.Command{ - Use: "init", - Short: "Scaffold a new project.", - Long: `Scaffold a project. - -Writes the following files: -- a boilerplate license file -- a PROJECT file with the domain and repo -- a Makefile to build the project -- a Gopkg.toml with project dependencies -- a Kustomization.yaml for customizating manifests -- a Patch file for customizing image for manager manifests -- a cmd/manager/main.go to run - -project will prompt the user to run 'dep ensure' after writing the project files. -`, - Example: `# Scaffold a project using the apache2 license with "The Kubernetes authors" as owners -kubebuilder init --domain k8s.io --license apache2 --owner "The Kubernetes authors" -`, - Run: func(cmd *cobra.Command, args []string) { - o.RunInit() - }, - } - - projectCmd.Flags().BoolVar( - &o.dep, "dep", true, "if specified, determines whether dep will be used.") - o.depFlag = projectCmd.Flag("dep") - - o.prj = projectForFlags(projectCmd.Flags()) - o.bp = boilerplateForFlags(projectCmd.Flags()) - o.gopkg = &project.GopkgToml{} - o.mgr = &manager.Cmd{} - o.dkr = &manager.Dockerfile{} - - cmd.AddCommand(projectCmd) -} - -// projectForFlags registers flags for Project fields and returns the Project -func projectForFlags(f *flag.FlagSet) *project.Project { - p := &project.Project{} - f.StringVar(&p.Repo, "repo", "","name of the github repo. "+ - "defaults to the go package of the current working directory.") - p.Version = "1" - p.Domain = "k8s.io" - return p -} - -// boilerplateForFlags registers flags for Boilerplate fields and returns the Boilerplate -func boilerplateForFlags(f *flag.FlagSet) *project.Boilerplate { - b := &project.Boilerplate{} - f.StringVar(&b.Path, "path", "", "path for boilerplate") - f.StringVar(&b.License, "license", "apache2","license to use to boilerplate. Maybe one of apache2,none") - f.StringVar(&b.Owner, "owner", "","Owner to add to the copyright") - return b -} diff --git a/cmd/kubebuilder/main.go b/cmd/kubebuilder/main.go index c241b53fff8..398850e6442 100644 --- a/cmd/kubebuilder/main.go +++ b/cmd/kubebuilder/main.go @@ -25,7 +25,6 @@ import ( "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/initproject" "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/v0" "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/v1" "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/version" "github.com/spf13/cobra" @@ -49,14 +48,15 @@ func main() { "\nCurrent GOPATH=%s. \nCurrent directory=%s", gopath, wd) } util.Repo = strings.Replace(wd, util.GoSrc+string(filepath.Separator), "", 1) + + // add init command initproject.AddInit(cmd) + + // add version command version.AddVersion(cmd) - if util.IsNewVersion() || util.IsProjectNotInitialized() { - v1.AddCmds(cmd) - } else { - v0.AddCmds(cmd) - } + // add all commands corresponding to v1 project + v1.AddCmds(cmd) if err := cmd.Execute(); err != nil { log.Fatal(err)