| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You 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 |
| // |
| // http://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. |
| |
| // Package bufconfig contains the configuration functionality. |
| package bufconfig |
| |
| import ( |
| "context" |
| "fmt" |
| ) |
| |
| import ( |
| "github.com/apache/dubbo-kubernetes/pkg/bufman/bufpkg/bufcheck/bufbreaking/bufbreakingconfig" |
| "github.com/apache/dubbo-kubernetes/pkg/bufman/bufpkg/bufcheck/buflint/buflintconfig" |
| "github.com/apache/dubbo-kubernetes/pkg/bufman/bufpkg/bufmodule/bufmoduleconfig" |
| "github.com/apache/dubbo-kubernetes/pkg/bufman/bufpkg/bufmodule/bufmoduleref" |
| "github.com/apache/dubbo-kubernetes/pkg/bufman/pkg/storage" |
| ) |
| |
| const ( |
| // ExternalConfigV1FilePath is the default configuration file path. |
| ExternalConfigV1FilePath = "buf.yaml" |
| |
| // ExternalConfigV1Beta1FilePath is the v1beta1 file path. |
| ExternalConfigV1Beta1FilePath = "buf.yaml" |
| |
| // V1Version is the v1 version. |
| V1Version = "v1" |
| |
| // V1Beta1Version is the v1beta1 version. |
| V1Beta1Version = "v1beta1" |
| |
| // backupExternalConfigV1FilePath is another acceptable configuration file path for v1. |
| // |
| // Originally we thought we were going to move to buf.mod, and had this around for |
| // a while, but then reverted back to buf.yaml. We still need to support buf.mod as |
| // we released with it, however. |
| backupExternalConfigV1FilePath = "buf.mod" |
| ) |
| |
| var ( |
| // All versions are all the versions in order. |
| AllVersions = []string{ |
| V1Beta1Version, |
| V1Version, |
| } |
| |
| // AllConfigFilePaths are all acceptable config file paths without overrides. |
| // |
| // These are in the order we should check. |
| AllConfigFilePaths = []string{ |
| ExternalConfigV1FilePath, |
| backupExternalConfigV1FilePath, |
| } |
| ) |
| |
| // Config is the user config. |
| type Config struct { |
| Version string |
| ModuleIdentity bufmoduleref.ModuleIdentity |
| Build *bufmoduleconfig.Config |
| Breaking *bufbreakingconfig.Config |
| Lint *buflintconfig.Config |
| } |
| |
| // GetConfigForBucket gets the Config for the YAML data at ConfigFilePath. |
| // |
| // If the data is of length 0, returns the default config. |
| func GetConfigForBucket(ctx context.Context, readBucket storage.ReadBucket) (*Config, error) { |
| return getConfigForBucket(ctx, readBucket) |
| } |
| |
| // GetConfigForData gets the Config for the given JSON or YAML data. |
| // |
| // If the data is of length 0, returns the default config. |
| func GetConfigForData(ctx context.Context, data []byte) (*Config, error) { |
| return getConfigForData(ctx, data) |
| } |
| |
| // WriteConfig writes an initial configuration file into the bucket. |
| func WriteConfig( |
| ctx context.Context, |
| writeBucket storage.WriteBucket, |
| options ...WriteConfigOption, |
| ) error { |
| return writeConfig( |
| ctx, |
| writeBucket, |
| options..., |
| ) |
| } |
| |
| // WriteConfigOption is an option for WriteConfig. |
| type WriteConfigOption func(*writeConfigOptions) |
| |
| // WriteConfigWithDocumentationComments returns a new WriteConfigOption that documents the resulting configuration file. |
| func WriteConfigWithDocumentationComments() WriteConfigOption { |
| return func(writeConfigOptions *writeConfigOptions) { |
| writeConfigOptions.documentationComments = true |
| } |
| } |
| |
| // WriteConfigWithUncomment returns a new WriteConfigOption that uncomments the resulting configuration file |
| // options that are commented out by default. |
| // |
| // If this option is used, WriteConfigWithDocumentationComments must also be used. |
| func WriteConfigWithUncomment() WriteConfigOption { |
| return func(writeConfigOptions *writeConfigOptions) { |
| writeConfigOptions.uncomment = true |
| } |
| } |
| |
| // WriteConfigWithModuleIdentity returns a new WriteConfigOption that sets the name of the |
| // module to the given ModuleIdentity. |
| // |
| // The default is to not set the name. |
| // |
| // Only use in tests. |
| func WriteConfigWithModuleIdentity(moduleIdentity bufmoduleref.ModuleIdentity) WriteConfigOption { |
| return func(writeConfigOptions *writeConfigOptions) { |
| writeConfigOptions.moduleIdentity = moduleIdentity |
| } |
| } |
| |
| // WriteConfigWithDependencyModuleReferences returns a new WriteConfigOption that sets the |
| // dependencies of the module. |
| // |
| // The default is to not have any dependencies. |
| // If this option is used, WriteConfigWithModuleIdentity must also be used. |
| // |
| // Only use in tests. |
| func WriteConfigWithDependencyModuleReferences(dependencyModuleReferences ...bufmoduleref.ModuleReference) WriteConfigOption { |
| return func(writeConfigOptions *writeConfigOptions) { |
| writeConfigOptions.dependencyModuleReferences = dependencyModuleReferences |
| } |
| } |
| |
| // WriteConfigWithBreakingConfig returns a new WriteConfigOption that sets the breaking change |
| // config for the module. |
| // |
| // If this option is used then the version used must be consistent with the rest of the config. |
| func WriteConfigWithBreakingConfig(breakingConfig *bufbreakingconfig.Config) WriteConfigOption { |
| return func(writeConfigOptions *writeConfigOptions) { |
| writeConfigOptions.breakingConfig = breakingConfig |
| } |
| } |
| |
| // WriteConfigWithLintConfig returns a new WriteConfigOption that sets the lint config for the module. |
| // |
| // If this option is used then the version used must be consistent with the rest of the config. |
| func WriteConfigWithLintConfig(lintConfig *buflintconfig.Config) WriteConfigOption { |
| return func(writeConfigOptions *writeConfigOptions) { |
| writeConfigOptions.lintConfig = lintConfig |
| } |
| } |
| |
| // WriteConfigWithVersion returns a new WriteConfigOption that sets the version of the config |
| // being written. |
| // |
| // If this is not set, the default is v1beta1. |
| func WriteConfigWithVersion(version string) WriteConfigOption { |
| return func(writeConfigOptions *writeConfigOptions) { |
| writeConfigOptions.version = version |
| } |
| } |
| |
| // ReadConfigOS reads the configuration from the OS or an override, if any. |
| // |
| // ONLY USE IN CLI TOOLS. |
| func ReadConfigOS( |
| ctx context.Context, |
| readBucket storage.ReadBucket, |
| options ...ReadConfigOSOption, |
| ) (*Config, error) { |
| return readConfigOS( |
| ctx, |
| readBucket, |
| options..., |
| ) |
| } |
| |
| // ReadConfigOSOption is an option for ReadConfig. |
| type ReadConfigOSOption func(*readConfigOSOptions) |
| |
| // ReadConfigOSWithOverride sets the override. |
| // |
| // If override is set, this will first check if the override ends in .json or .yaml, if so, |
| // this reads the file at this path and uses it. Otherwise, this assumes this is configuration |
| // data in either JSON or YAML format, and unmarshals it. |
| // |
| // If no override is set, this reads ExternalConfigFilePath in the bucket. |
| func ReadConfigOSWithOverride(override string) ReadConfigOSOption { |
| return func(readConfigOSOptions *readConfigOSOptions) { |
| readConfigOSOptions.override = override |
| } |
| } |
| |
| // ExistingConfigFilePath checks if a configuration file exists, and if so, returns the path |
| // within the ReadBucket of this configuration file. |
| // |
| // Returns empty string and no error if no configuration file exists. |
| func ExistingConfigFilePath(ctx context.Context, readBucket storage.ReadBucket) (string, error) { |
| for _, configFilePath := range AllConfigFilePaths { |
| exists, err := storage.Exists(ctx, readBucket, configFilePath) |
| if err != nil { |
| return "", err |
| } |
| if exists { |
| return configFilePath, nil |
| } |
| } |
| return "", nil |
| } |
| |
| // ValidateVersion checks that a given version string is valid. |
| func ValidateVersion(version string) error { |
| switch version { |
| case V1Version, V1Beta1Version: |
| return nil |
| default: |
| return fmt.Errorf("invalid config version %q provided", version) |
| } |
| } |
| |
| // ExternalConfigV1Beta1 represents the on-disk representation of the Config |
| // at version v1beta1. |
| type ExternalConfigV1Beta1 struct { |
| Version string `json:"version,omitempty" yaml:"version,omitempty"` |
| Name string `json:"name,omitempty" yaml:"name,omitempty"` |
| Deps []string `json:"deps,omitempty" yaml:"deps,omitempty"` |
| Build bufmoduleconfig.ExternalConfigV1Beta1 `json:"build,omitempty" yaml:"build,omitempty"` |
| Breaking bufbreakingconfig.ExternalConfigV1Beta1 `json:"breaking,omitempty" yaml:"breaking,omitempty"` |
| Lint buflintconfig.ExternalConfigV1Beta1 `json:"lint,omitempty" yaml:"lint,omitempty"` |
| } |
| |
| // ExternalConfigV1 represents the on-disk representation of the Config |
| // at version v1. |
| type ExternalConfigV1 struct { |
| Version string `json:"version,omitempty" yaml:"version,omitempty"` |
| Name string `json:"name,omitempty" yaml:"name,omitempty"` |
| Deps []string `json:"deps,omitempty" yaml:"deps,omitempty"` |
| Build bufmoduleconfig.ExternalConfigV1 `json:"build,omitempty" yaml:"build,omitempty"` |
| Breaking bufbreakingconfig.ExternalConfigV1 `json:"breaking,omitempty" yaml:"breaking,omitempty"` |
| Lint buflintconfig.ExternalConfigV1 `json:"lint,omitempty" yaml:"lint,omitempty"` |
| } |
| |
| // ExternalConfigVersion defines the subset of all config |
| // file versions that is used to determine the configuration version. |
| type ExternalConfigVersion struct { |
| Version string `json:"version,omitempty" yaml:"version,omitempty"` |
| } |