Repository: deepmap/oapi-codegen (go)

Issue:
Make FieldName, MethodName sanitization more robust
Since there are some weird specs out there, the code-generation fails on some edge-cases like
`+, ()` in the field-name.

It would be good to have this sanitized as well

Pull request description:
Fix #71 - Improve sanitization of typenames
This appends various weird characters to the blacklist
of characters, which are not compatible as a Go-method-name.

Fixes:

- #71 

Patch:
diff --git a/README.md b/README.md
index c99d50d..cdcd382 100644
--- a/README.md
+++ b/README.md
@@ -339,8 +339,9 @@ you can specify any combination of those.
 - `client`: generate the client boilerplate. It, too, requires the types to be
  present in its package.
 - `spec`: embed the OpenAPI spec into the generated code as a gzipped blob. This
- is useful for creating runtime validators.
- 
+- `skip-fmt`: skip running `go fmt` on the generated code. This is useful for debugging
+ the generated file in case the spec contains weird strings.
+
 So, for example, if you would like to produce only the server code, you could
 run `oapi-generate --generate types,server`. You could generate `types` and `server`
 into separate files, but both are required for the server code.  
diff --git a/cmd/oapi-codegen/oapi-codegen.go b/cmd/oapi-codegen/oapi-codegen.go
index 2fd4300..591c6f5 100644
--- a/cmd/oapi-codegen/oapi-codegen.go
+++ b/cmd/oapi-codegen/oapi-codegen.go
@@ -38,7 +38,7 @@ func main() {
 	)
 	flag.StringVar(&packageName, "package", "", "The package name for generated code")
 	flag.StringVar(&generate, "generate", "types,client,server,spec",
-		`Comma-separated list of code to generate; valid options: "types", client", "server", "spec"  (default types,client,server,"spec")`)
+		`Comma-separated list of code to generate; valid options: "types", client", "chi-server", "server", "skip-fmt", '"spec"  (default types,client,server,"spec")`)
 	flag.StringVar(&outputFile, "o", "", "Where to output generated code, stdout is default")
 	flag.Parse()
 
@@ -70,6 +70,8 @@ func main() {
 			opts.GenerateTypes = true
 		case "spec":
 			opts.EmbedSpec = true
+		case "skip-fmt":
+			opts.SkipFmt = true
 		default:
 			fmt.Printf("unknown generate option %s\n", g)
 			flag.PrintDefaults()
diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go
index f030dff..bc839a1 100644
--- a/pkg/codegen/codegen.go
+++ b/pkg/codegen/codegen.go
@@ -36,6 +36,7 @@ type Options struct {
 	GenerateClient     bool // GenerateClient specifies whether to generate client boilerplate
 	GenerateTypes      bool // GenerateTypes specifies whether to generate type definitions
 	EmbedSpec          bool // Whether to embed the swagger spec in the generated code
+	SkipFmt            bool // Whether to skip go fmt on the generated code
 }
 
 // Uses the Go templating engine to generate all of our server wrappers from
@@ -232,6 +233,9 @@ func Generate(swagger *openapi3.Swagger, packageName string, opts Options) (stri
 
 	// The generation code produces unindented horrors. Use the Go formatter
 	// to make it all pretty.
+	if opts.SkipFmt {
+		return goCode, nil
+	}
 	outBytes, err := format.Source([]byte(goCode))
 	if err != nil {
 		fmt.Println(goCode)
diff --git a/pkg/codegen/utils.go b/pkg/codegen/utils.go
index b10bc1b..5b8f883 100644
--- a/pkg/codegen/utils.go
+++ b/pkg/codegen/utils.go
@@ -53,10 +53,11 @@ func LowercaseFirstCharacter(str string) string {
 }
 
 // This function will convert query-arg style strings to CamelCase. We will
-// use (., -, _, ~, ' ') as valid delimiters for words. So, "word.word-word~word_word word"
-// would be converted to WordWordWordWord
+// use `., -, +, :, ;, _, ~, ' ', (, ), {, }, [, ]` as valid delimiters for words.
+// So, "word.word-word+word:word;word_word~word word(word)word{word}[word]"
+// would be converted to WordWordWordWordWordWordWordWordWordWordWordWordWord
 func ToCamelCase(str string) string {
-	separators := []string{".", "-", "_", "~", " "}
+	separators := []string{".", "-", "+", ":", ";", "_", "~", " ", "(", ")", "{", "}", "[", "]"}
 	in := []string{str}
 	out := make([]string, 0)
 


Test patch:
diff --git a/pkg/codegen/utils_test.go b/pkg/codegen/utils_test.go
index 39f6d8d..db4582b 100644
--- a/pkg/codegen/utils_test.go
+++ b/pkg/codegen/utils_test.go
@@ -22,7 +22,7 @@ import (
 
 func TestStringOps(t *testing.T) {
 	// Test that each substitution works
-	assert.Equal(t, "WordWordWORDWordWord", ToCamelCase("word.word-WORD_word~word"), "Camel case conversion failed")
+	assert.Equal(t, "WordWordWORDWordWordWordWordWordWordWordWordWordWord", ToCamelCase("word.word-WORD+Word_word~word(Word)Word{Word}Word[Word]Word:Word;"), "Camel case conversion failed")
 
 	// Make sure numbers don't interact in a funny way.
 	assert.Equal(t, "Number1234", ToCamelCase("number-1234"), "Number Camelcasing not working.")