Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 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
8 changes: 8 additions & 0 deletions doc/config-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ This document describes the schema for the librarian.yaml.
| `cargo` | list of [CargoTool](#cargotool-configuration) (optional) | Defines tools to install via cargo. |
| `npm` | list of [NPMTool](#npmtool-configuration) (optional) | Defines tools to install via npm. |
| `pip` | list of [PipTool](#piptool-configuration) (optional) | Defines tools to install via pip. |
| `go` | list of [GoTool](#gotool-configuration) (optional) | Defines tools to install via go. |

## CargoTool Configuration

Expand All @@ -83,6 +84,13 @@ This document describes the schema for the librarian.yaml.
| `version` | string | Is the version to install. |
| `package` | string | Is the pip install specifier (e.g., "pkg@git+https://..."). |

## GoTool Configuration

| Field | Type | Description |
| :--- | :--- | :--- |
| `name` | string | Is the go module name. |
| `version` | string | Is the version to install. |

## Default Configuration

| Field | Type | Description |
Expand Down
12 changes: 12 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ type Tools struct {

// Pip defines tools to install via pip.
Pip []*PipTool `yaml:"pip,omitempty"`

// Go defines tools to install via go.
Go []*GoTool `yaml:"go,omitempty"`
}

// CargoTool defines a tool to install via cargo.
Expand Down Expand Up @@ -177,6 +180,15 @@ type PipTool struct {
Package string `yaml:"package,omitempty"`
}

// GoTool defines a tool to install via go.
type GoTool struct {
// Name is the go module name.
Name string `yaml:"name"`

// Version is the version to install.
Version string `yaml:"version,omitempty"`
}
Comment thread
sofisl marked this conversation as resolved.

// Default contains default settings for all libraries.
type Default struct {
// Keep lists files and directories to preserve during regeneration.
Expand Down
2 changes: 1 addition & 1 deletion internal/librarian/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func generateLibraries(ctx context.Context, cfg *config.Config, libraries []*con
g, gctx = errgroup.WithContext(ctx)
for _, library := range libraries {
g.Go(func() error {
if err := golang.Format(gctx, library); err != nil {
if err := golang.Format(gctx, library, cfg.Tools); err != nil {
return fmt.Errorf("format library %q (%s): %w", library.Name, cfg.Language, err)
}
return nil
Expand Down
3 changes: 2 additions & 1 deletion internal/librarian/golang/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
)

// Format formats a generated Go library.
func Format(ctx context.Context, library *config.Library) error {
func Format(ctx context.Context, library *config.Library, tools *config.Tools) error {
// No need to format the root module because it does not
// have generated code.
if library.Name == rootModule {
Expand All @@ -33,6 +33,7 @@ func Format(ctx context.Context, library *config.Library) error {
if err != nil {
return err
}

Comment thread
sofisl marked this conversation as resolved.
Outdated
return command.Run(ctx, "goimports", args...)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/librarian/golang/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func main() {
t.Fatal(err)
}
}
if err := Format(t.Context(), test.library); err != nil {
if err := Format(t.Context(), test.library, nil); err != nil {
t.Fatal(err)
}
for _, aPath := range test.goFilePath {
Expand Down
46 changes: 36 additions & 10 deletions internal/librarian/golang/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,48 @@ package golang

import (
"context"
_ "embed"
"errors"
"fmt"

"github.com/googleapis/librarian/internal/command"
"github.com/googleapis/librarian/internal/config"
"github.com/googleapis/librarian/internal/yaml"
)

var tools = []string{
"github.com/googleapis/gapic-generator-go/cmd/protoc-gen-go_gapic@v0.58.0",
"golang.org/x/tools/cmd/goimports@latest",
"google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0",
"google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.11",
}
//go:embed librarian.yaml
var librarianYAML []byte

// ErrMissingToolVersion indicates a go tool entry is missing its version.
var ErrMissingToolVersion = errors.New("go tool missing version")
Comment thread
sofisl marked this conversation as resolved.
Outdated

// Install installs the tools required for Go library generation.
func Install(ctx context.Context) error {
for _, tool := range tools {
if err := command.Run(ctx, command.Go, "install", tool); err != nil {
return err
func Install(ctx context.Context, tools *config.Tools) error {
Comment thread
sofisl marked this conversation as resolved.
if tools == nil || len(tools.Go) == 0 {
Comment thread
sofisl marked this conversation as resolved.
Outdated
return installFallbackTools(ctx)
}
return installGoTools(ctx, tools.Go)
}

func installFallbackTools(ctx context.Context) error {
cfg, err := yaml.Unmarshal[config.Config](librarianYAML)
if err != nil {
return fmt.Errorf("parsing embedded librarian.yaml: %w", err)
}
if cfg.Tools == nil || len(cfg.Tools.Go) == 0 {
Comment thread
sofisl marked this conversation as resolved.
Outdated
return fmt.Errorf("no go tools defined in embedded librarian.yaml")
}
return installGoTools(ctx, cfg.Tools.Go)
}

func installGoTools(ctx context.Context, goTools []*config.GoTool) error {
for _, tool := range goTools {
if tool.Version == "" {
return fmt.Errorf("%w: %s", ErrMissingToolVersion, tool.Name)
}
toolStr := fmt.Sprintf("%s@%s", tool.Name, tool.Version)
if err := command.Run(ctx, command.Go, "install", toolStr); err != nil {
return fmt.Errorf("install %s: %w", toolStr, err)
Comment thread
sofisl marked this conversation as resolved.
Outdated
}
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion internal/librarian/golang/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
func TestInstall(t *testing.T) {
gobin := t.TempDir()
t.Setenv("GOBIN", gobin)
if err := Install(t.Context()); err != nil {
if err := Install(t.Context(), nil); err != nil {
t.Fatal(err)
}
suffix := ""
Expand Down
28 changes: 28 additions & 0 deletions internal/librarian/golang/librarian.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Comment thread
sofisl marked this conversation as resolved.
#
# TODO(https://github.com/googleapis/librarian/issues/5449): move this file to
# github.com/googleapis/google-cloud-go after the repository has migrated to
# librarian.
language: go
tools:
go:
- name: github.com/googleapis/gapic-generator-go/cmd/protoc-gen-go_gapic
version: v0.58.0
- name: golang.org/x/tools/cmd/goimports
version: v0.44.0
- name: google.golang.org/grpc/cmd/protoc-gen-go-grpc
version: v1.3.0
- name: google.golang.org/protobuf/cmd/protoc-gen-go
version: v1.36.11
9 changes: 7 additions & 2 deletions internal/librarian/librarian.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,22 @@ from librarian.yaml in the current directory.`,
if lang == "" {
lang = cfg.Language
}
var tools *config.Tools
if cfg != nil {
tools = cfg.Tools
}

switch lang {
case config.LanguageFake:
return nil
case config.LanguageGo:
return golang.Install(ctx)
return golang.Install(ctx, tools)
case config.LanguageNodejs:
return nodejs.Install(ctx)
case config.LanguagePython:
return python.Install(ctx)
case config.LanguageRust:
return rust.Install(ctx, cfg.Tools)
return rust.Install(ctx, tools)
default:
return fmt.Errorf("language %q does not support install", lang)
}
Expand Down
Loading