Skip to content

Commit 51e163e

Browse files
committed
feat: add a new command to init
feat: separate file fix: doc nit feat: doc nit fix: some nits feat: file perm and error when outputPath exists feat: golang lint
1 parent a6fca17 commit 51e163e

File tree

3 files changed

+158
-0
lines changed

3 files changed

+158
-0
lines changed

pkg/cli/alpha.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"strings"
2222

2323
"github.com/spf13/cobra"
24+
"sigs.k8s.io/kubebuilder/v3/pkg/cli/alpha"
2425
)
2526

2627
const (
@@ -29,6 +30,7 @@ const (
2930

3031
var alphaCommands = []*cobra.Command{
3132
newAlphaCommand(),
33+
alpha.NewScaffoldCommand(),
3234
}
3335

3436
func newAlphaCommand() *cobra.Command {

pkg/cli/alpha/generate.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package alpha
15+
16+
import (
17+
"log"
18+
19+
"github.com/spf13/cobra"
20+
"sigs.k8s.io/kubebuilder/v3/pkg/rescaffold"
21+
)
22+
23+
// NewScaffoldCommand return a new scaffold command
24+
func NewScaffoldCommand() *cobra.Command {
25+
opts := rescaffold.MigrateOptions{}
26+
scaffoldCmd := &cobra.Command{
27+
Use: "generate",
28+
Short: "Re-scaffold an existing Kuberbuilder project",
29+
Long: `It's an experimental feature that has the purpose of re-scaffolding the whole project from the scratch
30+
using the current version of KubeBuilder binary available.
31+
# make sure the PROJECT file is in the 'input-dir' argument, the default is the current directory.
32+
$ kubebuilder alpha generate --input-dir="./test" --output-dir="./my-output"
33+
Then we will re-scaffold the project by Kubebuilder in the directory specified by 'output-dir'.
34+
`,
35+
PreRunE: func(cmd *cobra.Command, _ []string) error {
36+
return opts.Validate()
37+
},
38+
Run: func(cmd *cobra.Command, args []string) {
39+
if err := opts.Rescaffold(); err != nil {
40+
log.Fatalf("Failed to rescaffold %s", err)
41+
}
42+
},
43+
}
44+
scaffoldCmd.Flags().StringVar(&opts.InputDir, "input-dir", "",
45+
"path to a Kubebuilder project file if not in the current working directory")
46+
scaffoldCmd.Flags().StringVar(&opts.OutputDir, "output-dir", "",
47+
"path to output the scaffolding. defaults a directory in the current working directory")
48+
49+
return scaffoldCmd
50+
}

pkg/rescaffold/migrate.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package rescaffold
15+
16+
import (
17+
"fmt"
18+
"log"
19+
"os"
20+
"os/exec"
21+
22+
"github.com/spf13/afero"
23+
"sigs.k8s.io/kubebuilder/v3/pkg/config/store"
24+
"sigs.k8s.io/kubebuilder/v3/pkg/config/store/yaml"
25+
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
26+
"sigs.k8s.io/kubebuilder/v3/pkg/plugin/util"
27+
)
28+
29+
type MigrateOptions struct {
30+
InputDir string
31+
OutputDir string
32+
}
33+
34+
const DefaultOutputDir = "output-dir"
35+
36+
func (opts *MigrateOptions) Rescaffold() error {
37+
config := yaml.New(machinery.Filesystem{FS: afero.NewOsFs()})
38+
if err := config.LoadFrom(opts.InputDir); err != nil {
39+
log.Fatal(err)
40+
}
41+
// create output directory
42+
if err := os.MkdirAll(opts.OutputDir, 0755); err != nil {
43+
log.Fatal(err)
44+
}
45+
// use the new directory to set up the new project
46+
if err := os.Chdir(opts.OutputDir); err != nil {
47+
log.Fatal(err)
48+
}
49+
// init project with plugins
50+
if err := kubebuilderInit(config); err != nil {
51+
log.Fatal(err)
52+
}
53+
return nil
54+
}
55+
56+
func (opts *MigrateOptions) Validate() error {
57+
cwd, err := os.Getwd()
58+
if err != nil {
59+
log.Fatal(err)
60+
}
61+
// get PROJECT path from command args
62+
inputPath, err := getInputPath(cwd, opts.InputDir)
63+
if err != nil {
64+
log.Fatal(err)
65+
}
66+
opts.InputDir = inputPath
67+
// get output path from command args
68+
opts.OutputDir, err = getOutputPath(cwd, opts.OutputDir)
69+
if err != nil {
70+
log.Fatal(err)
71+
}
72+
// check whether the kubebuilder binary is accessible
73+
_, err = exec.LookPath("kubebuilder")
74+
return err
75+
}
76+
77+
func getInputPath(currentWorkingDirectory string, inputPath string) (string, error) {
78+
if inputPath == "" {
79+
inputPath = currentWorkingDirectory
80+
}
81+
projectPath := fmt.Sprintf("%s/%s", inputPath, yaml.DefaultPath)
82+
if _, err := os.Stat(projectPath); os.IsNotExist(err) {
83+
return "", fmt.Errorf("PROJECT path: %s does not exist. %v", projectPath, err)
84+
}
85+
return projectPath, nil
86+
}
87+
88+
func getOutputPath(currentWorkingDirectory, outputPath string) (string, error) {
89+
if outputPath == "" {
90+
outputPath = fmt.Sprintf("%s/%s", currentWorkingDirectory, DefaultOutputDir)
91+
}
92+
_, err := os.Stat(outputPath)
93+
if err == nil {
94+
return "", fmt.Errorf("Output path: %s already exists. %v", outputPath, err)
95+
}
96+
if os.IsNotExist(err) {
97+
return outputPath, nil
98+
}
99+
return "", err
100+
}
101+
102+
func kubebuilderInit(_ store.Store) error {
103+
var args []string
104+
args = append(args, "init")
105+
return util.RunCmd("kubebuilder init", "kubebuilder", args...)
106+
}

0 commit comments

Comments
 (0)