-
Notifications
You must be signed in to change notification settings - Fork 16
feat: migrate logger generics #187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit 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 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. 📒 Files selected for processing (1)
WalkthroughAdds 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
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Poem
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 theLogger()method signature, ensuring type-safe generic application, and falls back toanyif 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
-
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. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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) | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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...)
})
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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() signaturesYour 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 literalsRegex 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.
📒 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 migrationPlacing 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 migrationsIf 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) pathGood assertions and message check. Parallel test is safe given per-test temp dirs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)andfunc 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]andConfigurableLogger[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.
📒 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.
| 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)) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ 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.
| 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).
Summary
Logger()to apply specific generics, e.g. zapTesting
make lintmake testhttps://chatgpt.com/codex/tasks/task_e_68aaf8dd7e6c8326b772dab0107af213
Summary by CodeRabbit
New Features
Tests