sigs.k8s.io/kubebuilder/v3@v3.14.0/pkg/plugins/golang/v2/init.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 //go:deprecated This package has been deprecated 18 package v2 19 20 import ( 21 "fmt" 22 "os" 23 "path/filepath" 24 "strings" 25 26 log "github.com/sirupsen/logrus" 27 "github.com/spf13/pflag" 28 29 "sigs.k8s.io/kubebuilder/v3/pkg/config" 30 cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2" 31 "sigs.k8s.io/kubebuilder/v3/pkg/internal/validation" 32 "sigs.k8s.io/kubebuilder/v3/pkg/machinery" 33 "sigs.k8s.io/kubebuilder/v3/pkg/plugin" 34 "sigs.k8s.io/kubebuilder/v3/pkg/plugin/util" 35 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang" 36 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds" 37 ) 38 39 // Variables and function to check Go version requirements. 40 var ( 41 goVerMin = golang.MustParse("go1.13") 42 goVerMax = golang.MustParse("go2.0alpha1") 43 ) 44 45 var _ plugin.InitSubcommand = &initSubcommand{} 46 47 type initSubcommand struct { 48 config config.Config 49 50 // For help text. 51 commandName string 52 53 // boilerplate options 54 license string 55 owner string 56 57 // config options 58 domain string 59 repo string 60 name string 61 62 // flags 63 fetchDeps bool 64 skipGoVersionCheck bool 65 } 66 67 func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) { 68 p.commandName = cliMeta.CommandName 69 70 subcmdMeta.Description = `Initialize a new project including the following files: 71 - a "go.mod" with project dependencies 72 - a "PROJECT" file that stores project configuration 73 - a "Makefile" with several useful make targets for the project 74 - several YAML files for project deployment under the "config" directory 75 - a "main.go" file that creates the manager that will run the project controllers 76 ` 77 subcmdMeta.Examples = fmt.Sprintf(` # Initialize a new project with your domain and name in copyright 78 %[1]s init --plugins go/v2 --domain example.org --owner "Your name" 79 80 # Initialize a new project defining a specific project version 81 %[1]s init --plugins go/v2 --project-version 2 82 `, cliMeta.CommandName) 83 } 84 85 func (p *initSubcommand) BindFlags(fs *pflag.FlagSet) { 86 fs.BoolVar(&p.skipGoVersionCheck, "skip-go-version-check", 87 false, "if specified, skip checking the Go version") 88 89 // dependency args 90 fs.BoolVar(&p.fetchDeps, "fetch-deps", true, "ensure dependencies are downloaded") 91 92 // boilerplate args 93 fs.StringVar(&p.license, "license", "apache2", 94 "license to use to boilerplate, may be one of 'apache2', 'none'") 95 fs.StringVar(&p.owner, "owner", "", "owner to add to the copyright") 96 97 // project args 98 fs.StringVar(&p.domain, "domain", "my.domain", "domain for groups") 99 fs.StringVar(&p.repo, "repo", "", "name to use for go module (e.g., github.com/user/repo), "+ 100 "defaults to the go package of the current working directory.") 101 fs.StringVar(&p.name, "project-name", "", "name of this project") 102 } 103 104 func (p *initSubcommand) InjectConfig(c config.Config) error { 105 p.config = c 106 107 if err := p.config.SetDomain(p.domain); err != nil { 108 return err 109 } 110 111 // Try to guess repository if flag is not set. 112 if p.repo == "" { 113 repoPath, err := golang.FindCurrentRepo() 114 if err != nil { 115 return fmt.Errorf("error finding current repository: %v", err) 116 } 117 p.repo = repoPath 118 } 119 if err := p.config.SetRepository(p.repo); err != nil { 120 return err 121 } 122 123 if p.config.GetVersion().Compare(cfgv2.Version) > 0 { 124 // Assign a default project name 125 if p.name == "" { 126 dir, err := os.Getwd() 127 if err != nil { 128 return fmt.Errorf("error getting current directory: %v", err) 129 } 130 p.name = strings.ToLower(filepath.Base(dir)) 131 } 132 // Check if the project name is a valid k8s namespace (DNS 1123 label). 133 if err := validation.IsDNS1123Label(p.name); err != nil { 134 return fmt.Errorf("project name (%s) is invalid: %v", p.name, err) 135 } 136 if err := p.config.SetProjectName(p.name); err != nil { 137 return err 138 } 139 } 140 141 return nil 142 } 143 144 func (p *initSubcommand) PreScaffold(machinery.Filesystem) error { 145 // Ensure Go version is in the allowed range if check not turned off. 146 if !p.skipGoVersionCheck { 147 if err := golang.ValidateGoVersion(goVerMin, goVerMax); err != nil { 148 return err 149 } 150 } 151 152 return nil 153 } 154 155 func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error { 156 scaffolder := scaffolds.NewInitScaffolder(p.config, p.license, p.owner) 157 scaffolder.InjectFS(fs) 158 err := scaffolder.Scaffold() 159 if err != nil { 160 return err 161 } 162 163 if !p.fetchDeps { 164 log.Println("Skipping fetching dependencies.") 165 return nil 166 } 167 168 // Ensure that we are pinning controller-runtime version 169 // xref: https://github.com/kubernetes-sigs/kubebuilder/issues/997 170 err = util.RunCmd("Get controller runtime", "go", "get", 171 "sigs.k8s.io/controller-runtime@"+scaffolds.ControllerRuntimeVersion) 172 if err != nil { 173 return err 174 } 175 176 return nil 177 } 178 179 func (p *initSubcommand) PostScaffold() error { 180 err := util.RunCmd("Update dependencies", "go", "mod", "tidy") 181 if err != nil { 182 return err 183 } 184 185 fmt.Printf("Next: define a resource with:\n$ %s create api\n", p.commandName) 186 return nil 187 }