Skip to content

Commit ab5f969

Browse files
timothy-kingGo LUCI
authored and
Go LUCI
committed
internal/gcimporter: moving FindPkg
Moves FindPkg and related variables from gcimporter.go to exportdata.go. This is a part of minimizing the code delta between internal/gcimporter and GOROOT/src/internal/exportdata. Updates golang/go#70651 Change-Id: I74d2ba2085d0b034ff9f98f7cae17a2231ae3a6c Reviewed-on: https://go-review.googlesource.com/c/tools/+/634518 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Robert Findley <rfindley@google.com> Commit-Queue: Tim King <taking@google.com>
1 parent 5e47a3d commit ab5f969

File tree

2 files changed

+119
-119
lines changed

2 files changed

+119
-119
lines changed

internal/gcimporter/exportdata.go

+119
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,14 @@ package gcimporter
1010

1111
import (
1212
"bufio"
13+
"bytes"
1314
"fmt"
15+
"go/build"
16+
"os"
17+
"os/exec"
18+
"path/filepath"
1419
"strings"
20+
"sync"
1521
)
1622

1723
// FindExportData positions the reader r at the beginning of the
@@ -99,3 +105,116 @@ func FindExportData(r *bufio.Reader) (size int64, err error) {
99105

100106
return
101107
}
108+
109+
// FindPkg returns the filename and unique package id for an import
110+
// path based on package information provided by build.Import (using
111+
// the build.Default build.Context). A relative srcDir is interpreted
112+
// relative to the current working directory.
113+
// If no file was found, an empty filename is returned.
114+
func FindPkg(path, srcDir string) (filename, id string) {
115+
if path == "" {
116+
return
117+
}
118+
119+
var noext string
120+
switch {
121+
default:
122+
// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
123+
// Don't require the source files to be present.
124+
if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
125+
srcDir = abs
126+
}
127+
bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
128+
if bp.PkgObj == "" {
129+
var ok bool
130+
if bp.Goroot && bp.Dir != "" {
131+
filename, ok = lookupGorootExport(bp.Dir)
132+
}
133+
if !ok {
134+
id = path // make sure we have an id to print in error message
135+
return
136+
}
137+
} else {
138+
noext = strings.TrimSuffix(bp.PkgObj, ".a")
139+
id = bp.ImportPath
140+
}
141+
142+
case build.IsLocalImport(path):
143+
// "./x" -> "/this/directory/x.ext", "/this/directory/x"
144+
noext = filepath.Join(srcDir, path)
145+
id = noext
146+
147+
case filepath.IsAbs(path):
148+
// for completeness only - go/build.Import
149+
// does not support absolute imports
150+
// "/x" -> "/x.ext", "/x"
151+
noext = path
152+
id = path
153+
}
154+
155+
if false { // for debugging
156+
if path != id {
157+
fmt.Printf("%s -> %s\n", path, id)
158+
}
159+
}
160+
161+
if filename != "" {
162+
if f, err := os.Stat(filename); err == nil && !f.IsDir() {
163+
return
164+
}
165+
}
166+
167+
// try extensions
168+
for _, ext := range pkgExts {
169+
filename = noext + ext
170+
if f, err := os.Stat(filename); err == nil && !f.IsDir() {
171+
return
172+
}
173+
}
174+
175+
filename = "" // not found
176+
return
177+
}
178+
179+
var pkgExts = [...]string{".a", ".o"}
180+
181+
var exportMap sync.Map // package dir → func() (string, bool)
182+
183+
// lookupGorootExport returns the location of the export data
184+
// (normally found in the build cache, but located in GOROOT/pkg
185+
// in prior Go releases) for the package located in pkgDir.
186+
//
187+
// (We use the package's directory instead of its import path
188+
// mainly to simplify handling of the packages in src/vendor
189+
// and cmd/vendor.)
190+
func lookupGorootExport(pkgDir string) (string, bool) {
191+
f, ok := exportMap.Load(pkgDir)
192+
if !ok {
193+
var (
194+
listOnce sync.Once
195+
exportPath string
196+
)
197+
f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) {
198+
listOnce.Do(func() {
199+
cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkgDir)
200+
cmd.Dir = build.Default.GOROOT
201+
var output []byte
202+
output, err := cmd.Output()
203+
if err != nil {
204+
return
205+
}
206+
207+
exports := strings.Split(string(bytes.TrimSpace(output)), "\n")
208+
if len(exports) != 1 {
209+
return
210+
}
211+
212+
exportPath = exports[0]
213+
})
214+
215+
return exportPath, exportPath != ""
216+
})
217+
}
218+
219+
return f.(func() (string, bool))()
220+
}

internal/gcimporter/gcimporter.go

-119
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,11 @@ package gcimporter // import "golang.org/x/tools/internal/gcimporter"
2323

2424
import (
2525
"bufio"
26-
"bytes"
2726
"fmt"
28-
"go/build"
2927
"go/token"
3028
"go/types"
3129
"io"
3230
"os"
33-
"os/exec"
34-
"path/filepath"
35-
"strings"
36-
"sync"
3731
)
3832

3933
const (
@@ -45,119 +39,6 @@ const (
4539
trace = false
4640
)
4741

48-
var exportMap sync.Map // package dir → func() (string, bool)
49-
50-
// lookupGorootExport returns the location of the export data
51-
// (normally found in the build cache, but located in GOROOT/pkg
52-
// in prior Go releases) for the package located in pkgDir.
53-
//
54-
// (We use the package's directory instead of its import path
55-
// mainly to simplify handling of the packages in src/vendor
56-
// and cmd/vendor.)
57-
func lookupGorootExport(pkgDir string) (string, bool) {
58-
f, ok := exportMap.Load(pkgDir)
59-
if !ok {
60-
var (
61-
listOnce sync.Once
62-
exportPath string
63-
)
64-
f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) {
65-
listOnce.Do(func() {
66-
cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkgDir)
67-
cmd.Dir = build.Default.GOROOT
68-
var output []byte
69-
output, err := cmd.Output()
70-
if err != nil {
71-
return
72-
}
73-
74-
exports := strings.Split(string(bytes.TrimSpace(output)), "\n")
75-
if len(exports) != 1 {
76-
return
77-
}
78-
79-
exportPath = exports[0]
80-
})
81-
82-
return exportPath, exportPath != ""
83-
})
84-
}
85-
86-
return f.(func() (string, bool))()
87-
}
88-
89-
var pkgExts = [...]string{".a", ".o"}
90-
91-
// FindPkg returns the filename and unique package id for an import
92-
// path based on package information provided by build.Import (using
93-
// the build.Default build.Context). A relative srcDir is interpreted
94-
// relative to the current working directory.
95-
// If no file was found, an empty filename is returned.
96-
func FindPkg(path, srcDir string) (filename, id string) {
97-
if path == "" {
98-
return
99-
}
100-
101-
var noext string
102-
switch {
103-
default:
104-
// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
105-
// Don't require the source files to be present.
106-
if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
107-
srcDir = abs
108-
}
109-
bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
110-
if bp.PkgObj == "" {
111-
var ok bool
112-
if bp.Goroot && bp.Dir != "" {
113-
filename, ok = lookupGorootExport(bp.Dir)
114-
}
115-
if !ok {
116-
id = path // make sure we have an id to print in error message
117-
return
118-
}
119-
} else {
120-
noext = strings.TrimSuffix(bp.PkgObj, ".a")
121-
id = bp.ImportPath
122-
}
123-
124-
case build.IsLocalImport(path):
125-
// "./x" -> "/this/directory/x.ext", "/this/directory/x"
126-
noext = filepath.Join(srcDir, path)
127-
id = noext
128-
129-
case filepath.IsAbs(path):
130-
// for completeness only - go/build.Import
131-
// does not support absolute imports
132-
// "/x" -> "/x.ext", "/x"
133-
noext = path
134-
id = path
135-
}
136-
137-
if false { // for debugging
138-
if path != id {
139-
fmt.Printf("%s -> %s\n", path, id)
140-
}
141-
}
142-
143-
if filename != "" {
144-
if f, err := os.Stat(filename); err == nil && !f.IsDir() {
145-
return
146-
}
147-
}
148-
149-
// try extensions
150-
for _, ext := range pkgExts {
151-
filename = noext + ext
152-
if f, err := os.Stat(filename); err == nil && !f.IsDir() {
153-
return
154-
}
155-
}
156-
157-
filename = "" // not found
158-
return
159-
}
160-
16142
// Import imports a gc-generated package given its import path and srcDir, adds
16243
// the corresponding package object to the packages map, and returns the object.
16344
// The packages map must contain all packages already imported.

0 commit comments

Comments
 (0)