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

Skip to content

Conversation

@ReneWerner87
Copy link
Member

@ReneWerner87 ReneWerner87 commented Aug 24, 2025

Summary

  • add migration to update logger interfaces and functions for generics
  • register migration and cover with tests
  • infer logger type from Logger() to apply specific generics, e.g. zap

Testing

  • make lint
  • make test

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

Summary by CodeRabbit

  • New Features

    • Added an automatic migration that updates logger usage to the generics-based API for upgrades from 2.x to <4.0. It detects the project’s logger type, inserts the appropriate generic (defaults to a safe fallback), and is executed as part of the migration sequence.
  • Tests

    • Added tests for default, custom logger types and a non-Fiber skip case to verify correct transformations and migration output.

@coderabbitai
Copy link

coderabbitai bot commented Aug 24, 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 14 minutes and 32 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 276fd30 and 81d62b5.

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

Walkthrough

Adds a new v3 migration, MigrateLoggerGenerics, that infers logger types from Logger() signatures and rewrites logger-related identifiers to generic forms; registers this migration in the v3 migrations list between MigrateLoggerTags and MigrateStaticRoutes. Includes tests for default, zap, and non-Fiber cases.

Changes

Cohort / File(s) Summary of Changes
Migration registry update
cmd/internal/migrations/lists.go
Inserts v3migrations.MigrateLoggerGenerics into the v3 Migration entry (From ">=2.0.0-0", To "<4.0.0-0") after MigrateLoggerTags and before MigrateStaticRoutes.
New v3 migration: logger generics
cmd/internal/migrations/v3/logger_generics.go
Adds MigrateLoggerGenerics(cmd *cobra.Command, cwd string, _, _ *semver.Version) error which parses Go imports/signatures to infer logger type (fallback any) and applies regex-based rewrites to AllLogger, ConfigurableLogger, DefaultLogger, SetLogger, and LoggerToWriter to index into generics maps using the detected type.
Tests for migration
cmd/internal/migrations/v3/logger_generics_test.go
Adds three tests: default (any) migration, *zap.Logger detection, and skip behavior for non-Fiber loggers; assert transformed code and migration output message.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant CLI as CLI Migrator
  participant FS as Filesystem
  participant V3 as v3.MigrateLoggerGenerics

  Dev->>CLI: run migration (v3)
  CLI->>V3: Invoke MigrateLoggerGenerics(cwd)
  V3->>FS: Read Go files (imports + AST parse)
  V3->>V3: Detect logger type from Logger() signature
  alt logger type found
    V3->>FS: Apply regex rewrites to add [<type>] to logger symbols
  else no type found
    V3->>FS: Apply rewrites using [any] as fallback
  end
  V3-->>CLI: Return status (success/no-op/error)
  CLI-->>Dev: Print "Migrating logger generics" on change
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

✏️ Feature

Poem

I’m a rabbit with a tiny keyboard spring,
I hop through code and give it a fling.
I find the logger, sniff its type,
Swap in generics — quick and spry.
Thump-thump, migration done — I dance and sing. 🐇✨

✨ 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-24-12-05-05

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
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 to update logger interfaces and functions to leverage Go generics. The migration automatically infers the appropriate logger type, such as zap.Logger, or defaults to any, and applies it to various logger-related calls and declarations. This streamlines the process of adapting existing codebases to the new generic logger patterns.

Highlights

  • New Migration Added: A new migration step, MigrateLoggerGenerics, has been introduced and registered within the CLI tool's v3 migrations.
  • Logger Generics Adoption: The migration automatically updates existing logger interfaces (AllLogger, ConfigurableLogger) and functions (DefaultLogger, SetLogger, LoggerToWriter) to correctly utilize Go generics.
  • Intelligent Type Inference: The migration intelligently infers the specific logger type (e.g., *zap.Logger) by analyzing the Logger() method signature, ensuring type-safe generic application, and falls back to any if a specific type cannot be determined.
  • Automated Code Updates: This change provides an automated way to update existing codebases to align with the new generic logger patterns, reducing manual effort and potential errors.
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 introduces a new migration to update logger interfaces and functions to use generics. The changes include adding the migration logic, registering it, and providing test coverage. The implementation of the migration in cmd/internal/migrations/v3/logger_generics.go is correct, but contains repetitive code for string replacements. I've suggested a refactoring to improve maintainability by reducing code duplication. The tests are well-written and cover the intended functionality.

Comment on lines 27 to 61
content = reAllLogger.ReplaceAllStringFunc(content, func(m string) string {
sub := reAllLogger.FindStringSubmatch(m)
if len(sub) != 3 {
return m
}
return fmt.Sprintf("%s.AllLogger[%s]%s", sub[1], loggerType, sub[2])
})
content = reConfigurableLogger.ReplaceAllStringFunc(content, func(m string) string {
sub := reConfigurableLogger.FindStringSubmatch(m)
if len(sub) != 3 {
return m
}
return fmt.Sprintf("%s.ConfigurableLogger[%s]%s", sub[1], loggerType, sub[2])
})
content = reDefaultLogger.ReplaceAllStringFunc(content, func(m string) string {
sub := reDefaultLogger.FindStringSubmatch(m)
if len(sub) != 2 {
return m
}
return fmt.Sprintf("%s.DefaultLogger[%s]()", sub[1], loggerType)
})
content = reSetLogger.ReplaceAllStringFunc(content, func(m string) string {
sub := reSetLogger.FindStringSubmatch(m)
if len(sub) != 2 {
return m
}
return fmt.Sprintf("%s.SetLogger[%s](", sub[1], loggerType)
})
content = reLoggerToWriter.ReplaceAllStringFunc(content, func(m string) string {
sub := reLoggerToWriter.FindStringSubmatch(m)
if len(sub) != 2 {
return m
}
return fmt.Sprintf("%s.LoggerToWriter[%s](", sub[1], loggerType)
})
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The series of ReplaceAllStringFunc calls for different logger functions is quite repetitive. To improve maintainability and reduce code duplication, you can refactor this logic. By defining a structure to hold the regular expression, replacement format string, and expected number of submatches, you can iterate over a slice of these structures and apply the replacements in a loop. This makes the code more concise and easier to modify in the future.

		type replacement struct {
			re               *regexp.Regexp
			format           string
			expectedSubmatch int
		}

		replacements := []replacement{
			{reAllLogger, "%s.AllLogger[%s]%s", 3},
			{reConfigurableLogger, "%s.ConfigurableLogger[%s]%s", 3},
			{reDefaultLogger, "%s.DefaultLogger[%s]()", 2},
			{reSetLogger, "%s.SetLogger[%s](", 2},
			{reLoggerToWriter, "%s.LoggerToWriter[%s](", 2},
		}

		for _, r := range replacements {
			content = r.re.ReplaceAllStringFunc(content, func(m string) string {
				sub := r.re.FindStringSubmatch(m)
				if len(sub) != r.expectedSubmatch {
					return m
				}

				args := []interface{}{sub[1], loggerType}
				if len(sub) > 2 {
					args = append(args, sub[2])
				}

				return fmt.Sprintf(r.format, args...)
			})
		}

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: 1

🧹 Nitpick comments (4)
cmd/internal/migrations/v3/logger_generics.go (3)

21-26: Infer logger type across the package, not just per-file (avoid falling back to any in split files)

Today you infer loggerType only from the same file. In real projects, Logger() may live in logger.go while usages are elsewhere, causing those files to default to any unnecessarily. Consider a pre-pass to scan the tree once and compute a package-wide fallback type, then use the per-file type when present.

I can wire a light-weight pre-scan helper (no AST needed) and use it when the per-file inference yields "any". Want me to push a patch?


14-20: Handle parenthesized or named return types in Logger() signatures

Your current reLoggerType misses valid forms like:

  • func (c *L) Logger() (*zap.Logger) { ... }
  • func (c *L) Logger() (l *zap.Logger) { ... }

Add a second regex (as in the diff above) to capture parenthesized/named returns before the function body.


21-73: Note on comment/string literals

Regex replacement runs on the entire source including comments/strings, so occurrences like "// use fiberlog.DefaultLogger()" will be rewritten. Low risk, but noisy diffs. If this becomes a problem, we can parse tokens and skip comments/strings or strip them before replacement.

If you want, I can provide a token-scan that ignores comments and string literals with go/scanner to keep changes minimal and safe.

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

49-86: Great coverage for zap-specific inference; add idempotency and alias-scope tests

  • Idempotency: run the migration twice and assert the second pass emits no "Migrating logger generics" and makes no further changes.
  • Alias scope: include another import that exposes DefaultLogger() (non-fiber) and assert it is not rewritten once alias filtering is added.

Here are test stubs you can add after adopting alias filtering:

@@
 func Test_MigrateLoggerGenerics_Zap(t *testing.T) {
@@
 }
 
+func Test_MigrateLoggerGenerics_Idempotent(t *testing.T) {
+	t.Parallel()
+	dir, err := os.MkdirTemp("", "mloggenericstestidemp")
+	require.NoError(t, err)
+	defer func() { require.NoError(t, os.RemoveAll(dir)) }()
+
+	file := writeTempFile(t, dir, `package main
+import fiberlog "github.com/gofiber/fiber/v2/log"
+type customLogger struct{}
+func (c *customLogger) Logger() *customLogger { return nil }
+var _ fiberlog.AllLogger = (*customLogger)(nil)
+func main() { _ = fiberlog.DefaultLogger().Logger() }`)
+
+	var buf1 bytes.Buffer
+	cmd1 := newCmd(&buf1)
+	require.NoError(t, v3.MigrateLoggerGenerics(cmd1, dir, nil, nil))
+	content1 := readFile(t, file)
+	assert.Contains(t, content1, "DefaultLogger[")
+	assert.Contains(t, buf1.String(), "Migrating logger generics")
+
+	var buf2 bytes.Buffer
+	cmd2 := newCmd(&buf2)
+	require.NoError(t, v3.MigrateLoggerGenerics(cmd2, dir, nil, nil))
+	assert.NotContains(t, buf2.String(), "Migrating logger generics")
+	content2 := readFile(t, file)
+	assert.Equal(t, content1, content2)
+}
+
+func Test_MigrateLoggerGenerics_OnlyFiberLogAlias(t *testing.T) {
+	t.Parallel()
+	dir, err := os.MkdirTemp("", "mloggenericstestalias")
+	require.NoError(t, err)
+	defer func() { require.NoError(t, os.RemoveAll(dir)) }()
+
+	file := writeTempFile(t, dir, `package main
+import (
+    fiberlog "github.com/gofiber/fiber/v2/log"
+    other "github.com/some/otherpkg"
+)
+func main() {
+    _ = fiberlog.DefaultLogger()
+    _ = other.DefaultLogger() // must not be rewritten
+}`)
+	var buf bytes.Buffer
+	cmd := newCmd(&buf)
+	require.NoError(t, v3.MigrateLoggerGenerics(cmd, dir, nil, nil))
+	content := readFile(t, file)
+	assert.Contains(t, content, "fiberlog.DefaultLogger[")
+	assert.Contains(t, content, "other.DefaultLogger()") // unchanged
+}
📜 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 287db05 and 6479278.

📒 Files selected for processing (3)
  • cmd/internal/migrations/lists.go (1 hunks)
  • cmd/internal/migrations/v3/logger_generics.go (1 hunks)
  • cmd/internal/migrations/v3/logger_generics_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
cmd/internal/migrations/lists.go (1)
cmd/internal/migrations/v3/logger_generics.go (1)
  • MigrateLoggerGenerics (13-73)
cmd/internal/migrations/v3/logger_generics.go (1)
cmd/internal/helpers.go (1)
  • ChangeFileContent (38-79)
cmd/internal/migrations/v3/logger_generics_test.go (1)
cmd/internal/migrations/v3/logger_generics.go (1)
  • MigrateLoggerGenerics (13-73)
🔇 Additional comments (3)
cmd/internal/migrations/lists.go (2)

46-47: Good insertion point for the new migration

Placing MigrateLoggerGenerics right after MigrateLoggerTags and before MigrateStaticRoutes makes sense and preserves the existing sequencing. No concerns with the registration itself.


38-47: Double-check ordering dependencies with other v3 migrations

If any of the earlier migrations (e.g., MigrateGenericHelpers or MigrateLoggerTags) alter identifiers that your regexes depend on, confirm MigrateLoggerGenerics runs after them. Current placement looks correct, but worth verifying in real repos to avoid missed matches.

Would you like me to run a quick repo-wide search script on the PR branch to ensure no earlier migration renames these symbols in a way that could impact your patterns?

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

14-47: Solid coverage for default (any) path

Good assertions and message check. Parallel test is safe given per-test temp dirs.

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: 1

♻️ Duplicate comments (2)
cmd/internal/migrations/v3/logger_generics.go (2)

62-96: DRY up repetitive ReplaceAll blocks with a small loop.

The five near-identical ReplaceAllStringFunc blocks increase maintenance surface. Collapse them into a table-driven loop. This mirrors a previously suggested refactor.

-		content = reAllLogger.ReplaceAllStringFunc(content, func(m string) string {
-			sub := reAllLogger.FindStringSubmatch(m)
-			if len(sub) != 3 {
-				return m
-			}
-			return fmt.Sprintf("%s.AllLogger[%s]%s", sub[1], loggerType, sub[2])
-		})
-		content = reConfigurableLogger.ReplaceAllStringFunc(content, func(m string) string {
-			sub := reConfigurableLogger.FindStringSubmatch(m)
-			if len(sub) != 3 {
-				return m
-			}
-			return fmt.Sprintf("%s.ConfigurableLogger[%s]%s", sub[1], loggerType, sub[2])
-		})
-		content = reDefaultLogger.ReplaceAllStringFunc(content, func(m string) string {
-			sub := reDefaultLogger.FindStringSubmatch(m)
-			if len(sub) != 2 {
-				return m
-			}
-			return fmt.Sprintf("%s.DefaultLogger[%s]()", sub[1], loggerType)
-		})
-		content = reSetLogger.ReplaceAllStringFunc(content, func(m string) string {
-			sub := reSetLogger.FindStringSubmatch(m)
-			if len(sub) != 2 {
-				return m
-			}
-			return fmt.Sprintf("%s.SetLogger[%s](", sub[1], loggerType)
-		})
-		content = reLoggerToWriter.ReplaceAllStringFunc(content, func(m string) string {
-			sub := reLoggerToWriter.FindStringSubmatch(m)
-			if len(sub) != 2 {
-				return m
-			}
-			return fmt.Sprintf("%s.LoggerToWriter[%s](", sub[1], loggerType)
-		})
+		type replacement struct {
+			re               *regexp.Regexp
+			format           string
+			expectedSubmatch int
+		}
+		replacements := []replacement{
+			{re: reAllLogger, format: "%s.AllLogger[%s]%s", expectedSubmatch: 3},
+			{re: reConfigurableLogger, format: "%s.ConfigurableLogger[%s]%s", expectedSubmatch: 3},
+			{re: reDefaultLogger, format: "%s.DefaultLogger[%s]()", expectedSubmatch: 2},
+			{re: reSetLogger, format: "%s.SetLogger[%s](", expectedSubmatch: 2},
+			{re: reLoggerToWriter, format: "%s.LoggerToWriter[%s](", expectedSubmatch: 2},
+		}
+		for _, r := range replacements {
+			content = r.re.ReplaceAllStringFunc(content, func(m string) string {
+				sub := r.re.FindStringSubmatch(m)
+				if len(sub) != r.expectedSubmatch {
+					return m
+				}
+				args := []any{sub[1], loggerType}
+				if len(sub) > 2 {
+					args = append(args, sub[2])
+				}
+				return fmt.Sprintf(r.format, args...)
+			})
+		}

18-20: Broaden Logger() return-type detection (parenthesized/named/multiline).

Logger() can legally return types via parenthesized/named returns and across newlines; the current regex misses these. Add a secondary regex to capture func Logger() (*zap.Logger) and func Logger() (l *zap.Logger) forms and fall back to it if the primary doesn’t match.

 func MigrateLoggerGenerics(cmd *cobra.Command, cwd string, _, _ *semver.Version) error {
 	fiberImport := regexp.MustCompile(`^github\.com/gofiber/fiber/v\d+/log$`)
-	reLoggerType := regexp.MustCompile(`(?m)^func\s+(?:\(\w+\s+\*?\w+\)\s+)?Logger\(\)\s*(\*?\w+(?:\.\w+)*)\s*{`)
+	// Matches: func Logger() *zap.Logger { ... } or with receiver
+	reLoggerType := regexp.MustCompile(`(?m)^func\s+(?:\(\w+\s+\*?\w+\)\s+)?Logger\(\)\s*(\*?\w+(?:\.\w+)*)\s*{`)
+	// Matches parenthesized/named returns (also across newlines):
+	//   func Logger() (*zap.Logger) { ... }
+	//   func Logger() (l *zap.Logger) { ... }
+	reLoggerTypeParen := regexp.MustCompile(`(?ms)^func\s+(?:\(\w+\s+\*?\w+\)\s+)?Logger\(\)\s*\(\s*(?:\w+\s+)?(\*?\w+(?:\.\w+)*)\s*\)\s*{`)
-		loggerType := "any"
-		if m := reLoggerType.FindStringSubmatch(content); len(m) == 2 {
-			loggerType = m[1]
-		}
+		loggerType := "any"
+		if m := reLoggerType.FindStringSubmatch(content); len(m) == 2 && m[1] != "" {
+			loggerType = m[1]
+		} else if m := reLoggerTypeParen.FindStringSubmatch(content); len(m) == 2 && m[1] != "" {
+			loggerType = m[1]
+		}
🧹 Nitpick comments (2)
cmd/internal/migrations/v3/logger_generics_test.go (2)

14-47: Solid happy-path coverage; add assertion for interface rewrites.

You already assert for AllLogger[any] and ConfigurableLogger[any]. Consider asserting the rewritten interface assertions too (e.g., var _ log.AllLogger[any] = ...) to prove replacements occur in type positions, not just calls.


49-86: Zap case looks good; add a variant for parenthesized/named returns.

To validate the enhanced Logger() return detection, add a test where Logger() returns via parentheses and/or named identifier.

+func Test_MigrateLoggerGenerics_ZapParenAndNamed(t *testing.T) {
+	t.Parallel()
+	dir := t.TempDir()
+	file := writeTempFile(t, dir, `package main
+import (
+    flog "github.com/gofiber/fiber/v2/log"
+    "go.uber.org/zap"
+)
+type customLogger struct{}
+// parenthesized
+func (c *customLogger) Logger() (*zap.Logger) { return nil }
+var _ flog.AllLogger = (*customLogger)(nil)
+var _ flog.ConfigurableLogger = (*customLogger)(nil)
+func main() {
+    _ = flog.DefaultLogger().Logger()
+}`)
+	var buf bytes.Buffer
+	cmd := newCmd(&buf)
+	require.NoError(t, v3.MigrateLoggerGenerics(cmd, dir, nil, nil))
+	content := readFile(t, file)
+	assert.Contains(t, content, "AllLogger[*zap.Logger]")
+	assert.Contains(t, content, "ConfigurableLogger[*zap.Logger]")
+	assert.Contains(t, content, "DefaultLogger[*zap.Logger]()")
+}
📜 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 6479278 and 276fd30.

📒 Files selected for processing (2)
  • cmd/internal/migrations/v3/logger_generics.go (1 hunks)
  • cmd/internal/migrations/v3/logger_generics_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
cmd/internal/migrations/v3/logger_generics.go (1)
cmd/internal/helpers.go (1)
  • ChangeFileContent (38-79)
cmd/internal/migrations/v3/logger_generics_test.go (1)
cmd/internal/migrations/v3/logger_generics.go (1)
  • MigrateLoggerGenerics (17-108)
🔇 Additional comments (3)
cmd/internal/migrations/v3/logger_generics.go (2)

50-56: Patterns look good and are safely scoped to the detected alias(es).

Nice containment: alias is escaped with QuoteMeta and the patterns avoid reprocessing already generic identifiers via [^\\w\\[]. This significantly reduces false positives compared to prior iterations.


102-107: Progress message gated on actual edits — good UX.

Printing only when changes occurred keeps migrations quiet on no-ops and helps users see what ran. Tests assert this behavior; keep it.

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

88-117: Non-Fiber skip is well covered.

Good guard ensuring we don’t touch similarly named APIs from other packages and that no progress message is emitted.

Comment on lines +37 to +44
alias := "log"
if imp.Name != nil {
alias = imp.Name.Name
} else if idx := strings.LastIndex(path, "/"); idx != -1 {
alias = path[idx+1:]
}
aliases = append(aliases, regexp.QuoteMeta(alias))
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Skip dot-import and blank identifier aliases to avoid unusable matchers.

Dot-imports expose identifiers without alias and _ aliases are not referenced. Including them generates patterns that never match ((\.)\.AllLogger...). Filter them out.

-			alias := "log"
-			if imp.Name != nil {
-				alias = imp.Name.Name
+			alias := "log"
+			if imp.Name != nil {
+				// ignore dot-imports and blank identifier imports
+				if imp.Name.Name == "." || imp.Name.Name == "_" {
+					continue
+				}
+				alias = imp.Name.Name
📝 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
alias := "log"
if imp.Name != nil {
alias = imp.Name.Name
} else if idx := strings.LastIndex(path, "/"); idx != -1 {
alias = path[idx+1:]
}
aliases = append(aliases, regexp.QuoteMeta(alias))
}
alias := "log"
if imp.Name != nil {
// ignore dot-imports and blank identifier imports
if imp.Name.Name == "." || imp.Name.Name == "_" {
continue
}
alias = imp.Name.Name
} else if idx := strings.LastIndex(path, "/"); idx != -1 {
alias = path[idx+1:]
}
aliases = append(aliases, regexp.QuoteMeta(alias))
🤖 Prompt for AI Agents
In cmd/internal/migrations/v3/logger_generics.go around lines 37 to 44, the
current logic adds aliases for imports but doesn't skip dot-imports (Name ==
".") or blank identifier aliases ("_"), which produces unusable regex fragments;
update the conditional so if imp.Name != nil and imp.Name.Name is "." or "_" you
continue/skip and do not derive or append an alias, otherwise keep the existing
logic to use imp.Name.Name or the last path segment and then append
regexp.QuoteMeta(alias).

@ReneWerner87 ReneWerner87 added the ✏️ Feature New feature or request label Aug 24, 2025
@ReneWerner87 ReneWerner87 merged commit 0c58401 into master Aug 24, 2025
13 checks passed
@ReneWerner87 ReneWerner87 deleted the codex/2025-08-24-12-05-05 branch August 24, 2025 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex ✏️ Feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants