Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion internal/librarian/java/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,17 @@ func Generate(ctx context.Context, cfg *config.Config, library *config.Library,
if err := os.MkdirAll(outdir, 0755); err != nil {
return fmt.Errorf("failed to create output directory %q: %w", outdir, err)
}
// generate repo metadata prior to client because info is needed for
// owlbot.py to generate README.md
if err := generateRepoMetadata(cfg, library, outdir, googleapisDir); err != nil {
return fmt.Errorf("failed to generate .repo-metadata.json: %w", err)
}
for _, api := range library.APIs {
if err := generateAPI(ctx, cfg, api, library, googleapisDir, outdir); err != nil {
return fmt.Errorf("failed to generate api %q: %w", api.Path, err)
}
}
return postProcessLibrary(cfg, library, outdir, googleapisDir)
return nil
}

func generateAPI(ctx context.Context, cfg *config.Config, api *config.API, library *config.Library, googleapisDir, outdir string) error {
Expand Down
98 changes: 2 additions & 96 deletions internal/librarian/java/postprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import (
"github.com/googleapis/librarian/internal/config"
"github.com/googleapis/librarian/internal/filesystem"
"github.com/googleapis/librarian/internal/license"
"github.com/googleapis/librarian/internal/repometadata"
"github.com/googleapis/librarian/internal/serviceconfig"
)

type postProcessParams struct {
Expand Down Expand Up @@ -218,11 +216,9 @@ func copyProtos(googleapisDir string, protos []string, destDir string) error {
return nil
}

// postProcessLibrary coordinates all library-level post-processing tasks,
// generateRepoMetadata coordinates all library-level post-processing tasks,
// such as generating .repo-metadata.json.
func postProcessLibrary(cfg *config.Config, library *config.Library, outDir, googleapisDir string) error {
// TODO(https://github.com/googleapis/librarian/issues/4217): update pom files.
// TODO(https://github.com/googleapis/librarian/issues/4218): generate README.md
func generateRepoMetadata(cfg *config.Config, library *config.Library, outDir, googleapisDir string) error {
metadata, err := deriveRepoMetadata(cfg, library, googleapisDir)
if err != nil {
return fmt.Errorf("failed to derive repo metadata: %w", err)
Expand All @@ -232,93 +228,3 @@ func postProcessLibrary(cfg *config.Config, library *config.Library, outDir, goo
}
return nil
}

// deriveRepoMetadata constructs the repoMetadata for a Java library using
// information from the primary service configuration and library-level overrides.
func deriveRepoMetadata(cfg *config.Config, library *config.Library, googleapisDir string) (*repoMetadata, error) {
serviceconfig.SortAPIs(library.APIs)
sharedMetadata, err := repometadata.FromLibrary(cfg, library, googleapisDir)
if err != nil {
return nil, err
}

metadata := &repoMetadata{
APIShortname: sharedMetadata.APIShortname,
NamePretty: sharedMetadata.NamePretty,
ProductDocumentation: sharedMetadata.ProductDocumentation,
APIDescription: sharedMetadata.APIDescription,
ReleaseLevel: sharedMetadata.ReleaseLevel,
Language: config.LanguageJava,
Repo: sharedMetadata.Repo,
RepoShort: fmt.Sprintf("%s-%s", config.LanguageJava, library.Name),
DistributionName: sharedMetadata.DistributionName,
APIID: sharedMetadata.APIID,
LibraryType: repometadata.GAPICAutoLibraryType,
RequiresBilling: true,
}

// Java-specific overrides and optional fields
if library.Java.APIIDOverride != "" {
metadata.APIID = library.Java.APIIDOverride
}
if library.Java.APIDescriptionOverride != "" {
metadata.APIDescription = library.Java.APIDescriptionOverride
}
if library.Java.DistributionNameOverride != "" {
metadata.DistributionName = library.Java.DistributionNameOverride
}
if library.Java.IssueTrackerOverride != "" {
metadata.IssueTracker = library.Java.IssueTrackerOverride
}
if library.Java.LibraryTypeOverride != "" {
metadata.LibraryType = library.Java.LibraryTypeOverride
}
if library.Java.NamePrettyOverride != "" {
metadata.NamePretty = library.Java.NamePrettyOverride
}
if library.Java.ProductDocumentationOverride != "" {
metadata.ProductDocumentation = library.Java.ProductDocumentationOverride
}
if library.Java.ClientDocumentationOverride != "" {
metadata.ClientDocumentation = library.Java.ClientDocumentationOverride
}
metadata.RequiresBilling = !library.Java.BillingNotRequired
// Java only fields
metadata.CodeownerTeam = library.Java.CodeownerTeam
metadata.ExtraVersionedModules = library.Java.ExtraVersionedModules
metadata.ExcludedDependencies = library.Java.ExcludedDependencies
metadata.ExcludedPoms = library.Java.ExcludedPoms
metadata.MinJavaVersion = library.Java.MinJavaVersion
metadata.RecommendedPackage = library.Java.RecommendedPackage
metadata.RestDocumentation = library.Java.RestDocumentation
metadata.RpcDocumentation = library.Java.RpcDocumentation

// distribution_name default for Java is groupId:artifactId
if !strings.Contains(metadata.DistributionName, ":") {
metadata.DistributionName = deriveDistributionName(library)
}
// Default ClientDocumentation uses artifact ID
if metadata.ClientDocumentation == "" {
parts := strings.Split(metadata.DistributionName, ":")
artifactID := parts[len(parts)-1]
metadata.ClientDocumentation = fmt.Sprintf("https://cloud.google.com/java/docs/reference/%s/latest/overview", artifactID)
}
// transport
apiCfg, err := serviceconfig.Find(googleapisDir, library.APIs[0].Path, config.LanguageJava)
if err != nil {
return nil, fmt.Errorf("failed to find api config: %w", err)
}
transport := serviceconfig.GRPCRest
if apiCfg != nil {
transport = apiCfg.Transport(config.LanguageJava)
}
switch transport {
case "grpc":
metadata.Transport = "grpc"
case "rest":
metadata.Transport = "http"
default:
metadata.Transport = "both"
}
return metadata, nil
}
51 changes: 0 additions & 51 deletions internal/librarian/java/postprocess_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ import (
"strings"

"testing"

"github.com/google/go-cmp/cmp"
"github.com/googleapis/librarian/internal/config"
)

func TestPostProcessAPI(t *testing.T) {
Expand Down Expand Up @@ -307,51 +304,3 @@ func TestAddMissingHeaders(t *testing.T) {
})
}
}

func TestDeriveRepoMetadata_Overrides(t *testing.T) {
t.Parallel()
apiPath := "google/cloud/secretmanager/v1"
googleapis := "internal/testdata/googleapis"

cfg := &config.Config{
Language: config.LanguageJava,
Repo: "googleapis/google-cloud-java",
}
library := &config.Library{
Name: "secretmanager",
APIs: []*config.API{{Path: apiPath}},
Java: &config.JavaModule{
GroupID: "com.custom",
DistributionNameOverride: "com.custom:custom-artifact",
APIIDOverride: "custom.googleapis.com",
APIDescriptionOverride: "Custom description",
NamePrettyOverride: "Custom Pretty Name",
ProductDocumentationOverride: "https://custom.docs",
ClientDocumentationOverride: "https://custom.client.docs",
BillingNotRequired: true,
LibraryTypeOverride: "OTHER",
},
}
got, err := deriveRepoMetadata(cfg, library, googleapis)
if err != nil {
t.Fatalf("deriveRepoMetadata failed: %v", err)
}
want := &repoMetadata{
NamePretty: "Custom Pretty Name",
ProductDocumentation: "https://custom.docs",
APIDescription: "Custom description",
ClientDocumentation: "https://custom.client.docs",
ReleaseLevel: "",
Transport: "both",
Language: "java",
Repo: "googleapis/google-cloud-java",
RepoShort: "java-secretmanager",
DistributionName: "com.custom:custom-artifact",
APIID: "custom.googleapis.com",
LibraryType: "OTHER",
RequiresBilling: false,
}
if diff := cmp.Diff(want, got, cmp.AllowUnexported(repoMetadata{})); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
}
101 changes: 100 additions & 1 deletion internal/librarian/java/repometadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@

package java

import "github.com/googleapis/librarian/internal/repometadata"
import (
"fmt"
"strings"

"github.com/googleapis/librarian/internal/config"
"github.com/googleapis/librarian/internal/repometadata"
"github.com/googleapis/librarian/internal/serviceconfig"
)

// repoMetadata represents the .repo-metadata.json file structure for Java.
//
Expand Down Expand Up @@ -63,3 +70,95 @@ type repoMetadata struct {
func (metadata *repoMetadata) write(libraryOutputDir string) error {
return repometadata.WriteJSON(metadata, " ", libraryOutputDir, ".repo-metadata.json")
}

// deriveRepoMetadata constructs the repoMetadata for a Java library using
// information from the primary service configuration and library-level overrides.
func deriveRepoMetadata(cfg *config.Config, library *config.Library, googleapisDir string) (*repoMetadata, error) {
serviceconfig.SortAPIs(library.APIs)
sharedMetadata, err := repometadata.FromLibrary(cfg, library, googleapisDir)
if err != nil {
return nil, err
}

metadata := &repoMetadata{
APIShortname: sharedMetadata.APIShortname,
NamePretty: sharedMetadata.NamePretty,
ProductDocumentation: sharedMetadata.ProductDocumentation,
APIDescription: sharedMetadata.APIDescription,
ReleaseLevel: sharedMetadata.ReleaseLevel,
Language: config.LanguageJava,
Repo: sharedMetadata.Repo,
RepoShort: fmt.Sprintf("%s-%s", config.LanguageJava, library.Name),
DistributionName: sharedMetadata.DistributionName,
APIID: sharedMetadata.APIID,
LibraryType: repometadata.GAPICAutoLibraryType,
RequiresBilling: true,
}

// Java-specific overrides and optional fields
if library.Java != nil {
if library.Java.APIIDOverride != "" {
metadata.APIID = library.Java.APIIDOverride
}
if library.Java.APIDescriptionOverride != "" {
metadata.APIDescription = library.Java.APIDescriptionOverride
}
if library.Java.DistributionNameOverride != "" {
metadata.DistributionName = library.Java.DistributionNameOverride
}
if library.Java.IssueTrackerOverride != "" {
metadata.IssueTracker = library.Java.IssueTrackerOverride
}
if library.Java.LibraryTypeOverride != "" {
metadata.LibraryType = library.Java.LibraryTypeOverride
}
if library.Java.NamePrettyOverride != "" {
metadata.NamePretty = library.Java.NamePrettyOverride
}
if library.Java.ProductDocumentationOverride != "" {
metadata.ProductDocumentation = library.Java.ProductDocumentationOverride
}
if library.Java.ClientDocumentationOverride != "" {
metadata.ClientDocumentation = library.Java.ClientDocumentationOverride
}
metadata.RequiresBilling = !library.Java.BillingNotRequired
// Java only fields
metadata.CodeownerTeam = library.Java.CodeownerTeam
metadata.ExtraVersionedModules = library.Java.ExtraVersionedModules
metadata.ExcludedDependencies = library.Java.ExcludedDependencies
metadata.ExcludedPoms = library.Java.ExcludedPoms
metadata.MinJavaVersion = library.Java.MinJavaVersion
metadata.RecommendedPackage = library.Java.RecommendedPackage
metadata.RestDocumentation = library.Java.RestDocumentation
metadata.RpcDocumentation = library.Java.RpcDocumentation
}

// distribution_name default for Java is groupId:artifactId
if !strings.Contains(metadata.DistributionName, ":") {
metadata.DistributionName = deriveDistributionName(library)
}
// Default ClientDocumentation uses artifact ID
if metadata.ClientDocumentation == "" {
parts := strings.Split(metadata.DistributionName, ":")
artifactID := parts[len(parts)-1]
metadata.ClientDocumentation = fmt.Sprintf("https://cloud.google.com/java/docs/reference/%s/latest/overview", artifactID)
}
// transport
apiCfg, err := serviceconfig.Find(googleapisDir, library.APIs[0].Path, config.LanguageJava)
if err != nil {
return nil, fmt.Errorf("failed to find api config: %w", err)
}
transport := serviceconfig.GRPCRest
if apiCfg != nil {
transport = apiCfg.Transport(config.LanguageJava)
}
switch transport {
case "grpc":
metadata.Transport = "grpc"
case "rest":
metadata.Transport = "http"
default:
metadata.Transport = "both"
}
return metadata, nil
}
49 changes: 49 additions & 0 deletions internal/librarian/java/repometadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/googleapis/librarian/internal/config"
)

func TestRepoMetadata_write(t *testing.T) {
Expand Down Expand Up @@ -84,3 +85,51 @@ func TestRepoMetadata_write(t *testing.T) {
t.Errorf("write() mismatch (-want +got):\n%s", diff)
}
}

func TestDeriveRepoMetadata_Overrides(t *testing.T) {
t.Parallel()
apiPath := "google/cloud/secretmanager/v1"
googleapis := "internal/testdata/googleapis"

cfg := &config.Config{
Language: config.LanguageJava,
Repo: "googleapis/google-cloud-java",
}
library := &config.Library{
Name: "secretmanager",
APIs: []*config.API{{Path: apiPath}},
Java: &config.JavaModule{
GroupID: "com.custom",
DistributionNameOverride: "com.custom:custom-artifact",
APIIDOverride: "custom.googleapis.com",
APIDescriptionOverride: "Custom description",
NamePrettyOverride: "Custom Pretty Name",
ProductDocumentationOverride: "https://custom.docs",
ClientDocumentationOverride: "https://custom.client.docs",
BillingNotRequired: true,
LibraryTypeOverride: "OTHER",
},
}
got, err := deriveRepoMetadata(cfg, library, googleapis)
if err != nil {
t.Fatalf("deriveRepoMetadata failed: %v", err)
}
want := &repoMetadata{
NamePretty: "Custom Pretty Name",
ProductDocumentation: "https://custom.docs",
APIDescription: "Custom description",
ClientDocumentation: "https://custom.client.docs",
ReleaseLevel: "",
Transport: "both",
Language: "java",
Repo: "googleapis/google-cloud-java",
RepoShort: "java-secretmanager",
DistributionName: "com.custom:custom-artifact",
APIID: "custom.googleapis.com",
LibraryType: "OTHER",
RequiresBilling: false,
}
if diff := cmp.Diff(want, got, cmp.AllowUnexported(repoMetadata{})); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
}
Loading