@@ -25,16 +25,19 @@ package main
25
25
26
26
import (
27
27
"bytes"
28
+ "encoding/json"
28
29
"fmt"
29
30
"go/format"
30
31
"go/printer"
31
32
"go/token"
32
33
"log"
34
+ "net/http"
33
35
"os"
34
36
"path/filepath"
35
37
"regexp"
36
38
"sort"
37
39
"strings"
40
+ "sync"
38
41
39
42
goldmarkcodeblock "cloud.google.com/go/internal/godocfx/goldmark-codeblock"
40
43
"cloud.google.com/go/internal/godocfx/pkgload"
@@ -84,18 +87,19 @@ type example struct {
84
87
85
88
// item represents a DocFX item.
86
89
type item struct {
87
- UID string `yaml:"uid"`
88
- Name string `yaml:"name,omitempty"`
89
- ID string `yaml:"id,omitempty"`
90
- Summary string `yaml:"summary,omitempty"`
91
- Parent string `yaml:"parent,omitempty"`
92
- Type string `yaml:"type,omitempty"`
93
- Langs []string `yaml:"langs,omitempty"`
94
- Syntax syntax `yaml:"syntax,omitempty"`
95
- Examples []example `yaml:"codeexamples,omitempty"`
96
- Children []child `yaml:"children,omitempty"`
97
- AltLink string `yaml:"alt_link,omitempty"`
98
- Status string `yaml:"status,omitempty"`
90
+ UID string `yaml:"uid"`
91
+ Name string `yaml:"name,omitempty"`
92
+ ID string `yaml:"id,omitempty"`
93
+ Summary string `yaml:"summary,omitempty"`
94
+ Parent string `yaml:"parent,omitempty"`
95
+ Type string `yaml:"type,omitempty"`
96
+ Langs []string `yaml:"langs,omitempty"`
97
+ Syntax syntax `yaml:"syntax,omitempty"`
98
+ Examples []example `yaml:"codeexamples,omitempty"`
99
+ Children []child `yaml:"children,omitempty"`
100
+ AltLink string `yaml:"alt_link,omitempty"`
101
+ Status string `yaml:"status,omitempty"`
102
+ FriendlyAPIName string `yaml:"friendlyApiName,omitempty"`
99
103
}
100
104
101
105
func (p * page ) addItem (i * item ) {
@@ -125,7 +129,7 @@ type result struct {
125
129
// workingDir is the directory to use to run go commands.
126
130
//
127
131
// optionalExtraFiles is a list of paths relative to the module root to include.
128
- func parse (glob string , workingDir string , optionalExtraFiles []string , filter []string ) (* result , error ) {
132
+ func parse (glob string , workingDir string , optionalExtraFiles []string , filter []string , namer * friendlyAPINamer ) (* result , error ) {
129
133
pages := map [string ]* page {}
130
134
131
135
pkgInfos , err := pkgload .Load (glob , workingDir , filter )
@@ -162,16 +166,21 @@ func parse(glob string, workingDir string, optionalExtraFiles []string, filter [
162
166
for _ , pi := range pkgInfos {
163
167
link := newLinker (pi )
164
168
topLevelDecls := pkgsite .TopLevelDecls (pi .Doc )
169
+ friendly , err := namer .friendlyAPIName (pi .Doc .ImportPath )
170
+ if err != nil {
171
+ return nil , err
172
+ }
165
173
pkgItem := & item {
166
- UID : pi .Doc .ImportPath ,
167
- Name : pi .Doc .ImportPath ,
168
- ID : pi .Doc .Name ,
169
- Summary : toHTML (pi .Doc .Doc ),
170
- Langs : onlyGo ,
171
- Type : "package" ,
172
- Examples : processExamples (pi .Doc .Examples , pi .Fset ),
173
- AltLink : "https://pkg.go.dev/" + pi .Doc .ImportPath ,
174
- Status : pi .Status ,
174
+ UID : pi .Doc .ImportPath ,
175
+ Name : pi .Doc .ImportPath ,
176
+ ID : pi .Doc .Name ,
177
+ Summary : toHTML (pi .Doc .Doc ),
178
+ Langs : onlyGo ,
179
+ Type : "package" ,
180
+ Examples : processExamples (pi .Doc .Examples , pi .Fset ),
181
+ AltLink : "https://pkg.go.dev/" + pi .Doc .ImportPath ,
182
+ Status : pi .Status ,
183
+ FriendlyAPIName : friendly ,
175
184
}
176
185
pkgPage := & page {Items : []* item {pkgItem }}
177
186
pages [pi .Doc .ImportPath ] = pkgPage
@@ -640,3 +649,68 @@ func hasPrefix(s string, prefixes []string) bool {
640
649
}
641
650
return false
642
651
}
652
+
653
+ // repoMetadata is the JSON format of the .repo-metadata-full.json file.
654
+ // See https://raw.githubusercontent.com/googleapis/google-cloud-go/main/internal/.repo-metadata-full.json.
655
+ type repoMetadata map [string ]repoMetadataItem
656
+
657
+ type repoMetadataItem struct {
658
+ Description string `json:"description"`
659
+ }
660
+
661
+ type friendlyAPINamer struct {
662
+ // metaURL is the URL to .repo-metadata-full.json, which contains metadata
663
+ // about packages in this repo. See
664
+ // https://raw.githubusercontent.com/googleapis/google-cloud-go/main/internal/.repo-metadata-full.json.
665
+ metaURL string
666
+
667
+ // metadata caches the repo metadata results.
668
+ metadata repoMetadata
669
+ // getOnce ensures we only fetch the metadata JSON once.
670
+ getOnce sync.Once
671
+ }
672
+
673
+ // vNumberRE is a heuristic for API versions.
674
+ var vNumberRE = regexp .MustCompile (`apiv[0-9][^/]*` )
675
+
676
+ // friendlyAPIName returns the friendlyAPIName for the given import path.
677
+ // We rely on the .repo-metadata-full.json file to get the description of the
678
+ // API for the given import path. We use the importPath to parse out the
679
+ // API version, since that isn't included in the metadata.
680
+ //
681
+ // If no API description is found, friendlyAPIName returns "".
682
+ // If no API version is found, friendlyAPIName only returns the description.
683
+ //
684
+ // See https://github.com/googleapis/google-cloud-go/issues/5949.
685
+ func (d * friendlyAPINamer ) friendlyAPIName (importPath string ) (string , error ) {
686
+ var err error
687
+ d .getOnce .Do (func () {
688
+ resp , getErr := http .Get (d .metaURL )
689
+ if err != nil {
690
+ err = fmt .Errorf ("error getting repo metadata: %v" , getErr )
691
+ return
692
+ }
693
+ defer resp .Body .Close ()
694
+ if decodeErr := json .NewDecoder (resp .Body ).Decode (& d .metadata ); err != nil {
695
+ err = fmt .Errorf ("failed to decode repo metadata: %v" , decodeErr )
696
+ return
697
+ }
698
+ })
699
+ if err != nil {
700
+ return "" , err
701
+ }
702
+ if d .metadata == nil {
703
+ return "" , fmt .Errorf ("no metadata found: earlier error fetching?" )
704
+ }
705
+ pkg , ok := d .metadata [importPath ]
706
+ if ! ok {
707
+ return "" , nil
708
+ }
709
+
710
+ if apiV := vNumberRE .FindString (importPath ); apiV != "" {
711
+ version := strings .TrimPrefix (apiV , "api" )
712
+ return fmt .Sprintf ("%s %s" , pkg .Description , version ), nil
713
+ }
714
+
715
+ return pkg .Description , nil
716
+ }
0 commit comments