Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions tools/driver/packages/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ import (
"sync"

"github.com/peterebden/go-cli-init/v5/logging"
"github.com/please-build/go-rules/tools/please_go/packageinfo"
"golang.org/x/sync/errgroup"
"golang.org/x/term"
"golang.org/x/tools/go/packages"

"github.com/please-build/go-rules/tools/please_go/packageinfo"
)

var log = logging.MustGetLogger()
Expand Down Expand Up @@ -421,7 +420,7 @@ func loadStdlibPackages() ([]*packages.Package, error) {
} else if err != nil {
return nil, err
}
pkgs = append(pkgs, packageinfo.FromBuildPackageForModule(pkg))
pkgs = append(pkgs, packageinfo.FromBuildPackageForModule(pkg, ""))
}
return pkgs, nil
}
Expand Down
8 changes: 3 additions & 5 deletions tools/please_go/packageinfo/moduleinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,7 @@ func WriteModuleInfo(importPath string, srcRoot, importconfig string, installPkg
} else if err != nil {
return fmt.Errorf("failed to import directory %s: %w", dir, err)
}
pkg := FromBuildPackageForModule(bpkg)

pkg.ExportFile = imports[pkg.PkgPath]
pkgs = append(pkgs, pkg)
pkgs = append(pkgs, FromBuildPackageForModule(bpkg, imports[bpkg.ImportPath]))
}
// If we're doing the stdlib, limit it to just things in the importconfig (i.e. no cmd/ packages)
pkgs = slices.DeleteFunc(pkgs, func(pkg *packages.Package) bool {
Expand Down Expand Up @@ -117,7 +114,7 @@ func loadImportConfig(filename string) (map[string]string, error) {
}

// FromBuildPackageForModule creates a packages Package from a build Package for a module.
func FromBuildPackageForModule(bpkg *build.Package) *packages.Package {
func FromBuildPackageForModule(bpkg *build.Package, exportFile string) *packages.Package {
goFiles := make([]string, len(bpkg.GoFiles)+len(bpkg.TestGoFiles)+len(bpkg.XTestGoFiles))
for i, file := range bpkg.GoFiles {
goFiles[i] = filepath.Join(bpkg.Dir, file)
Expand Down Expand Up @@ -145,5 +142,6 @@ func FromBuildPackageForModule(bpkg *build.Package) *packages.Package {
OtherFiles: slices.Concat(bpkg.CFiles, bpkg.CXXFiles, bpkg.MFiles, bpkg.HFiles, bpkg.SFiles, bpkg.SwigFiles, bpkg.SwigCXXFiles, bpkg.SysoFiles),
EmbedPatterns: bpkg.EmbedPatterns,
Imports: imports,
ExportFile: exportFile,
}
}
30 changes: 17 additions & 13 deletions tools/please_go/packageinfo/packageinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,11 @@ func WritePackageInfo(importPath string, srcRoot string, imports map[string]stri
} else if err != nil {
return fmt.Errorf("failed to import directory %s: %w", dir, err)
}
pkg := fromBuildPackage(bpkg, subrepo, module)

if subrepo != "" {
_, pkgPath, ok := strings.Cut(imports[pkg.PkgPath], pkg.PkgPath)
if !ok {
return fmt.Errorf("Cannot determine export file path for package %s from %s", pkg.PkgPath, imports[pkg.PkgPath])
}
// This is a really gross hack to sneak both paths through the one field.
pkg.ExportFile = filepath.Join(subrepo, pkgPath) + "|" + imports[pkg.PkgPath]
} else {
pkg.ExportFile = imports[pkg.PkgPath]
pkg, err := fromBuildPackage(bpkg, subrepo, module, imports[importPath])
if err != nil {
return fmt.Errorf("creating packages.Package: %w", err)
}

pkgs = append(pkgs, pkg)
}

Expand Down Expand Up @@ -95,7 +88,8 @@ func fromBuildPackage(
bpkg *build.Package,
subrepo string,
module string,
) *packages.Package {
exportFile string,
) (*packages.Package, error) {
goFiles := make([]string, len(bpkg.GoFiles)+len(bpkg.TestGoFiles)+len(bpkg.XTestGoFiles))
compiledGoFiles := make([]string, len(goFiles))
for i, file := range slices.Concat(bpkg.GoFiles, bpkg.TestGoFiles, bpkg.XTestGoFiles) {
Expand All @@ -115,6 +109,15 @@ func fromBuildPackage(
imports[imp] = &packages.Package{ID: imp, PkgPath: imp}
}

if subrepo != "" {
_, pkgPath, ok := strings.Cut(exportFile, bpkg.ImportPath)
if !ok {
return nil, fmt.Errorf("Cannot determine export file path for package %s from %s", bpkg.ImportPath, exportFile)
}
// This is a really gross hack to sneak both paths through the one field.
exportFile = filepath.Join(subrepo, pkgPath) + "|" + exportFile
}

name := bpkg.Name
id := bpkg.ImportPath
if len(bpkg.XTestGoFiles) > 0 || len(bpkg.XTestImports) > 0 {
Expand All @@ -130,9 +133,10 @@ func fromBuildPackage(
GoFiles: goFiles,
CompiledGoFiles: compiledGoFiles,
OtherFiles: slices.Concat(bpkg.CFiles, bpkg.CXXFiles, bpkg.MFiles, bpkg.HFiles, bpkg.SFiles, bpkg.SwigFiles, bpkg.SwigCXXFiles, bpkg.SysoFiles),
ExportFile: exportFile,
EmbedPatterns: bpkg.EmbedPatterns,
Imports: imports,
}
}, nil
}

// modulePath returns the import path for a module, or the given one if the module isn't set.
Expand Down
63 changes: 63 additions & 0 deletions tools/please_go/packageinfo/packageinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,66 @@ func Hello() {

assert.Equal(t, expected, pkgs)
}

func TestWritePackageInfo_ExternalTest(t *testing.T) {
tmpDir := t.TempDir()

// Create a simple package "foo" with only an external test file
fooDir := filepath.Join(tmpDir, "foo")
err := os.MkdirAll(fooDir, 0755)
require.NoError(t, err)

testSrc := `package foo_test

import (
"testing"
"module/foo"
)

func TestHello(t *testing.T) {
}
`
err = os.WriteFile(filepath.Join(fooDir, "foo_test.go"), []byte(testSrc), 0644)
require.NoError(t, err)

imports := map[string]string{
"module/foo/foo_test_lib": "foo/foo_test_lib.a",
}

var buf bytes.Buffer
err = WritePackageInfo(
"module/foo/foo_test_lib",
fooDir,
imports,
"",
"",
true, // includeTests = true
&buf,
)
require.NoError(t, err)

var pkgs []*packages.Package
err = json.Unmarshal(buf.Bytes(), &pkgs)
require.NoError(t, err)

expected := []*packages.Package{
{
ID: "module/foo/foo_test_lib_test",
Name: "foo_test",
PkgPath: "module/foo/foo_test_lib_test",
GoFiles: []string{filepath.Join(fooDir, "foo_test.go")},
CompiledGoFiles: []string{filepath.Join(fooDir, "foo_test.go")},
ExportFile: "foo/foo_test_lib.a",
Imports: map[string]*packages.Package{
"module/foo": {
ID: "module/foo",
},
"testing": {
ID: "testing",
},
},
},
}

assert.Equal(t, expected, pkgs)
}
Loading