diff --git a/examples/swagger/simple/str_key/models/my_config.k b/examples/swagger/simple/str_key/models/my_config.k new file mode 100644 index 0000000..3c5612a --- /dev/null +++ b/examples/swagger/simple/str_key/models/my_config.k @@ -0,0 +1,24 @@ +""" +This file was generated by the KCL auto-gen tool. DO NOT EDIT. +Editing this file might prove futile when you re-run the KCL auto-gen generate command. +""" + + +schema My_Config: + r""" + my config + + Attributes + ---------- + "my-name" : str, default is Undefined, optional + my name + "my-labels" : {str:int}, default is Undefined, optional + my labels + """ + + + "my-name"?: str + + "my-labels"?: {str:int} + + diff --git a/examples/swagger/simple/str_key/str_key.golden.yaml b/examples/swagger/simple/str_key/str_key.golden.yaml new file mode 100644 index 0000000..9811c6c --- /dev/null +++ b/examples/swagger/simple/str_key/str_key.golden.yaml @@ -0,0 +1,15 @@ +definitions: + My-Config: + type: object + properties: + my-name: + type: string + my-labels: + type: object + additionalProperties: + type: integer +swagger: "2.0" +info: + title: kcl + version: v0.0.2 +paths: {} diff --git a/pkg/kube_resource/generator/testdata/array_branch/models/operator_victoriametrics_com_v1beta1_vm_agent.k b/pkg/kube_resource/generator/testdata/array_branch/models/operator_victoriametrics_com_v1beta1_vm_agent.k index 19ee1d3..9a797bf 100644 --- a/pkg/kube_resource/generator/testdata/array_branch/models/operator_victoriametrics_com_v1beta1_vm_agent.k +++ b/pkg/kube_resource/generator/testdata/array_branch/models/operator_victoriametrics_com_v1beta1_vm_agent.k @@ -43,7 +43,7 @@ schema OperatorVictoriametricsComV1beta1VMAgentSpec: Attributes ---------- - _ : str, default is Undefined, optional + "-" : str, default is Undefined, optional ParsingError contents error with context if operator was failed to parse json object from kubernetes api server affinity : any, default is Undefined, optional Affinity If specified, the pod's scheduling constraints. @@ -208,7 +208,7 @@ schema OperatorVictoriametricsComV1beta1VMAgentSpec: """ - _?: str + "-"?: str affinity?: any diff --git a/pkg/swagger/generator/language.go b/pkg/swagger/generator/language.go index 11fb8d4..1214284 100644 --- a/pkg/swagger/generator/language.go +++ b/pkg/swagger/generator/language.go @@ -21,6 +21,7 @@ import ( "path" "path/filepath" "reflect" + "regexp" "sort" "strings" @@ -32,6 +33,7 @@ import ( var ( // DefaultLanguageFunc defines the default generation language DefaultLanguageFunc func() *LanguageOpts + validNameRegexp = regexp.MustCompile(`\$?^[a-zA-Z_][a-zA-Z0-9_]*$`) ) const ( @@ -91,12 +93,12 @@ func (l *LanguageOpts) MangleVarName(name string) string { // MangleModelName adds "$" prefix to name if it is conflict with KCL keyword func (l *LanguageOpts) MangleModelName(modelName string) string { - // replace all the "-" to "_" in the model name lastDotIndex := strings.LastIndex(modelName, ".") shortName := modelName[lastDotIndex+1:] - if strings.Contains(shortName, "-") { - log.Printf("[WARN] the modelName %s contains symbol '-' which is forbidden in KCL. Will be replaced by '_'", shortName) - modelName = modelName[:lastDotIndex+1] + strings.Replace(shortName, "-", "_", -1) + // Replace all the "-" to "_" in the model name + if strings.Contains(shortName, "-") || strings.Contains(shortName, ".") { + log.Printf("[WARN] the modelName %s contains symbols '-' or '.' which is forbidden in KCL. Will be replaced by '_'", shortName) + modelName = modelName[:lastDotIndex+1] + strings.Replace(strings.Replace(shortName, "-", "_", -1), ".", "_", -1) } for _, kw := range l.ReservedWords { if modelName == kw { @@ -106,6 +108,19 @@ func (l *LanguageOpts) MangleModelName(modelName string) string { return modelName } +// ManglePropertyName adds "$" prefix to name if it is conflict with KCL keyword or adds quotes " +func (l *LanguageOpts) ManglePropertyName(name string) string { + if !validNameRegexp.MatchString(name) { + name = fmt.Sprintf(`"%s"`, name) + } + for _, kw := range l.ReservedWords { + if name == kw { + return fmt.Sprintf("$%s", name) + } + } + return name +} + // MangleFileName makes sure a file name gets a safe name func (l *LanguageOpts) MangleFileName(name string) string { if l.fileNameFunc != nil { diff --git a/pkg/swagger/generator/model.go b/pkg/swagger/generator/model.go index 7542dae..f5caf84 100644 --- a/pkg/swagger/generator/model.go +++ b/pkg/swagger/generator/model.go @@ -1184,7 +1184,7 @@ func (sg *schemaGenContext) buildItems() error { // This is a tuple, build a new model that represents this if sg.Named { sg.GenSchema.Name = sg.Name - sg.GenSchema.EscapedName = DefaultLanguageFunc().MangleModelName(sg.GenSchema.Name) + sg.GenSchema.EscapedName = DefaultLanguageFunc().ManglePropertyName(sg.GenSchema.Name) sg.GenSchema.KclType = sg.TypeResolver.kclTypeName(sg.Name) for i, s := range sg.Schema.Items.Schemas { elProp := sg.NewTupleElement(&s, i) @@ -1211,7 +1211,7 @@ func (sg *schemaGenContext) buildItems() error { } sg.MergeResult(elProp, false) elProp.GenSchema.Name = "p" + strconv.Itoa(i) - elProp.GenSchema.EscapedName = DefaultLanguageFunc().MangleModelName(elProp.GenSchema.Name) + elProp.GenSchema.EscapedName = DefaultLanguageFunc().ManglePropertyName(elProp.GenSchema.Name) sg.GenSchema.Properties = append(sg.GenSchema.Properties, elProp.GenSchema) sg.GenSchema.IsTuple = true } @@ -1433,7 +1433,7 @@ func (sg *schemaGenContext) makeGenSchema() error { sg.GenSchema.KeyVar = sg.KeyVar sg.GenSchema.OriginalName = sg.Name sg.GenSchema.Name = sg.KclName() - sg.GenSchema.EscapedName = DefaultLanguageFunc().MangleModelName(sg.GenSchema.Name) + sg.GenSchema.EscapedName = DefaultLanguageFunc().ManglePropertyName(sg.GenSchema.Name) sg.GenSchema.Title = sg.Schema.Title sg.GenSchema.Description = trimBOM(sg.Schema.Description) sg.GenSchema.ReceiverName = sg.Receiver diff --git a/pkg/swagger/generator/template_repo.go b/pkg/swagger/generator/template_repo.go index ee3982a..bb005a7 100644 --- a/pkg/swagger/generator/template_repo.go +++ b/pkg/swagger/generator/template_repo.go @@ -133,15 +133,12 @@ func DefaultFuncMap(lang *LanguageOpts) template.FuncMap { var properties GenSchemaList for _, one := range allOf { if !one.IsBaseType { - for _, p := range one.Properties { - properties = append(properties, p) - } + properties = append(properties, one.Properties...) } } return properties }, "toKCLValue": lang.ToKclValue, - "escapeKeyword": lang.MangleModelName, "nonEmptyValue": lang.NonEmptyValue, } }