x/tools/go/packages: add Embed support

Add EmbedFiles and EmbedPatterns to the exported set of information in
the Package struct. Available on Go 1.16+, everywhere that go:embed is
available.

Fixes golang/go#50720

Change-Id: Ie84402ace1151fedaaa2a81c881d0e3d1e3ed9a7
Reviewed-on: https://go-review.googlesource.com/c/tools/+/379974
Reviewed-by: Michael Matloob <matloob@golang.org>
Trust: Michael Matloob <matloob@golang.org>
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Chris Koch 2022-01-20 12:00:47 -08:00 committed by Robert Findley
parent 1428e83b47
commit 87a8611856
3 changed files with 43 additions and 2 deletions

View File

@ -393,6 +393,8 @@ type jsonPackage struct {
CompiledGoFiles []string
IgnoredGoFiles []string
IgnoredOtherFiles []string
EmbedPatterns []string
EmbedFiles []string
CFiles []string
CgoFiles []string
CXXFiles []string
@ -565,6 +567,8 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse
GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles),
CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles),
OtherFiles: absJoin(p.Dir, otherFiles(p)...),
EmbedFiles: absJoin(p.Dir, p.EmbedFiles),
EmbedPatterns: absJoin(p.Dir, p.EmbedPatterns),
IgnoredFiles: absJoin(p.Dir, p.IgnoredGoFiles, p.IgnoredOtherFiles),
forTest: p.ForTest,
depsErrors: p.DepsErrors,

View File

@ -80,6 +80,12 @@ const (
// NeedModule adds Module.
NeedModule
// NeedEmbedFiles adds EmbedFiles.
NeedEmbedFiles
// NeedEmbedPatterns adds EmbedPatterns.
NeedEmbedPatterns
)
const (
@ -296,6 +302,14 @@ type Package struct {
// including assembly, C, C++, Fortran, Objective-C, SWIG, and so on.
OtherFiles []string
// EmbedFiles lists the absolute file paths of the package's files
// embedded with go:embed.
EmbedFiles []string
// EmbedPatterns lists the absolute file patterns of the package's
// files embedded with go:embed.
EmbedPatterns []string
// IgnoredFiles lists source files that are not part of the package
// using the current build configuration but that might be part of
// the package using other build configurations.
@ -431,6 +445,8 @@ type flatPackage struct {
GoFiles []string `json:",omitempty"`
CompiledGoFiles []string `json:",omitempty"`
OtherFiles []string `json:",omitempty"`
EmbedFiles []string `json:",omitempty"`
EmbedPatterns []string `json:",omitempty"`
IgnoredFiles []string `json:",omitempty"`
ExportFile string `json:",omitempty"`
Imports map[string]string `json:",omitempty"`
@ -454,6 +470,8 @@ func (p *Package) MarshalJSON() ([]byte, error) {
GoFiles: p.GoFiles,
CompiledGoFiles: p.CompiledGoFiles,
OtherFiles: p.OtherFiles,
EmbedFiles: p.EmbedFiles,
EmbedPatterns: p.EmbedPatterns,
IgnoredFiles: p.IgnoredFiles,
ExportFile: p.ExportFile,
}
@ -481,6 +499,8 @@ func (p *Package) UnmarshalJSON(b []byte) error {
GoFiles: flat.GoFiles,
CompiledGoFiles: flat.CompiledGoFiles,
OtherFiles: flat.OtherFiles,
EmbedFiles: flat.EmbedFiles,
EmbedPatterns: flat.EmbedPatterns,
ExportFile: flat.ExportFile,
}
if len(flat.Imports) > 0 {
@ -752,6 +772,12 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
ld.pkgs[i].OtherFiles = nil
ld.pkgs[i].IgnoredFiles = nil
}
if ld.requestedMode&NeedEmbedFiles == 0 {
ld.pkgs[i].EmbedFiles = nil
}
if ld.requestedMode&NeedEmbedPatterns == 0 {
ld.pkgs[i].EmbedPatterns = nil
}
if ld.requestedMode&NeedCompiledGoFiles == 0 {
ld.pkgs[i].CompiledGoFiles = nil
}

View File

@ -1077,6 +1077,10 @@ func testAbsoluteFilenames(t *testing.T, exporter packagestest.Exporter) {
"e/e2.go": `package main; import _ "golang.org/fake/c"`,
"f/f.go": `package f`,
"f/f.s": ``,
"g/g.go": `package g; import _ "embed";` + "\n//go:embed g2.txt\n" + `var s string`,
"g/g2.txt": "hello",
"h/h.go": `package g; import _ "embed";` + "\n//go:embed a*.txt\n" + `var s string`,
"h/aa.txt": "hello",
}}})
defer exported.Cleanup()
exported.Config.Dir = filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "a/a.go")))
@ -1103,6 +1107,8 @@ func testAbsoluteFilenames(t *testing.T, exporter packagestest.Exporter) {
{"golang.org/fake/subdir/e", "d.go"},
{"golang.org/fake/e", "e.go e2.go"},
{"golang.org/fake/f", "f.go f.s"},
{"golang.org/fake/g", "g.go g2.txt"},
{"golang.org/fake/h", "h.go aa.txt"},
// Relative paths
{"./a", "a.go"},
{"./b/vendor/a", "a.go"},
@ -1112,8 +1118,10 @@ func testAbsoluteFilenames(t *testing.T, exporter packagestest.Exporter) {
{"./subdir/e", "d.go"},
{"./e", "e.go e2.go"},
{"./f", "f.go f.s"},
{"./g", "g.go g2.txt"},
{"./h", "h.go aa.txt"},
} {
exported.Config.Mode = packages.LoadFiles
exported.Config.Mode = packages.LoadFiles | packages.NeedEmbedFiles
pkgs, err := packages.Load(exported.Config, test.pattern)
if err != nil {
t.Errorf("pattern %s: %v", test.pattern, err)
@ -1133,6 +1141,9 @@ func testAbsoluteFilenames(t *testing.T, exporter packagestest.Exporter) {
for _, filename := range pkg.OtherFiles {
checkFile(filename)
}
for _, filename := range pkg.EmbedFiles {
checkFile(filename)
}
for _, filename := range pkg.IgnoredFiles {
checkFile(filename)
}
@ -2707,7 +2718,7 @@ func errorMessages(errors []packages.Error) []string {
}
func srcs(p *packages.Package) []string {
return cleanPaths(append(p.GoFiles[:len(p.GoFiles):len(p.GoFiles)], p.OtherFiles...))
return cleanPaths(append(append(p.GoFiles[:len(p.GoFiles):len(p.GoFiles)], p.OtherFiles...), p.EmbedFiles...))
}
// cleanPaths attempts to reduce path names to stable forms