1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package cmd
6
7import (
8	"bytes"
9	"context"
10	"flag"
11	"fmt"
12	"net/url"
13	"os"
14	"strings"
15
16	"golang.org/x/tools/internal/lsp/browser"
17	"golang.org/x/tools/internal/lsp/debug"
18)
19
20// version implements the version command.
21type version struct {
22	app *Application
23}
24
25// bug implements the bug command.
26type bug struct{}
27
28func (v *version) Name() string      { return "version" }
29func (v *version) Usage() string     { return "" }
30func (v *version) ShortHelp() string { return "print the gopls version information" }
31func (v *version) DetailedHelp(f *flag.FlagSet) {
32	fmt.Fprint(f.Output(), ``)
33	f.PrintDefaults()
34}
35
36// Run collects some basic information and then prepares an issue ready to
37// be reported.
38func (v *version) Run(ctx context.Context, args ...string) error {
39	debug.PrintVersionInfo(os.Stdout, v.app.Verbose, debug.PlainText)
40	return nil
41}
42
43func (b *bug) Name() string      { return "bug" }
44func (b *bug) Usage() string     { return "" }
45func (b *bug) ShortHelp() string { return "report a bug in gopls" }
46func (b *bug) DetailedHelp(f *flag.FlagSet) {
47	fmt.Fprint(f.Output(), ``)
48	f.PrintDefaults()
49}
50
51const goplsBugPrefix = "gopls: "
52const goplsBugHeader = `Please answer these questions before submitting your issue. Thanks!
53
54#### What did you do?
55If possible, provide a recipe for reproducing the error.
56A complete runnable program is good.
57A link on play.golang.org is better.
58A failing unit test is the best.
59
60#### What did you expect to see?
61
62
63#### What did you see instead?
64
65
66`
67
68// Run collects some basic information and then prepares an issue ready to
69// be reported.
70func (b *bug) Run(ctx context.Context, args ...string) error {
71	buf := &bytes.Buffer{}
72	fmt.Fprint(buf, goplsBugHeader)
73	debug.PrintVersionInfo(buf, true, debug.Markdown)
74	body := buf.String()
75	title := strings.Join(args, " ")
76	if !strings.HasPrefix(title, goplsBugPrefix) {
77		title = goplsBugPrefix + title
78	}
79	if !browser.Open("https://github.com/golang/go/issues/new?title=" + url.QueryEscape(title) + "&body=" + url.QueryEscape(body)) {
80		fmt.Print("Please file a new issue at golang.org/issue/new using this template:\n\n")
81		fmt.Print(body)
82	}
83	return nil
84}
85