internal/frontend: avoid decoding source twice
We were decoding the source for both doc rendering and getting the
list of source files. Decode it just once.
Change-Id: Ib1eaa71d06ea1afd53e1b17e6e460bf75f1910b6
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/262579
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/internal/frontend/doc.go b/internal/frontend/doc.go
index c81eef5..c80a6cc 100644
--- a/internal/frontend/doc.go
+++ b/internal/frontend/doc.go
@@ -30,12 +30,18 @@
// fetchDocumentationDetails returns a DocumentationDetails.
func fetchDocumentationDetails(ctx context.Context, ds internal.DataSource, um *internal.UnitMeta) (_ *DocumentationDetails, err error) {
+ derrors.Wrap(&err, "fetchDocumentationDetails(%q, %q, %q)", um.Path, um.ModulePath, um.Version)
+
u, err := ds.GetUnit(ctx, um, internal.WithDocumentation)
if err != nil {
return nil, err
}
if experiment.IsActive(ctx, internal.ExperimentFrontendRenderDoc) && len(u.Documentation.Source) > 0 {
- dd, err := renderDoc(ctx, u)
+ docPkg, err := godoc.DecodePackage(u.Documentation.Source)
+ if err != nil {
+ return nil, err
+ }
+ dd, err := renderDoc(ctx, u, docPkg)
if err != nil {
log.Errorf(ctx, "render doc failed: %v", err)
// Fall through to use stored doc.
@@ -50,15 +56,11 @@
}, nil
}
-func renderDoc(ctx context.Context, u *internal.Unit) (_ *DocumentationDetails, err error) {
+func renderDoc(ctx context.Context, u *internal.Unit, docPkg *godoc.Package) (_ *DocumentationDetails, err error) {
defer derrors.Wrap(&err, "renderDoc")
defer middleware.ElapsedStat(ctx, "renderDoc")()
start := time.Now()
- docPkg, err := godoc.DecodePackage(u.Documentation.Source)
- if err != nil {
- return nil, err
- }
modInfo := &godoc.ModuleInfo{
ModulePath: u.ModulePath,
ResolvedVersion: u.Version,
@@ -83,11 +85,7 @@
}
// sourceFiles returns the .go files for a package.
-func sourceFiles(u *internal.Unit) ([]*File, error) {
- docPkg, err := godoc.DecodePackage(u.Documentation.Source)
- if err != nil {
- return nil, err
- }
+func sourceFiles(u *internal.Unit, docPkg *godoc.Package) []*File {
var files []*File
for _, f := range docPkg.Files {
if strings.HasSuffix(f.Name, "_test.go") {
@@ -98,7 +96,7 @@
URL: u.SourceInfo.FileURL(path.Join(internal.Suffix(u.Path, u.ModulePath), f.Name)),
})
}
- return files, nil
+ return files
}
// fileSource returns the original filepath in the module zip where the given
diff --git a/internal/frontend/unit_main.go b/internal/frontend/unit_main.go
index 76c8050..b7c6382 100644
--- a/internal/frontend/unit_main.go
+++ b/internal/frontend/unit_main.go
@@ -122,7 +122,11 @@
files []*File
)
if unit.Documentation != nil {
- docHTML := getHTML(ctx, unit)
+ docPkg, err := godoc.DecodePackage(unit.Documentation.Source)
+ if err != nil {
+ return nil, err
+ }
+ docHTML := getHTML(ctx, unit, docPkg)
// TODO: Deprecate godoc.Parse. The sidenav and body can
// either be rendered using separate functions, or all this content can
// be passed to the template via the UnitPage struct.
@@ -146,7 +150,7 @@
end()
end = middleware.ElapsedStat(ctx, "sourceFiles")
- files, err = sourceFiles(unit)
+ files = sourceFiles(unit, docPkg)
end()
if err != nil {
return nil, err
@@ -234,9 +238,9 @@
return sdirs
}
-func getHTML(ctx context.Context, u *internal.Unit) safehtml.HTML {
+func getHTML(ctx context.Context, u *internal.Unit, docPkg *godoc.Package) safehtml.HTML {
if experiment.IsActive(ctx, internal.ExperimentFrontendRenderDoc) && len(u.Documentation.Source) > 0 {
- dd, err := renderDoc(ctx, u)
+ dd, err := renderDoc(ctx, u, docPkg)
if err != nil {
log.Errorf(ctx, "render doc failed: %v", err)
// Fall through to use stored doc.