diff --git a/.gitignore b/.gitignore index 9152893..70cf02d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,7 @@ goc # the temp file to save service address -_svrs_address.txt \ No newline at end of file +_svrs_address.txt + +# other +*.iml \ No newline at end of file diff --git a/cmd/build.go b/cmd/build.go index 4617b86..393a5e5 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -71,7 +71,7 @@ func runBuild(args []string, wd string) { defer gocBuild.Clean() // doCover with original buildFlags, with new GOPATH( tmp:original ) // in the tmp directory - cover.Execute(buildFlags, gocBuild.NewGOPATH, gocBuild.TmpDir, mode, agentPort, center) + cover.Execute(buildFlags, gocBuild.NewGOPATH, gocBuild.TmpDir, coverMode.String(), agentPort.String(), center) // do install in the temporary directory err = gocBuild.Build() if err != nil { diff --git a/cmd/commonflags.go b/cmd/commonflags.go index c12d70e..8f93dcc 100644 --- a/cmd/commonflags.go +++ b/cmd/commonflags.go @@ -1,6 +1,25 @@ +/* + Copyright 2020 Qiniu Cloud (qiniu.com) + + 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 cmd import ( + "fmt" + "net" + "github.com/spf13/pflag" "github.com/spf13/viper" ) @@ -8,8 +27,7 @@ import ( var ( target string center string - mode string - agentPort string + agentPort AgentPort debugGoc bool buildFlags string @@ -17,6 +35,10 @@ var ( goRunArguments string ) +var coverMode = CoverMode{ + mode: "count", +} + // addBasicFlags adds a func addBasicFlags(cmdset *pflag.FlagSet) { cmdset.StringVar(¢er, "center", "http://127.0.0.1:7777", "cover profile host center") @@ -26,8 +48,8 @@ func addBasicFlags(cmdset *pflag.FlagSet) { func addCommonFlags(cmdset *pflag.FlagSet) { addBasicFlags(cmdset) - cmdset.StringVar(&mode, "mode", "count", "coverage mode: set, count, atomic") - cmdset.StringVar(&agentPort, "agentport", "", "specify fixed port for registered service communicate with goc server. if not provided, using a random one") + cmdset.Var(&coverMode, "mode", "coverage mode: set, count, atomic") + cmdset.Var(&agentPort, "agentport", "a fixed port such as :8100 for registered service communicate with goc server. if not provided, using a random one") cmdset.StringVar(&buildFlags, "buildflags", "", "specify the build flags") // bind to viper viper.BindPFlags(cmdset) @@ -46,3 +68,54 @@ func addRunFlags(cmdset *pflag.FlagSet) { // bind to viper viper.BindPFlags(cmdset) } + +// add Cover Mode check +type CoverMode struct { + mode string +} + +func (m *CoverMode) String() string { + return m.mode +} + +func (m *CoverMode) Set(v string) error { + if v == "" { + m.mode = "count" + return nil + } + if v != "set" && v != "count" && v != "atomic" { + return fmt.Errorf("unknown mode") + } + m.mode = v + return nil +} + +func (m *CoverMode) Type() string { + return "string" +} + +// add agentPort check +type AgentPort struct { + port string +} + +func (agent *AgentPort) String() string { + return agent.port +} + +func (agent *AgentPort) Set(v string) error { + if v == "" { + agent.port = "" + return nil + } + _, _, err := net.SplitHostPort(v) + if err != nil { + return err + } + agent.port = v + return nil +} + +func (agent *AgentPort) Type() string { + return "string" +} diff --git a/cmd/commonflags_test.go b/cmd/commonflags_test.go new file mode 100644 index 0000000..ea5f4f0 --- /dev/null +++ b/cmd/commonflags_test.go @@ -0,0 +1,110 @@ +/* + Copyright 2020 Qiniu Cloud (qiniu.com) + + 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 cmd + +import ( + "errors" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCoverModeFlag(t *testing.T) { + var tcs = []struct { + value string + expectedValue interface{} + err interface{} + }{ + { + value: "", + expectedValue: "count", + err: nil, + }, + { + value: "set", + expectedValue: "set", + err: nil, + }, + { + value: "count", + expectedValue: "count", + err: nil, + }, + { + value: "atomic", + expectedValue: "atomic", + err: nil, + }, + { + value: "xxxxx", + expectedValue: "", + err: errors.New("unknown mode"), + }, + { + value: "123333", + expectedValue: "", + err: errors.New("unknown mode"), + }, + } + for _, tc := range tcs { + mode := &CoverMode{} + err := mode.Set(tc.value) + actual := mode.String() + assert.Equal(t, actual, tc.expectedValue, fmt.Sprintf("check mode flag value failed, expected %s, got %s", tc.expectedValue, actual)) + assert.Equal(t, err, tc.err, fmt.Sprintf("check mode flag error, expected %s, got %s", tc.err, err)) + } +} + +func TestAgentPortFlag(t *testing.T) { + var tcs = []struct { + value string + expectedValue interface{} + isErr bool + }{ + { + value: "", + expectedValue: "", + isErr: false, + }, + { + value: ":8888", + expectedValue: ":8888", + isErr: false, + }, + { + value: "8888", + expectedValue: "", + isErr: true, + }, + { + value: "::8888", + expectedValue: "", + isErr: true, + }, + } + for _, tc := range tcs { + agent := &AgentPort{} + err := agent.Set(tc.value) + if tc.isErr { + assert.NotEqual(t, nil, err, fmt.Sprintf("check agentport flag error, expected %v, got %v", nil, err)) + } else { + actual := agent.String() + assert.Equal(t, tc.expectedValue, actual, fmt.Sprintf("check agentport flag value failed, expected %s, got %s", tc.expectedValue, actual)) + } + } +} diff --git a/cmd/cover.go b/cmd/cover.go index d394980..b2d7034 100644 --- a/cmd/cover.go +++ b/cmd/cover.go @@ -18,7 +18,6 @@ package cmd import ( "github.com/qiniu/goc/pkg/cover" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -41,14 +40,7 @@ goc cover --center=http://127.0.0.1:7777 --target=/path/to/target --mode=atomic Run: func(cmd *cobra.Command, args []string) { var buildFlags string buildFlags = viper.GetString("buildflags") - if mode == "" { - log.Fatalf("Error: flag needs an argument: -mode %v", mode) - } - if mode != "set" && mode != "count" && mode != "atomic" { - log.Fatalf("unknown -mode %v", mode) - } - - cover.Execute(buildFlags, "", target, mode, agentPort, center) + cover.Execute(buildFlags, "", target, coverMode.String(), agentPort.String(), center) }, } diff --git a/cmd/install.go b/cmd/install.go index dbe1f7a..f334f34 100644 --- a/cmd/install.go +++ b/cmd/install.go @@ -64,7 +64,7 @@ func runInstall(args []string, wd string) { defer gocBuild.Clean() // doCover with original buildFlags, with new GOPATH( tmp:original ) // in the tmp directory - cover.Execute(buildFlags, gocBuild.NewGOPATH, gocBuild.TmpDir, mode, agentPort, center) + cover.Execute(buildFlags, gocBuild.NewGOPATH, gocBuild.TmpDir, coverMode.String(), agentPort.String(), center) // do install in the temporary directory err = gocBuild.Install() if err != nil { diff --git a/cmd/run.go b/cmd/run.go index 99a8368..bf0bdeb 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -60,7 +60,7 @@ goc run . [--buildflags] [--exec] [--arguments] fmt.Printf("[goc] goc server started: %s \n", gocServer) // execute covers for the target source with original buildFlags and new GOPATH( tmp:original ) - cover.Execute(buildFlags, gocBuild.NewGOPATH, gocBuild.TmpDir, mode, "", gocServer) + cover.Execute(buildFlags, gocBuild.NewGOPATH, gocBuild.TmpDir, coverMode.String(), "", gocServer) if err := gocBuild.Run(); err != nil { log.Fatalf("Fail to run: %v", err) diff --git a/pkg/cover/cover.go b/pkg/cover/cover.go index 09eea15..201dd57 100644 --- a/pkg/cover/cover.go +++ b/pkg/cover/cover.go @@ -126,7 +126,6 @@ func Execute(args, newGopath, target, mode, agentPort, center string) error { log.Errorf("Target directory %s not exist", target) return ErrCoverPkgFailed } - listArgs := []string{"-json"} if len(args) != 0 { listArgs = append(listArgs, args) @@ -302,7 +301,7 @@ func AddCounters(pkg *Package, mode, newgopath string) (*PackageCover, error) { cmd := buildCoverCmd(file, coverVar, pkg, mode, newgopath) out, err := cmd.CombinedOutput() if err != nil { - return nil, fmt.Errorf("execute go tool cover -mode=atomic -var %s -o %s/%s failed, err: %v, out: %s", coverVar.Var, pkg.Dir, file, err, string(out)) + return nil, fmt.Errorf("execute go tool cover -mode=%s -var %s -o %s/%s failed, err: %v, out: %s", mode, coverVar.Var, pkg.Dir, file, err, string(out)) } }