Skip to content

feat: migrate fiber utils imports#166

Merged
ReneWerner87 merged 4 commits into
masterfrom
codex/2025-08-22-22-17-57
Aug 22, 2025
Merged

feat: migrate fiber utils imports#166
ReneWerner87 merged 4 commits into
masterfrom
codex/2025-08-22-22-17-57

Conversation

@ReneWerner87
Copy link
Copy Markdown
Member

@ReneWerner87 ReneWerner87 commented Aug 22, 2025

Summary

  • update utils migration to use github.com/gofiber/utils
  • rewrite deprecated helper names and map string helpers to stdlib
  • expand tests for utils import and helper replacement

Testing

  • go test ./...

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

Summary by CodeRabbit

  • New Features

    • Migration assistant now automatically rewrites deprecated utils imports to the new package and updates related helper calls during upgrades from 2.x to <4.0, improving accuracy and providing clear console messaging.
  • Tests

    • Added tests to validate import/path rewrites, helper remapping, and expected log output.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 22, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Warning

Rate limit exceeded

@ReneWerner87 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 11 minutes and 52 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between ffdb6f1 and 743fab9.

📒 Files selected for processing (2)
  • cmd/internal/migrations/v3/common.go (1 hunks)
  • cmd/internal/migrations/v3/common_test.go (1 hunks)

Walkthrough

Adds a new migration step v3.MigrateUtilsImport to rewrite Fiber utils imports/usages, wires it into the v3 migration sequence between Monitor import and Healthcheck config migrations, and introduces tests validating path and symbol transformations plus log output.

Changes

Cohort / File(s) Summary
Migration wiring
cmd/internal/migrations/lists.go
Inserts v3migrations.MigrateUtilsImport into the v3 migration Functions list between MigrateMonitorImport and MigrateHealthcheckConfig.
Migration implementation
cmd/internal/migrations/v3/common.go
Adds MigrateUtilsImport to transform github.com/gofiber/fiber/v\d+/utils imports to github.com/gofiber/utils and remap affected helpers (bytes/string variants, GetString/GetBytes/ImmutableString/AssertEqual) via content rewrites.
Tests
cmd/internal/migrations/v3/common_test.go
Adds Test_MigrateUtilsImport covering import path replacement, symbol remaps, preserved snippets, and expected log message.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as CLI
  participant Runner as MigrationRunner
  participant V3 as v3 Migrations

  User->>CLI: fiber-cli migrate
  CLI->>Runner: DoMigration(version >=2.0.0 <4.0.0-0)
  Runner->>V3: MigrateMonitorImport
  Note right of V3: existing step
  Runner->>V3: MigrateUtilsImport
  Note right of V3: new step\n- rewrite imports\n- remap utils symbols
  Runner->>V3: MigrateHealthcheckConfig
  Note right of V3: subsequent step
  V3-->>Runner: results/errors propagate
  Runner-->>CLI: migration summary
  CLI-->>User: output/logs
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

✏️ Feature

Poem

A whisker twitch, a hop in time,
I nudge the imports, line by line.
From Fiber’s burrow to utils new,
Trim and fold—now tidy, too.
Carrot-shaped regex, swift and bright,
Migration done—code feels light. 🥕✨

✨ 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-08-22-22-17-57

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 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
Copy Markdown
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 introduces a new migration step to update existing Go projects using the Fiber framework. The migration focuses on standardizing the import path for Fiber's utility functions and automatically refactoring deprecated utility helper calls to their new equivalents or to standard library functions where applicable.

Highlights

  • New Utility Migration: A new migration function, MigrateUtilsImport, has been added to the v3 migration list to automate updates related to Fiber's utility package.
  • Import Path Update: The migration automatically changes the import path for Fiber utilities from github.com/gofiber/fiber/vX/utils to the standalone github.com/gofiber/utils.
  • Helper Function Refactoring: Deprecated utility functions like GetString, GetBytes, and ImmutableString are automatically replaced with ToString, CopyBytes, and direct type casting to string, respectively.
  • Standard Library Mapping: Common string manipulation functions from utils (e.g., Trim, EqualFold) are remapped to their counterparts in Go's strings package, ensuring proper usage and future compatibility.
  • Comprehensive Testing: New tests have been added to verify the correctness of the utility import and helper replacement logic, covering various scenarios including byte-based and string-based utility calls.
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.

Comment thread cmd/internal/migrations/v3/common.go Fixed
Copy link
Copy Markdown
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 migrates Fiber utils imports to the new github.com/gofiber/utils package and updates several deprecated helper functions. The implementation is logically sound, particularly the use of placeholders to handle tricky renames. I've provided a couple of suggestions to improve the maintainability of the migration logic and the robustness of its corresponding test.

Comment thread cmd/internal/migrations/v3/common.go Outdated
Comment on lines +532 to +555
// protect byte helper replacements so we can safely map string helpers to the
// standard library without affecting byte-based calls
content = strings.ReplaceAll(content, "utils.TrimRightBytes", "utils.__fiberTrimRight__")
content = strings.ReplaceAll(content, "utils.TrimLeftBytes", "utils.__fiberTrimLeft__")
content = strings.ReplaceAll(content, "utils.TrimBytes", "utils.__fiberTrim__")
content = strings.ReplaceAll(content, "utils.EqualFoldBytes", "utils.__fiberEqualFold__")

// map removed string helpers to the strings package
content = strings.ReplaceAll(content, "utils.TrimRight", "strings.TrimRight")
content = strings.ReplaceAll(content, "utils.TrimLeft", "strings.TrimLeft")
content = strings.ReplaceAll(content, "utils.Trim", "strings.Trim")
content = strings.ReplaceAll(content, "utils.EqualFold", "strings.EqualFold")

// restore byte helper placeholders to their new names
content = strings.ReplaceAll(content, "utils.__fiberTrimRight__", "utils.TrimRight")
content = strings.ReplaceAll(content, "utils.__fiberTrimLeft__", "utils.TrimLeft")
content = strings.ReplaceAll(content, "utils.__fiberTrim__", "utils.Trim")
content = strings.ReplaceAll(content, "utils.__fiberEqualFold__", "utils.EqualFold")

// other removed helpers
content = strings.ReplaceAll(content, "utils.GetString", "utils.ToString")
content = strings.ReplaceAll(content, "utils.GetBytes", "utils.CopyBytes")
content = strings.ReplaceAll(content, "utils.ImmutableString", "string")
content = strings.ReplaceAll(content, "utils.AssertEqual", "assert.Equal")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The current implementation with multiple strings.ReplaceAll calls is correct, but it can be made more idiomatic and readable by using strings.NewReplacer. This also groups related replacements together, making the logic clearer.

The migration can be structured into three stages using replacers: protecting byte helpers, mapping string/other helpers, and restoring byte helpers.

		// The migration is done in stages to correctly handle renaming of functions
		// that have similar names (e.g. Trim vs TrimBytes).

		// Stage 1: Protect byte helper functions by renaming them to temporary placeholders.
		// This prevents them from being affected by the string helper replacements.
		protector := strings.NewReplacer(
			"utils.TrimRightBytes", "utils.__fiberTrimRight__",
			"utils.TrimLeftBytes", "utils.__fiberTrimLeft__",
			"utils.TrimBytes", "utils.__fiberTrim__",
			"utils.EqualFoldBytes", "utils.__fiberEqualFold__",
		)
		content = protector.Replace(content)

		// Stage 2: Map removed string helpers to the standard library's `strings` package
		// and rename other deprecated helpers.
		mapper := strings.NewReplacer(
			"utils.TrimRight", "strings.TrimRight",
			"utils.TrimLeft", "strings.TrimLeft",
			"utils.Trim", "strings.Trim",
			"utils.EqualFold", "strings.EqualFold",
			"utils.GetString", "utils.ToString",
			"utils.GetBytes", "utils.CopyBytes",
			"utils.ImmutableString", "string",
			"utils.AssertEqual", "assert.Equal",
		)
		content = mapper.Replace(content)

		// Stage 3: Restore the byte helper functions from their placeholders to their new names.
		restorer := strings.NewReplacer(
			"utils.__fiberTrimRight__", "utils.TrimRight",
			"utils.__fiberTrimLeft__", "utils.TrimLeft",
			"utils.__fiberTrim__", "utils.Trim",
			"utils.__fiberEqualFold__", "utils.EqualFold",
		)
		content = restorer.Replace(content)

Comment on lines +557 to +606
func Test_MigrateUtilsImport(t *testing.T) {
t.Parallel()

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

file := writeTempFile(t, dir, `package main
import "github.com/gofiber/fiber/v3/utils"
var (
_ = utils.TrimBytes([]byte("x"), " ")
_ = utils.TrimRightBytes([]byte("x"), " ")
_ = utils.TrimLeftBytes([]byte("x"), " ")
_ = utils.EqualFoldBytes([]byte("A"), []byte("a"))
_ = utils.Trim(" x ", " ")
_ = utils.TrimRight("x ", " ")
_ = utils.TrimLeft(" x", " ")
_ = utils.EqualFold("A", "a")
_ = utils.GetString([]byte("a"))
_ = utils.GetBytes("a")
_ = utils.ImmutableString([]byte("b"))
)`)

var buf bytes.Buffer
cmd := newCmd(&buf)
require.NoError(t, v3.MigrateUtilsImport(cmd, dir, nil, nil))

content := readFile(t, file)
assert.Contains(t, content, "github.com/gofiber/utils\"")
assert.NotContains(t, content, "fiber/v3/utils")
assert.NotContains(t, content, "TrimBytes(")
assert.NotContains(t, content, "TrimRightBytes(")
assert.NotContains(t, content, "TrimLeftBytes(")
assert.NotContains(t, content, "EqualFoldBytes(")
assert.NotContains(t, content, "GetString(")
assert.NotContains(t, content, "GetBytes(")
assert.NotContains(t, content, "ImmutableString(")
assert.Contains(t, content, "utils.Trim(")
assert.Contains(t, content, "utils.TrimRight(")
assert.Contains(t, content, "utils.TrimLeft(")
assert.Contains(t, content, "utils.EqualFold(")
assert.Contains(t, content, "strings.Trim(")
assert.Contains(t, content, "strings.TrimRight(")
assert.Contains(t, content, "strings.TrimLeft(")
assert.Contains(t, content, "strings.EqualFold(")
assert.Contains(t, content, "utils.ToString(")
assert.Contains(t, content, "utils.CopyBytes(")
assert.Contains(t, content, "string([]byte(\"b\"))")
assert.Contains(t, buf.String(), "Migrating utils imports")
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The test is quite comprehensive, which is great. However, it could be made more robust and complete.

  1. Use assert.Equal for exact match: Instead of multiple assert.Contains and assert.NotContains, you could compare the entire file content with an expected string. This makes the test stricter and less prone to passing incorrectly if, for example, formatting changes.

  2. Missing test case: The migration for utils.AssertEqual to assert.Equal is not covered in this test.

Here is a suggested improvement that addresses both points:

func Test_MigrateUtilsImport(t *testing.T) {
	t.Parallel()

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

	file := writeTempFile(t, dir, `package main

import (
	"github.com/gofiber/fiber/v3/utils"
	"github.com/stretchr/testify/assert"
)

var (
	_ = utils.TrimBytes([]byte("x"), " ")
	_ = utils.TrimRightBytes([]byte("x"), " ")
	_ = utils.TrimLeftBytes([]byte("x"), " ")
	_ = utils.EqualFoldBytes([]byte("A"), []byte("a"))
	_ = utils.Trim(" x ", " ")
	_ = utils.TrimRight("x ", " ")
	_ = utils.TrimLeft(" x", " ")
	_ = utils.EqualFold("A", "a")
	_ = utils.GetString([]byte("a"))
	_ = utils.GetBytes("a")
	_ = utils.ImmutableString([]byte("b"))
	_ = utils.AssertEqual(nil, 1, 1)
)
`)

	var buf bytes.Buffer
	cmd := newCmd(&buf)
	require.NoError(t, v3.MigrateUtilsImport(cmd, dir, nil, nil))

	content := readFile(t, file)
	expected := `package main

import (
	"github.com/gofiber/utils"
	"github.com/stretchr/testify/assert"
)

var (
	_ = utils.Trim([]byte("x"), " ")
	_ = utils.TrimRight([]byte("x"), " ")
	_ = utils.TrimLeft([]byte("x"), " ")
	_ = utils.EqualFold([]byte("A"), []byte("a"))
	_ = strings.Trim(" x ", " ")
	_ = strings.TrimRight("x ", " ")
	_ = strings.TrimLeft(" x", " ")
	_ = strings.EqualFold("A", "a")
	_ = utils.ToString([]byte("a"))
	_ = utils.CopyBytes("a")
	_ = string([]byte("b"))
	_ = assert.Equal(nil, 1, 1)
)
`
	assert.Equal(t, expected, content)
	assert.Contains(t, buf.String(), "Migrating utils imports")
}

Copy link
Copy Markdown

@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: 2

🧹 Nitpick comments (1)
cmd/internal/migrations/v3/common.go (1)

524-565: Add imports for strings and testify/assert when migrating utils imports

The current MigrateUtilsImport callback rewrites helper calls to strings.* and assert.Equal, but doesn’t ensure the corresponding packages are imported—this will break builds in files that didn’t already import "strings" or "github.com/stretchr/testify/assert". To avoid this, detect usage of those qualifiers and inject the needed import(s) immediately after the package line if missing. For example, at the end of your ChangeFileContent callback (just before return content), add:

+               // ensure necessary imports when we introduced new qualifiers
+               needsStrings := strings.Contains(content, "strings.") &&
+                   !regexp.MustCompile(`(?m)^\s*import\s+(?:\(\s*(?s:[^)]*"strings"[^)]*)\)|"strings"|[A-Za-z_]\w*\s+"strings")`).MatchString(content)
+               needsAssert := strings.Contains(content, "assert.") &&
+                   !regexp.MustCompile(`(?m)^\s*import\s+(?:\(\s*(?s:[^)]*"github\.com/stretchr/testify/assert"[^)]*)\)|"github\.com/stretchr/testify/assert"|[A-Za-z_]\w*\s+"github\.com/stretchr/testify/assert")`).MatchString(content)
+               if needsStrings || needsAssert {
+                   var imports []string
+                   if needsStrings {
+                       imports = append(imports, `"strings"`)
+                   }
+                   if needsAssert {
+                       imports = append(imports, `"github.com/stretchr/testify/assert"`)
+                   }
+                   rePkg := regexp.MustCompile(`(?m)^package\s+\w+`)
+                   var decl string
+                   if len(imports) == 1 {
+                       decl = "import " + imports[0]
+                   } else {
+                       decl = "import (\n\t" + strings.Join(imports, "\n\t") + "\n)"
+                   }
+                   content = rePkg.ReplaceAllString(content, "$0\n\n"+decl)
+               }

This will automatically add:

  • import "strings" when you replace byte helpers with strings.*
  • import "github.com/stretchr/testify/assert" when you map utils.AssertEqual to assert.Equal
📜 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 9147dc4 and ffdb6f1.

📒 Files selected for processing (3)
  • cmd/internal/migrations/lists.go (1 hunks)
  • cmd/internal/migrations/v3/common.go (1 hunks)
  • cmd/internal/migrations/v3/common_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
cmd/internal/migrations/v3/common_test.go (1)
cmd/internal/migrations/v3/common.go (1)
  • MigrateUtilsImport (525-565)
cmd/internal/migrations/v3/common.go (1)
cmd/internal/helpers.go (1)
  • ChangeFileContent (36-68)
cmd/internal/migrations/lists.go (1)
cmd/internal/migrations/v3/common.go (1)
  • MigrateUtilsImport (525-565)
🔇 Additional comments (1)
cmd/internal/migrations/lists.go (1)

50-52: Good placement in the v3 migration chain

Registering MigrateUtilsImport immediately after MigrateMonitorImport and before config migrations is reasonable. It runs early enough to normalize imports and symbols, minimizing follow-on surprises in later steps.

Comment thread cmd/internal/migrations/v3/common_test.go
Comment on lines +524 to +565
// MigrateUtilsImport replaces old Fiber utils imports and updates removed helpers
func MigrateUtilsImport(cmd *cobra.Command, cwd string, _, _ *semver.Version) error {
reImport := regexp.MustCompile(`github\.com/gofiber/fiber/v\d+/utils`)

err := internal.ChangeFileContent(cwd, func(content string) string {
// update import path
content = reImport.ReplaceAllString(content, "github.com/gofiber/utils")

// protect byte helper replacements so we can safely map string helpers to the
// standard library without affecting byte-based calls
content = strings.ReplaceAll(content, "utils.TrimRightBytes", "utils.__fiberTrimRight__")
content = strings.ReplaceAll(content, "utils.TrimLeftBytes", "utils.__fiberTrimLeft__")
content = strings.ReplaceAll(content, "utils.TrimBytes", "utils.__fiberTrim__")
content = strings.ReplaceAll(content, "utils.EqualFoldBytes", "utils.__fiberEqualFold__")

// map removed string helpers to the strings package
content = strings.ReplaceAll(content, "utils.TrimRight", "strings.TrimRight")
content = strings.ReplaceAll(content, "utils.TrimLeft", "strings.TrimLeft")
content = strings.ReplaceAll(content, "utils.Trim", "strings.Trim")
content = strings.ReplaceAll(content, "utils.EqualFold", "strings.EqualFold")

// restore byte helper placeholders to their new names
content = strings.ReplaceAll(content, "utils.__fiberTrimRight__", "utils.TrimRight")
content = strings.ReplaceAll(content, "utils.__fiberTrimLeft__", "utils.TrimLeft")
content = strings.ReplaceAll(content, "utils.__fiberTrim__", "utils.Trim")
content = strings.ReplaceAll(content, "utils.__fiberEqualFold__", "utils.EqualFold")

// other removed helpers
content = strings.ReplaceAll(content, "utils.GetString", "utils.ToString")
content = strings.ReplaceAll(content, "utils.GetBytes", "utils.CopyBytes")
content = strings.ReplaceAll(content, "utils.ImmutableString", "string")
content = strings.ReplaceAll(content, "utils.AssertEqual", "assert.Equal")

return content
})
if err != nil {
return fmt.Errorf("failed to migrate utils imports: %w", err)
}

cmd.Println("Migrating utils imports")
return nil
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Cover alias imports of Fiber utils; current replacements only match the literal utils. qualifier

If a project imports Fiber utils with an alias (e.g., u "github.com/gofiber/fiber/v3/utils"), none of the symbol remaps fire because every replacement key is hard-coded to utils.X. That will leave string helpers like u.Trim unmigrated (and likely broken) after you switch the import path.

Refactor to detect all aliases used for the utils import (defaulting to utils when unaliased) and apply the same placeholder/restoration routine per alias.

Apply this diff in-place to the migration (keeps your placeholder strategy intact, but loops over detected aliases and handles both grouped and single-line imports):

 func MigrateUtilsImport(cmd *cobra.Command, cwd string, _, _ *semver.Version) error {
-        reImport := regexp.MustCompile(`github\.com/gofiber/fiber/v\d+/utils`)
+        reImport := regexp.MustCompile(`github\.com/gofiber/fiber/v\d+/utils`)
+        // capture alias names for the utils import in both grouped and single-line forms
+        reAlias := regexp.MustCompile(`(?m)^\s*(\w+)\s+"github\.com/gofiber/(?:fiber/v\d+/)?utils"`)

         err := internal.ChangeFileContent(cwd, func(content string) string {
                 // update import path
                 content = reImport.ReplaceAllString(content, "github.com/gofiber/utils")

-                // protect byte helper replacements so we can safely map string helpers to the
-                // standard library without affecting byte-based calls
-                content = strings.ReplaceAll(content, "utils.TrimRightBytes", "utils.__fiberTrimRight__")
-                content = strings.ReplaceAll(content, "utils.TrimLeftBytes", "utils.__fiberTrimLeft__")
-                content = strings.ReplaceAll(content, "utils.TrimBytes", "utils.__fiberTrim__")
-                content = strings.ReplaceAll(content, "utils.EqualFoldBytes", "utils.__fiberEqualFold__")
-
-                // map removed string helpers to the strings package
-                content = strings.ReplaceAll(content, "utils.TrimRight", "strings.TrimRight")
-                content = strings.ReplaceAll(content, "utils.TrimLeft", "strings.TrimLeft")
-                content = strings.ReplaceAll(content, "utils.Trim", "strings.Trim")
-                content = strings.ReplaceAll(content, "utils.EqualFold", "strings.EqualFold")
-
-                // restore byte helper placeholders to their new names
-                content = strings.ReplaceAll(content, "utils.__fiberTrimRight__", "utils.TrimRight")
-                content = strings.ReplaceAll(content, "utils.__fiberTrimLeft__", "utils.TrimLeft")
-                content = strings.ReplaceAll(content, "utils.__fiberTrim__", "utils.Trim")
-                content = strings.ReplaceAll(content, "utils.__fiberEqualFold__", "utils.EqualFold")
-
-                // other removed helpers
-                content = strings.ReplaceAll(content, "utils.GetString", "utils.ToString")
-                content = strings.ReplaceAll(content, "utils.GetBytes", "utils.CopyBytes")
-                content = strings.ReplaceAll(content, "utils.ImmutableString", "string")
-                content = strings.ReplaceAll(content, "utils.AssertEqual", "assert.Equal")
+                // build the set of qualifiers to rewrite (default "utils" + any explicit aliases found)
+                aliases := map[string]struct{}{"utils": {}}
+                for _, m := range reAlias.FindAllStringSubmatch(content, -1) {
+                        if len(m) > 1 && m[1] != "" {
+                                aliases[m[1]] = struct{}{}
+                        }
+                }
+
+                // apply rewrites for each qualifier
+                for alias := range aliases {
+                        prefix := alias + "."
+
+                        // protect byte helper replacements so we can safely map string helpers to stdlib
+                        content = strings.ReplaceAll(content, prefix+"TrimRightBytes", prefix+"__fiberTrimRight__")
+                        content = strings.ReplaceAll(content, prefix+"TrimLeftBytes",  prefix+"__fiberTrimLeft__")
+                        content = strings.ReplaceAll(content, prefix+"TrimBytes",      prefix+"__fiberTrim__")
+                        content = strings.ReplaceAll(content, prefix+"EqualFoldBytes", prefix+"__fiberEqualFold__")
+
+                        // map removed string helpers to the strings package
+                        content = strings.ReplaceAll(content, prefix+"TrimRight", "strings.TrimRight")
+                        content = strings.ReplaceAll(content, prefix+"TrimLeft",  "strings.TrimLeft")
+                        content = strings.ReplaceAll(content, prefix+"Trim",      "strings.Trim")
+                        content = strings.ReplaceAll(content, prefix+"EqualFold", "strings.EqualFold")
+
+                        // restore byte helper placeholders to their new names
+                        content = strings.ReplaceAll(content, prefix+"__fiberTrimRight__",  prefix+"TrimRight")
+                        content = strings.ReplaceAll(content, prefix+"__fiberTrimLeft__",   prefix+"TrimLeft")
+                        content = strings.ReplaceAll(content, prefix+"__fiberTrim__",       prefix+"Trim")
+                        content = strings.ReplaceAll(content, prefix+"__fiberEqualFold__",  prefix+"EqualFold")
+
+                        // other removed helpers
+                        content = strings.ReplaceAll(content, prefix+"GetString",        prefix+"ToString")
+                        content = strings.ReplaceAll(content, prefix+"GetBytes",         prefix+"CopyBytes")
+                        content = strings.ReplaceAll(content, prefix+"ImmutableString",  "string")
+                        content = strings.ReplaceAll(content, prefix+"AssertEqual",      "assert.Equal")
+                }
 
                 return content
         })
         if err != nil {
                 return fmt.Errorf("failed to migrate utils imports: %w", err)
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// MigrateUtilsImport replaces old Fiber utils imports and updates removed helpers
func MigrateUtilsImport(cmd *cobra.Command, cwd string, _, _ *semver.Version) error {
reImport := regexp.MustCompile(`github\.com/gofiber/fiber/v\d+/utils`)
err := internal.ChangeFileContent(cwd, func(content string) string {
// update import path
content = reImport.ReplaceAllString(content, "github.com/gofiber/utils")
// protect byte helper replacements so we can safely map string helpers to the
// standard library without affecting byte-based calls
content = strings.ReplaceAll(content, "utils.TrimRightBytes", "utils.__fiberTrimRight__")
content = strings.ReplaceAll(content, "utils.TrimLeftBytes", "utils.__fiberTrimLeft__")
content = strings.ReplaceAll(content, "utils.TrimBytes", "utils.__fiberTrim__")
content = strings.ReplaceAll(content, "utils.EqualFoldBytes", "utils.__fiberEqualFold__")
// map removed string helpers to the strings package
content = strings.ReplaceAll(content, "utils.TrimRight", "strings.TrimRight")
content = strings.ReplaceAll(content, "utils.TrimLeft", "strings.TrimLeft")
content = strings.ReplaceAll(content, "utils.Trim", "strings.Trim")
content = strings.ReplaceAll(content, "utils.EqualFold", "strings.EqualFold")
// restore byte helper placeholders to their new names
content = strings.ReplaceAll(content, "utils.__fiberTrimRight__", "utils.TrimRight")
content = strings.ReplaceAll(content, "utils.__fiberTrimLeft__", "utils.TrimLeft")
content = strings.ReplaceAll(content, "utils.__fiberTrim__", "utils.Trim")
content = strings.ReplaceAll(content, "utils.__fiberEqualFold__", "utils.EqualFold")
// other removed helpers
content = strings.ReplaceAll(content, "utils.GetString", "utils.ToString")
content = strings.ReplaceAll(content, "utils.GetBytes", "utils.CopyBytes")
content = strings.ReplaceAll(content, "utils.ImmutableString", "string")
content = strings.ReplaceAll(content, "utils.AssertEqual", "assert.Equal")
return content
})
if err != nil {
return fmt.Errorf("failed to migrate utils imports: %w", err)
}
cmd.Println("Migrating utils imports")
return nil
}
// MigrateUtilsImport replaces old Fiber utils imports and updates removed helpers
func MigrateUtilsImport(cmd *cobra.Command, cwd string, _, _ *semver.Version) error {
reImport := regexp.MustCompile(`github\.com/gofiber/fiber/v\d+/utils`)
// capture alias names for the utils import in both grouped and single-line forms
reAlias := regexp.MustCompile(`(?m)^\s*(\w+)\s+"github\.com/gofiber/(?:fiber/v\d+/)?utils"`)
err := internal.ChangeFileContent(cwd, func(content string) string {
// update import path
content = reImport.ReplaceAllString(content, "github.com/gofiber/utils")
// build the set of qualifiers to rewrite (default "utils" + any explicit aliases found)
aliases := map[string]struct{}{"utils": {}}
for _, m := range reAlias.FindAllStringSubmatch(content, -1) {
if len(m) > 1 && m[1] != "" {
aliases[m[1]] = struct{}{}
}
}
// apply rewrites for each qualifier
for alias := range aliases {
prefix := alias + "."
// protect byte helper replacements so we can safely map string helpers to stdlib
content = strings.ReplaceAll(content, prefix+"TrimRightBytes", prefix+"__fiberTrimRight__")
content = strings.ReplaceAll(content, prefix+"TrimLeftBytes", prefix+"__fiberTrimLeft__")
content = strings.ReplaceAll(content, prefix+"TrimBytes", prefix+"__fiberTrim__")
content = strings.ReplaceAll(content, prefix+"EqualFoldBytes", prefix+"__fiberEqualFold__")
// map removed string helpers to the strings package
content = strings.ReplaceAll(content, prefix+"TrimRight", "strings.TrimRight")
content = strings.ReplaceAll(content, prefix+"TrimLeft", "strings.TrimLeft")
content = strings.ReplaceAll(content, prefix+"Trim", "strings.Trim")
content = strings.ReplaceAll(content, prefix+"EqualFold", "strings.EqualFold")
// restore byte helper placeholders to their new names
content = strings.ReplaceAll(content, prefix+"__fiberTrimRight__", prefix+"TrimRight")
content = strings.ReplaceAll(content, prefix+"__fiberTrimLeft__", prefix+"TrimLeft")
content = strings.ReplaceAll(content, prefix+"__fiberTrim__", prefix+"Trim")
content = strings.ReplaceAll(content, prefix+"__fiberEqualFold__", prefix+"EqualFold")
// other removed helpers
content = strings.ReplaceAll(content, prefix+"GetString", prefix+"ToString")
content = strings.ReplaceAll(content, prefix+"GetBytes", prefix+"CopyBytes")
content = strings.ReplaceAll(content, prefix+"ImmutableString", "string")
content = strings.ReplaceAll(content, prefix+"AssertEqual", "assert.Equal")
}
return content
})
if err != nil {
return fmt.Errorf("failed to migrate utils imports: %w", err)
}
cmd.Println("Migrating utils imports")
return nil
}

@ReneWerner87 ReneWerner87 merged commit 0a9ffbb into master Aug 22, 2025
13 checks passed
@ReneWerner87 ReneWerner87 deleted the codex/2025-08-22-22-17-57 branch August 22, 2025 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants