feat: add SetGlobalStateOptions and ResetGlobalState#2393
Conversation
Add SetGlobalStateOptions to allow setting globalState.options without calling Generate, following the pattern established by SetGlobalStateSpec (PR oapi-codegen#1174). Add ResetGlobalState to reset all global state fields to their zero values, preventing state leakage between successive Generate calls when using oapi-codegen as a library. Fixes oapi-codegen#1805
Greptile SummaryThis PR adds APIs for controlling codegen's package-level state. The main changes are:
Confidence Score: 3/5This is close, but the reset behavior should be fixed before merging.
|
| Filename | Overview |
|---|---|
| pkg/codegen/codegen.go | Adds global state helper APIs, but the reset helper misses option-derived package globals outside globalState. |
Reviews (1): Last reviewed commit: "feat: add SetGlobalStateOptions and Rese..." | Re-trigger Greptile
| func ResetGlobalState() { | ||
| globalState.options = Configuration{} | ||
| globalState.spec = nil | ||
| globalState.importMapping = nil | ||
| globalState.initialismsMap = nil | ||
| globalState.typeMapping = TypeMapping{} | ||
| globalState.resolvedNames = nil | ||
| globalState.resolvedClientWrapperNames = nil | ||
| globalState.streamingContentTypeRegexes = nil | ||
| } |
There was a problem hiding this comment.
Generate mutates the package-level responseTypeSuffix when OutputOptions.ResponseTypeSuffix is set, but this reset path does not restore it. When a library caller generates once with a custom suffix, calls ResetGlobalState(), and then generates again with default options, the second output still uses the old suffix because Generate only writes responseTypeSuffix for non-empty overrides. That leaves types like GetPetResult in output that should have gone back to GetPetResponse.
| func ResetGlobalState() { | |
| globalState.options = Configuration{} | |
| globalState.spec = nil | |
| globalState.importMapping = nil | |
| globalState.initialismsMap = nil | |
| globalState.typeMapping = TypeMapping{} | |
| globalState.resolvedNames = nil | |
| globalState.resolvedClientWrapperNames = nil | |
| globalState.streamingContentTypeRegexes = nil | |
| } | |
| func ResetGlobalState() { | |
| globalState.options = Configuration{} | |
| globalState.spec = nil | |
| globalState.importMapping = nil | |
| globalState.initialismsMap = nil | |
| globalState.typeMapping = TypeMapping{} | |
| globalState.resolvedNames = nil | |
| globalState.resolvedClientWrapperNames = nil | |
| globalState.streamingContentTypeRegexes = nil | |
| responseTypeSuffix = "Response" | |
| } |
| func ResetGlobalState() { | ||
| globalState.options = Configuration{} | ||
| globalState.spec = nil | ||
| globalState.importMapping = nil | ||
| globalState.initialismsMap = nil | ||
| globalState.typeMapping = TypeMapping{} | ||
| globalState.resolvedNames = nil | ||
| globalState.resolvedClientWrapperNames = nil | ||
| globalState.streamingContentTypeRegexes = nil | ||
| } |
There was a problem hiding this comment.
makeInitialismsMap rebuilds the package-level targetWordRegex with any configured AdditionalInitialisms, but ResetGlobalState() only clears the map stored inside globalState. After one generation adds an initialism such as FOO, a reset still leaves ToCamelCaseWithInitialism and paths like media type name generation using a regex that uppercases FOO. A later default generation can therefore still get names influenced by the previous options.
Problem
When using oapi-codegen as a library and calling
Generatemultiple times in a single process (e.g., to split client operations by tags into separate files), theglobalState.optionsfrom the first call persists and affects subsequent calls. This makes it impossible to generate separate files with different configurations.Solution
This PR adds two new exported functions, following the pattern established by
SetGlobalStateSpec(PR #1174):SetGlobalStateOptions(opts Configuration)— Allows settingglobalState.optionswithout callingGenerate. Useful when you need to override options between successiveGeneratecalls.ResetGlobalState()— Resets all global state fields to their zero values. This is a more thorough reset that prevents any state leakage between calls, including options, spec, import mappings, type mappings, initialisms, resolved names, and streaming content type regexes.Usage
Or for just overriding options:
Fixes #1805