Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configurable base plugin support in buf.plugin.yaml #3513

Merged
merged 7 commits into from
Dec 6, 2024
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
10 changes: 10 additions & 0 deletions private/bufpkg/bufremoteplugin/bufremoteplugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ func PluginRegistryToProtoRegistryConfig(pluginRegistry *bufremotepluginconfig.R
case pluginRegistry.Go != nil:
goConfig := &registryv1alpha1.GoConfig{}
goConfig.MinimumVersion = pluginRegistry.Go.MinVersion
if pluginRegistry.Go.BasePluginIdentity != nil {
goConfig.BasePluginName = pluginRegistry.Go.BasePluginIdentity.IdentityString()
}
if pluginRegistry.Go.Deps != nil {
goConfig.RuntimeLibraries = make([]*registryv1alpha1.GoConfig_RuntimeLibrary, 0, len(pluginRegistry.Go.Deps))
for _, dependency := range pluginRegistry.Go.Deps {
Expand Down Expand Up @@ -249,6 +252,13 @@ func ProtoRegistryConfigToPluginRegistry(config *registryv1alpha1.RegistryConfig
case config.GetGoConfig() != nil:
goConfig := &bufremotepluginconfig.GoRegistryConfig{}
goConfig.MinVersion = config.GetGoConfig().GetMinimumVersion()
if config.GetGoConfig().GetBasePluginName() != "" {
basePluginIdentity, err := bufremotepluginref.PluginIdentityForString(config.GetGoConfig().GetBasePluginName())
if err != nil {
return nil, err
}
goConfig.BasePluginIdentity = basePluginIdentity
}
runtimeLibraries := config.GetGoConfig().GetRuntimeLibraries()
if runtimeLibraries != nil {
goConfig.Deps = make([]*bufremotepluginconfig.GoRegistryDependencyConfig, 0, len(runtimeLibraries))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ type RegistryConfig struct {

// GoRegistryConfig is the registry configuration for a Go plugin.
type GoRegistryConfig struct {
MinVersion string
Deps []*GoRegistryDependencyConfig
MinVersion string
Deps []*GoRegistryDependencyConfig
BasePluginIdentity bufremotepluginref.PluginIdentity
}

// GoRegistryDependencyConfig is the go registry dependency configuration.
Expand Down Expand Up @@ -440,6 +441,7 @@ type ExternalGoRegistryConfig struct {
Module string `json:"module,omitempty" yaml:"module,omitempty"`
Version string `json:"version,omitempty" yaml:"version,omitempty"`
} `json:"deps,omitempty" yaml:"deps,omitempty"`
BasePluginName string `json:"base_plugin_name,omitempty" yaml:"base_plugin_name,omitempty"`
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
BasePluginName string `json:"base_plugin_name,omitempty" yaml:"base_plugin_name,omitempty"`
BasePlugin string `json:"base_plugin,omitempty" yaml:"base_plugin,omitempty"`

This might be clearer and more concise. The intended format is remote/owner/plugin

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in a2edfb7 to "base plugin" terminology.

}

// ExternalNPMRegistryConfig is the external registry configuration for a JavaScript NPM plugin.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ func TestGetConfigForBucket(t *testing.T) {
require.NoError(t, err)
pluginDependency, err := bufremotepluginref.PluginReferenceForString("buf.build/library/go:v1.28.0", 1)
require.NoError(t, err)
basePluginIdentity, err := bufremotepluginref.PluginIdentityForString("buf.build/library/go")
require.NoError(t, err)
require.Equal(
t,
&Config{
Expand All @@ -53,7 +55,8 @@ func TestGetConfigForBucket(t *testing.T) {
OutputLanguages: []string{"go"},
Registry: &RegistryConfig{
Go: &GoRegistryConfig{
MinVersion: "1.18",
MinVersion: "1.18",
BasePluginIdentity: basePluginIdentity,
Deps: []*GoRegistryDependencyConfig{
{
Module: "google.golang.org/grpc",
Expand Down Expand Up @@ -82,6 +85,8 @@ func TestParsePluginConfigGoYAML(t *testing.T) {
require.NoError(t, err)
pluginDependency, err := bufremotepluginref.PluginReferenceForString("buf.build/library/go:v1.28.0", 1)
require.NoError(t, err)
basePluginIdentity, err := bufremotepluginref.PluginIdentityForString("buf.build/library/go")
require.NoError(t, err)
require.Equal(
t,
&Config{
Expand All @@ -95,7 +100,8 @@ func TestParsePluginConfigGoYAML(t *testing.T) {
OutputLanguages: []string{"go"},
Registry: &RegistryConfig{
Go: &GoRegistryConfig{
MinVersion: "1.18",
MinVersion: "1.18",
BasePluginIdentity: basePluginIdentity,
Deps: []*GoRegistryDependencyConfig{
{
Module: "google.golang.org/grpc",
Expand Down
44 changes: 35 additions & 9 deletions private/bufpkg/bufremoteplugin/bufremotepluginconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package bufremotepluginconfig
import (
"errors"
"fmt"
"slices"
"strings"

"buf.build/go/spdx"
Expand Down Expand Up @@ -60,7 +61,7 @@ func newConfig(externalConfig ExternalConfig, options []ConfigOption) (*Config,
dependencies = append(dependencies, reference)
}
}
registryConfig, err := newRegistryConfig(externalConfig.Registry)
registryConfig, err := newRegistryConfig(externalConfig.Registry, dependencies, opts.overrideRemote)
if err != nil {
return nil, err
}
Expand All @@ -87,7 +88,11 @@ func newConfig(externalConfig ExternalConfig, options []ConfigOption) (*Config,
}, nil
}

func newRegistryConfig(externalRegistryConfig ExternalRegistryConfig) (*RegistryConfig, error) {
func newRegistryConfig(
externalRegistryConfig ExternalRegistryConfig,
pluginDependencies []bufremotepluginref.PluginReference,
overrideRemote string,
) (*RegistryConfig, error) {
var (
isGoEmpty = externalRegistryConfig.Go == nil
isNPMEmpty = externalRegistryConfig.NPM == nil
Expand Down Expand Up @@ -125,7 +130,7 @@ func newRegistryConfig(externalRegistryConfig ExternalRegistryConfig) (*Registry
options := OptionsSliceToPluginOptions(externalRegistryConfig.Opts)
switch {
case !isGoEmpty:
goRegistryConfig, err := newGoRegistryConfig(externalRegistryConfig.Go)
goRegistryConfig, err := newGoRegistryConfig(externalRegistryConfig.Go, pluginDependencies, overrideRemote)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -242,14 +247,18 @@ func newNPMRegistryConfig(externalNPMRegistryConfig *ExternalNPMRegistryConfig)
}, nil
}

func newGoRegistryConfig(externalGoRegistryConfig *ExternalGoRegistryConfig) (*GoRegistryConfig, error) {
func newGoRegistryConfig(
externalGoRegistryConfig *ExternalGoRegistryConfig,
pluginDependencies []bufremotepluginref.PluginReference,
overrideRemote string,
) (*GoRegistryConfig, error) {
if externalGoRegistryConfig == nil {
return nil, nil
}
if externalGoRegistryConfig.MinVersion != "" && !modfile.GoVersionRE.MatchString(externalGoRegistryConfig.MinVersion) {
return nil, fmt.Errorf("the go minimum version %q must be a valid semantic version in the form of <major>.<minor>", externalGoRegistryConfig.MinVersion)
}
var dependencies []*GoRegistryDependencyConfig
var runtimeDependencies []*GoRegistryDependencyConfig
for _, dep := range externalGoRegistryConfig.Deps {
if dep.Module == "" {
return nil, errors.New("go runtime dependency requires a non-empty module name")
Expand All @@ -260,17 +269,34 @@ func newGoRegistryConfig(externalGoRegistryConfig *ExternalGoRegistryConfig) (*G
if !semver.IsValid(dep.Version) {
return nil, fmt.Errorf("go runtime dependency %s:%s does not have a valid semantic version", dep.Module, dep.Version)
}
dependencies = append(
dependencies,
runtimeDependencies = append(
runtimeDependencies,
&GoRegistryDependencyConfig{
Module: dep.Module,
Version: dep.Version,
},
)
}
// If a base plugin name is specified, it must also exist in the top-level plugin dependencies
// list.
var basePluginIdentity bufremotepluginref.PluginIdentity
if externalGoRegistryConfig.BasePluginName != "" {
var err error
basePluginIdentity, err = pluginIdentityForStringWithOverrideRemote(externalGoRegistryConfig.BasePluginName, overrideRemote)
if err != nil {
return nil, fmt.Errorf("failed to parse base plugin: %w", err)
}
ok := slices.ContainsFunc(pluginDependencies, func(ref bufremotepluginref.PluginReference) bool {
return ref.IdentityString() == basePluginIdentity.IdentityString()
})
if !ok {
return nil, fmt.Errorf("base plugin %q not found in plugin dependencies", externalGoRegistryConfig.BasePluginName)
}
}
return &GoRegistryConfig{
MinVersion: externalGoRegistryConfig.MinVersion,
Deps: dependencies,
MinVersion: externalGoRegistryConfig.MinVersion,
Deps: runtimeDependencies,
BasePluginIdentity: basePluginIdentity,
}, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ deps:
output_languages: [go]
registry:
go:
base_plugin_name: buf.build/library/go
min_version: 1.18
deps:
- module: google.golang.org/grpc
Expand Down
Loading
Loading