Skip to content

Commit

Permalink
Add initial Python Repository config support (#2544)
Browse files Browse the repository at this point in the history
Co-authored-by: Philip K. Warren <[email protected]>
  • Loading branch information
stefanvanburen and pkwarren committed Nov 6, 2023
1 parent 9227f5f commit f7ec813
Show file tree
Hide file tree
Showing 7 changed files with 1,008 additions and 574 deletions.
52 changes: 52 additions & 0 deletions private/bufpkg/bufplugin/bufplugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ func PluginToProtoPluginRegistryType(plugin Plugin) registryv1alpha1.PluginRegis
registryType = registryv1alpha1.PluginRegistryType_PLUGIN_REGISTRY_TYPE_MAVEN
} else if plugin.Registry().Swift != nil {
registryType = registryv1alpha1.PluginRegistryType_PLUGIN_REGISTRY_TYPE_SWIFT
} else if plugin.Registry().Python != nil {
registryType = registryv1alpha1.PluginRegistryType_PLUGIN_REGISTRY_TYPE_PYTHON
}
}
return registryType
Expand Down Expand Up @@ -187,6 +189,12 @@ func PluginRegistryToProtoRegistryConfig(pluginRegistry *bufpluginconfig.Registr
} else if pluginRegistry.Swift != nil {
swiftConfig := SwiftRegistryConfigToProtoSwiftConfig(pluginRegistry.Swift)
registryConfig.RegistryConfig = &registryv1alpha1.RegistryConfig_SwiftConfig{SwiftConfig: swiftConfig}
} else if pluginRegistry.Python != nil {
pythonConfig, err := PythonRegistryConfigToProtoPythonConfig(pluginRegistry.Python)
if err != nil {
return nil, err
}
registryConfig.RegistryConfig = &registryv1alpha1.RegistryConfig_PythonConfig{PythonConfig: pythonConfig}
}
return registryConfig, nil
}
Expand Down Expand Up @@ -250,10 +258,54 @@ func ProtoRegistryConfigToPluginRegistry(config *registryv1alpha1.RegistryConfig
return nil, err
}
registryConfig.Swift = swiftConfig
} else if protoPythonConfig := config.GetPythonConfig(); protoPythonConfig != nil {
pythonConfig, err := ProtoPythonConfigToPythonRegistryConfig(protoPythonConfig)
if err != nil {
return nil, err
}
registryConfig.Python = pythonConfig
}
return registryConfig, nil
}

func ProtoPythonConfigToPythonRegistryConfig(protoPythonConfig *registryv1alpha1.PythonConfig) (*bufpluginconfig.PythonRegistryConfig, error) {
pythonConfig := &bufpluginconfig.PythonRegistryConfig{
RequiresPython: protoPythonConfig.RequiresPython,
}
switch protoPythonConfig.GetPackageType() {
case registryv1alpha1.PythonPackageType_PYTHON_PACKAGE_TYPE_RUNTIME:
pythonConfig.PackageType = "runtime"
case registryv1alpha1.PythonPackageType_PYTHON_PACKAGE_TYPE_STUB_ONLY:
pythonConfig.PackageType = "stub-only"
default:
return nil, fmt.Errorf("unknown package type: %v", protoPythonConfig.GetPackageType())
}
for _, runtimeLibrary := range protoPythonConfig.GetRuntimeLibraries() {
pythonConfig.Deps = append(pythonConfig.Deps, runtimeLibrary.DependencySpecification)
}
return pythonConfig, nil
}

func PythonRegistryConfigToProtoPythonConfig(pythonConfig *bufpluginconfig.PythonRegistryConfig) (*registryv1alpha1.PythonConfig, error) {
protoPythonConfig := &registryv1alpha1.PythonConfig{
RequiresPython: pythonConfig.RequiresPython,
}
switch pythonConfig.PackageType {
case "runtime":
protoPythonConfig.PackageType = registryv1alpha1.PythonPackageType_PYTHON_PACKAGE_TYPE_RUNTIME
case "stub-only":
protoPythonConfig.PackageType = registryv1alpha1.PythonPackageType_PYTHON_PACKAGE_TYPE_STUB_ONLY
default:
return nil, fmt.Errorf(`invalid python config package_type; expecting one of "runtime" or "stub-only", got %q`, pythonConfig.PackageType)
}
for _, dependencySpecification := range pythonConfig.Deps {
protoPythonConfig.RuntimeLibraries = append(protoPythonConfig.RuntimeLibraries, &registryv1alpha1.PythonConfig_RuntimeLibrary{
DependencySpecification: dependencySpecification,
})
}
return protoPythonConfig, nil
}

func ProtoSwiftConfigToSwiftRegistryConfig(protoSwiftConfig *registryv1alpha1.SwiftConfig) (*bufpluginconfig.SwiftRegistryConfig, error) {
swiftConfig := &bufpluginconfig.SwiftRegistryConfig{}
runtimeLibs := protoSwiftConfig.GetRuntimeLibraries()
Expand Down
42 changes: 32 additions & 10 deletions private/bufpkg/bufplugin/bufpluginconfig/bufpluginconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,19 @@ type Config struct {
// LicenseURL specifies where the plugin's license can be found.
LicenseURL string
// IntegrationGuideURL is an optional attribute used to specify where
// the the plugin integration guide can be found.
// the plugin integration guide can be found.
IntegrationGuideURL string
}

// RegistryConfig is the configuration for the registry of a plugin.
//
// Only one field will be set.
type RegistryConfig struct {
Go *GoRegistryConfig
NPM *NPMRegistryConfig
Maven *MavenRegistryConfig
Swift *SwiftRegistryConfig
Go *GoRegistryConfig
NPM *NPMRegistryConfig
Maven *MavenRegistryConfig
Swift *SwiftRegistryConfig
Python *PythonRegistryConfig
// Options is the set of options passed into the plugin for the
// remote registry.
//
Expand Down Expand Up @@ -230,6 +231,16 @@ type SwiftRegistryDependencyPlatformConfig struct {
WatchOS string
}

// PythonRegistryConfig is the registry configuration for a Python plugin.
type PythonRegistryConfig struct {
// Deps are the dependency specifications for the generated SDK.
Deps []string
// RequiresPython is the `Requires-Python` for the generated SDK.
RequiresPython string
// PackageType is the package type for the generated SDK.
PackageType string
}

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

Expand Down Expand Up @@ -355,11 +366,12 @@ type ExternalDependency struct {
// ExternalRegistryConfig is the external configuration for the registry
// of a plugin.
type ExternalRegistryConfig struct {
Go *ExternalGoRegistryConfig `json:"go,omitempty" yaml:"go,omitempty"`
NPM *ExternalNPMRegistryConfig `json:"npm,omitempty" yaml:"npm,omitempty"`
Maven *ExternalMavenRegistryConfig `json:"maven,omitempty" yaml:"maven,omitempty"`
Swift *ExternalSwiftRegistryConfig `json:"swift,omitempty" yaml:"swift,omitempty"`
Opts []string `json:"opts,omitempty" yaml:"opts,omitempty"`
Go *ExternalGoRegistryConfig `json:"go,omitempty" yaml:"go,omitempty"`
NPM *ExternalNPMRegistryConfig `json:"npm,omitempty" yaml:"npm,omitempty"`
Maven *ExternalMavenRegistryConfig `json:"maven,omitempty" yaml:"maven,omitempty"`
Swift *ExternalSwiftRegistryConfig `json:"swift,omitempty" yaml:"swift,omitempty"`
Python *ExternalPythonRegistryConfig `json:"python,omitempty" yaml:"python,omitempty"`
Opts []string `json:"opts,omitempty" yaml:"opts,omitempty"`
}

// ExternalGoRegistryConfig is the external registry configuration for a Go plugin.
Expand Down Expand Up @@ -467,6 +479,16 @@ type ExternalSwiftRegistryDependencyPlatformConfig struct {
WatchOS string `json:"watchos,omitempty" yaml:"watchos,omitempty"`
}

type ExternalPythonRegistryConfig struct {
// Deps are dependency specifications for the generated SDK.
Deps []string `json:"deps,omitempty" yaml:"deps,omitempty"`
// RequiresPython specifies the `Requires-Python` of the generated metadata file.
RequiresPython string `json:"requires_python,omitempty" yaml:"requires_python,omitempty"`
// PackageType is the type of package generated.
// Must be one of "runtime" or "stub-only".
PackageType string `json:"package_type,omitempty" yaml:"package_type,omitempty"`
}

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

func TestParsePluginConfigPythonYAML(t *testing.T) {
t.Parallel()
pluginConfig, err := ParseConfig(filepath.Join("testdata", "success", "python", "buf.plugin.yaml"))
require.NoError(t, err)
pluginIdentity, err := bufpluginref.PluginIdentityForString("buf.build/community/nipunn1313-mypy")
require.NoError(t, err)
require.Equal(
t,
&Config{
Name: pluginIdentity,
PluginVersion: "v3.5.0",
SourceURL: "https://github.com/nipunn1313/mypy-protobuf",
Description: "Generate mypy stub files from Protobuf definitions.",
SPDXLicenseID: "Apache-2.0",
LicenseURL: "https://github.com/nipunn1313/mypy-protobuf/blob/v3.5.0/LICENSE",
OutputLanguages: []string{"python"},
Registry: &RegistryConfig{
Python: &PythonRegistryConfig{
PackageType: "stub-only",
RequiresPython: ">=3.8",
Deps: []string{
"protobuf>=4.23.4",
"types-protobuf>=4.23.0.2",
},
},
},
},
pluginConfig,
)
}

func TestParsePluginConfigOptionsYAML(t *testing.T) {
t.Parallel()
pluginConfig, err := ParseConfig(filepath.Join("testdata", "success", "options", "buf.plugin.yaml"))
Expand Down
42 changes: 38 additions & 4 deletions private/bufpkg/bufplugin/bufpluginconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,19 @@ func newConfig(externalConfig ExternalConfig, options []ConfigOption) (*Config,

func newRegistryConfig(externalRegistryConfig ExternalRegistryConfig) (*RegistryConfig, error) {
var (
isGoEmpty = externalRegistryConfig.Go == nil
isNPMEmpty = externalRegistryConfig.NPM == nil
isMavenEmpty = externalRegistryConfig.Maven == nil
isSwiftEmpty = externalRegistryConfig.Swift == nil
isGoEmpty = externalRegistryConfig.Go == nil
isNPMEmpty = externalRegistryConfig.NPM == nil
isMavenEmpty = externalRegistryConfig.Maven == nil
isSwiftEmpty = externalRegistryConfig.Swift == nil
isPythonEmpty = externalRegistryConfig.Python == nil
)
var registryCount int
for _, isEmpty := range []bool{
isGoEmpty,
isNPMEmpty,
isMavenEmpty,
isSwiftEmpty,
isPythonEmpty,
} {
if !isEmpty {
registryCount++
Expand Down Expand Up @@ -150,6 +152,15 @@ func newRegistryConfig(externalRegistryConfig ExternalRegistryConfig) (*Registry
Swift: swiftRegistryConfig,
Options: options,
}, nil
case !isPythonEmpty:
pythonRegistryConfig, err := newPythonRegistryConfig(externalRegistryConfig.Python)
if err != nil {
return nil, err
}
return &RegistryConfig{
Python: pythonRegistryConfig,
Options: options,
}, nil
default:
return nil, errors.New("unknown registry configuration")
}
Expand Down Expand Up @@ -323,6 +334,29 @@ func swiftExternalDependencyToDependencyConfig(externalDep ExternalSwiftRegistry
}, nil
}

func newPythonRegistryConfig(externalPythonRegistryConfig *ExternalPythonRegistryConfig) (*PythonRegistryConfig, error) {
if externalPythonRegistryConfig == nil {
return nil, nil
}
var dependencySpecifications []string
for _, externalDependencySpecification := range externalPythonRegistryConfig.Deps {
if externalDependencySpecification == "" {
return nil, fmt.Errorf("python registry config cannot have an empty dependency specification")
}
dependencySpecifications = append(dependencySpecifications, externalDependencySpecification)
}
switch externalPythonRegistryConfig.PackageType {
case "runtime", "stub-only":
default:
return nil, errors.New(`python registry config package_type must be one of: "runtime" or "stub-only"`)
}
return &PythonRegistryConfig{
Deps: dependencySpecifications,
RequiresPython: externalPythonRegistryConfig.RequiresPython,
PackageType: externalPythonRegistryConfig.PackageType,
}, nil
}

func pluginIdentityForStringWithOverrideRemote(identityStr string, overrideRemote string) (bufpluginref.PluginIdentity, error) {
identity, err := bufpluginref.PluginIdentityForString(identityStr)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: v1
name: buf.build/community/nipunn1313-mypy
plugin_version: v3.5.0
source_url: https://github.com/nipunn1313/mypy-protobuf
description: Generate mypy stub files from Protobuf definitions.
spdx_license_id: Apache-2.0
license_url: https://github.com/nipunn1313/mypy-protobuf/blob/v3.5.0/LICENSE
output_languages:
- python
registry:
python:
package_type: "stub-only"
requires_python: ">=3.8"
deps:
- "protobuf>=4.23.4"
- "types-protobuf>=4.23.0.2"
Loading

0 comments on commit f7ec813

Please sign in to comment.