Skip to content

Commit c6de69c

Browse files
authored
feat(internal/godocfx): add status to packages and TOCs (#4547)
1 parent 653b82b commit c6de69c

File tree

4 files changed

+109
-19
lines changed

4 files changed

+109
-19
lines changed

internal/godocfx/parse.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ type tableOfContents []*tocItem
4949

5050
// tocItem is an item in a TOC.
5151
type tocItem struct {
52-
UID string `yaml:"uid,omitempty"`
53-
Name string `yaml:"name,omitempty"`
54-
Items []*tocItem `yaml:"items,omitempty"`
55-
Href string `yaml:"href,omitempty"`
52+
UID string `yaml:"uid,omitempty"`
53+
Name string `yaml:"name,omitempty"`
54+
Items []*tocItem `yaml:"items,omitempty"`
55+
Href string `yaml:"href,omitempty"`
56+
Status string `yaml:"status,omitempty"`
5657
}
5758

5859
func (t *tocItem) addItem(i *tocItem) {
@@ -169,6 +170,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string, filter [
169170
Type: "package",
170171
Examples: processExamples(pi.Doc.Examples, pi.Fset),
171172
AltLink: "https://pkg.go.dev/" + pi.Doc.ImportPath,
173+
Status: pi.Status,
172174
}
173175
pkgPage := &page{Items: []*item{pkgItem}}
174176
pages[pi.Doc.ImportPath] = pkgPage
@@ -545,12 +547,6 @@ func buildTOC(mod string, pis []pkgload.Info, extraFiles []extraFile) tableOfCon
545547
Name: mod,
546548
}
547549

548-
// Assume the module root has a package.
549-
modTOC.addItem(&tocItem{
550-
UID: mod,
551-
Name: mod,
552-
})
553-
554550
for _, ef := range extraFiles {
555551
modTOC.addItem(&tocItem{
556552
Href: ef.dstRelativePath,
@@ -560,31 +556,35 @@ func buildTOC(mod string, pis []pkgload.Info, extraFiles []extraFile) tableOfCon
560556

561557
toc = append(toc, modTOC)
562558

563-
if len(pis) == 1 {
564-
// The module only has one package.
565-
return toc
566-
}
567-
568559
trimmedPkgs := []string{}
560+
statuses := map[string]string{}
569561
for _, pi := range pis {
570562
importPath := pi.Doc.ImportPath
571563
if importPath == mod {
564+
// Add the module root package immediately with the full name.
565+
modTOC.addItem(&tocItem{
566+
UID: mod,
567+
Name: mod,
568+
Status: pi.Status,
569+
})
572570
continue
573571
}
574572
if !strings.HasPrefix(importPath, mod) {
575573
panic(fmt.Sprintf("Package %q does not start with %q, should never happen", importPath, mod))
576574
}
577575
trimmed := strings.TrimPrefix(importPath, mod+"/")
578576
trimmedPkgs = append(trimmedPkgs, trimmed)
577+
statuses[trimmed] = pi.Status
579578
}
580579

581580
sort.Strings(trimmedPkgs)
582581

583582
for _, trimmed := range trimmedPkgs {
584583
uid := mod + "/" + trimmed
585584
pkgTOCItem := &tocItem{
586-
UID: uid,
587-
Name: trimmed,
585+
UID: uid,
586+
Name: trimmed,
587+
Status: statuses[trimmed],
588588
}
589589
modTOC.addItem(pkgTOCItem)
590590
}

internal/godocfx/pkgload/load.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type Info struct {
3434
Fset *token.FileSet
3535
// ImportRenames is a map from package path to local name or "".
3636
ImportRenames map[string]string
37+
Status string
3738
}
3839

3940
// Load parses the given glob and returns info for the matching packages.
@@ -157,12 +158,36 @@ func Load(glob, workingDir string, filter []string) ([]Info, error) {
157158
Doc: docPkg,
158159
Fset: fset,
159160
ImportRenames: imports,
161+
Status: pkgStatus(pkgPath, docPkg.Doc),
160162
})
161163
}
162164

163165
return result, nil
164166
}
165167

168+
// pkgStatus returns the status of the given package with the
169+
// given GoDoc.
170+
//
171+
// pkgStatus does not use repo-metadata-full.json because it's
172+
// not available for all modules nor all versions.
173+
func pkgStatus(importPath, doc string) string {
174+
switch {
175+
case strings.Contains(doc, "\nDeprecated:"):
176+
return "deprecated"
177+
case strings.Contains(doc, "This package is in alpha"):
178+
return "alpha"
179+
case strings.Contains(doc, "This package is in beta"):
180+
return "beta"
181+
182+
case strings.Contains(importPath, "alpha"):
183+
return "alpha"
184+
case strings.Contains(importPath, "beta"):
185+
return "beta"
186+
}
187+
188+
return ""
189+
}
190+
166191
func hasPrefix(s string, prefixes []string) bool {
167192
for _, prefix := range prefixes {
168193
if strings.HasPrefix(s, prefix) {
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package pkgload
16+
17+
import "testing"
18+
19+
func TestPkgStatus(t *testing.T) {
20+
tests := []struct {
21+
importPath string
22+
doc string
23+
want string
24+
}{
25+
{
26+
importPath: "cloud.google.com/go",
27+
want: "",
28+
},
29+
{
30+
importPath: "cloud.google.com/go/storage/v1alpha1",
31+
want: "alpha",
32+
},
33+
{
34+
importPath: "cloud.google.com/go/storage/v2beta2",
35+
want: "beta",
36+
},
37+
{
38+
doc: "NOTE: This package is in beta. It is not stable, and may be subject to changes.",
39+
want: "beta",
40+
},
41+
{
42+
doc: "NOTE: This package is in alpha. It is not stable, and is likely to change.",
43+
want: "alpha",
44+
},
45+
{
46+
doc: "Package foo is great\nDeprecated: not anymore",
47+
want: "deprecated",
48+
},
49+
{
50+
importPath: "cloud.google.com/go/storage/v1alpha1",
51+
doc: "Package foo is great\nDeprecated: not anymore",
52+
want: "deprecated", // Deprecated comes before alpha and beta.
53+
},
54+
{
55+
importPath: "cloud.google.com/go/storage/v1beta1",
56+
doc: "Package foo is great\nDeprecated: not anymore",
57+
want: "deprecated", // Deprecated comes before alpha and beta.
58+
},
59+
}
60+
for _, test := range tests {
61+
if got := pkgStatus(test.importPath, test.doc); got != test.want {
62+
t.Errorf("pkgStatus(%q, %q) got %q, want %q", test.importPath, test.doc, got, test.want)
63+
}
64+
}
65+
}

internal/godocfx/testdata/golden/toc.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
- uid: cloud.google.com/go/storage
33
name: cloud.google.com/go/storage
44
items:
5-
- uid: cloud.google.com/go/storage
6-
name: cloud.google.com/go/storage
75
- name: README
86
href: pkg-readme.md
7+
- uid: cloud.google.com/go/storage
8+
name: cloud.google.com/go/storage

0 commit comments

Comments
 (0)