1
0
mirror of https://github.com/golang/go synced 2024-10-01 03:08:33 -06:00
go/internal/lsp/lsprpc/autostart_posix.go
Rob Findley a208025ccb internal/lsp/lsprpc: automatically resolve and start the remote gopls
Most users will not want to manage their own gopls instance, but may
still want to benefit from using a shared instance.

This CL adds support for an 'auto' network type that can be encoded in
the -remote flag similarly to UDS (i.e. -remote="auto;uniqueid"). In
this mode, the actual remote address will be resolved automatically
based on the executing environment and unique identifier, and the remote
server will be started if it isn't already running.

Updates golang/go#34111

Change-Id: Ib62159765a108f3645f57709b8ff079b39dd6727
Reviewed-on: https://go-review.googlesource.com/c/tools/+/220137
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
2020-02-24 22:51:55 +00:00

50 lines
1.5 KiB
Go

// Copyright 2020 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.
// +build !windows
package lsprpc
import (
"crypto/sha1"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
)
// autoNetworkAddress resolves an id on the 'auto' pseduo-network to a
// real network and address. On unix, this uses unix domain sockets.
func autoNetworkAddress(goplsPath, id string) (network string, address string) {
// Especially when doing local development or testing, it's important that
// the remote gopls instance we connect to is running the same binary as our
// forwarder. So we encode a short hash of the binary path into the daemon
// socket name. If possible, we also include the buildid in this hash, to
// account for long-running processes where the binary has been subsequently
// rebuilt.
h := sha1.New()
cmd := exec.Command("go", "tool", "buildid", goplsPath)
cmd.Stdout = h
var pathHash []byte
if err := cmd.Run(); err == nil {
pathHash = h.Sum(nil)
} else {
log.Printf("error getting current buildid: %v", err)
sum := sha1.Sum([]byte(goplsPath))
pathHash = sum[:]
}
shortHash := fmt.Sprintf("%x", pathHash)[:6]
user := os.Getenv("USER")
if user == "" {
user = "shared"
}
basename := filepath.Base(goplsPath)
idComponent := ""
if id != "" {
idComponent = "-" + id
}
return "unix", filepath.Join(os.TempDir(), fmt.Sprintf("%s-%s-daemon.%s%s", basename, shortHash, user, idComponent))
}