From 87a8611856c16053279b8253ad6fd1e17fab0307 Mon Sep 17 00:00:00 2001 From: Chris Koch Date: Thu, 20 Jan 2022 12:00:47 -0800 Subject: [PATCH] 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 Trust: Michael Matloob Trust: Robert Findley Run-TryBot: Robert Findley gopls-CI: kokoro TryBot-Result: Gopher Robot --- go/packages/golist.go | 4 ++++ go/packages/packages.go | 26 ++++++++++++++++++++++++++ go/packages/packages_test.go | 15 +++++++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/go/packages/golist.go b/go/packages/golist.go index 0e1e7f11fe..645f0c7ec8 100644 --- a/go/packages/golist.go +++ b/go/packages/golist.go @@ -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, diff --git a/go/packages/packages.go b/go/packages/packages.go index 1b5424e78f..4dfebc0f6e 100644 --- a/go/packages/packages.go +++ b/go/packages/packages.go @@ -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 } diff --git a/go/packages/packages_test.go b/go/packages/packages_test.go index 6549fd6106..df95d6adfb 100644 --- a/go/packages/packages_test.go +++ b/go/packages/packages_test.go @@ -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