Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@ReneWerner87
Copy link
Member

@ReneWerner87 ReneWerner87 commented Sep 3, 2025

Summary

  • update v3 migrator to use new Context and SetContext APIs when migrating Fiber apps
  • skip rewriting contexts when already migrated to preserve idempotency
  • add multi-run tests covering Context, UserContext, and SetContext conversions

Testing

  • make lint
  • make test

https://chatgpt.com/codex/tasks/task_e_68b81fba6ca083268127e47e711ab24c

Summary by CodeRabbit

  • Bug Fixes

    • Safer, conditional migration of context-related methods to prevent unintended rewrites.
    • Automatically converts deprecated user-context setters to the new API while preserving existing read-only access patterns.
  • Refactor

    • Replaced blanket rewrites with structure-aware transformations for greater accuracy and determinism.
  • Tests

    • Updated expectations to the new context API.
    • Added idempotence tests to ensure consistent results across multiple runs.

@coderabbitai
Copy link

coderabbitai bot commented Sep 3, 2025

Walkthrough

Adds a guarded AST-based migration that conditionally rewrites Fiber context calls: renames Context() to RequestCtx() for Fiber-context receivers unless SetContext is already present; renames SetUserContext(...) to SetContext(...); keeps UserContext()→Context(). Updates tests to reflect new outputs and idempotence.

Changes

Cohort / File(s) Summary
Migration logic (v3 context methods)
cmd/internal/migrations/v3/context_methods.go
Replaces unconditional Context→RequestCtx rewrite with an AST-guarded pass that skips when SetContext exists. Adds regex-based SetUserContext→SetContext rewrite for Fiber-context receivers. Retains UserContext()→Context() rewrite. Removes prior comment-out strategy for SetUserContext.
Tests
cmd/internal/migrations/v3/context_methods_test.go
Updates expectations to RequestCtx/Context/SetContext patterns, removes UserContext/SetUserContext references, adds multi-run idempotence test and adjusted occurrence counts.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant M as Migrator
  participant FS as Source File
  participant AST as AST Parser

  M->>FS: Read Go source
  M->>AST: Parse file
  AST-->>M: AST nodes

  rect rgba(220,235,255,0.4)
    note over M: Find X.Context() calls (no args)
    M->>M: Determine receiver type (Fiber context?)
    alt SetContext already present
      M->>M: Skip Context→RequestCtx rewrite
    else No SetContext present
      M->>FS: Rewrite X.Context() → X.RequestCtx()
    end
  end

  rect rgba(220,255,220,0.4)
    note over M: Replace SetUserContext(...)
    M->>FS: X.SetUserContext(...) → X.SetContext(...) (Fiber context)
  end

  rect rgba(255,245,220,0.5)
    note over M: Replace UserContext()
    M->>FS: X.UserContext() → X.Context() (Fiber context)
  end

  M->>FS: Write formatted source (if changed)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

✏️ Feature, codex

Poem

In burrows of code I twitch my nose,
Renaming trails where Context goes.
SetUserContext hops away—so neat!
SetContext now with lighter feet.
RequestCtx nibble, UserContext no—
Idempotent fields where carrots grow.
Thump! The migration’s good to go. 🥕

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/2025-09-03-12-12-29

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @ReneWerner87, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the v3 migration tool for Fiber applications by adapting it to recent changes in Fiber's context handling. The primary goal is to ensure a smooth and reliable upgrade path for users by automatically adjusting their codebase to the new Context and SetContext method signatures, while also guaranteeing that the migration process is idempotent.

Highlights

  • Fiber Context API Migration: The v3 migrator has been updated to correctly handle the new Context() and SetContext() APIs in Fiber applications. This includes migrating old Context() calls to RequestCtx(), UserContext() to Context(), and SetUserContext() to SetContext().
  • Idempotency: The migrator now includes logic to skip rewriting context methods if they have already been migrated, ensuring that running the migration tool multiple times produces consistent results without unintended changes.
  • Enhanced Testing: New and updated tests have been added to cover the conversions of Context(), UserContext(), and SetContext() methods, including a specific test case to verify the migrator's idempotency across multiple runs.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the v3 migrator to use the new Context and SetContext APIs when migrating Fiber apps. It also skips rewriting contexts when already migrated to preserve idempotency and adds multi-run tests covering Context, UserContext, and SetContext conversions. I have identified a potential issue in the test case where the count of SetContext( is asserted, which might not accurately reflect the intended behavior after multiple migrations.

Comment on lines 91 to +93
second := readFile(t, file)
assert.Equal(t, first, second)
assert.Equal(t, 1, strings.Count(second, "TODO: SetUserContext was removed"))
assert.Equal(t, 1, strings.Count(second, "SetContext("))
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The assertion assert.Equal(t, 1, strings.Count(second, "TODO: SetUserContext was removed")) is no longer valid since SetUserContext is now replaced with SetContext. This test should be updated to reflect the new code.

I suggest changing the assertion to check for the correct number of SetContext( calls after the migration. Since the goal is to ensure idempotency, the count should remain consistent after multiple runs.

Consider updating the assertion to check for the correct number of SetContext( calls after the migration. This will ensure that the test accurately reflects the intended behavior of the migration.

I recommend updating the assertion to check for the correct number of SetContext( calls after the migration. This will ensure that the test accurately reflects the intended behavior of the migration.

Suggested change
second := readFile(t, file)
assert.Equal(t, first, second)
assert.Equal(t, 1, strings.Count(second, "TODO: SetUserContext was removed"))
assert.Equal(t, 1, strings.Count(second, "SetContext("))
assert.Equal(t, 1, strings.Count(second, "SetContext("))

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

Codex Review: Here are some suggestions.

Reply with @codex fix comments to fix any unresolved comments.

About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you open a pull request for review, mark a draft as ready, or comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex fix this CI failure" or "@codex address that feedback".

Comment on lines +23 to +24
// old Context() returned fasthttp.RequestCtx
if !strings.Contains(orig, ".SetContext(") {

Choose a reason for hiding this comment

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

[P1] Skip Context rewrite only when SetContext detected

The AST rewrite that renames Context() calls to RequestCtx() only skips when the original source contains .SetContext(. Files that initially call c.UserContext() but never SetUserContext are migrated in two steps: the first pass turns UserContext() into Context() but introduces no SetContext, so a second run enters this block and rewrites that newly produced Context() to RequestCtx(). The return type then changes from context.Context to *fasthttp.RequestCtx, causing type errors for code that re-runs the migrator on already migrated files that only used UserContext().

Useful? React with 👍 / 👎.

Copy link
Member Author

Choose a reason for hiding this comment

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

is it not working, we have a unittest for this case and it already test this

@ReneWerner87 ReneWerner87 added this to v3 Sep 3, 2025
@ReneWerner87 ReneWerner87 merged commit 66877cf into master Sep 3, 2025
12 of 13 checks passed
@ReneWerner87 ReneWerner87 deleted the codex/2025-09-03-12-12-29 branch September 3, 2025 12:18
@github-project-automation github-project-automation bot moved this to Done in v3 Sep 3, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
cmd/internal/migrations/v3/context_methods.go (2)

29-42: baseIdent misses common nodes (Index/Paren/TypeAssert/Star); extend to avoid skipped rewrites.

Without handling these, patterns like ctxs[i].Context() or (c).Context() won’t be rewritten.

Apply:

-				baseIdent := func(expr ast.Expr) *ast.Ident {
+				baseIdent := func(expr ast.Expr) *ast.Ident {
 					for {
 						switch e := expr.(type) {
 						case *ast.Ident:
 							return e
 						case *ast.SelectorExpr:
 							expr = e.X
 						case *ast.CallExpr:
 							expr = e.Fun
+						case *ast.IndexExpr:
+							expr = e.X
+						case *ast.IndexListExpr:
+							expr = e.X
+						case *ast.ParenExpr:
+							expr = e.X
+						case *ast.TypeAssertExpr:
+							expr = e.X
+						case *ast.StarExpr:
+							expr = e.X
 						default:
 							return nil
 						}
 					}
 				}

67-79: Regex-based UserContext→Context can alter strings/comments and misses complex receivers; prefer AST.

Consider an AST pass similar to fixSetUserContextCalls for X.UserContext() → X.Context() on fiber Ctx, covering chains and index expressions.

cmd/internal/migrations/v3/context_methods_test.go (1)

196-211: Consider an index-expression test (nice-to-have).

Covers ctxs[i].Context() and (c).Context() cases once baseIdent is extended.

Example:

func Test_MigrateContextMethods_IndexAndParen(t *testing.T) {
	t.Parallel()
	dir, err := os.MkdirTemp("", "mcmtest-index")
	require.NoError(t, err)
	defer func() { require.NoError(t, os.RemoveAll(dir)) }()
	file := writeTempFile(t, dir, `package main
import "github.com/gofiber/fiber/v2"
func handler(c fiber.Ctx, ctxs []fiber.Ctx) error {
    rc := ctxs[0].Context()
    _ = (c).Context().SetBodyStreamWriter(nil)
    _ = rc
    return nil
}`)
	var buf bytes.Buffer
	cmd := newCmd(&buf)
	require.NoError(t, v3.MigrateContextMethods(cmd, dir, nil, nil))
	content := readFile(t, file)
	assert.Equal(t, 2, strings.Count(content, ".RequestCtx()"))
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ef273a3 and b1e9bfe.

📒 Files selected for processing (2)
  • cmd/internal/migrations/v3/context_methods.go (2 hunks)
  • cmd/internal/migrations/v3/context_methods_test.go (3 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.
Learnt from: ReneWerner87
PR: gofiber/contrib#0
File: :0-0
Timestamp: 2024-11-29T15:24:06.083Z
Learning: When customizing the Fiber context to achieve version independence, using generics in methods like `Status` and `Type` allows for fluent method chaining. Implementing a generic interface for `Ctx` on the `App` prevents class switching when registering custom contexts that use fluent methods. Providing multiple `New` methods allows users who do not wish to customize the context to continue using `fiber.New` without changes.
📚 Learning: 2024-11-08T04:10:42.990Z
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.

Applied to files:

  • cmd/internal/migrations/v3/context_methods.go
  • cmd/internal/migrations/v3/context_methods_test.go
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

  • cmd/internal/migrations/v3/context_methods.go
📚 Learning: 2024-11-29T15:24:06.083Z
Learnt from: ReneWerner87
PR: gofiber/contrib#0
File: :0-0
Timestamp: 2024-11-29T15:24:06.083Z
Learning: When customizing the Fiber context to achieve version independence, using generics in methods like `Status` and `Type` allows for fluent method chaining. Implementing a generic interface for `Ctx` on the `App` prevents class switching when registering custom contexts that use fluent methods. Providing multiple `New` methods allows users who do not wish to customize the context to continue using `fiber.New` without changes.

Applied to files:

  • cmd/internal/migrations/v3/context_methods.go
🧬 Code graph analysis (1)
cmd/internal/migrations/v3/context_methods_test.go (1)
cmd/internal/migrations/v3/context_methods.go (1)
  • MigrateContextMethods (19-106)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build (1.25.x, windows-latest)
  • GitHub Check: Build (1.25.x, macos-latest)
  • GitHub Check: Build (1.25.x, ubuntu-latest)
  • GitHub Check: Build (1.25.x, macos-13)
🔇 Additional comments (7)
cmd/internal/migrations/v3/context_methods_test.go (7)

38-43: Good end-to-end assertions for primary migration path.


66-69: Nice focused check for SetUserContext assignment case.


93-94: Solid idempotency assertion.


96-132: Strong multi-run coverage.


165-187: Chained call case covered; thanks.


189-213: Multiple Context() usages covered; good.


134-163: Non-fiber types skip verified; good.

Comment on lines +96 to 132
func Test_MigrateContextMethods_MultipleRuns(t *testing.T) {
t.Parallel()

dir, err := os.MkdirTemp("", "mcmtestmulti2")
require.NoError(t, err)
defer func() { require.NoError(t, os.RemoveAll(dir)) }()

file := writeTempFile(t, dir, `package main
import "github.com/gofiber/fiber/v2"
func handler(c fiber.Ctx) error {
ctx := c.Context()
uc := c.UserContext()
c.SetUserContext(ctx)
c.SetUserContext(c.Context())
_ = uc
return nil
}`)

var buf bytes.Buffer
cmd := newCmd(&buf)
require.NoError(t, v3.MigrateContextMethods(cmd, dir, nil, nil))
first := readFile(t, file)

require.Contains(t, first, "ctx := c.RequestCtx()")
require.Contains(t, first, "uc := c.Context()")
require.Contains(t, first, "c.SetContext(ctx)")
require.Contains(t, first, "c.SetContext(c.RequestCtx())")
require.NotContains(t, first, ".UserContext()")
require.NotContains(t, first, "SetUserContext")

require.NoError(t, v3.MigrateContextMethods(cmd, dir, nil, nil))
second := readFile(t, file)
assert.Equal(t, first, second)
assert.Equal(t, 1, strings.Count(second, "uc := c.Context()"))
assert.Equal(t, 2, strings.Count(second, ".RequestCtx()"))
assert.Equal(t, 2, strings.Count(second, "SetContext("))
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add a mixed-file test to catch the guard edge case.

This reproduces SetUserContext→SetContext with an existing SetContext elsewhere; ensures the argument becomes RequestCtx.

Apply:

@@
 func Test_MigrateContextMethods_MultipleRuns(t *testing.T) {
@@
 }
 
+func Test_MigrateContextMethods_MixedFileWithExistingSetContext(t *testing.T) {
+	t.Parallel()
+	dir, err := os.MkdirTemp("", "mcmtest-mixed")
+	require.NoError(t, err)
+	defer func() { require.NoError(t, os.RemoveAll(dir)) }()
+
+	file := writeTempFile(t, dir, `package main
+import "github.com/gofiber/fiber/v2"
+func handler(c fiber.Ctx) error {
+    // already migrated in this file:
+    c.SetContext(c.RequestCtx())
+    // still old call:
+    _ = c.SetUserContext(c.Context())
+    // chain that must stay valid:
+    c.Status(200).Context().SetBodyStreamWriter(nil)
+    return nil
+}`)
+
+	var buf bytes.Buffer
+	cmd := newCmd(&buf)
+	require.NoError(t, v3.MigrateContextMethods(cmd, dir, nil, nil))
+	content := readFile(t, file)
+	assert.Contains(t, content, "c.SetContext(c.RequestCtx())")                 // unchanged existing
+	assert.NotContains(t, content, "SetUserContext(")                           // renamed
+	assert.Contains(t, content, "SetContext(c.RequestCtx())")                   // fixed arg
+	assert.NotContains(t, content, ".Context().SetBodyStreamWriter")            // chained fix
+	assert.Contains(t, content, ".RequestCtx().SetBodyStreamWriter")            // chained fix
+}
🤖 Prompt for AI Agents
In cmd/internal/migrations/v3/context_methods_test.go around lines 96–132, add a
mixed-file test that reproduces the guard edge case where an existing SetContext
call in the file prevents proper transformation of SetUserContext → SetContext;
the test should create a temp file containing both SetUserContext calls and
existing SetContext usages, run v3.MigrateContextMethods twice, then assert that
SetUserContext calls were converted to SetContext with RequestCtx() arguments,
that existing SetContext calls remain unchanged, and that counts of "uc :=
c.Context()", ".RequestCtx()", and "SetContext(" match the expected numbers to
ensure idempotence.

Comment on lines +23 to +66
// old Context() returned fasthttp.RequestCtx
if !strings.Contains(orig, ".SetContext(") {
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "", content, parser.ParseComments)
if err == nil {
modified := false
baseIdent := func(expr ast.Expr) *ast.Ident {
for {
switch e := expr.(type) {
case *ast.Ident:
return e
case *ast.SelectorExpr:
expr = e.X
case *ast.CallExpr:
expr = e.Fun
default:
return nil
}
}
}
ast.Inspect(file, func(n ast.Node) bool {
call, ok := n.(*ast.CallExpr)
if !ok {
return true
}
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok || sel.Sel.Name != "Context" || len(call.Args) != 0 {
return true
}
if ident := baseIdent(sel.X); ident != nil && isFiberCtx(orig, ident.Name) {
sel.Sel.Name = "RequestCtx"
modified = true
}
return true
})
if modified {
var buf bytes.Buffer
if err := format.Node(&buf, fset, file); err == nil {
content = buf.String()
}
}
}
}

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Guard can silently miss/produce invalid migrations in mixed files; handle SetUserContext args and chained Context() regardless of the guard.

If a file already contains SetContext(, the guarded pass skips all Context()→RequestCtx() rewrites. That can leave:

  • SetUserContext(c.Context()) → SetContext(c.Context()) (wrong type)
  • Chains like c.Status(...).Context().SetBodyStreamWriter(...) unchanged (compile error)

Add a targeted, always-on AST pass that:

  • Renames SetUserContext → SetContext for fiber Ctx receivers
  • Rewrites its argument from .Context() → .RequestCtx()
  • Optionally rewrites chained .Context(). → .RequestCtx().

Apply within-file call to a helper (see diff in lines 81-93) and add the helper below:

// place near the bottom of this file
func fixSetUserContextCalls(orig, content string) string {
	fset := token.NewFileSet()
	file, err := parser.ParseFile(fset, "", content, parser.ParseComments)
	if err != nil {
		return content
	}
	modified := false

	baseIdent := func(expr ast.Expr) *ast.Ident {
		for {
			switch e := expr.(type) {
			case *ast.Ident:
				return e
			case *ast.SelectorExpr:
				expr = e.X
			case *ast.CallExpr:
				expr = e.Fun
			case *ast.IndexExpr, *ast.IndexListExpr:
				expr = e.(interface{ GetX() ast.Expr }).GetX()
			case *ast.ParenExpr:
				expr = e.X
			case *ast.TypeAssertExpr:
				expr = e.X
			case *ast.StarExpr:
				expr = e.X
			default:
				return nil
			}
		}
	}

	ast.Inspect(file, func(n ast.Node) bool {
		ce, ok := n.(*ast.CallExpr)
		if !ok {
			return true
		}
		sel, ok := ce.Fun.(*ast.SelectorExpr)
		if !ok {
			return true
		}
		recv := baseIdent(sel.X)
		if recv == nil || !isFiberCtx(orig, recv.Name) {
			return true
		}

		// Normalize SetUserContext → SetContext
		if sel.Sel.Name == "SetUserContext" {
			sel.Sel.Name = "SetContext"
			modified = true
		}

		// If first arg is <recv>.Context(), make it <recv>.RequestCtx()
		if sel.Sel.Name == "SetContext" && len(ce.Args) >= 1 {
			if argCall, ok := ce.Args[0].(*ast.CallExpr); ok {
				if argSel, ok := argCall.Fun.(*ast.SelectorExpr); ok && argSel.Sel.Name == "Context" {
					if aRecv := baseIdent(argSel.X); aRecv != nil && aRecv.Name == recv.Name {
						argSel.Sel.Name = "RequestCtx"
						modified = true
					}
				}
			}
		}
		return true
	})

	if !modified {
		return content
	}
	var buf bytes.Buffer
	if err := format.Node(&buf, fset, file); err != nil {
		return content
	}
	return buf.String()
}

Comment on lines +81 to 93
// SetUserContext renamed to SetContext
reSetUserCtx := regexp.MustCompile(`(\w+)\.SetUserContext\(`)
content = reSetUserCtx.ReplaceAllStringFunc(content, func(match string) string {
parts := reSetUserCtx.FindStringSubmatch(match)
if len(parts) != 2 {
return match
}
ident := parts[3]
if !isFiberCtx(orig, ident) {
return line
ident := parts[1]
if isFiberCtx(orig, ident) {
return ident + ".SetContext("
}
return fmt.Sprintf("%s// TODO: SetUserContext was removed, please migrate manually: %s", parts[1], parts[2])
return match
})
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Regex-only SetUserContext rename can break types in mixed files; replace with AST helper.

Tie the rename to argument fixups even when SetContext already exists.

Apply:

-		// SetUserContext renamed to SetContext
-		reSetUserCtx := regexp.MustCompile(`(\w+)\.SetUserContext\(`)
-		content = reSetUserCtx.ReplaceAllStringFunc(content, func(match string) string {
-			parts := reSetUserCtx.FindStringSubmatch(match)
-			if len(parts) != 2 {
-				return match
-			}
-			ident := parts[1]
-			if isFiberCtx(orig, ident) {
-				return ident + ".SetContext("
-			}
-			return match
-		})
+		// SetUserContext → SetContext + fix arg: <recv>.Context() → <recv>.RequestCtx()
+		content = fixSetUserContextCalls(orig, content)

Add the helper per earlier comment.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In cmd/internal/migrations/v3/context_methods.go around lines 81 to 93, the
current regex-only replacement for renaming SetUserContext -> SetContext can
break types in mixed files and misses tying the rename to argument fixups;
replace this block with an AST-based helper call (the helper referenced in the
earlier comment) that walks the Go AST, finds selector expressions calling
.SetUserContext on idents, verifies the receiver is a fiber.Context via
isFiberCtx, replaces the selector to .SetContext, and performs the necessary
argument adjustments (including adding/removing context arg) even when a
.SetContext already exists; invoke that helper here instead of using
regexp.ReplaceAllStringFunc to ensure type-safe, idempotent transformations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants