internal/load: add package
Package load is added for loading Go packages from source.
Change-Id: I13f113b3e0eaa2c3ba131941af0bafb82f740c49
Reviewed-on: https://go-review.googlesource.com/c/pkgsite-metrics/+/465188
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Julie Qiu <julieqiu@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Julie Qiu <julieqiu@google.com>
Run-TryBot: Julie Qiu <julieqiu@google.com>
diff --git a/internal/load/load.go b/internal/load/load.go
new file mode 100644
index 0000000..6083328
--- /dev/null
+++ b/internal/load/load.go
@@ -0,0 +1,49 @@
+// Copyright 2022 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.
+
+package load
+
+import (
+ "fmt"
+ "go/build"
+ "strings"
+
+ "golang.org/x/tools/go/packages"
+)
+
+// DefaultConfig returns a packages.Config suitable for LoadPackages.
+func DefaultConfig() *packages.Config {
+ return &packages.Config{
+ Mode: packages.NeedName | packages.NeedImports | packages.NeedTypes |
+ packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedDeps |
+ packages.NeedModule,
+ Tests: false,
+ BuildFlags: []string{fmt.Sprintf("-tags=%s", strings.Join(build.Default.BuildTags, ","))},
+ }
+}
+
+// Packages loads Go packages from source.
+// In addition to the packages, it returns all errors from loading the packages.
+// If the third return value is non-nil, that indicates a problem performing the load itself,
+// not a problem with the code being loaded.
+func Packages(cfg *packages.Config, patterns ...string) ([]*packages.Package, []error, error) {
+ pkgs, err := packages.Load(cfg, patterns...)
+ if err != nil {
+ return nil, nil, err
+ }
+ var errors []error
+ packages.Visit(pkgs, nil, func(pkg *packages.Package) {
+ for _, err := range pkg.Errors {
+ errors = append(errors, err)
+ }
+ })
+ // Truncate the list of errors. Sometimes the full list is so large that the BigQuery
+ // upload payload exceeds the maximum size. And even when that doesn't happen, more
+ // than a few errors is just a waste of space.
+ const maxErrors = 20
+ if len(errors) > maxErrors {
+ errors = append(errors[:maxErrors], fmt.Errorf("... and %d more errors", len(errors)-maxErrors))
+ }
+ return pkgs, errors, nil
+}