Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
24f5683
feat: fill group id from defaults
JoeWang1127 Jun 27, 2026
7825029
add unit tests
JoeWang1127 Jun 27, 2026
668480f
add comments
JoeWang1127 Jun 27, 2026
f41253d
docs
JoeWang1127 Jun 27, 2026
896ea81
update unit tests
JoeWang1127 Jun 27, 2026
341ba9a
format
JoeWang1127 Jun 27, 2026
7e77e71
update unit tests
JoeWang1127 Jun 27, 2026
6e2d753
Merge branch 'main' into feat/group-id-mapping
JoeWang1127 Jun 27, 2026
6673862
Merge branch 'main' into feat/group-id-mapping
JoeWang1127 Jun 27, 2026
3cddc81
do not fill prefix
JoeWang1127 Jun 27, 2026
790cfe8
do not override existing id
JoeWang1127 Jun 27, 2026
1c26fa2
Merge branch 'main' into feat/group-id-mapping
JoeWang1127 Jun 29, 2026
68a35b7
update name
JoeWang1127 Jun 29, 2026
175798f
exact match
JoeWang1127 Jun 29, 2026
3c8d35c
format
JoeWang1127 Jun 29, 2026
2bd892a
docs
JoeWang1127 Jun 29, 2026
b9c3a2b
Merge branch 'main' into feat/group-id-mapping
JoeWang1127 Jun 29, 2026
b9141cd
add unit tests
JoeWang1127 Jun 29, 2026
f8679fa
update unit tests
JoeWang1127 Jun 29, 2026
27782bd
Merge branch 'main' into feat/group-id-mapping
JoeWang1127 Jun 29, 2026
ca360b7
Merge branch 'main' into feat/group-id-mapping
JoeWang1127 Jun 30, 2026
cc42c83
review
JoeWang1127 Jun 30, 2026
8b82d17
format
JoeWang1127 Jun 30, 2026
93bc421
update unit tests
JoeWang1127 Jun 30, 2026
19ae443
Merge branch 'main' into feat/group-id-mapping
JoeWang1127 Jun 30, 2026
f6b7948
replace break to return
JoeWang1127 Jun 30, 2026
5ea00de
create helper func
JoeWang1127 Jun 30, 2026
9ad74d3
comment
JoeWang1127 Jun 30, 2026
088e723
refactor
JoeWang1127 Jun 30, 2026
02767a2
Merge branch 'main' into feat/group-id-mapping
JoeWang1127 Jul 1, 2026
81dbf1d
do not return lib
JoeWang1127 Jul 1, 2026
abcb0b9
return
JoeWang1127 Jul 1, 2026
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
1 change: 1 addition & 0 deletions doc/config-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ This document describes the schema for the librarian.yaml.

| Field | Type | Description |
| :--- | :--- | :--- |
| `custom_group_ids` | map[string]string | Maps API path prefixes (e.g., "google/shopping") to their corresponding Maven Group IDs (e.g., "com.google.shopping"). Use this to override the default "com.google.cloud" Group ID for specific API paths (e.g., maps, ads, shopping). |
| `libraries_bom_version` | string | Is the version of the libraries-bom to use for Java. |

## JavaFileCopy Configuration
Expand Down
5 changes: 5 additions & 0 deletions internal/config/language.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,11 @@ type DartPackage struct {

// JavaDefault contains Java-specific default configuration.
type JavaDefault struct {
// CustomGroupIDs maps API path prefixes (e.g., "google/shopping") to their
// corresponding Maven Group IDs (e.g., "com.google.shopping").
// Use this to override the default "com.google.cloud" Group ID for specific API
// paths (e.g., maps, ads, shopping).
CustomGroupIDs map[string]string `yaml:"custom_group_ids,omitempty"`
// LibrariesBOMVersion is the version of the libraries-bom to use for Java.
LibrariesBOMVersion string `yaml:"libraries_bom_version,omitempty"`
}
Expand Down
46 changes: 36 additions & 10 deletions internal/librarian/library.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,22 @@ func fillDefaults(lib *config.Library, d *config.Default) *config.Library {
if lib.Output == "" {
lib.Output = d.Output
}
if d.Go != nil {
switch {
case d.Go != nil:
return fillGo(lib, d)
}
if d.Rust != nil {
case d.Java != nil:
return fillJava(lib, d)
case d.Rust != nil:
return fillRust(lib, d)
}
if d.Dart != nil {
case d.Dart != nil:
return fillDart(lib, d)
}
if d.Python != nil {
case d.Python != nil:
return fillPython(lib, d)
}
if d.Swift != nil {
case d.Swift != nil:
return fillSwift(lib, d)
default:
return lib
}
return lib
}

// fillGo populates empty Go-specific fields in lib from the provided default.
Expand Down Expand Up @@ -97,6 +97,32 @@ func union(a, b []string) []string {
return res
}

// fillJava populates empty Java-specific fields in lib from the provided default.
func fillJava(lib *config.Library, d *config.Default) *config.Library {
if lib.Java == nil {
lib.Java = &config.JavaModule{}
}
fillGroupIDIfEmpty(lib, d)
return lib
}

// fillGroupIDIfEmpty sets the Java group ID on lib if one is not already configured.
// It matches the library's API paths against the custom group ID prefixes in default
// and assigns the first matching group ID.
func fillGroupIDIfEmpty(lib *config.Library, d *config.Default) {
if lib.Java.GroupID != "" || d.Java.CustomGroupIDs == nil {
return
}
for _, api := range lib.APIs {
for apiPrefix, groupID := range d.Java.CustomGroupIDs {
if api.Path == apiPrefix || strings.HasPrefix(api.Path, apiPrefix+"/") {
lib.Java.GroupID = groupID
return
}
}
}
}
Comment thread
zhumin8 marked this conversation as resolved.

// fillRust populates empty Rust-specific fields in lib from the provided default.
func fillRust(lib *config.Library, d *config.Default) *config.Library {
if lib.Rust == nil {
Expand Down
211 changes: 211 additions & 0 deletions internal/librarian/library_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,217 @@ func TestFillDefaults(t *testing.T) {
}
}

func TestFillDefaults_Java(t *testing.T) {
defaults := &config.Default{
Java: &config.JavaDefault{
CustomGroupIDs: map[string]string{
"google/shopping": "com.google.shopping",
"google/exact/v1": "com.google.exact",
"google/maps": "com.google.maps",
"google/ads": "com.google.api-ads",
"google/analytics": "com.google.analytics",
},
},
}
for _, test := range []struct {
name string
lib *config.Library
defaults *config.Default
want *config.Library
}{
{
name: "shopping library",
lib: &config.Library{
Name: "shopping-merchant-issue-resolution",
APIs: []*config.API{
{Path: "google/shopping/merchant/issueresolution/v1"},
{Path: "google/shopping/merchant/issueresolution/v1beta"},
},
},
defaults: defaults,
want: &config.Library{
Name: "shopping-merchant-issue-resolution",
APIs: []*config.API{
{Path: "google/shopping/merchant/issueresolution/v1"},
{Path: "google/shopping/merchant/issueresolution/v1beta"},
},
Java: &config.JavaModule{
GroupID: "com.google.shopping",
},
},
},
{
name: "do not override custom artifact id",
lib: &config.Library{
Name: "custom-shopping",
APIs: []*config.API{
{Path: "google/shopping/merchant/issueresolution/v1"},
{Path: "google/shopping/merchant/issueresolution/v1beta"},
},
Java: &config.JavaModule{
ArtifactID: "custom-shopping-id",
},
},
defaults: defaults,
want: &config.Library{
Name: "custom-shopping",
APIs: []*config.API{
{Path: "google/shopping/merchant/issueresolution/v1"},
{Path: "google/shopping/merchant/issueresolution/v1beta"},
},
Java: &config.JavaModule{
ArtifactID: "custom-shopping-id",
GroupID: "com.google.shopping",
},
},
},
{
name: "maps library",
lib: &config.Library{
Name: "maps-routeoptimization",
APIs: []*config.API{{Path: "google/maps/routeoptimization/v1"}},
},
defaults: defaults,
want: &config.Library{
Name: "maps-routeoptimization",
APIs: []*config.API{{Path: "google/maps/routeoptimization/v1"}},
Java: &config.JavaModule{
GroupID: "com.google.maps",
},
},
},
{
name: "ads library",
lib: &config.Library{
Name: "admanager",
APIs: []*config.API{{Path: "google/ads/admanager/v1"}},
},
defaults: defaults,
want: &config.Library{
Name: "admanager",
APIs: []*config.API{{Path: "google/ads/admanager/v1"}},
Java: &config.JavaModule{
GroupID: "com.google.api-ads",
},
},
},
{
name: "analytics library",
lib: &config.Library{
Name: "analytics-admin",
APIs: []*config.API{
{Path: "google/analytics/admin/v1beta"},
{Path: "google/analytics/admin/v1alpha"},
},
},
defaults: defaults,
want: &config.Library{
Name: "analytics-admin",
APIs: []*config.API{
{Path: "google/analytics/admin/v1beta"},
{Path: "google/analytics/admin/v1alpha"},
},
Java: &config.JavaModule{
GroupID: "com.google.analytics",
},
},
},
{
name: "do not fill if group id already set",
lib: &config.Library{
Name: "common-protos",
APIs: []*config.API{
{Path: "google/shopping/type"},
},
Java: &config.JavaModule{
GroupID: "com.google.api.grpc",
},
},
defaults: defaults,
want: &config.Library{
Name: "common-protos",
APIs: []*config.API{
{Path: "google/shopping/type"},
},
Java: &config.JavaModule{
GroupID: "com.google.api.grpc",
},
},
},
{
name: "prefix match respects path segment boundaries",
lib: &config.Library{
Name: "shopping-foo",
APIs: []*config.API{
{Path: "google/shopping-foo/v1"},
},
},
defaults: defaults,
want: &config.Library{
Name: "shopping-foo",
APIs: []*config.API{
{Path: "google/shopping-foo/v1"},
},
Java: &config.JavaModule{},
},
},
{
name: "no matching api prefix leaves group id empty",
lib: &config.Library{
Name: "unknown",
APIs: []*config.API{{Path: "google/unknown/v1"}},
},
defaults: defaults,
want: &config.Library{
Name: "unknown",
APIs: []*config.API{{Path: "google/unknown/v1"}},
Java: &config.JavaModule{},
},
},
{
name: "library does not change with nil map",
lib: &config.Library{
Name: "lib",
APIs: []*config.API{{Path: "google/example/v1"}},
},
defaults: &config.Default{
Java: &config.JavaDefault{},
},
want: &config.Library{
Name: "lib",
APIs: []*config.API{{Path: "google/example/v1"}},
Java: &config.JavaModule{},
},
},
{
name: "api path exact match",
lib: &config.Library{
Name: "exact",
APIs: []*config.API{
{Path: "google/exact/v1"},
},
},
defaults: defaults,
want: &config.Library{
Name: "exact",
APIs: []*config.API{
{Path: "google/exact/v1"},
},
Java: &config.JavaModule{
GroupID: "com.google.exact",
},
},
},
} {
t.Run(test.name, func(t *testing.T) {
got := fillJava(test.lib, test.defaults)
if diff := cmp.Diff(test.want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
})
}
}

func TestFillDefaults_Rust(t *testing.T) {
defaults := &config.Default{
Rust: &config.RustDefault{
Expand Down
Loading