From a8f2cf1196481db2c81b4918d48282b8344ed271 Mon Sep 17 00:00:00 2001 From: guoxudong Date: Tue, 8 Dec 2020 11:17:06 +0800 Subject: [PATCH 1/4] update add/merge cmd --- .gitignore | 4 +- cmd/add.go | 68 +++++------- cmd/add_test.go | 191 --------------------------------- cmd/merge.go | 16 +-- cmd/root.go | 11 +- cmd/utils.go | 15 ++- cmd/utils_test.go | 60 ++++++++++- docs/README.md | 2 +- docs/en-us/cli/kubecm_add.md | 18 +--- docs/en-us/cli/kubecm_merge.md | 6 +- docs/zh-cn/cli/kubecm_add.md | 8 -- docs/zh-cn/cli/kubecm_merge.md | 4 - 12 files changed, 131 insertions(+), 272 deletions(-) delete mode 100644 cmd/add_test.go diff --git a/.gitignore b/.gitignore index a3b21afe..49c53732 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,6 @@ dist/ kubecm target -tmp \ No newline at end of file +tmp +mergeDir +config.yaml \ No newline at end of file diff --git a/cmd/add.go b/cmd/add.go index e257bf76..f0492a97 100644 --- a/cmd/add.go +++ b/cmd/add.go @@ -3,7 +3,7 @@ package cmd import ( "errors" "fmt" - "os" + "strconv" "strings" "github.com/spf13/cobra" @@ -20,26 +20,24 @@ type AddCommand struct { func (ac *AddCommand) Init() { ac.command = &cobra.Command{ Use: "add", - Short: "Merge configuration file with $HOME/.kube/config", - Long: "Merge configuration file with $HOME/.kube/config", + Short: "Add kubeconfig to $HOME/.kube/config", + Long: "Add kubeconfig to $HOME/.kube/config", RunE: func(cmd *cobra.Command, args []string) error { return ac.runAdd(cmd, args) }, Example: addExample(), } ac.command.Flags().StringP("file", "f", "", "Path to merge kubeconfig files") - ac.command.Flags().StringP("name", "n", "", "The name of contexts. if this field is null,it will be named with file name.") - ac.command.Flags().BoolP("cover", "c", false, "Overwrite the original kubeconfig file") _ = ac.command.MarkFlagRequired("file") } func (ac *AddCommand) runAdd(cmd *cobra.Command, args []string) error { file, _ := ac.command.Flags().GetString("file") - if fileNotExists(file) { - return errors.New(file + " file does not exist") + file, err := CheckAndTransformFilePath(file) + if err != nil { + return err } - name := ac.command.Flag("name").Value.String() - newConfig, err := formatNewConfig(file, name) + newConfig, newName, err := formatNewConfig(file) if err != nil { return err } @@ -48,25 +46,29 @@ func (ac *AddCommand) runAdd(cmd *cobra.Command, args []string) error { return err } outConfig := appendConfig(oldConfig, newConfig) - cover, _ := ac.command.Flags().GetBool("cover") - err = WriteConfig(cover, file, outConfig) + cover := BoolUI(fmt.Sprintf("Are you sure you want to add 「%s」 to the 「%s」context?", newName, cfgFile)) + confirm, err := strconv.ParseBool(cover) + if err != nil { + return err + } + err = WriteConfig(confirm, file, outConfig) if err != nil { return err } return nil } -func formatNewConfig(file, nameFlag string) (*clientcmdapi.Config, error) { +func formatNewConfig(file string) (*clientcmdapi.Config, string, error) { config, err := clientcmd.LoadFromFile(file) if err != nil { - return nil, err + return nil, "", err } if len(config.AuthInfos) != 1 { - return nil, errors.New("Only support add 1 context. You can use `merge` cmd") + return nil, "", errors.New("Only support add 1 context. You can use `merge` cmd") } - name, err := formatAndCheckName(file, nameFlag) + name, err := formatAndCheckName(file) if err != nil { - return nil, err + return nil, "", err } suffix := HashSuf(config) userName := fmt.Sprintf("user-%v", suffix) @@ -89,14 +91,16 @@ func formatNewConfig(file, nameFlag string) (*clientcmdapi.Config, error) { break } fmt.Printf("Context Add: %s \n", name) - return config, nil + return config, name, nil } -func formatAndCheckName(file, name string) (string, error) { - if name == "" { - n := strings.Split(file, "/") - result := strings.Split(n[len(n)-1], ".") - name = result[0] +func formatAndCheckName(file string) (string, error) { + n := strings.Split(file, "/") + result := strings.Split(n[len(n)-1], ".") + name := result[0] + nameConfirm := BoolUI(fmt.Sprintf("Need to rename 「%s」 context?", name)) + if nameConfirm == "True" { + name = PromptUI("Rename", name) } config, err := clientcmd.LoadFromFile(cfgFile) if err != nil { @@ -104,29 +108,15 @@ func formatAndCheckName(file, name string) (string, error) { } for key := range config.Contexts { if key == name { - return key, errors.New("The name: " + name + " already exists, please replace it") + return key, errors.New("The name: 「" + name + "」 already exists, please select another one.") } } return name, nil } -func fileNotExists(path string) bool { - _, err := os.Stat(path) //os.Stat获取文件信息 - if err != nil { - return !os.IsExist(err) - } - return false -} - func addExample() string { return ` -# Merge 1.yaml with $HOME/.kube/config -kubecm add -f 1.yaml - -# Merge 1.yaml and name contexts test with $HOME/.kube/config -kubecm add -f 1.yaml -n test - -# Overwrite the original kubeconfig file -kubecm add -f 1.yaml -c +# Merge test.yaml with $HOME/.kube/config +kubecm add -f test.yaml ` } diff --git a/cmd/add_test.go b/cmd/add_test.go deleted file mode 100644 index 772cae14..00000000 --- a/cmd/add_test.go +++ /dev/null @@ -1,191 +0,0 @@ -package cmd - -import ( - "io/ioutil" - "os" - "reflect" - "strings" - "testing" - - apiequality "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/util/diff" - "k8s.io/client-go/tools/clientcmd" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -var ( - addRootConfigConflictAlfa = clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "black-user": {Token: "black-token"}}, - Clusters: map[string]*clientcmdapi.Cluster{ - "pig-cluster": {Server: "http://pig.org:8080"}}, - Contexts: map[string]*clientcmdapi.Context{ - "root-context": {AuthInfo: "black-user", Cluster: "pig-cluster", Namespace: "saw-ns"}}, - } - addConfigAlfa = clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "red-user": {Token: "red-token"}}, - Clusters: map[string]*clientcmdapi.Cluster{ - "cow-cluster": {Server: "http://cow.org:8080"}}, - Contexts: map[string]*clientcmdapi.Context{ - "federal-context": {AuthInfo: "red-user", Cluster: "cow-cluster", Namespace: "hammer-ns"}}, - } - addWantConfigAlfa = clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "user-gmbtgkhfch": {Token: "red-token"}}, - Clusters: map[string]*clientcmdapi.Cluster{ - "cluster-gmbtgkhfch": {Server: "http://cow.org:8080"}}, - Contexts: map[string]*clientcmdapi.Context{ - "name": {AuthInfo: "user-gmbtgkhfch", Cluster: "cluster-gmbtgkhfch", Namespace: "hammer-ns"}}, - } - addTestWantConfigAlfa = clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "user-gmbtgkhfch": {Token: "red-token"}}, - Clusters: map[string]*clientcmdapi.Cluster{ - "cluster-gmbtgkhfch": {Server: "http://cow.org:8080"}}, - Contexts: map[string]*clientcmdapi.Context{ - "test": {AuthInfo: "user-gmbtgkhfch", Cluster: "cluster-gmbtgkhfch", Namespace: "hammer-ns"}}, - } -) - -func Test_formatNewConfig(t *testing.T) { - rootConfig, _ := ioutil.TempFile("", "") - defer os.Remove(rootConfig.Name()) - configFile, _ := ioutil.TempFile("", "") - defer os.Remove(configFile.Name()) - _ = clientcmd.WriteToFile(addRootConfigConflictAlfa, rootConfig.Name()) - _ = clientcmd.WriteToFile(addConfigAlfa, configFile.Name()) - wantName := splitTempName(configFile.Name()) - wantConfig := clientcmdapi.NewConfig() - addWantConfigAlfa.DeepCopyInto(wantConfig) - for key, obj := range wantConfig.Contexts { - wantConfig.Contexts[wantName] = obj - delete(wantConfig.Contexts, key) - break - } - cfgFile = rootConfig.Name() - - type args struct { - file string - nameFlag string - } - tests := []struct { - name string - args args - want *clientcmdapi.Config - wantErr bool - }{ - // TODO: Add test cases. - {"name-is-null", args{configFile.Name(), ""}, wantConfig, false}, - {"name-is-set", args{configFile.Name(), "test"}, &addTestWantConfigAlfa, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := formatNewConfig(tt.args.file, tt.args.nameFlag) - if err != nil { - return - } - checkResult(tt.want, got, t) - }) - } -} - -func Test_formatAndCheckName(t *testing.T) { - rootConfig, _ := ioutil.TempFile("", "") - defer os.Remove(rootConfig.Name()) - configFile, _ := ioutil.TempFile("", "") - defer os.Remove(configFile.Name()) - _ = clientcmd.WriteToFile(addRootConfigConflictAlfa, rootConfig.Name()) - _ = clientcmd.WriteToFile(addConfigAlfa, configFile.Name()) - wantName := splitTempName(configFile.Name()) - cfgFile = rootConfig.Name() - - type args struct { - file string - name string - } - tests := []struct { - name string - args args - want string - wantErr bool - }{ - // TODO: Add test cases. - {"name-is-null", args{configFile.Name(), ""}, wantName, false}, - {"name-is-set", args{configFile.Name(), "test"}, "test", false}, - {"name-is-exists", args{configFile.Name(), "root-context"}, "root-context", true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := formatAndCheckName(tt.args.file, tt.args.name) - if (err != nil) != tt.wantErr { - t.Errorf("formatAndCheckName() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("formatAndCheckName() got = %v, want %v", got, tt.want) - } - }) - } -} - -func splitTempName(path string) string { - name := strings.Split(path, "/") - wantName := name[len(name)-1] - return wantName -} - -func checkResult(want, got *clientcmdapi.Config, t *testing.T) { - testSetNilMapsToEmpties(reflect.ValueOf(&got)) - testSetNilMapsToEmpties(reflect.ValueOf(&want)) - testClearLocationOfOrigin(got) - - if !apiequality.Semantic.DeepEqual(want, got) { - t.Errorf("diff: %v", diff.ObjectDiff(want, got)) - t.Errorf("expected: %#v\n actual: %#v", want, got) - } -} - -func testClearLocationOfOrigin(config *clientcmdapi.Config) { - for key, obj := range config.AuthInfos { - obj.LocationOfOrigin = "" - config.AuthInfos[key] = obj - } - for key, obj := range config.Clusters { - obj.LocationOfOrigin = "" - config.Clusters[key] = obj - } - for key, obj := range config.Contexts { - obj.LocationOfOrigin = "" - config.Contexts[key] = obj - } -} - -func testSetNilMapsToEmpties(curr reflect.Value) { - actualCurrValue := curr - if curr.Kind() == reflect.Ptr { - actualCurrValue = curr.Elem() - } - - switch actualCurrValue.Kind() { - case reflect.Map: - for _, mapKey := range actualCurrValue.MapKeys() { - currMapValue := actualCurrValue.MapIndex(mapKey) - testSetNilMapsToEmpties(currMapValue) - } - - case reflect.Struct: - for fieldIndex := 0; fieldIndex < actualCurrValue.NumField(); fieldIndex++ { - currFieldValue := actualCurrValue.Field(fieldIndex) - - if currFieldValue.Kind() == reflect.Map && currFieldValue.IsNil() { - newValue := reflect.MakeMap(currFieldValue.Type()) - currFieldValue.Set(newValue) - } else { - testSetNilMapsToEmpties(currFieldValue.Addr()) - } - } - - } - -} diff --git a/cmd/merge.go b/cmd/merge.go index a54e774e..08aed679 100644 --- a/cmd/merge.go +++ b/cmd/merge.go @@ -3,6 +3,8 @@ package cmd import ( "fmt" "io/ioutil" + "k8s.io/client-go/tools/clientcmd" + "strconv" "github.com/spf13/cobra" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" @@ -26,7 +28,6 @@ func (mc *MergeCommand) Init() { Example: mergeExample(), } mc.command.Flags().StringP("folder", "f", "", "Kubeconfig folder") - mc.command.Flags().BoolP("cover", "c", false, "Overwrite the original kubeconfig file") _ = mc.command.MarkFlagRequired("folder") } @@ -36,14 +37,18 @@ func (mc MergeCommand) runMerge(command *cobra.Command, args []string) error { mc.command.Printf("Loading kubeconfig file: %v \n", files) configs := clientcmdapi.NewConfig() for _, yaml := range files { - config, err := formatNewConfig(yaml, "") + config, err := clientcmd.LoadFromFile(yaml) if err != nil { return err } configs = appendConfig(configs, config) } - cover, _ := mc.command.Flags().GetBool("cover") - err := WriteConfig(cover, folder, configs) + cover := BoolUI(fmt.Sprintf("Are you sure you want to overwrite the「%s」file?", cfgFile)) + confirm, err := strconv.ParseBool(cover) + if err != nil { + return err + } + err = WriteConfig(confirm, folder, configs) if err != nil { return err } @@ -67,8 +72,5 @@ func mergeExample() string { return ` # Merge kubeconfig in the dir directory kubecm merge -f dir - -# Merge kubeconfig in the directory and overwrite the original kubeconfig file -kubecm merge -f dir -c ` } diff --git a/cmd/root.go b/cmd/root.go index f1ab4516..0cc247dc 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -45,7 +45,7 @@ Manage your kubeconfig more easily. | <| |_| | |_) | __/ (__| | | | | | |_|\_\\__,_|_.__/ \___|\___|_| |_| |_| -Find more information at: https://github.com/sunny0826/kubecm +Find more information at: https://kubecm.cloud `, }, } @@ -62,6 +62,15 @@ func (cli *Cli) setFlags() { //Run command func (cli *Cli) Run() error { + // check and format kubeconfig path + config, err := CheckAndTransformFilePath(cfgFile) + if err != nil { + return err + } + err = flag.Set("config", config) + if err != nil { + return err + } return cli.rootCmd.Execute() } diff --git a/cmd/utils.go b/cmd/utils.go index ad87db9e..f7efe73e 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -9,6 +9,7 @@ import ( "log" "os" "os/user" + "path/filepath" "strings" "github.com/bndr/gotabulate" @@ -182,7 +183,7 @@ func BoolUI(label string) string { } prompt := promptui.Select{ Label: label, - Items: []string{"True", "False"}, + Items: []string{"False", "True"}, Templates: templates, Size: 2, } @@ -322,3 +323,15 @@ func appendConfig(c1, c2 *clientcmdapi.Config) *clientcmdapi.Config { _ = mergo.Merge(config, c2) return config } + +// CheckAndTransformFilePath return converted path +func CheckAndTransformFilePath(path string) (string, error) { + if strings.HasPrefix(path, "~/") { + path = filepath.Join(homeDir(), path[2:]) + } + _, err := os.Stat(path) //os.Stat获取文件信息 + if err != nil { + return "", err + } + return path, nil +} diff --git a/cmd/utils_test.go b/cmd/utils_test.go index 75c416a9..0829933f 100644 --- a/cmd/utils_test.go +++ b/cmd/utils_test.go @@ -1,9 +1,12 @@ package cmd import ( + apiequality "k8s.io/apimachinery/pkg/api/equality" + "reflect" "testing" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + "k8s.io/apimachinery/pkg/util/diff" ) var ( @@ -55,7 +58,62 @@ func Test_appendConfig(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := appendConfig(tt.args.c1, tt.args.c2) - checkResult(tt.want, got, t) + checkResult(tt.want, got,"", t) }) } } + +func checkResult(want, got *clientcmdapi.Config, wantname string, t *testing.T) { + testSetNilMapsToEmpties(reflect.ValueOf(&got)) + testSetNilMapsToEmpties(reflect.ValueOf(&want)) + testClearLocationOfOrigin(got) + + if !apiequality.Semantic.DeepEqual(want, got) { + t.Errorf("diff: %v", diff.ObjectDiff(want, got)) + t.Errorf("expected: %#v\n actual: %#v", want, got) + } +} + +func testClearLocationOfOrigin(config *clientcmdapi.Config) { + for key, obj := range config.AuthInfos { + obj.LocationOfOrigin = "" + config.AuthInfos[key] = obj + } + for key, obj := range config.Clusters { + obj.LocationOfOrigin = "" + config.Clusters[key] = obj + } + for key, obj := range config.Contexts { + obj.LocationOfOrigin = "" + config.Contexts[key] = obj + } +} + +func testSetNilMapsToEmpties(curr reflect.Value) { + actualCurrValue := curr + if curr.Kind() == reflect.Ptr { + actualCurrValue = curr.Elem() + } + + switch actualCurrValue.Kind() { + case reflect.Map: + for _, mapKey := range actualCurrValue.MapKeys() { + currMapValue := actualCurrValue.MapIndex(mapKey) + testSetNilMapsToEmpties(currMapValue) + } + + case reflect.Struct: + for fieldIndex := 0; fieldIndex < actualCurrValue.NumField(); fieldIndex++ { + currFieldValue := actualCurrValue.Field(fieldIndex) + + if currFieldValue.Kind() == reflect.Map && currFieldValue.IsNil() { + newValue := reflect.MakeMap(currFieldValue.Type()) + currFieldValue.Set(newValue) + } else { + testSetNilMapsToEmpties(currFieldValue.Addr()) + } + } + + } + +} diff --git a/docs/README.md b/docs/README.md index 080816ab..75257c2f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,7 +14,7 @@ Manage your kubeconfig more easily. | <| |_| | |_) | __/ (__| | | | | | |_|\_\\__,_|_.__/ \___|\___|_| |_| |_| -Find more information at: https://github.com/sunny0826/kubecm +Find more information at: https://kubecm.cloud Usage: kubecm [flags] diff --git a/docs/en-us/cli/kubecm_add.md b/docs/en-us/cli/kubecm_add.md index 6b267686..b41249ef 100644 --- a/docs/en-us/cli/kubecm_add.md +++ b/docs/en-us/cli/kubecm_add.md @@ -1,10 +1,10 @@ ## kubecm add -Merge configuration file with $HOME/.kube/config +Add kubeconfig to $HOME/.kube/config ### Synopsis -Merge configuration file with $HOME/.kube/config +Add kubeconfig to $HOME/.kube/config ``` kubecm add [flags] @@ -14,28 +14,20 @@ kubecm add [flags] ``` -# Merge 1.yaml with $HOME/.kube/config -kubecm add -f 1.yaml - -# Merge 1.yaml and name contexts test with $HOME/.kube/config -kubecm add -f 1.yaml -n test - -# Overwrite the original kubeconfig file -kubecm add -f 1.yaml -c +# Merge test.yaml with $HOME/.kube/config +kubecm add -f test.yaml ``` ### Options ``` - -c, --cover Overwrite the original kubeconfig file -f, --file string Path to merge kubeconfig files -h, --help help for add - -n, --name string The name of contexts. if this field is null,it will be named with file name. ``` ### Options inherited from parent commands ``` - --config string path of kubeconfig (default "/Users/guoxudong/.kube/config") + --config string path of kubeconfig (default "/Users/saybot/.kube/config") ``` diff --git a/docs/en-us/cli/kubecm_merge.md b/docs/en-us/cli/kubecm_merge.md index f4ffa4dd..8a634e32 100644 --- a/docs/en-us/cli/kubecm_merge.md +++ b/docs/en-us/cli/kubecm_merge.md @@ -17,15 +17,11 @@ kubecm merge [flags] # Merge kubeconfig in the dir directory kubecm merge -f dir -# Merge kubeconfig in the directory and overwrite the original kubeconfig file -kubecm merge -f dir -c - ``` ### Options ``` - -c, --cover Overwrite the original kubeconfig file -f, --folder string Kubeconfig folder -h, --help help for merge ``` @@ -33,5 +29,5 @@ kubecm merge -f dir -c ### Options inherited from parent commands ``` - --config string path of kubeconfig (default "/Users/guoxudong/.kube/config") + --config string path of kubeconfig (default "/Users/saybot/.kube/config") ``` diff --git a/docs/zh-cn/cli/kubecm_add.md b/docs/zh-cn/cli/kubecm_add.md index 7ec71e40..7559ca44 100644 --- a/docs/zh-cn/cli/kubecm_add.md +++ b/docs/zh-cn/cli/kubecm_add.md @@ -17,21 +17,13 @@ kubecm add [flags] # Merge 1.yaml with $HOME/.kube/config kubecm add -f 1.yaml -# Merge 1.yaml and name contexts test with $HOME/.kube/config -kubecm add -f 1.yaml -n test - -# Overwrite the original kubeconfig file -kubecm add -f 1.yaml -c - ``` ### 选项 ``` - -c, --cover Overwrite the original kubeconfig file -f, --file string Path to merge kubeconfig files -h, --help help for add - -n, --name string The name of contexts. if this field is null,it will be named with file name. ``` ### 全局选项 diff --git a/docs/zh-cn/cli/kubecm_merge.md b/docs/zh-cn/cli/kubecm_merge.md index 5a9dbc1d..e1a78819 100644 --- a/docs/zh-cn/cli/kubecm_merge.md +++ b/docs/zh-cn/cli/kubecm_merge.md @@ -17,15 +17,11 @@ kubecm merge [flags] # Merge kubeconfig in the dir directory kubecm merge -f dir -# Merge kubeconfig in the directory and overwrite the original kubeconfig file -kubecm merge -f dir -c - ``` ### 选项 ``` - -c, --cover Overwrite the original kubeconfig file -f, --folder string Kubeconfig folder -h, --help help for merge ``` From 4fb6d3f6f15faf8cfaf99a11fb65e577669251a4 Mon Sep 17 00:00:00 2001 From: guoxudong Date: Tue, 8 Dec 2020 12:49:16 +0800 Subject: [PATCH 2/4] fix --- .github/workflows/go.yaml | 2 +- cmd/utils_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml index 5f11e922..51c0b8f6 100644 --- a/.github/workflows/go.yaml +++ b/.github/workflows/go.yaml @@ -3,7 +3,7 @@ name: Go on: push: branches: - - "*" + - "master" pull_request: branches: - master diff --git a/cmd/utils_test.go b/cmd/utils_test.go index 0829933f..bc5cd825 100644 --- a/cmd/utils_test.go +++ b/cmd/utils_test.go @@ -5,8 +5,8 @@ import ( "reflect" "testing" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/apimachinery/pkg/util/diff" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) var ( @@ -58,7 +58,7 @@ func Test_appendConfig(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := appendConfig(tt.args.c1, tt.args.c2) - checkResult(tt.want, got,"", t) + checkResult(tt.want, got, "", t) }) } } From e49eb01148c667c4bfe53a2dce5d51c86bb07a1b Mon Sep 17 00:00:00 2001 From: guoxudong Date: Tue, 8 Dec 2020 13:08:29 +0800 Subject: [PATCH 3/4] fix --- cmd/merge.go | 3 ++- cmd/utils_test.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/merge.go b/cmd/merge.go index 08aed679..4549b81b 100644 --- a/cmd/merge.go +++ b/cmd/merge.go @@ -3,9 +3,10 @@ package cmd import ( "fmt" "io/ioutil" - "k8s.io/client-go/tools/clientcmd" "strconv" + "k8s.io/client-go/tools/clientcmd" + "github.com/spf13/cobra" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) diff --git a/cmd/utils_test.go b/cmd/utils_test.go index bc5cd825..ad390ef4 100644 --- a/cmd/utils_test.go +++ b/cmd/utils_test.go @@ -1,10 +1,11 @@ package cmd import ( - apiequality "k8s.io/apimachinery/pkg/api/equality" "reflect" "testing" + apiequality "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/util/diff" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) From ad2054a97def26e311f257973c0824fa5dc1d7d1 Mon Sep 17 00:00:00 2001 From: guoxudong Date: Tue, 8 Dec 2020 13:12:04 +0800 Subject: [PATCH 4/4] fix action --- .github/workflows/go.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml index 51c0b8f6..a920c083 100644 --- a/.github/workflows/go.yaml +++ b/.github/workflows/go.yaml @@ -5,8 +5,6 @@ on: branches: - "master" pull_request: - branches: - - master jobs: test: