Skip to content

Commit

Permalink
Add Cargo Registry support to buf.plugin.yaml (#2956)
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanvanburen committed May 8, 2024
1 parent eaec0b4 commit 79f9211
Show file tree
Hide file tree
Showing 9 changed files with 1,004 additions and 574 deletions.
50 changes: 50 additions & 0 deletions private/bufpkg/bufplugin/bufplugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ func PluginToProtoPluginRegistryType(plugin Plugin) registryv1alpha1.PluginRegis
registryType = registryv1alpha1.PluginRegistryType_PLUGIN_REGISTRY_TYPE_SWIFT
} else if plugin.Registry().Python != nil {
registryType = registryv1alpha1.PluginRegistryType_PLUGIN_REGISTRY_TYPE_PYTHON
} else if plugin.Registry().Cargo != nil {
registryType = registryv1alpha1.PluginRegistryType_PLUGIN_REGISTRY_TYPE_CARGO
}
}
return registryType
Expand Down Expand Up @@ -195,6 +197,12 @@ func PluginRegistryToProtoRegistryConfig(pluginRegistry *bufpluginconfig.Registr
return nil, err
}
registryConfig.RegistryConfig = &registryv1alpha1.RegistryConfig_PythonConfig{PythonConfig: pythonConfig}
} else if pluginRegistry.Cargo != nil {
cargoConfig, err := CargoRegistryConfigToProtoCargoConfig(pluginRegistry.Cargo)
if err != nil {
return nil, err
}
registryConfig.RegistryConfig = &registryv1alpha1.RegistryConfig_CargoConfig{CargoConfig: cargoConfig}
}
return registryConfig, nil
}
Expand Down Expand Up @@ -264,10 +272,49 @@ func ProtoRegistryConfigToPluginRegistry(config *registryv1alpha1.RegistryConfig
return nil, err
}
registryConfig.Python = pythonConfig
} else if protoCargoConfig := config.GetCargoConfig(); protoCargoConfig != nil {
cargoConfig, err := ProtoCargoConfigToCargoRegistryConfig(protoCargoConfig)
if err != nil {
return nil, err
}
registryConfig.Cargo = cargoConfig
}
return registryConfig, nil
}

// ProtoCargoConfigToCargoRegistryConfig converts protoCargoConfig to an equivalent [*bufpluginconfig.CargoRegistryConfig].
func ProtoCargoConfigToCargoRegistryConfig(protoCargoConfig *registryv1alpha1.CargoConfig) (*bufpluginconfig.CargoRegistryConfig, error) {
cargoConfig := &bufpluginconfig.CargoRegistryConfig{
RustVersion: protoCargoConfig.RustVersion,
}
for _, dependency := range protoCargoConfig.RuntimeLibraries {
cargoConfig.Deps = append(cargoConfig.Deps, bufpluginconfig.CargoRegistryDependency{
Name: dependency.Name,
VersionRequirement: dependency.VersionRequirement,
DefaultFeatures: dependency.DefaultFeatures,
Features: dependency.Features,
})
}
return cargoConfig, nil
}

// CargoRegistryConfigToProtoCargoConfig converts cargoConfig to an equivalent [*registryv1alpha1.CargoConfig].
func CargoRegistryConfigToProtoCargoConfig(cargoConfig *bufpluginconfig.CargoRegistryConfig) (*registryv1alpha1.CargoConfig, error) {
protoCargoConfig := &registryv1alpha1.CargoConfig{
RustVersion: cargoConfig.RustVersion,
}
for _, dependency := range cargoConfig.Deps {
protoCargoConfig.RuntimeLibraries = append(protoCargoConfig.RuntimeLibraries, &registryv1alpha1.CargoConfig_RuntimeLibrary{
Name: dependency.Name,
VersionRequirement: dependency.VersionRequirement,
DefaultFeatures: dependency.DefaultFeatures,
Features: dependency.Features,
})
}
return protoCargoConfig, nil
}

// ProtoPythonConfigToPythonRegistryConfig converts protoPythonConfig to an equivalent [*bufpluginconfig.PythonRegistryConfig].
func ProtoPythonConfigToPythonRegistryConfig(protoPythonConfig *registryv1alpha1.PythonConfig) (*bufpluginconfig.PythonRegistryConfig, error) {
pythonConfig := &bufpluginconfig.PythonRegistryConfig{
RequiresPython: protoPythonConfig.RequiresPython,
Expand All @@ -286,6 +333,7 @@ func ProtoPythonConfigToPythonRegistryConfig(protoPythonConfig *registryv1alpha1
return pythonConfig, nil
}

// PythonRegistryConfigToProtoPythonConfig converts pythonConfig to an equivalent [*registryv1alpha1.PythonConfig].
func PythonRegistryConfigToProtoPythonConfig(pythonConfig *bufpluginconfig.PythonRegistryConfig) (*registryv1alpha1.PythonConfig, error) {
protoPythonConfig := &registryv1alpha1.PythonConfig{
RequiresPython: pythonConfig.RequiresPython,
Expand All @@ -306,6 +354,7 @@ func PythonRegistryConfigToProtoPythonConfig(pythonConfig *bufpluginconfig.Pytho
return protoPythonConfig, nil
}

// ProtoSwiftConfigToSwiftRegistryConfig converts protoSwiftConfig to an equivalent [*bufpluginconfig.SwiftRegistryConfig].
func ProtoSwiftConfigToSwiftRegistryConfig(protoSwiftConfig *registryv1alpha1.SwiftConfig) (*bufpluginconfig.SwiftRegistryConfig, error) {
swiftConfig := &bufpluginconfig.SwiftRegistryConfig{}
runtimeLibs := protoSwiftConfig.GetRuntimeLibraries()
Expand Down Expand Up @@ -340,6 +389,7 @@ func ProtoSwiftConfigToSwiftRegistryConfig(protoSwiftConfig *registryv1alpha1.Sw
return swiftConfig, nil
}

// SwiftRegistryConfigToProtoSwiftConfig converts swiftConfig to an equivalent [*registryv1alpha1.SwiftConfig].
func SwiftRegistryConfigToProtoSwiftConfig(swiftConfig *bufpluginconfig.SwiftRegistryConfig) *registryv1alpha1.SwiftConfig {
protoSwiftConfig := &registryv1alpha1.SwiftConfig{}
if swiftConfig.Dependencies != nil {
Expand Down
13 changes: 13 additions & 0 deletions private/bufpkg/bufplugin/bufplugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,19 @@ func TestPluginRegistryRoundTrip(t *testing.T) {
},
},
})
assertPluginRegistryRoundTrip(t, &bufpluginconfig.RegistryConfig{
Cargo: &bufpluginconfig.CargoRegistryConfig{
RustVersion: "1.60",
Deps: []bufpluginconfig.CargoRegistryDependency{
{
Name: "prost",
VersionRequirement: "0.12.3",
DefaultFeatures: true,
Features: []string{"some/feature"},
},
},
},
})
}

func assertPluginRegistryRoundTrip(t testing.TB, config *bufpluginconfig.RegistryConfig) {
Expand Down
50 changes: 50 additions & 0 deletions private/bufpkg/bufplugin/bufpluginconfig/bufpluginconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ type RegistryConfig struct {
Maven *MavenRegistryConfig
Swift *SwiftRegistryConfig
Python *PythonRegistryConfig
Cargo *CargoRegistryConfig
// Options is the set of options passed into the plugin for the
// remote registry.
//
Expand Down Expand Up @@ -241,6 +242,31 @@ type PythonRegistryConfig struct {
PackageType string
}

// CargoRegistryDependency defines a runtime dependency for a generated crate.
// It is the subset of a full Cargo dependency specification, which contains
// fields that are currently irrelevant for Generated SDKs.
// Ref: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
type CargoRegistryDependency struct {
// Name specifies the name of the dependency.
Name string
// VersionRequirement specifies the version requirement of the dependency.
VersionRequirement string
// DefaultFeatures specifies whether or not the default features will
// be enabled for the dependency.
DefaultFeatures bool
// Features specifies the features enabled for the dependency.
Features []string
}

// CargoRegistryConfig is the registry configuration for a Cargo plugin.
type CargoRegistryConfig struct {
// RustVersion specifies the minimum supported Rust version (MSRV) for the generated crate.
// Ref: https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field
RustVersion string
// Deps specifies the runtime dependencies of the crate.
Deps []CargoRegistryDependency
}

// ConfigOption is an optional option used when loading a Config.
type ConfigOption func(*configOptions)

Expand Down Expand Up @@ -371,6 +397,7 @@ type ExternalRegistryConfig struct {
Maven *ExternalMavenRegistryConfig `json:"maven,omitempty" yaml:"maven,omitempty"`
Swift *ExternalSwiftRegistryConfig `json:"swift,omitempty" yaml:"swift,omitempty"`
Python *ExternalPythonRegistryConfig `json:"python,omitempty" yaml:"python,omitempty"`
Cargo *ExternalCargoRegistryConfig `json:"cargo,omitempty" yaml:"cargo,omitempty"`
Opts []string `json:"opts,omitempty" yaml:"opts,omitempty"`
}

Expand Down Expand Up @@ -479,6 +506,7 @@ type ExternalSwiftRegistryDependencyPlatformConfig struct {
WatchOS string `json:"watchos,omitempty" yaml:"watchos,omitempty"`
}

// ExternalPythonRegistryConfig is the registry configuration for a Python plugin.
type ExternalPythonRegistryConfig struct {
// Deps are dependency specifications for the generated SDK.
Deps []string `json:"deps,omitempty" yaml:"deps,omitempty"`
Expand All @@ -489,6 +517,28 @@ type ExternalPythonRegistryConfig struct {
PackageType string `json:"package_type,omitempty" yaml:"package_type,omitempty"`
}

// ExternalCargoDependency specifies a runtime dependency for a Cargo generated SDK.
type ExternalCargoDependency struct {
// Name specifies the name of the dependency.
Name string `json:"name,omitempty" yaml:"name,omitempty"`
// VersionRequirement specifies the version requirement of the dependency.
VersionRequirement string `json:"req,omitempty" yaml:"req,omitempty"`
// DefaultFeatures specifies whether or not the default features will
// be enabled for the dependency.
DefaultFeatures bool `json:"default_features,omitempty" yaml:"default_features,omitempty"`
// Features specifies the features enabled for the dependency.
Features []string `json:"features,omitempty" yaml:"features,omitempty"`
}

// ExternalCargoRegistryConfig is the registry configuration for a Rust plugin.
type ExternalCargoRegistryConfig struct {
// RustVersion specifies the minimum supported Rust version (MSRV) for the generated crate.
// Ref: https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field
RustVersion string `json:"rust_version,omitempty" yaml:"rust_version,omitempty"`
// Deps specifies the dependencies for the generated SDK.
Deps []ExternalCargoDependency `json:"deps,omitempty" yaml:"deps,omitempty"`
}

type externalConfigVersion struct {
Version string `json:"version,omitempty" yaml:"version,omitempty"`
}
Expand Down
35 changes: 35 additions & 0 deletions private/bufpkg/bufplugin/bufpluginconfig/bufpluginconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,41 @@ func TestParsePluginConfigPythonYAML(t *testing.T) {
)
}

func TestParsePluginConfigCargoYAML(t *testing.T) {
t.Parallel()
pluginConfig, err := ParseConfig(filepath.Join("testdata", "success", "cargo", "buf.plugin.yaml"))
require.NoError(t, err)
pluginIdentity, err := bufpluginref.PluginIdentityForString("buf.build/community/neoeinstein-prost")
require.NoError(t, err)
require.Equal(
t,
&Config{
Name: pluginIdentity,
PluginVersion: "v0.3.1",
SourceURL: "https://github.com/neoeinstein/protoc-gen-prost",
Description: "Generates code using the Prost! code generation engine.",
SPDXLicenseID: "Apache-2.0",
LicenseURL: "https://github.com/neoeinstein/protoc-gen-prost/blob/protoc-gen-prost-v0.3.1/LICENSE",
OutputLanguages: []string{"rust"},
Registry: &RegistryConfig{
Cargo: &CargoRegistryConfig{
RustVersion: "1.60",
Deps: []CargoRegistryDependency{
{
Name: "prost",
VersionRequirement: "0.12.3",
DefaultFeatures: true,
Features: []string{"a-feature"},
},
},
},
Options: map[string]string{"enable_type_names": "true"},
},
},
pluginConfig,
)
}

func TestParsePluginConfigOptionsYAML(t *testing.T) {
t.Parallel()
pluginConfig, err := ParseConfig(filepath.Join("testdata", "success", "options", "buf.plugin.yaml"))
Expand Down
30 changes: 30 additions & 0 deletions private/bufpkg/bufplugin/bufpluginconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func newRegistryConfig(externalRegistryConfig ExternalRegistryConfig) (*Registry
isMavenEmpty = externalRegistryConfig.Maven == nil
isSwiftEmpty = externalRegistryConfig.Swift == nil
isPythonEmpty = externalRegistryConfig.Python == nil
isCargoEmpty = externalRegistryConfig.Cargo == nil
)
var registryCount int
for _, isEmpty := range []bool{
Expand All @@ -100,6 +101,7 @@ func newRegistryConfig(externalRegistryConfig ExternalRegistryConfig) (*Registry
isMavenEmpty,
isSwiftEmpty,
isPythonEmpty,
isCargoEmpty,
} {
if !isEmpty {
registryCount++
Expand Down Expand Up @@ -161,6 +163,15 @@ func newRegistryConfig(externalRegistryConfig ExternalRegistryConfig) (*Registry
Python: pythonRegistryConfig,
Options: options,
}, nil
case !isCargoEmpty:
cargoRegistryConfig, err := newCargoRegistryConfig(externalRegistryConfig.Cargo)
if err != nil {
return nil, err
}
return &RegistryConfig{
Cargo: cargoRegistryConfig,
Options: options,
}, nil
default:
return nil, errors.New("unknown registry configuration")
}
Expand Down Expand Up @@ -357,6 +368,25 @@ func newPythonRegistryConfig(externalPythonRegistryConfig *ExternalPythonRegistr
}, nil
}

func newCargoRegistryConfig(externalCargoRegistryConfig *ExternalCargoRegistryConfig) (*CargoRegistryConfig, error) {
if externalCargoRegistryConfig == nil {
return nil, nil
}
config := &CargoRegistryConfig{
RustVersion: externalCargoRegistryConfig.RustVersion,
}
for _, dependency := range externalCargoRegistryConfig.Deps {
if dependency.Name == "" {
return nil, fmt.Errorf("cargo registry dependency cannot have empty name")
}
if dependency.VersionRequirement == "" {
return nil, fmt.Errorf("cargo registry dependency cannot have empty req")
}
config.Deps = append(config.Deps, CargoRegistryDependency(dependency))
}
return config, nil
}

func pluginIdentityForStringWithOverrideRemote(identityStr string, overrideRemote string) (bufpluginref.PluginIdentity, error) {
identity, err := bufpluginref.PluginIdentityForString(identityStr)
if err != nil {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
version: v1
name: buf.build/community/neoeinstein-prost
plugin_version: v0.3.1
source_url: https://github.com/neoeinstein/protoc-gen-prost
description: Generates code using the Prost! code generation engine.
output_languages:
- rust
spdx_license_id: Apache-2.0
license_url: https://github.com/neoeinstein/protoc-gen-prost/blob/protoc-gen-prost-v0.3.1/LICENSE
registry:
# NOTE: This configuration does not perfectly match with the version in
# plugins, because we want values to be set to check for round-tripping.
cargo:
# https://github.com/neoeinstein/protoc-gen-prost/blob/protoc-gen-prost-v0.3.1/protoc-gen-prost/Cargo.toml#L21
# https://github.com/tokio-rs/prost/blob/v0.12.3/prost-build/Cargo.toml#L15
rust_version: "1.60"
deps:
# https://github.com/tokio-rs/prost/blob/v0.12.3/prost-build/Cargo.toml#L30
- name: prost
req: "0.12.3"
default_features: true
features: ["a-feature"]
# https://github.com/neoeinstein/protoc-gen-prost/tree/protoc-gen-prost-v0.3.1/protoc-gen-prost#options
opts:
# `Any` support.
- enable_type_names=true

0 comments on commit 79f9211

Please sign in to comment.