зеркало из https://github.com/golang/tools.git
93 строки
2.5 KiB
Go
93 строки
2.5 KiB
Go
// Copyright 2024 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.
|
|
|
|
// The drivertest package provides a fake implementation of the go/packages
|
|
// driver protocol that delegates to the go list driver. It may be used to test
|
|
// programs such as gopls that specialize behavior when a go/packages driver is
|
|
// in use.
|
|
//
|
|
// The driver is run as a child of the current process, by calling [RunIfChild]
|
|
// at process start, and running go/packages with the environment variables set
|
|
// by [Env].
|
|
package drivertest
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"log"
|
|
"os"
|
|
|
|
"golang.org/x/tools/go/packages"
|
|
)
|
|
|
|
const runAsDriverEnv = "DRIVERTEST_RUN_AS_DRIVER"
|
|
|
|
// RunIfChild runs the current process as a go/packages driver, if configured
|
|
// to do so by the current environment (see [Env]).
|
|
//
|
|
// Otherwise, RunIfChild is a no op.
|
|
func RunIfChild() {
|
|
if os.Getenv(runAsDriverEnv) != "" {
|
|
main()
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
|
|
// Env returns additional environment variables for use in [packages.Config]
|
|
// to enable the use of drivertest as the driver.
|
|
//
|
|
// t abstracts a *testing.T or log.Default().
|
|
func Env(t interface{ Fatal(...any) }) []string {
|
|
exe, err := os.Executable()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return []string{"GOPACKAGESDRIVER=" + exe, runAsDriverEnv + "=1"}
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
dec := json.NewDecoder(os.Stdin)
|
|
var request packages.DriverRequest
|
|
if err := dec.Decode(&request); err != nil {
|
|
log.Fatalf("decoding request: %v", err)
|
|
}
|
|
|
|
config := packages.Config{
|
|
Mode: request.Mode,
|
|
Env: append(request.Env, "GOPACKAGESDRIVER=off"), // avoid recursive invocation
|
|
BuildFlags: request.BuildFlags,
|
|
Tests: request.Tests,
|
|
Overlay: request.Overlay,
|
|
}
|
|
pkgs, err := packages.Load(&config, flag.Args()...)
|
|
if err != nil {
|
|
log.Fatalf("load failed: %v", err)
|
|
}
|
|
|
|
var roots []string
|
|
for _, pkg := range pkgs {
|
|
roots = append(roots, pkg.ID)
|
|
}
|
|
var allPackages []*packages.Package
|
|
packages.Visit(pkgs, nil, func(pkg *packages.Package) {
|
|
newImports := make(map[string]*packages.Package)
|
|
for path, imp := range pkg.Imports {
|
|
newImports[path] = &packages.Package{ID: imp.ID}
|
|
}
|
|
pkg.Imports = newImports
|
|
allPackages = append(allPackages, pkg)
|
|
})
|
|
|
|
enc := json.NewEncoder(os.Stdout)
|
|
response := packages.DriverResponse{
|
|
Roots: roots,
|
|
Packages: allPackages,
|
|
}
|
|
if err := enc.Encode(response); err != nil {
|
|
log.Fatalf("encoding response: %v", err)
|
|
}
|
|
}
|