1
0
mirror of https://github.com/golang/go synced 2024-11-18 03:04:45 -07:00

internal/lsp: use -json for module upgrades

This is better than parsing the default output.
Also, change the start progress message, since it ends up duplicating
the title in the message that the user sees.

Change-Id: I3540d30c7976c6be0722531b2e258341081e0b72
Reviewed-on: https://go-review.googlesource.com/c/tools/+/251920
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Rebecca Stambler 2020-08-31 15:33:05 -04:00
parent 6e59e24738
commit 6fbec87eed
2 changed files with 33 additions and 22 deletions

View File

@ -6,7 +6,9 @@ package cache
import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"regexp"
@ -273,6 +275,15 @@ func (muh *modUpgradeHandle) upgrades(ctx context.Context, snapshot *snapshot) (
return data.upgrades, data.err
}
// moduleUpgrade describes a module that can be upgraded to a particular
// version.
type moduleUpgrade struct {
Path string
Update struct {
Version string
}
}
func (s *snapshot) ModUpgrade(ctx context.Context, fh source.FileHandle) (map[string]string, error) {
if err := s.awaitLoaded(ctx); err != nil {
return nil, err
@ -306,7 +317,7 @@ func (s *snapshot) ModUpgrade(ctx context.Context, fh source.FileHandle) (map[st
}
// Run "go list -mod readonly -u -m all" to be able to see which deps can be
// upgraded without modifying mod file.
args := []string{"-u", "-m", "all"}
args := []string{"-u", "-m", "-json", "all"}
if !snapshot.view.tmpMod || containsVendor(fh.URI()) {
// Use -mod=readonly if the module contains a vendor directory
// (see golang/go#38711).
@ -316,28 +327,26 @@ func (s *snapshot) ModUpgrade(ctx context.Context, fh source.FileHandle) (map[st
if err != nil {
return &modUpgradeData{err: err}
}
upgradesList := strings.Split(stdout.String(), "\n")
if len(upgradesList) <= 1 {
return nil
var upgradeList []moduleUpgrade
dec := json.NewDecoder(stdout)
for {
var m moduleUpgrade
if err := dec.Decode(&m); err == io.EOF {
break
} else if err != nil {
return &modUpgradeData{err: err}
}
upgradeList = append(upgradeList, m)
}
if len(upgradeList) <= 1 {
return &modUpgradeData{}
}
upgrades := make(map[string]string)
for _, upgrade := range upgradesList[1:] {
// Example: "github.com/x/tools v1.1.0 [v1.2.0]"
info := strings.Split(upgrade, " ")
if len(info) != 3 {
for _, upgrade := range upgradeList[1:] {
if upgrade.Update.Version == "" {
continue
}
dep, version := info[0], info[2]
// Make sure that the format matches our expectation.
if len(version) < 2 {
continue
}
if version[0] != '[' || version[len(version)-1] != ']' {
continue
}
latest := version[1 : len(version)-1] // remove the "[" and "]"
upgrades[dep] = latest
upgrades[upgrade.Path] = upgrade.Update.Version
}
return &modUpgradeData{
upgrades: upgrades,

View File

@ -105,7 +105,7 @@ func (s *Server) executeCommand(ctx context.Context, params *protocol.ExecuteCom
// clients are aware of the work item before the command completes. This
// matters for regtests, where having a continuous thread of work is
// convenient for assertions.
work := s.progress.start(ctx, title, title+": running...", params.WorkDoneToken, cancel)
work := s.progress.start(ctx, title, "Running...", params.WorkDoneToken, cancel)
go func() {
defer cancel()
err := s.runCommand(ctx, work, command, params.Arguments)
@ -117,10 +117,12 @@ func (s *Server) executeCommand(ctx context.Context, params *protocol.ExecuteCom
work.end(title + ": failed")
// Show a message when work completes with error, because the progress end
// message is typically dismissed immediately by LSP clients.
s.client.ShowMessage(ctx, &protocol.ShowMessageParams{
if err := s.client.ShowMessage(ctx, &protocol.ShowMessageParams{
Type: protocol.Error,
Message: fmt.Sprintf("%s: An error occurred: %v", title, err),
})
}); err != nil {
event.Error(ctx, title+": failed to show message", err)
}
default:
work.end(command.Name + ": completed")
}