GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — feat: add SetGlobalStateOptions and ResetGlobalState by toller892 · Pull Request #2393 · oapi-codegen/oapi-codegen

Conversation

@toller892

@toller892 toller892 commented Jun 2, 2026

Copy link
Copy Markdown

Problem

When using oapi-codegen as a library and calling Generate multiple times in a single process (e.g., to split client operations by tags into separate files), the globalState.options from 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 setting globalState.options without calling Generate. Useful when you need to override options between successive Generate calls.

  • 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

// Generate with first set of options
result1, err := codegen.Generate(spec, opts1)

// Reset state before next call
codegen.ResetGlobalState()

// Generate with different options
result2, err := codegen.Generate(spec, opts2)

Or for just overriding options:

codegen.SetGlobalStateOptions(newOpts)
result, err := codegen.Generate(spec, newOpts)

Fixes #1805

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

greptile-apps[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@toller892
feat: add SetGlobalStateOptions and ResetGlobalState functions
755c05b
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
@toller892
toller892 requested a review from a team as a code owner June 2, 2026 03:07
@greptile-apps

greptile-apps Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds APIs for controlling codegen's package-level state. The main changes are:

  • Added SetGlobalStateOptions to set stored code generation options directly.
  • Added ResetGlobalState to clear the fields inside globalState.
  • Documented these helpers as support for repeated Generate calls in one process.

Confidence Score: 3/5

This is close, but the reset behavior should be fixed before merging.

  • Repeated Generate calls can still inherit a previous response suffix after ResetGlobalState().

  • Additional initialism handling can also leak through a package-level regex that is not cleared.

  • The changed API is small and the issues are localized to the reset helper.

  • pkg/codegen/codegen.go should reset all option-derived package globals, not only fields inside globalState.

Important Files Changed

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

greptile-apps[bot]
greptile-apps Bot reviewed Jun 2, 2026
View reviewed changes
Comment thread pkg/codegen/codegen.go
Comment on lines +1488 to +1497
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
}

@greptile-apps greptile-apps Bot Jun 2, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Reset misses response suffix

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.

Suggested change
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"
}

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread pkg/codegen/codegen.go
Comment on lines +1488 to +1497
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
}

@greptile-apps greptile-apps Bot Jun 2, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Reset leaves initialism regex

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.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@adamwg adamwg mentioned this pull request Jun 18, 2026
schemas: Prime oapi-codegen's global state to make capitalization consistent crossplane/cli#130
Merged
3 tasks done
adamwg added a commit to crossplane/cli that referenced this pull request Jun 23, 2026
@adamwg
schemas: Prime oapi-codegen's global state to make capitalization con…
8a7d372
…sistent

The oapi-codegen package we use to generate Go code keeps a bunch of internal
global state that affects how code is generated. In particular, the name
normalizer it uses to form types names is a global variable initialized when we
call `codegen.Generate`.

We call some of the codegen package's utility functions to form custom names for
types before generating code. These utility functions also use the global state
set up by `codegen.Generate`, which isn't initialized when we call them,
resulting in the utility functions producing different names than we
expect. This makes our code generation non-deterministic: we get different name
capitalization depending what order schemas get generated in.

Make a no-op call to `codegen.Generate` with our desired options before calling
the mutators to ensure that the global state is initialized for all our
calls. Note that once oapi-codegen/oapi-codegen#2393 is
merged in the upstream code generator, we can use the new
`SetGlobalStateOptions` function rather than the dummy `Generate` call.

Fixes #113

Signed-off-by: Adam Wolfe Gordon <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@greptile-apps greptile-apps[bot] greptile-apps[bot] left review comments

At least 1 approving review is required to merge this pull request.

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Allow resetting globalState.options

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@toller892
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.