internal/gapicgen: generate a package manifest

I output the file to internal/.repo-metadata-full.json, but I'm open to
other paths or filenames.

This only covers packages generated by the microgenerator. I left a TODO
to include the other packages/clients. Where it makes sense, we may just
wait for the microgenerator to pick the rest up.

Change-Id: I29aa50103fce4d67cf9a0047a2eac5d6076609d9
Reviewed-on: https://code-review.googlesource.com/c/gocloud/+/50990
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Noah Dietz <ndietz@google.com>
diff --git a/internal/.repo-metadata-full.json b/internal/.repo-metadata-full.json
new file mode 100644
index 0000000..9fbcd55
--- /dev/null
+++ b/internal/.repo-metadata-full.json
@@ -0,0 +1 @@
+[{"pkg_name":"cloud.google.com/go/texttospeech/apiv1","description":"Cloud Text-to-Speech API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/texttospeech/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/asset/apiv1","description":"Cloud Asset API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/asset/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/language/apiv1","description":"Cloud Natural Language API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/language/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/language/apiv1beta2","description":"Cloud Natural Language API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/language/apiv1beta2","release_level":"beta"},{"pkg_name":"cloud.google.com/go/phishingprotection/apiv1beta1","description":"Phishing Protection API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/phishingprotection/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/translate/apiv3","description":"Cloud Translation API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/translate/apiv3","release_level":"ga"},{"pkg_name":"cloud.google.com/go/scheduler/apiv1","description":"Cloud Scheduler API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/scheduler/apiv1","release_level":"ga"},{"pkg_name":"cloud.google.com/go/scheduler/apiv1beta1","description":"Cloud Scheduler API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/scheduler/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/speech/apiv1","description":"Cloud Speech-to-Text API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/speech/apiv1","release_level":"ga"},{"pkg_name":"cloud.google.com/go/speech/apiv1p1beta1","description":"Cloud Speech-to-Text API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/speech/apiv1p1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/bigquery/datatransfer/apiv1","description":"BigQuery Data Transfer API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/bigquery/datatransfer/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/bigquery/storage/apiv1alpha2","description":"BigQuery Storage API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/bigquery/storage/apiv1alpha2","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/bigquery/storage/apiv1beta1","description":"BigQuery Storage API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/bigquery/storage/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/bigquery/storage/apiv1beta2","description":"BigQuery Storage API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/bigquery/storage/apiv1beta2","release_level":"beta"},{"pkg_name":"cloud.google.com/go/iot/apiv1","description":"Cloud IoT API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/iot/apiv1","release_level":"ga"},{"pkg_name":"cloud.google.com/go/recommender/apiv1beta1","description":"Recommender API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/recommender/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/cloudtasks/apiv2","description":"Cloud Tasks API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/cloudtasks/apiv2","release_level":"ga"},{"pkg_name":"cloud.google.com/go/cloudtasks/apiv2beta2","description":"Cloud Tasks API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/cloudtasks/apiv2beta2","release_level":"beta"},{"pkg_name":"cloud.google.com/go/cloudtasks/apiv2beta3","description":"Cloud Tasks API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/cloudtasks/apiv2beta3","release_level":"beta"},{"pkg_name":"cloud.google.com/go/videointelligence/apiv1","description":"Cloud Video Intelligence API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/videointelligence/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/vision/apiv1","description":"Cloud Vision API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/vision/apiv1","release_level":"ga"},{"pkg_name":"cloud.google.com/go/webrisk/apiv1beta1","description":"Web Risk API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/webrisk/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/secretmanager/apiv1beta1","description":"Secret Manager API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/secretmanager/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/osconfig/apiv1beta","description":"Cloud OS Config API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/osconfig/apiv1beta","release_level":"beta"},{"pkg_name":"cloud.google.com/go/osconfig/agentendpoint/apiv1beta","description":"Cloud OS Config API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/osconfig/agentendpoint/apiv1beta","release_level":"beta"},{"pkg_name":"cloud.google.com/go/datacatalog/apiv1beta1","description":"Google Cloud Data Catalog API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/datacatalog/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/dataproc/apiv1","description":"Cloud Dataproc API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/dataproc/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/dataproc/apiv1beta2","description":"Cloud Dataproc API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/dataproc/apiv1beta2","release_level":"beta"},{"pkg_name":"cloud.google.com/go/irm/apiv1alpha2","description":"Stackdriver Incident Response \u0026 Management API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/irm/apiv1alpha2","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/kms/apiv1","description":"Cloud Key Management Service (KMS) API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/kms/apiv1","release_level":"ga"},{"pkg_name":"cloud.google.com/go/oslogin/apiv1","description":"Cloud OS Login API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/oslogin/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/oslogin/apiv1beta","description":"Cloud OS Login API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/oslogin/apiv1beta","release_level":"beta"},{"pkg_name":"cloud.google.com/go/recaptchaenterprise/apiv1beta1","description":"reCAPTCHA Enterprise API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/recaptchaenterprise/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/redis/apiv1","description":"Google Cloud Memorystore for Redis API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/redis/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/redis/apiv1beta1","description":"Google Cloud Memorystore for Redis API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/redis/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/debugger/apiv2","description":"Stackdriver Debugger API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/debugger/apiv2","release_level":"ga"},{"pkg_name":"cloud.google.com/go/errorreporting/apiv1beta1","description":"Stackdriver Error Reporting API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/errorreporting/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/trace/apiv1","description":"Stackdriver Trace API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/trace/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/trace/apiv2","description":"Stackdriver Trace API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/trace/apiv2","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/dlp/apiv2","description":"Cloud Data Loss Prevention (DLP) API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/dlp/apiv2","release_level":"ga"},{"pkg_name":"cloud.google.com/go/spanner/admin/database/apiv1","description":"Cloud Spanner Database Admin API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/spanner/admin/database/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/spanner/admin/instance/apiv1","description":"Cloud Spanner Instance Admin API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/spanner/admin/instance/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/spanner/apiv1","description":"Cloud Spanner API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/spanner/apiv1","release_level":"ga"},{"pkg_name":"cloud.google.com/go/securitycenter/apiv1","description":"Cloud Security Command Center API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/securitycenter/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/securitycenter/apiv1beta1","description":"Cloud Security Command Center API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/securitycenter/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/firestore/apiv1/admin","description":"Google Cloud Firestore Admin API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/firestore/apiv1/admin","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/firestore/apiv1","description":"Cloud Firestore API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/firestore/apiv1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/firestore/apiv1beta1","description":"Cloud Firestore API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/firestore/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/cloudbuild/apiv1/v2","description":"Cloud Build API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/cloudbuild/apiv1/v2","release_level":"ga"},{"pkg_name":"cloud.google.com/go/dialogflow/apiv2","description":"Dialogflow API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/dialogflow/apiv2","release_level":"ga"},{"pkg_name":"cloud.google.com/go/iam/credentials/apiv1","description":"IAM Service Account Credentials API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/iam/credentials/apiv1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/longrunning/autogen","description":"Long Running Operations API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/longrunning/autogen","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/expr/apiv1alpha1","description":"Common Expression Language","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/expr/apiv1alpha1","release_level":"alpha"},{"pkg_name":"cloud.google.com/go/containeranalysis/apiv1beta1","description":"Container Analysis API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/containeranalysis/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/containeranalysis/apiv1beta1","description":"Container Analysis API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/containeranalysis/apiv1beta1","release_level":"beta"},{"pkg_name":"cloud.google.com/go/recommender/apiv1","description":"Recommender API","language":"Go","client_library_type":"generated","docs_url":"https://pkg.go.dev/cloud.google.com/go/recommender/apiv1","release_level":"alpha"}]
diff --git a/internal/gapicgen/generator/gapics.go b/internal/gapicgen/generator/gapics.go
index bc0a028..d40483f 100644
--- a/internal/gapicgen/generator/gapics.go
+++ b/internal/gapicgen/generator/gapics.go
@@ -17,6 +17,7 @@
 import (
 	"bytes"
 	"context"
+	"encoding/json"
 	"fmt"
 	"io"
 	"log"
@@ -25,6 +26,8 @@
 	"path/filepath"
 	"regexp"
 	"strings"
+
+	"gopkg.in/yaml.v2"
 )
 
 var dockerPullRegex = regexp.MustCompile("(googleapis/artman:[0-9]+.[0-9]+.[0-9]+)")
@@ -49,6 +52,10 @@
 		return err
 	}
 
+	if err := manifest(microgenGapicConfigs, googleapisDir, gocloudDir); err != nil {
+		return err
+	}
+
 	if err := setVersion(gocloudDir); err != nil {
 		return err
 	}
@@ -262,6 +269,53 @@
 	return c.Run()
 }
 
+// manifestEntry is used for JSON marshaling in manifest.
+type manifestEntry struct {
+	PkgName           string `json:"pkg_name"`
+	Description       string `json:"description"`
+	Language          string `json:"language"`
+	ClientLibraryType string `json:"client_library_type"`
+	DocsURL           string `json:"docs_url"`
+	ReleaseLevel      string `json:"release_level"`
+}
+
+// manifest writes a manifest file with info about all of the confs.
+//
+// TODO: there are some libraries that aren't listed in a config (manual,
+// not-microgen). We should add them to the output somehow. See
+// gapicsWithManual.
+func manifest(confs []*microgenConfig, googleapisDir, gocloudDir string) error {
+	var entries []manifestEntry
+	f, err := os.Create(filepath.Join(gocloudDir, "internal", ".repo-metadata-full.json"))
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	for _, conf := range confs {
+		yamlPath := filepath.Join(googleapisDir, conf.apiServiceConfigPath)
+		yamlFile, err := os.Open(yamlPath)
+		if err != nil {
+			return err
+		}
+		yamlConfig := struct {
+			Title string `yaml:"title"` // We only need the title field.
+		}{}
+		if err := yaml.NewDecoder(yamlFile).Decode(&yamlConfig); err != nil {
+			return fmt.Errorf("Decode: %v", err)
+		}
+		entry := manifestEntry{
+			PkgName:           conf.importPath,
+			Description:       yamlConfig.Title,
+			Language:          "Go",
+			ClientLibraryType: "generated",
+			DocsURL:           "https://pkg.go.dev/" + conf.importPath,
+			ReleaseLevel:      conf.releaseLevel,
+		}
+		entries = append(entries, entry)
+	}
+	return json.NewEncoder(f).Encode(entries)
+}
+
 // copyMicrogenFiles takes microgen files from gocloudDir/cloud.google.com/go
 // and places them in gocloudDir.
 func copyMicrogenFiles(gocloudDir string) error {
diff --git a/internal/gapicgen/go.mod b/internal/gapicgen/go.mod
index 3e3e6ae..b3b3989 100644
--- a/internal/gapicgen/go.mod
+++ b/internal/gapicgen/go.mod
@@ -19,5 +19,5 @@
 	google.golang.org/grpc v1.26.0 // indirect
 	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
 	gopkg.in/src-d/go-git.v4 v4.13.1
-	gopkg.in/yaml.v2 v2.2.8 // indirect
+	gopkg.in/yaml.v2 v2.2.8
 )