1// Copyright 2020 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 "context" 9 "encoding/json" 10 "flag" 11 "fmt" 12 "log" 13 "os" 14 15 "golang.org/x/tools/internal/lsp/lsprpc" 16 "golang.org/x/tools/internal/tool" 17) 18 19type inspect struct { 20 app *Application 21} 22 23func (i *inspect) subCommands() []tool.Application { 24 return []tool.Application{ 25 &listSessions{app: i.app}, 26 } 27} 28 29func (i *inspect) Name() string { return "inspect" } 30func (i *inspect) Usage() string { return "<subcommand> [args...]" } 31func (i *inspect) ShortHelp() string { 32 return "inspect server state (daemon mode only)" 33} 34func (i *inspect) DetailedHelp(f *flag.FlagSet) { 35 fmt.Fprint(f.Output(), "\nsubcommands:\n") 36 for _, c := range i.subCommands() { 37 fmt.Fprintf(f.Output(), " %s: %s\n", c.Name(), c.ShortHelp()) 38 } 39 f.PrintDefaults() 40} 41 42func (i *inspect) Run(ctx context.Context, args ...string) error { 43 if len(args) == 0 { 44 return tool.CommandLineErrorf("must provide subcommand to %q", i.Name()) 45 } 46 command, args := args[0], args[1:] 47 for _, c := range i.subCommands() { 48 if c.Name() == command { 49 return tool.Run(ctx, c, args) 50 } 51 } 52 return tool.CommandLineErrorf("unknown command %v", command) 53} 54 55// listSessions is an inspect subcommand to list current sessions. 56type listSessions struct { 57 app *Application 58} 59 60func (c *listSessions) Name() string { return "sessions" } 61func (c *listSessions) Usage() string { return "" } 62func (c *listSessions) ShortHelp() string { 63 return "print information about current gopls sessions" 64} 65 66const listSessionsExamples = ` 67Examples: 68 691) list sessions for the default daemon: 70 71$ gopls -remote=auto inspect sessions 72or just 73$ gopls inspect sessions 74 752) list sessions for a specific daemon: 76 77$ gopls -remote=localhost:8082 inspect sessions 78` 79 80func (c *listSessions) DetailedHelp(f *flag.FlagSet) { 81 fmt.Fprint(f.Output(), listSessionsExamples) 82 f.PrintDefaults() 83} 84 85func (c *listSessions) Run(ctx context.Context, args ...string) error { 86 remote := c.app.Remote 87 if remote == "" { 88 remote = "auto" 89 } 90 network, address := parseAddr(remote) 91 state, err := lsprpc.QueryServerState(ctx, network, address) 92 if err != nil { 93 return err 94 } 95 v, err := json.MarshalIndent(state, "", "\t") 96 if err != nil { 97 log.Fatal(err) 98 } 99 os.Stdout.Write(v) 100 return nil 101} 102