Skip to content

Commit

Permalink
feat!: added support for detecting new vs old SDKs and cleaned up con…
Browse files Browse the repository at this point in the history
…fig access patterns
  • Loading branch information
TristanSpeakEasy committed Oct 27, 2023
1 parent 6d97658 commit 8694c27
Show file tree
Hide file tree
Showing 6 changed files with 286 additions and 108 deletions.
166 changes: 129 additions & 37 deletions config.go
Original file line number Diff line number Diff line change
@@ -1,41 +1,45 @@
package config

import (
"github.com/AlekSi/pointer"
"github.com/mitchellh/mapstructure"
)

const (
Version = "1.0.0"
GithubWritePermission = "write"

// Constants to be used as keys in the config files

BaseServerURL = "baseServerUrl"
SDKClassName = "sdkClassName"
SingleTagPerOp = "singleTagPerOp"
TagNamespacingDisabled = "tagNamespacingDisabled"
Languages = "languages"
Mode = "mode"
GithubAccessToken = "github_access_token"
SpeakeasyApiKey = "speakeasy_api_key"
SpeakeasyServerURL = "speakeasy_server_url"
OpenAPIDocAuthHeader = "openapi_doc_auth_header"
OpenAPIDocAuthToken = "openapi_doc_auth_token"
OpenAPIDocs = "openapi_docs"
OmitDescriptionIfSummaryPresent = "omitDescriptionIfSummaryPresent"
DisableComments = "disableComments"
ClientServerStatusCodesAsErrors = "clientServerStatusCodesAsErrors"
Languages = "languages"
Mode = "mode"
GithubAccessToken = "github_access_token"
SpeakeasyApiKey = "speakeasy_api_key"
SpeakeasyServerURL = "speakeasy_server_url"
OpenAPIDocAuthHeader = "openapi_doc_auth_header"
OpenAPIDocAuthToken = "openapi_doc_auth_token"
OpenAPIDocs = "openapi_docs"
)

var CommentFields = []string{DisableComments, OmitDescriptionIfSummaryPresent}

type Management struct {
DocChecksum string `yaml:"docChecksum"`
DocVersion string `yaml:"docVersion"`
SpeakeasyVersion string `yaml:"speakeasyVersion"`
GenerationVersion string `yaml:"generationVersion,omitempty"`
}

type Comments struct {
OmitDescriptionIfSummaryPresent bool `yaml:"omitDescriptionIfSummaryPresent,omitempty"`
DisableComments bool `yaml:"disableComments,omitempty"`
}

type Generation struct {
CommentFields map[string]bool `yaml:"comments,omitempty"`
DevContainers *DevContainers `yaml:"devContainers,omitempty"`
Fields map[string]any `yaml:",inline"`
Comments *Comments `yaml:"comments,omitempty"`
DevContainers *DevContainers `yaml:"devContainers,omitempty"`
BaseServerURL string `yaml:"baseServerUrl,omitempty"`
SDKClassName string `yaml:"sdkClassName,omitempty"`
SingleTagPerOp bool `yaml:"singleTagPerOp,omitempty"`
TagNamespacingDisabled bool `yaml:"tagNamespacingDisabled,omitempty"`
RepoURL string `yaml:"repoURL,omitempty"`
}

type DevContainers struct {
Expand All @@ -49,7 +53,7 @@ type LanguageConfig struct {
Cfg map[string]any `yaml:",inline"`
}

type SdkGenConfigField struct {
type SDKGenConfigField struct {
Name string `yaml:"name" json:"name"`
Required bool `yaml:"required" json:"required"`
RequiredForPublishing *bool `yaml:"requiredForPublishing,omitempty" json:"required_for_publishing,omitempty"`
Expand All @@ -59,14 +63,15 @@ type SdkGenConfigField struct {
SecretName *string `yaml:"secretName,omitempty" json:"secret_name,omitempty"`
ValidationRegex *string `yaml:"validationRegex,omitempty" json:"validation_regex,omitempty"`
ValidationMessage *string `yaml:"validationMessage,omitempty" json:"validation_message,omitempty"`
TestValue *any `yaml:"testValue,omitempty" json:"test_value,omitempty"`
}

type Config struct {
ConfigVersion string `yaml:"configVersion"`
Management *Management `yaml:"management,omitempty"`
Generation Generation `yaml:"generation"`
Languages map[string]LanguageConfig `yaml:",inline"`
New bool `yaml:"-"`
New map[string]bool `yaml:"-"`
Features map[string]map[string]string `yaml:"features,omitempty"`
}

Expand Down Expand Up @@ -133,32 +138,51 @@ type Force struct {
Default bool `yaml:"default"`
}

type SdkGenConfig struct {
SdkGenLanguageConfig map[string][]SdkGenConfigField `json:"language_configs"`
SdkGenCommonConfig []SdkGenConfigField `json:"common_config"`
type SDKGenConfig struct {
SDKGenLanguageConfig map[string][]SDKGenConfigField `json:"language_configs"`
SDKGenCommonConfig []SDKGenConfigField `json:"common_config"`
}

func GetDefaultConfig(getLangDefaultFunc GetLanguageDefaultFunc, langs ...string) (*Config, error) {
func GetDefaultConfig(newSDK bool, getLangDefaultFunc GetLanguageDefaultFunc, langs map[string]bool) (*Config, error) {
defaults := GetGenerationDefaults(newSDK)

fields := map[string]any{}
for _, field := range defaults {
if field.DefaultValue != nil {
fields[field.Name] = *field.DefaultValue
}
}

var genConfig Generation

d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Result: &genConfig,
TagName: "yaml",
})
if err != nil {
return nil, err
}

if err := d.Decode(fields); err != nil {
return nil, err
}

cfg := &Config{
ConfigVersion: Version,
Generation: Generation{
Fields: map[string]any{
SDKClassName: "SDK",
SingleTagPerOp: false,
},
},
Languages: map[string]LanguageConfig{},
Features: map[string]map[string]string{},
Generation: genConfig,
Languages: map[string]LanguageConfig{},
Features: map[string]map[string]string{},
New: map[string]bool{},
}

for _, lang := range langs {
for lang, new := range langs {
langDefault := &LanguageConfig{
Version: "0.0.1",
}

if getLangDefaultFunc != nil {
var err error
langDefault, err = getLangDefaultFunc(lang)
langDefault, err = getLangDefaultFunc(lang, new)
if err != nil {
return nil, err
}
Expand All @@ -169,3 +193,71 @@ func GetDefaultConfig(getLangDefaultFunc GetLanguageDefaultFunc, langs ...string

return cfg, nil
}

func GetGenerationDefaults(newSDK bool) []SDKGenConfigField {
return []SDKGenConfigField{
{
Name: "baseServerURL",
Required: false,
DefaultValue: ptr(""),
Description: pointer.To("The base URL of the server. This value will be used if global servers are not defined in the spec."),
ValidationRegex: pointer.To(`^(https?):\/\/([\w\-]+\.)+\w+(\/.*)?$`),
ValidationMessage: pointer.To("Must be a valid server URL"),
},
{
Name: "sdkClassName",
Required: false,
DefaultValue: ptr("SDK"),
Description: pointer.To("Generated name of the root SDK class"),
ValidationRegex: pointer.To(`^[\w.\-]+$`),
ValidationMessage: pointer.To("Letters, numbers, or .-_ only"),
},
{
Name: "tagNamespacingDisabled",
Required: false,
DefaultValue: ptr(false),
Description: pointer.To("All operations will be created under the root SDK class instead of being namespaced by tag"),
},
{
Name: "singleTagPerOp",
Required: false,
DefaultValue: ptr(false),
Description: pointer.To("Operations with multiple tags will only generate methods namespaced by the first tag"),
},
{
Name: "disableComments",
Required: false,
DefaultValue: ptr(false),
Description: pointer.To("Disable generating comments from spec on the SDK"),
},
{
Name: "omitDescriptionIfSummaryPresent",
Required: false,
DefaultValue: ptr(false),
Description: pointer.To("Omit generating comment descriptions if spec provides a summary"),
},
}
}

func (c *Config) GetGenerationFieldsMap() (map[string]any, error) {
fields := map[string]any{}

// Yes the decoder can encode too :face_palm:
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Result: &fields,
TagName: "yaml",
})
if err != nil {
return nil, err
}

if err := d.Decode(c.Generation); err != nil {
return nil, err
}

return fields, nil
}

func ptr(a any) *any {
return &a
}
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
module github.com/speakeasy-api/sdk-gen-config

go 1.19
go 1.21

require (
github.com/AlekSi/pointer v1.2.0
github.com/mitchellh/mapstructure v1.5.0
github.com/stretchr/testify v1.8.1
gopkg.in/yaml.v3 v3.0.1
)
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w=
github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
Loading

0 comments on commit 8694c27

Please sign in to comment.