@@ -17,52 +17,51 @@ limitations under the License.
17
17
package initproject
18
18
19
19
import (
20
+ "bufio"
20
21
"fmt"
21
22
"log"
22
23
"os"
23
24
"os/exec"
24
25
"path/filepath"
25
- "strconv"
26
26
"strings"
27
27
28
28
"github.com/Masterminds/semver"
29
29
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util"
30
30
"github.com/spf13/cobra"
31
+ flag "github.com/spf13/pflag"
32
+ "sigs.k8s.io/controller-tools/pkg/scaffold"
33
+ "sigs.k8s.io/controller-tools/pkg/scaffold/input"
31
34
"sigs.k8s.io/controller-tools/pkg/scaffold/manager"
32
35
"sigs.k8s.io/controller-tools/pkg/scaffold/project"
33
36
)
34
37
35
- type initOptions struct {
36
- domain string
37
- copyright string
38
- bazel bool
39
- controllerOnly bool
40
- projectVersion string
41
- projectOptions
42
- }
43
-
44
38
func AddInit (cmd * cobra.Command ) {
45
- o := initOptions {}
39
+ o := projectOptions {}
46
40
47
41
initCmd := & cobra.Command {
48
42
Use : "init" ,
49
43
Short : "Initialize a new project" ,
50
- Long : `Initialize a new project including vendor/ directory and Go package directories.` ,
51
- Example : `# Initialize project structure
52
- kubebuilder init --domain mydomain
44
+ Long : `Initialize a new project including vendor/ directory and Go package directories.
45
+
46
+ Writes the following files:
47
+ - a boilerplate license file
48
+ - a PROJECT file with the domain and repo
49
+ - a Makefile to build the project
50
+ - a Gopkg.toml with project dependencies
51
+ - a Kustomization.yaml for customizating manifests
52
+ - a Patch file for customizing image for manager manifests
53
+ - a cmd/manager/main.go to run
54
+
55
+ project will prompt the user to run 'dep ensure' after writing the project files.
56
+ ` ,
57
+ Example : `# Scaffold a project using the apache2 license with "The Kubernetes authors" as owners
58
+ kubebuilder init --domain example.org --license apache2 --owner "The Kubernetes authors"
53
59
` ,
54
60
Run : func (cmd * cobra.Command , args []string ) {
55
- o .runInitRepo ()
61
+ o .RunInit ()
56
62
},
57
63
}
58
64
59
- v0comment := "Works only with project-version v0, "
60
- initCmd .Flags ().StringVar (& o .domain , "domain" , "" , "domain for the API groups" )
61
- initCmd .Flags ().StringVar (& o .copyright , "copyright" , filepath .Join ("hack" , "boilerplate.go.txt" ), v0comment + "Location of copyright boilerplate file." )
62
- initCmd .Flags ().BoolVar (& o .bazel , "bazel" , false , v0comment + "if true, setup Bazel workspace artifacts" )
63
- initCmd .Flags ().BoolVar (& o .controllerOnly , "controller-only" , false , v0comment + "if true, setup controller only" )
64
- initCmd .Flags ().StringVar (& o .projectVersion , "project-version" , "v1" , "if set to v0, init project with kubebuilder legacy version" )
65
-
66
65
initCmd .Flags ().BoolVar (
67
66
& o .dep , "dep" , true , "if specified, determines whether dep will be used." )
68
67
o .depFlag = initCmd .Flag ("dep" )
@@ -76,56 +75,114 @@ kubebuilder init --domain mydomain
76
75
cmd .AddCommand (initCmd )
77
76
}
78
77
79
- func (o * initOptions ) runInitRepo () {
78
+ type projectOptions struct {
79
+ prj * project.Project
80
+ bp * project.Boilerplate
81
+ gopkg * project.GopkgToml
82
+ mgr * manager.Cmd
83
+ dkr * manager.Dockerfile
84
+ dep bool
85
+ depFlag * flag.Flag
86
+ }
87
+
88
+ func (o * projectOptions ) RunInit () {
80
89
checkGoVersion ()
81
90
82
91
if ! depExists () {
83
92
log .Fatalf ("Dep is not installed. Follow steps at: https://golang.github.io/dep/docs/installation.html" )
84
93
}
85
94
86
- if o .projectVersion == "v1" {
87
- if len (o .domain ) != 0 {
88
- o .prj .Domain = o .domain
89
- }
90
- o .RunInit ()
95
+ if util .ProjectExist () {
96
+ fmt .Println ("Failed to initialize project bacause project is already initialized" )
91
97
return
92
98
}
99
+ // project and boilerplate must come before main so the boilerplate exists
100
+ s := & scaffold.Scaffold {
101
+ BoilerplateOptional : true ,
102
+ ProjectOptional : true ,
103
+ }
93
104
94
- if len (o .domain ) == 0 {
95
- log .Fatal ("Must specify --domain" )
105
+ p , err := o .prj .GetInput ()
106
+ if err != nil {
107
+ log .Fatal (err )
96
108
}
97
- cr := util .GetCopyright (o .copyright )
98
109
99
- fmt . Printf ( "Initializing project structure... \n " )
100
- if o . bazel {
101
- createBazelWorkspace ( )
110
+ b , err := o . bp . GetInput ( )
111
+ if err != nil {
112
+ log . Fatal ( err )
102
113
}
103
- createControllerManager (cr )
104
- //createInstaller(cr)
105
- createAPIs (cr , o .domain )
106
- //runCreateApiserver(cr)
107
-
108
- pkgs := []string {
109
- filepath .Join ("hack" ),
110
- filepath .Join ("pkg" ),
111
- filepath .Join ("pkg" , "controller" ),
112
- filepath .Join ("pkg" , "inject" ),
113
- //filepath.Join("pkg", "openapi"),
114
+
115
+ err = s .Execute (input.Options {ProjectPath : p .Path , BoilerplatePath : b .Path }, o .prj , o .bp )
116
+ if err != nil {
117
+ log .Fatal (err )
114
118
}
115
119
116
- fmt .Printf ("\t %s/\n " , filepath .Join ("pkg" , "controller" ))
117
- for _ , p := range pkgs {
118
- createPackage (cr , p )
120
+ // default controller manager image name
121
+ imgName := "controller:latest"
122
+
123
+ s = & scaffold.Scaffold {}
124
+ err = s .Execute (input.Options {ProjectPath : p .Path , BoilerplatePath : b .Path },
125
+ o .gopkg ,
126
+ o .mgr ,
127
+ & project.Makefile {Image : imgName },
128
+ o .dkr ,
129
+ & manager.APIs {},
130
+ & manager.Controller {},
131
+ & manager.Config {Image : imgName },
132
+ & project.GitIgnore {},
133
+ & project.Kustomize {},
134
+ & project.KustomizeImagePatch {})
135
+ if err != nil {
136
+ log .Fatal (err )
137
+ }
138
+
139
+ if ! o .depFlag .Changed {
140
+ reader := bufio .NewReader (os .Stdin )
141
+ fmt .Println ("Run `dep ensure` to fetch dependencies (Recommended) [y/n]?" )
142
+ o .dep = util .Yesno (reader )
143
+ }
144
+ if o .dep {
145
+ c := exec .Command ("dep" , "ensure" ) // #nosec
146
+ c .Stderr = os .Stderr
147
+ c .Stdout = os .Stdout
148
+ fmt .Println (strings .Join (c .Args , " " ))
149
+ if err := c .Run (); err != nil {
150
+ log .Fatal (err )
151
+ }
152
+
153
+ fmt .Println ("Running make..." )
154
+ c = exec .Command ("make" ) // #nosec
155
+ c .Stderr = os .Stderr
156
+ c .Stdout = os .Stdout
157
+ fmt .Println (strings .Join (c .Args , " " ))
158
+ if err := c .Run (); err != nil {
159
+ log .Fatal (err )
160
+ }
161
+ } else {
162
+ fmt .Println ("Skipping `dep ensure`. Dependencies will not be fetched." )
119
163
}
120
- doDockerfile ()
121
- doInject (cr )
122
- doArgs (cr , o .controllerOnly )
123
- RunVendorInstall (nil , []string {o .copyright })
124
- createBoilerplate ()
125
164
fmt .Printf ("Next: Define a resource with:\n " +
126
- "$ kubebuilder create resource\n " )
165
+ "$ kubebuilder create api\n " )
166
+ }
167
+
168
+ // projectForFlags registers flags for Project fields and returns the Project
169
+ func projectForFlags (f * flag.FlagSet ) * project.Project {
170
+ p := & project.Project {}
171
+ f .StringVar (& p .Repo , "repo" , "" , "name of the github repo. " +
172
+ "defaults to the go package of the current working directory." )
173
+ f .StringVar (& p .Domain , "domain" , "k8s.io" , "domain for groups" )
174
+ f .StringVar (& p .Version , "project-version" , "1" , "project version" )
175
+ return p
127
176
}
128
177
178
+ // boilerplateForFlags registers flags for Boilerplate fields and returns the Boilerplate
179
+ func boilerplateForFlags (f * flag.FlagSet ) * project.Boilerplate {
180
+ b := & project.Boilerplate {}
181
+ f .StringVar (& b .Path , "path" , "" , "path for boilerplate" )
182
+ f .StringVar (& b .License , "license" , "apache2" , "license to use to boilerplate. Maybe one of apache2,none" )
183
+ f .StringVar (& b .Owner , "owner" , "" , "Owner to add to the copyright" )
184
+ return b
185
+ }
129
186
func checkGoVersion () {
130
187
cmd := exec .Command ("go" , "version" )
131
188
out , err := cmd .Output ()
@@ -165,29 +222,3 @@ type templateArgs struct {
165
222
Repo string
166
223
ControllerOnly bool
167
224
}
168
-
169
- func versionCmp (v1 string , v2 string ) int {
170
- v1s := strings .Split (strings .Replace (v1 , "go" , "" , 1 ), "." )
171
- v2s := strings .Split (strings .Replace (v2 , "go" , "" , 1 ), "." )
172
- for i := 0 ; i < len (v1s ) && i < len (v2s ); i ++ {
173
- mv1 , err1 := strconv .Atoi (v1s [i ])
174
- mv2 , err2 := strconv .Atoi (v2s [i ])
175
- if err1 == nil && err2 == nil {
176
- cmp := mv1 - mv2
177
- if cmp > 0 {
178
- return 1
179
- } else if cmp < 0 {
180
- return - 1
181
- }
182
- } else {
183
- log .Fatalf ("Unexpected error comparing %v with %v" , v1 , v2 )
184
- }
185
- }
186
- if len (v1s ) == len (v2s ) {
187
- return 0
188
- } else if len (v1s ) > len (v2s ) {
189
- return 1
190
- } else {
191
- return - 1
192
- }
193
- }
0 commit comments