]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add bug command
authorJosh Bleecher Snyder <josharian@gmail.com>
Sun, 28 Aug 2016 17:38:41 +0000 (10:38 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Mon, 5 Sep 2016 15:48:08 +0000 (15:48 +0000)
This is a slightly rough, skeletal implementation.
We will polish and add to it through use.

.github/ISSUE_TEMPLATE will be updated in a
separate CL.

Fixes #16635

Change-Id: Icf284170d87e61b5b643366c85cffc48f149f730
Reviewed-on: https://go-review.googlesource.com/28485
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/go/bug.go [new file with mode: 0644]
src/cmd/go/main.go

diff --git a/src/cmd/go/bug.go b/src/cmd/go/bug.go
new file mode 100644 (file)
index 0000000..975c1cc
--- /dev/null
@@ -0,0 +1,129 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+       "bytes"
+       "fmt"
+       "io/ioutil"
+       "net/http"
+       "os/exec"
+       "runtime"
+       "strings"
+)
+
+var cmdBug = &Command{
+       Run:       runBug,
+       UsageLine: "bug",
+       Short:     "print information for bug reports",
+       Long: `
+Bug prints information that helps file effective bug reports.
+
+Bugs may be reported at https://golang.org/issue/new.
+       `,
+}
+
+func init() {
+       cmdBug.Flag.BoolVar(&buildV, "v", false, "")
+}
+
+func runBug(cmd *Command, args []string) {
+       inspectGoVersion()
+       fmt.Println("```")
+       fmt.Printf("go version %s %s/%s\n", runtime.Version(), runtime.GOOS, runtime.GOARCH)
+       for _, e := range mkEnv() {
+               fmt.Printf("%s=\"%s\"\n", e.name, e.value)
+       }
+       printOSDetails()
+       printCDetails()
+       fmt.Println("```")
+}
+
+func printOSDetails() {
+       switch runtime.GOOS {
+       case "darwin":
+               printCmdOut("uname -v: ", "uname", "-v")
+               printCmdOut("", "sw_vers")
+       case "linux":
+               printCmdOut("uname -sr: ", "uname", "-sr")
+               printCmdOut("libc:", "/lib/libc.so.6")
+       case "openbsd", "netbsd", "freebsd", "dragonfly":
+               printCmdOut("uname -v: ", "uname", "-v")
+       case "solaris":
+               out, err := ioutil.ReadFile("/etc/release")
+               if err == nil {
+                       fmt.Printf("/etc/release: %s\n", out)
+               } else {
+                       if buildV {
+                               fmt.Printf("failed to read /etc/release: %v\n", err)
+                       }
+               }
+       }
+}
+
+func printCDetails() {
+       printCmdOut("lldb --version: ", "lldb", "--version")
+       cmd := exec.Command("gdb", "--version")
+       out, err := cmd.Output()
+       if err == nil {
+               // There's apparently no combination of command line flags
+               // to get gdb to spit out its version without the license and warranty.
+               // Print up to the first newline.
+               idx := bytes.Index(out, []byte{'\n'})
+               line := out[:idx]
+               line = bytes.TrimSpace(line)
+               fmt.Printf("gdb --version: %s\n", line)
+       } else {
+               if buildV {
+                       fmt.Printf("failed to run gdb --version: %v\n", err)
+               }
+       }
+}
+
+func inspectGoVersion() {
+       resp, err := http.Get("https://golang.org/VERSION?m=text")
+       if err != nil {
+               if buildV {
+                       fmt.Printf("failed to GET golang.org/VERSION: %v\n", err)
+               }
+               return
+       }
+       defer resp.Body.Close()
+       body, err := ioutil.ReadAll(resp.Body)
+       if err != nil {
+               if buildV {
+                       fmt.Printf("failed to read from golang.org/VERSION: %v\n", err)
+               }
+               return
+       }
+
+       // golang.org/VERSION currently returns a whitespace-free string,
+       // but just in case, protect against that changing.
+       // Similarly so for runtime.Version.
+       release := string(bytes.TrimSpace(body))
+       vers := strings.TrimSpace(runtime.Version())
+
+       if vers == release {
+               // Up to date
+               return
+       }
+
+       // Devel version or outdated release. Either way, this request is apropos.
+       fmt.Printf("Please check whether the issue also reproduces on the latest release, %s.\n\n", release)
+}
+
+// printCmdOut prints the output of running the given command.
+// It ignores failures; 'go bug' is best effort.
+func printCmdOut(prefix, path string, args ...string) {
+       cmd := exec.Command(path, args...)
+       out, err := cmd.Output()
+       if err != nil {
+               if buildV {
+                       fmt.Printf("%s %s: %v\n", path, strings.Join(args, " "), err)
+               }
+               return
+       }
+       fmt.Printf("%s%s\n", prefix, bytes.TrimSpace(out))
+}
index 65ec61bd7dbf20416723e80d3ce34ae9070e3dca..8fdc87d665fe5c65fc48f560639c50c04136d56d 100644 (file)
@@ -79,6 +79,7 @@ var commands = []*Command{
        cmdClean,
        cmdDoc,
        cmdEnv,
+       cmdBug,
        cmdFix,
        cmdFmt,
        cmdGenerate,