Skip to content

Commit b7b8008

Browse files
authored
feat(internal/config): add import path to GoAPI (#3950)
Add `ImportPath` to GoAPI. The GAPIC import path is one of the input of `go_gapic_library` Bazel rule. The source of truth is BUILD.bazel so we need a field in GoAPI to store this value. Hardcode the import path and client directory for `ai` in google-cloud-go because these values are not from legacy librarian configs. For #3617
1 parent e77cccf commit b7b8008

6 files changed

Lines changed: 136 additions & 28 deletions

File tree

doc/config-schema.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ This document describes the schema for the librarian.yaml.
103103

104104
## DartPackage Configuration
105105

106-
[Link to code](../internal/config/language.go#L279)
106+
[Link to code](../internal/config/language.go#L280)
107107
| Field | Type | Description |
108108
| :--- | :--- | :--- |
109109
| `api_keys_environment_variables` | string | APIKeysEnvironmentVariables is a comma-separated list of environment variable names that can contain API keys (e.g., "GOOGLE_API_KEY,GEMINI_API_KEY"). |
@@ -132,6 +132,7 @@ This document describes the schema for the librarian.yaml.
132132
| `path` | string | |
133133
| `client_directory` | string | |
134134
| `disable_gapic` | bool | |
135+
| `import_path` | string | |
135136
| `nested_protos` | list of string | |
136137
| `proto_package` | string | |
137138

@@ -146,15 +147,15 @@ This document describes the schema for the librarian.yaml.
146147

147148
## PythonPackage Configuration
148149

149-
[Link to code](../internal/config/language.go#L264)
150+
[Link to code](../internal/config/language.go#L265)
150151
| Field | Type | Description |
151152
| :--- | :--- | :--- |
152153
| `opt_args` | list of string | OptArgs contains additional options passed to the generator, where the options are common to all apis. Example: ["warehouse-package-name=google-cloud-batch"] |
153154
| `opt_args_by_api` | map[string][]string | OptArgsByAPI contains additional options passed to the generator, where the options vary by api. In each entry, the key is the api (API path) and the value is the list of options to pass when generating that API. Example: {"google/cloud/secrets/v1beta": ["python-gapic-name=secretmanager"]} |
154155

155156
## RustCrate Configuration
156157

157-
[Link to code](../internal/config/language.go#L130)
158+
[Link to code](../internal/config/language.go#L131)
158159
| Field | Type | Description |
159160
| :--- | :--- | :--- |
160161
| (embedded) | [RustDefault](#rustdefault-configuration) | |
@@ -181,7 +182,7 @@ This document describes the schema for the librarian.yaml.
181182

182183
## RustDefault Configuration
183184

184-
[Link to code](../internal/config/language.go#L36)
185+
[Link to code](../internal/config/language.go#L37)
185186
| Field | Type | Description |
186187
| :--- | :--- | :--- |
187188
| `package_dependencies` | list of [RustPackageDependency](#rustpackagedependency-configuration) (optional) | PackageDependencies is a list of default package dependencies. |
@@ -191,15 +192,15 @@ This document describes the schema for the librarian.yaml.
191192

192193
## RustDiscovery Configuration
193194

194-
[Link to code](../internal/config/language.go#L246)
195+
[Link to code](../internal/config/language.go#L247)
195196
| Field | Type | Description |
196197
| :--- | :--- | :--- |
197198
| `operation_id` | string | OperationID is the ID of the LRO operation type (e.g., ".google.cloud.compute.v1.Operation"). |
198199
| `pollers` | list of [RustPoller](#rustpoller-configuration) | Pollers is a list of LRO polling configurations. |
199200

200201
## RustDocumentationOverride Configuration
201202

202-
[Link to code](../internal/config/language.go#L225)
203+
[Link to code](../internal/config/language.go#L226)
203204
| Field | Type | Description |
204205
| :--- | :--- | :--- |
205206
| `id` | string | ID is the fully qualified element ID (e.g., .google.cloud.dialogflow.v2.Message.field). |
@@ -208,7 +209,7 @@ This document describes the schema for the librarian.yaml.
208209

209210
## RustModule Configuration
210211

211-
[Link to code](../internal/config/language.go#L53)
212+
[Link to code](../internal/config/language.go#L54)
212213
| Field | Type | Description |
213214
| :--- | :--- | :--- |
214215
| `disabled_rustdoc_warnings` | yaml.StringSlice | DisabledRustdocWarnings specifies rustdoc lints to disable. An empty slice explicitly enables all warnings. |
@@ -237,7 +238,7 @@ This document describes the schema for the librarian.yaml.
237238

238239
## RustPackageDependency Configuration
239240

240-
[Link to code](../internal/config/language.go#L197)
241+
[Link to code](../internal/config/language.go#L198)
241242
| Field | Type | Description |
242243
| :--- | :--- | :--- |
243244
| `name` | string | Name is the dependency name. It is listed first so it appears at the top of each dependency entry in YAML. |
@@ -250,15 +251,15 @@ This document describes the schema for the librarian.yaml.
250251

251252
## RustPaginationOverride Configuration
252253

253-
[Link to code](../internal/config/language.go#L237)
254+
[Link to code](../internal/config/language.go#L238)
254255
| Field | Type | Description |
255256
| :--- | :--- | :--- |
256257
| `id` | string | ID is the fully qualified method ID (e.g., .google.cloud.sql.v1.Service.Method). |
257258
| `item_field` | string | ItemField is the name of the field used for items. |
258259

259260
## RustPoller Configuration
260261

261-
[Link to code](../internal/config/language.go#L255)
262+
[Link to code](../internal/config/language.go#L256)
262263
| Field | Type | Description |
263264
| :--- | :--- | :--- |
264265
| `prefix` | string | Prefix is an acceptable prefix for the URL path (e.g., "compute/v1/projects/{project}/zones/{zone}"). |

internal/config/language.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ type GoModule struct {
2323
ModulePathVersion string `yaml:"module_path_version,omitempty"`
2424
}
2525

26-
// GoAPI represents configuration for a single API api within a Go module.
26+
// GoAPI represents configuration for a single API within a Go module.
2727
type GoAPI struct {
2828
Path string `yaml:"path,omitempty"`
2929
ClientDirectory string `yaml:"client_directory,omitempty"`
3030
DisableGAPIC bool `yaml:"disable_gapic,omitempty"`
31+
ImportPath string `yaml:"import_path,omitempty"`
3132
NestedProtos []string `yaml:"nested_protos,omitempty"`
3233
ProtoPackage string `yaml:"proto_package,omitempty"`
3334
}

internal/librarian/golang/generate.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,17 @@ func buildGAPICImportPath(apiPath string, library *config.Library, goAPI *config
199199
clientDir = goAPI.ClientDirectory
200200
}
201201

202+
importPath := clientDir
203+
if goAPI != nil && goAPI.ImportPath != "" {
204+
importPath = goAPI.ImportPath
205+
}
206+
202207
var modulePathVersion string
203208
if library.Go != nil && library.Go.ModulePathVersion != "" {
204209
modulePathVersion = "/" + library.Go.ModulePathVersion
205210
}
206211
return fmt.Sprintf("cloud.google.com/go/%s%s/api%s;%s",
207-
clientDir, modulePathVersion, version, clientDir)
212+
importPath, modulePathVersion, version, clientDir)
208213
}
209214

210215
func findGoAPI(library *config.Library, apiPath string) *config.GoAPI {

internal/librarian/golang/generate_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,52 @@ func TestUpdateSnippetMetadata(t *testing.T) {
302302
t.Errorf("want version in snippet metadata, got:\n%s", s)
303303
}
304304
}
305+
306+
func TestBuildGAPICImportPath(t *testing.T) {
307+
for _, test := range []struct {
308+
name string
309+
apiPath string
310+
library *config.Library
311+
goAPI *config.GoAPI
312+
want string
313+
}{
314+
{
315+
name: "single version without customize client directory",
316+
apiPath: "google/cloud/accessapproval/v1",
317+
library: &config.Library{
318+
Name: "accessapproval",
319+
},
320+
want: "cloud.google.com/go/accessapproval/apiv1;accessapproval",
321+
},
322+
{
323+
name: "customize client directory",
324+
apiPath: "google/ai/generativelanguage/v1",
325+
library: &config.Library{
326+
Name: "ai",
327+
},
328+
goAPI: &config.GoAPI{
329+
ClientDirectory: "generativelanguage",
330+
},
331+
want: "cloud.google.com/go/generativelanguage/apiv1;generativelanguage",
332+
},
333+
{
334+
name: "customize import path and client directory",
335+
apiPath: "google/ai/generativelanguage/v1",
336+
library: &config.Library{
337+
Name: "ai",
338+
},
339+
goAPI: &config.GoAPI{
340+
ClientDirectory: "generativelanguage",
341+
ImportPath: "ai/generativelanguage",
342+
},
343+
want: "cloud.google.com/go/ai/generativelanguage/apiv1;generativelanguage",
344+
},
345+
} {
346+
t.Run(test.name, func(t *testing.T) {
347+
got := buildGAPICImportPath(test.apiPath, test.library, test.goAPI)
348+
if diff := cmp.Diff(test.want, got); diff != "" {
349+
t.Errorf("mismatch (-want +got):\n%s", diff)
350+
}
351+
})
352+
}
353+
}

tool/cmd/migrate/legacylibrarian.go

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package main
1616

1717
import (
1818
"context"
19+
"maps"
1920
"os"
2021
"path/filepath"
2122
"reflect"
@@ -28,14 +29,6 @@ import (
2829
"github.com/googleapis/librarian/internal/yaml"
2930
)
3031

31-
var (
32-
libraryOverrides = map[string]*config.Library{
33-
"ai": {
34-
ReleaseLevel: "beta",
35-
},
36-
}
37-
)
38-
3932
// RepoConfig represents the .librarian/generator-input/repo-config.yaml file in google-cloud-go repository.
4033
type RepoConfig struct {
4134
Modules []*RepoConfigModule `yaml:"modules"`
@@ -54,6 +47,7 @@ type RepoConfigAPI struct {
5447
Path string `yaml:"path"`
5548
ClientDirectory string `yaml:"client_directory,omitempty"`
5649
DisableGAPIC bool `yaml:"disable_gapic,omitempty"`
50+
ImportPath string `yaml:"import_path,omitempty"`
5751
NestedProtos []string `yaml:"nested_protos,omitempty"`
5852
ProtoPackage string `yaml:"proto_package,omitempty"`
5953
}
@@ -67,6 +61,41 @@ type MigrationInput struct {
6761
repoPath string
6862
}
6963

64+
var (
65+
addGoModules = map[string]*RepoConfigModule{
66+
"ai": {
67+
APIs: []*RepoConfigAPI{
68+
{
69+
Path: "google/ai/generativelanguage/v1",
70+
ClientDirectory: "generativelanguage",
71+
ImportPath: "ai/generativelanguage",
72+
},
73+
{
74+
Path: "google/ai/generativelanguage/v1alpha",
75+
ClientDirectory: "generativelanguage",
76+
ImportPath: "ai/generativelanguage",
77+
},
78+
{
79+
Path: "google/ai/generativelanguage/v1beta",
80+
ClientDirectory: "generativelanguage",
81+
ImportPath: "ai/generativelanguage",
82+
},
83+
{
84+
Path: "google/ai/generativelanguage/v1beta2",
85+
ClientDirectory: "generativelanguage",
86+
ImportPath: "ai/generativelanguage",
87+
},
88+
},
89+
},
90+
}
91+
92+
libraryOverrides = map[string]*config.Library{
93+
"ai": {
94+
ReleaseLevel: "beta",
95+
},
96+
}
97+
)
98+
7099
func runLibrarianMigration(ctx context.Context, language, repoPath string) error {
71100
librarianState, err := readState(repoPath)
72101
if err != nil {
@@ -194,6 +223,7 @@ func buildGoLibraries(input *MigrationInput) []*config.Library {
194223
return mod.Name
195224
})
196225
}
226+
maps.Copy(idToGoModule, addGoModules)
197227

198228
// Iterate libraries from idToLibraryState because librarianConfig.Libraries is a
199229
// subset of librarianState.Libraries.
@@ -224,6 +254,7 @@ func buildGoLibraries(input *MigrationInput) []*config.Library {
224254
Path: api.Path,
225255
ClientDirectory: api.ClientDirectory,
226256
DisableGAPIC: api.DisableGAPIC,
257+
ImportPath: api.ImportPath,
227258
NestedProtos: api.NestedProtos,
228259
ProtoPackage: api.ProtoPackage,
229260
})

tool/cmd/migrate/legacylibrarian_test.go

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -390,17 +390,15 @@ func TestBuildGoLibraries(t *testing.T) {
390390
},
391391
},
392392
{
393-
name: "go_libraries with non-default release level",
393+
name: "additional go module",
394394
input: &MigrationInput{
395395
librarianState: &legacyconfig.LibrarianState{
396396
Libraries: []*legacyconfig.LibraryState{
397397
{
398398
ID: "ai",
399399
APIs: []*legacyconfig.API{
400-
{
401-
Path: "google/another/api/v1",
402-
ServiceConfig: "another/config.yaml",
403-
},
400+
{Path: "google/ai/generativelanguage/v1"},
401+
{Path: "google/ai/generativelanguage/v1alpha"},
404402
},
405403
},
406404
},
@@ -412,11 +410,34 @@ func TestBuildGoLibraries(t *testing.T) {
412410
{
413411
Name: "ai",
414412
APIs: []*config.API{
415-
{
416-
Path: "google/another/api/v1",
417-
},
413+
{Path: "google/ai/generativelanguage/v1"},
414+
{Path: "google/ai/generativelanguage/v1alpha"},
418415
},
419416
ReleaseLevel: "beta",
417+
Go: &config.GoModule{
418+
GoAPIs: []*config.GoAPI{
419+
{
420+
Path: "google/ai/generativelanguage/v1",
421+
ClientDirectory: "generativelanguage",
422+
ImportPath: "ai/generativelanguage",
423+
},
424+
{
425+
Path: "google/ai/generativelanguage/v1alpha",
426+
ClientDirectory: "generativelanguage",
427+
ImportPath: "ai/generativelanguage",
428+
},
429+
{
430+
Path: "google/ai/generativelanguage/v1beta",
431+
ClientDirectory: "generativelanguage",
432+
ImportPath: "ai/generativelanguage",
433+
},
434+
{
435+
Path: "google/ai/generativelanguage/v1beta2",
436+
ClientDirectory: "generativelanguage",
437+
ImportPath: "ai/generativelanguage",
438+
},
439+
},
440+
},
420441
},
421442
},
422443
},

0 commit comments

Comments
 (0)