Skip to content

Commit ef2b90e

Browse files
authored
feat(internal): generate region tags for snippets (#3962)
I found a couple "manual" clients that needed repo-metadata entries, so I added them and included the updated JSON. There are many packages where it doesn't make sense to generate snippets with any sort of correct region tag. So, I just skipped them. We can come back if needed. The region tags end up slightly repetitive (e.g. accessapproval_generated_accessapproval_apiv1_Client_UpdateAccessApprovalSettings), but I think they're more predictable as-is because the package path may not always line up with the API shortname. More in depth configuration of the region tag would probably make things considerably more complex (need to associate every example with the underlying RPC?)
1 parent 2ed94d5 commit ef2b90e

File tree

11 files changed

+151
-14
lines changed

11 files changed

+151
-14
lines changed

internal/.repo-metadata-full.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@
263263
"docs_url": "https://pkg.go.dev/cloud.google.com/go/cloudtasks/apiv2beta3",
264264
"release_level": "beta"
265265
},
266+
"cloud.google.com/go/compute/metadata": {
267+
"distribution_name": "cloud.google.com/go/compute/metadata",
268+
"description": "Service Metadata API",
269+
"language": "Go",
270+
"client_library_type": "manual",
271+
"docs_url": "https://pkg.go.dev/cloud.google.com/go/compute/metadata",
272+
"release_level": "ga"
273+
},
266274
"cloud.google.com/go/container/apiv1": {
267275
"distribution_name": "cloud.google.com/go/container/apiv1",
268276
"description": "Kubernetes Engine API",
@@ -455,6 +463,14 @@
455463
"docs_url": "https://pkg.go.dev/cloud.google.com/go/functions/apiv1",
456464
"release_level": "ga"
457465
},
466+
"cloud.google.com/go/functions/metadata": {
467+
"distribution_name": "cloud.google.com/go/functions/metadata",
468+
"description": "Cloud Functions",
469+
"language": "Go",
470+
"client_library_type": "manual",
471+
"docs_url": "https://pkg.go.dev/cloud.google.com/go/functions/metadata",
472+
"release_level": "alpha"
473+
},
458474
"cloud.google.com/go/gaming/apiv1": {
459475
"distribution_name": "cloud.google.com/go/gaming/apiv1",
460476
"description": "Game Services API",

internal/gapicgen/generator/gapics.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ func (g *GapicGenerator) Regen(ctx context.Context) error {
8282
}
8383

8484
snippetDir := filepath.Join(g.googleCloudDir, "internal", "generated", "snippets")
85-
if err := gensnippets.Generate(g.googleCloudDir, snippetDir); err != nil {
85+
apiShortnames, err := g.parseAPIShortnames(microgenGapicConfigs, manualEntries)
86+
if err != nil {
87+
return err
88+
}
89+
if err := gensnippets.Generate(g.googleCloudDir, snippetDir, apiShortnames); err != nil {
8690
return fmt.Errorf("error generating snippets: %v", err)
8791
}
8892
if err := replaceAllForSnippets(g.googleCloudDir, snippetDir); err != nil {
@@ -329,6 +333,22 @@ var manualEntries = []manifestEntry{
329333
DocsURL: "https://pkg.go.dev/cloud.google.com/go/profiler",
330334
ReleaseLevel: "ga",
331335
},
336+
{
337+
DistributionName: "cloud.google.com/go/compute/metadata",
338+
Description: "Service Metadata API",
339+
Language: "Go",
340+
ClientLibraryType: "manual",
341+
DocsURL: "https://pkg.go.dev/cloud.google.com/go/compute/metadata",
342+
ReleaseLevel: "ga",
343+
},
344+
{
345+
DistributionName: "cloud.google.com/go/functions/metadata",
346+
Description: "Cloud Functions",
347+
Language: "Go",
348+
ClientLibraryType: "manual",
349+
DocsURL: "https://pkg.go.dev/cloud.google.com/go/functions/metadata",
350+
ReleaseLevel: "alpha",
351+
},
332352
// Manuals with a GAPIC.
333353
{
334354
DistributionName: "cloud.google.com/go/errorreporting",
@@ -425,3 +445,32 @@ func (g *GapicGenerator) copyMicrogenFiles() error {
425445
c.Dir = g.googleCloudDir
426446
return c.Run()
427447
}
448+
449+
func (g *GapicGenerator) parseAPIShortnames(confs []*microgenConfig, manualEntries []manifestEntry) (map[string]string, error) {
450+
shortnames := map[string]string{}
451+
for _, conf := range confs {
452+
yamlPath := filepath.Join(g.googleapisDir, conf.apiServiceConfigPath)
453+
yamlFile, err := os.Open(yamlPath)
454+
if err != nil {
455+
return nil, err
456+
}
457+
config := struct {
458+
Name string `yaml:"name"`
459+
}{}
460+
if err := yaml.NewDecoder(yamlFile).Decode(&config); err != nil {
461+
return nil, fmt.Errorf("Decode: %v", err)
462+
}
463+
shortname := strings.TrimSuffix(config.Name, ".googleapis.com")
464+
shortnames[conf.importPath] = shortname
465+
}
466+
467+
// Do our best for manuals.
468+
for _, manual := range manualEntries {
469+
p := strings.TrimPrefix(manual.DistributionName, "cloud.google.com/go/")
470+
if strings.Contains(p, "/") {
471+
p = p[0:strings.Index(p, "/")]
472+
}
473+
shortnames[manual.DistributionName] = p
474+
}
475+
return shortnames, nil
476+
}

internal/gapicgen/gensnippets/gensnippets.go

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import (
3434
)
3535

3636
// Generate reads all modules in rootDir and outputs their examples in outDir.
37-
func Generate(rootDir, outDir string) error {
37+
func Generate(rootDir, outDir string, apiShortnames map[string]string) error {
3838
if rootDir == "" {
3939
rootDir = "."
4040
}
@@ -60,18 +60,22 @@ func Generate(rootDir, outDir string) error {
6060
log.Printf("Processing examples in %v directories: %q\n", len(dirs), dirs)
6161

6262
trimPrefix := "cloud.google.com/go"
63+
errs := []error{}
6364
for _, dir := range dirs {
6465
// Load does not look at nested modules.
6566
pis, err := pkgload.Load("./...", dir, nil)
6667
if err != nil {
6768
return fmt.Errorf("failed to load packages: %v", err)
6869
}
6970
for _, pi := range pis {
70-
if err := processExamples(pi.Doc, pi.Fset, trimPrefix, outDir); err != nil {
71-
return fmt.Errorf("failed to process examples: %v", err)
71+
if err := processExamples(pi.Doc, pi.Fset, trimPrefix, outDir, apiShortnames); err != nil {
72+
errs = append(errs, fmt.Errorf("failed to process examples: %v", err))
7273
}
7374
}
7475
}
76+
if len(errs) > 0 {
77+
log.Fatal(errs)
78+
}
7579

7680
if len(dirs) > 0 {
7781
cmd := execabs.Command("goimports", "-w", ".")
@@ -84,11 +88,48 @@ func Generate(rootDir, outDir string) error {
8488
return nil
8589
}
8690

87-
func processExamples(pkg *doc.Package, fset *token.FileSet, trimPrefix, outDir string) error {
91+
var skip = map[string]bool{
92+
"cloud.google.com/go": true, // No product for root package.
93+
"cloud.google.com/go/civil": true, // General time/date package.
94+
"cloud.google.com/go/cloudbuild/apiv1": true, // Has v2.
95+
"cloud.google.com/go/cmd/go-cloud-debug-agent": true, // Command line tool.
96+
"cloud.google.com/go/container": true, // Deprecated.
97+
"cloud.google.com/go/containeranalysis/apiv1": true, // Accidental beta at wrong path?
98+
"cloud.google.com/go/grafeas/apiv1": true, // With containeranalysis.
99+
"cloud.google.com/go/httpreplay": true, // Helper.
100+
"cloud.google.com/go/httpreplay/cmd/httpr": true, // Helper.
101+
"cloud.google.com/go/longrunning": true, // Helper.
102+
"cloud.google.com/go/monitoring/apiv3": true, // Has v2.
103+
"cloud.google.com/go/translate": true, // Has newer version.
104+
}
105+
106+
func processExamples(pkg *doc.Package, fset *token.FileSet, trimPrefix, outDir string, apiShortnames map[string]string) error {
107+
if skip[pkg.ImportPath] {
108+
return nil
109+
}
88110
trimmed := strings.TrimPrefix(pkg.ImportPath, trimPrefix)
89111
outDir = filepath.Join(outDir, trimmed)
90112

91-
regionTag := "generated" + strings.ReplaceAll(trimmed, "/", "_")
113+
shortname, ok := apiShortnames[pkg.ImportPath]
114+
if !ok {
115+
// Do our best to find a shortname. For example,
116+
// cloud.google.com/go/bigtable/bttest should lead to
117+
// cloud.google.com/go/bigtable.
118+
bestMatch := ""
119+
for path := range apiShortnames {
120+
if strings.HasPrefix(pkg.ImportPath, path) {
121+
if len(path) > len(bestMatch) {
122+
bestMatch = path
123+
}
124+
}
125+
}
126+
if bestMatch == "" {
127+
return fmt.Errorf("could not find API shortname for %v", pkg.ImportPath)
128+
}
129+
log.Printf("The best match for %q is %q", pkg.ImportPath, bestMatch)
130+
shortname = apiShortnames[bestMatch]
131+
}
132+
regionTag := shortname + "_generated" + strings.ReplaceAll(trimmed, "/", "_")
92133

93134
// Note: variables and constants don't have examples.
94135

@@ -166,18 +207,17 @@ func writeExamples(outDir string, exs []*doc.Example, fset *token.FileSet, regio
166207
if _, err := f.WriteString(header()); err != nil {
167208
return err
168209
}
169-
// TODO(tbpg): print the right region tag.
170-
// tag := regionTag + "_" + ex.Name
210+
tag := regionTag + "_" + ex.Name
171211
// Include an extra newline to keep separate from the package declaration.
172-
// if _, err := fmt.Fprintf(f, "// [START %v]\n\n", tag); err != nil {
173-
// return err
174-
// }
212+
if _, err := fmt.Fprintf(f, "// [START %v]\n\n", tag); err != nil {
213+
return err
214+
}
175215
if _, err := f.WriteString(s); err != nil {
176216
return err
177217
}
178-
// if _, err := fmt.Fprintf(f, "// [END %v]\n", tag); err != nil {
179-
// return err
180-
// }
218+
if _, err := fmt.Fprintf(f, "// [END %v]\n", tag); err != nil {
219+
return err
220+
}
181221
}
182222
return nil
183223
}

internal/generated/snippets/accessapproval/apiv1/Client/ApproveApprovalRequest/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// [START accessapproval_generated_accessapproval_apiv1_Client_ApproveApprovalRequest]
16+
1517
package main
1618

1719
import (
@@ -40,3 +42,5 @@ func main() {
4042
// TODO: Use resp.
4143
_ = resp
4244
}
45+
46+
// [END accessapproval_generated_accessapproval_apiv1_Client_ApproveApprovalRequest]

internal/generated/snippets/accessapproval/apiv1/Client/DeleteAccessApprovalSettings/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// [START accessapproval_generated_accessapproval_apiv1_Client_DeleteAccessApprovalSettings]
16+
1517
package main
1618

1719
import (
@@ -36,3 +38,5 @@ func main() {
3638
// TODO: Handle error.
3739
}
3840
}
41+
42+
// [END accessapproval_generated_accessapproval_apiv1_Client_DeleteAccessApprovalSettings]

internal/generated/snippets/accessapproval/apiv1/Client/DismissApprovalRequest/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// [START accessapproval_generated_accessapproval_apiv1_Client_DismissApprovalRequest]
16+
1517
package main
1618

1719
import (
@@ -40,3 +42,5 @@ func main() {
4042
// TODO: Use resp.
4143
_ = resp
4244
}
45+
46+
// [END accessapproval_generated_accessapproval_apiv1_Client_DismissApprovalRequest]

internal/generated/snippets/accessapproval/apiv1/Client/GetAccessApprovalSettings/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// [START accessapproval_generated_accessapproval_apiv1_Client_GetAccessApprovalSettings]
16+
1517
package main
1618

1719
import (
@@ -40,3 +42,5 @@ func main() {
4042
// TODO: Use resp.
4143
_ = resp
4244
}
45+
46+
// [END accessapproval_generated_accessapproval_apiv1_Client_GetAccessApprovalSettings]

internal/generated/snippets/accessapproval/apiv1/Client/GetApprovalRequest/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// [START accessapproval_generated_accessapproval_apiv1_Client_GetApprovalRequest]
16+
1517
package main
1618

1719
import (
@@ -40,3 +42,5 @@ func main() {
4042
// TODO: Use resp.
4143
_ = resp
4244
}
45+
46+
// [END accessapproval_generated_accessapproval_apiv1_Client_GetApprovalRequest]

internal/generated/snippets/accessapproval/apiv1/Client/ListApprovalRequests/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// [START accessapproval_generated_accessapproval_apiv1_Client_ListApprovalRequests]
16+
1517
package main
1618

1719
import (
@@ -48,3 +50,5 @@ func main() {
4850
_ = resp
4951
}
5052
}
53+
54+
// [END accessapproval_generated_accessapproval_apiv1_Client_ListApprovalRequests]

internal/generated/snippets/accessapproval/apiv1/Client/NewClient/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// [START accessapproval_generated_accessapproval_apiv1_NewClient]
16+
1517
package main
1618

1719
import (
@@ -29,3 +31,5 @@ func main() {
2931
// TODO: Use client.
3032
_ = c
3133
}
34+
35+
// [END accessapproval_generated_accessapproval_apiv1_NewClient]

0 commit comments

Comments
 (0)