...

Package cmd

import "github.com/ory/go-acc/cmd"
Overview
Index

Overview ▾

Index ▾

Package files

root.go

Variables

RootCmd represents the base command when called without any subcommands

var RootCmd = &cobra.Command{
    Use:   "go-acc <flags> <packages...>",
    Short: "Receive accurate code coverage reports for Golang (Go)",
    Args:  cobra.MinimumNArgs(1),
    Example: `$ go-acc github.com/some/package
$ go-acc -o my-coverfile.txt github.com/some/package
$ go-acc ./...
$ go-acc $(glide novendor)
$ go-acc  --ignore pkga,pkgb .

You can pass all flags defined by "go test" after "--":
$ go-acc . -- -short -v -failfast

You can pick an alternative go test binary using:

GO_TEST_BINARY="go test"
GO_TEST_BINARY="gotest"
`,
    RunE: func(cmd *cobra.Command, args []string) error {
        mode, err := cmd.Flags().GetString("covermode")
        if err != nil {
            return err
        }

        if verbose, err := cmd.Flags().GetBool("verbose"); err != nil {
            return err
        } else if verbose {
            fmt.Println("Flag -v has been deprecated, use `go-acc -- -v` instead!")
        }

        ignores, err := cmd.Flags().GetStringSlice("ignore")
        if err != nil {
            return err
        }

        payload := "mode: " + mode + "\n"

        var packages []string
        var passthrough []string
        for _, a := range args {
            if len(a) == 0 {
                continue
            }

            if a[0] == '-' || len(passthrough) > 0 {
                passthrough = append(passthrough, a)
                continue
            }

            if len(a) > 4 && a[len(a)-4:] == "/..." {
                var buf bytes.Buffer
                c := exec.Command("go", "list", a)
                c.Stdout = &buf
                c.Stderr = &buf
                if err := c.Run(); err != nil {
                    check(fmt.Errorf("unable to run go list: %w", err))
                }

                var add []string
                for _, s := range strings.Split(buf.String(), "\n") {

                    if len(s) > 0 && !strings.HasPrefix(s, "go: ") {

                        ignore := false
                        for _, ignoreStr := range ignores {
                            if strings.Contains(s, ignoreStr) {
                                ignore = true
                                break
                            }
                        }

                        if !ignore {
                            add = append(add, s)
                        }
                    }
                }

                packages = append(packages, add...)
            } else {
                packages = append(packages, a)
            }
        }

        files := make([]string, len(packages))
        for k, pkg := range packages {
            files[k] = filepath.Join(os.TempDir(), uuid.New()) + ".cc.tmp"

            gotest := os.Getenv("GO_TEST_BINARY")
            if gotest == "" {
                gotest = "go test"
            }

            gt := strings.Split(gotest, " ")
            if len(gt) != 2 {
                gt = append(gt, "")
            }

            var c *exec.Cmd
            ca := append(append(
                []string{
                    gt[1],
                    "-covermode=" + mode,
                    "-coverprofile=" + files[k],
                    "-coverpkg=" + strings.Join(packages, ","),
                },
                passthrough...),
                pkg)
            c = exec.Command(gt[0], ca...)

            stderr, err := c.StderrPipe()
            check(err)

            stdout, err := c.StdoutPipe()
            check(err)

            check(c.Start())

            var wg sync.WaitGroup
            wg.Add(2)
            go scan(&wg, stderr)
            go scan(&wg, stdout)

            check(c.Wait())

            wg.Wait()
        }

        for _, file := range files {
            if _, err := os.Stat(file); os.IsNotExist(err) {
                continue
            }

            p, err := ioutil.ReadFile(file)
            check(err)

            ps := strings.Split(string(p), "\n")
            payload += strings.Join(ps[1:], "\n")
        }

        output, err := cmd.Flags().GetString("output")
        check(err)

        check(ioutil.WriteFile(output, []byte(payload), 0644))
        return nil
    },
}

func Execute

func Execute()

Execute adds all child commands to the root command sets flags appropriately. This is called by main.main(). It only needs to happen once to the rootCmd.