diff --git a/cmd/internal/migrations/lists.go b/cmd/internal/migrations/lists.go index 584fd9b..ef36344 100644 --- a/cmd/internal/migrations/lists.go +++ b/cmd/internal/migrations/lists.go @@ -45,6 +45,7 @@ var Migrations = []Migration{ v3migrations.MigrateMimeConstants, v3migrations.MigrateLoggerTags, v3migrations.MigrateLoggerGenerics, + v3migrations.MigrateLoggerConfig, v3migrations.MigrateStaticRoutes, v3migrations.MigrateTrustedProxyConfig, v3migrations.MigrateMount, diff --git a/cmd/internal/migrations/v3/logger_config.go b/cmd/internal/migrations/v3/logger_config.go new file mode 100644 index 0000000..b9509c9 --- /dev/null +++ b/cmd/internal/migrations/v3/logger_config.go @@ -0,0 +1,43 @@ +package v3 + +import ( + "fmt" + "regexp" + + semver "github.com/Masterminds/semver/v3" + "github.com/spf13/cobra" + + "github.com/gofiber/cli/cmd/internal" +) + +var ( + reLoggerImport = regexp.MustCompile(`(?m)^\s*(?:import\s+)?(?:([\w.]+)\s+)?"github\.com/gofiber/fiber/(?:v2|v3)/middleware/logger"`) + reLoggerOutputField = regexp.MustCompile(`((?:^|[{\n])\s*)Output(\s*:)`) +) + +func MigrateLoggerConfig(cmd *cobra.Command, cwd string, _, _ *semver.Version) error { + changed, err := internal.ChangeFileContent(cwd, func(content string) string { + aliases := collectAliases(content, reLoggerImport, []string{"logger"}) + if len(aliases) == 0 { + return content + } + + for _, alias := range aliases { + reConfig := regexp.MustCompile(regexp.QuoteMeta(alias) + `\.Config\s*\{`) + content = IterateConfigBlocks(content, reConfig, func(s string) string { + return reLoggerOutputField.ReplaceAllString(s, "${1}Stream${2}") + }) + } + + return content + }) + if err != nil { + return fmt.Errorf("failed to migrate logger configs: %w", err) + } + if !changed { + return nil + } + + cmd.Println("Migrating logger middleware configs") + return nil +} diff --git a/cmd/internal/migrations/v3/logger_config_test.go b/cmd/internal/migrations/v3/logger_config_test.go new file mode 100644 index 0000000..dfedfb2 --- /dev/null +++ b/cmd/internal/migrations/v3/logger_config_test.go @@ -0,0 +1,186 @@ +package v3_test + +import ( + "bytes" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/gofiber/cli/cmd/internal/migrations/v3" +) + +func Test_MigrateLoggerConfig(t *testing.T) { + t.Parallel() + + dir, err := os.MkdirTemp("", "mlogger") + require.NoError(t, err) + defer func() { require.NoError(t, os.RemoveAll(dir)) }() + + file := writeTempFile(t, dir, `package main +import ( + "os" + "github.com/gofiber/fiber/v2/middleware/logger" +) +var _ = logger.New(logger.Config{ + Output: os.Stdout, +})`) + + var buf bytes.Buffer + cmd := newCmd(&buf) + require.NoError(t, v3.MigrateLoggerConfig(cmd, dir, nil, nil)) + + content := readFile(t, file) + assert.Contains(t, content, "Stream:") + assert.NotContains(t, content, "Output:") + assert.Contains(t, buf.String(), "Migrating logger middleware configs") +} + +func Test_MigrateLoggerConfig_NoChange(t *testing.T) { + t.Parallel() + + dir, err := os.MkdirTemp("", "mlogger_noop") + require.NoError(t, err) + defer func() { require.NoError(t, os.RemoveAll(dir)) }() + + writeTempFile(t, dir, `package main +import "fmt" +func main() { fmt.Println("hello") } +`) + + var buf bytes.Buffer + cmd := newCmd(&buf) + require.NoError(t, v3.MigrateLoggerConfig(cmd, dir, nil, nil)) + + assert.Empty(t, buf.String()) +} + +func Test_MigrateLoggerConfig_MultipleFields(t *testing.T) { + t.Parallel() + + dir, err := os.MkdirTemp("", "mlogger_multi") + require.NoError(t, err) + defer func() { require.NoError(t, os.RemoveAll(dir)) }() + + file := writeTempFile(t, dir, `package main +import ( + "os" + "github.com/gofiber/fiber/v2/middleware/logger" +) +var _ = logger.New(logger.Config{ + Format: "[${time}] ${status}\n", + Output: os.Stderr, + TimeFormat: "2006-01-02", +})`) + + var buf bytes.Buffer + cmd := newCmd(&buf) + require.NoError(t, v3.MigrateLoggerConfig(cmd, dir, nil, nil)) + + content := readFile(t, file) + assert.Contains(t, content, "Stream:") + assert.NotContains(t, content, "Output:") + assert.Contains(t, content, "Format:") + assert.Contains(t, content, "TimeFormat:") +} + +func Test_MigrateLoggerConfig_OutputInStringLiteral(t *testing.T) { + t.Parallel() + + dir, err := os.MkdirTemp("", "mlogger_str") + require.NoError(t, err) + defer func() { require.NoError(t, os.RemoveAll(dir)) }() + + file := writeTempFile(t, dir, `package main +import ( + "os" + "github.com/gofiber/fiber/v2/middleware/logger" +) +var _ = logger.New(logger.Config{ + Format: "Output: ${status}\n", + Output: os.Stdout, +})`) + + var buf bytes.Buffer + cmd := newCmd(&buf) + require.NoError(t, v3.MigrateLoggerConfig(cmd, dir, nil, nil)) + + content := readFile(t, file) + assert.Contains(t, content, "Stream:") + assert.Contains(t, content, `"Output: ${status}\n"`, "string literal should not be modified") + assert.Contains(t, buf.String(), "Migrating logger middleware configs") +} + +func Test_MigrateLoggerConfig_WhitespaceBeforeBrace(t *testing.T) { + t.Parallel() + + dir, err := os.MkdirTemp("", "mlogger_ws") + require.NoError(t, err) + defer func() { require.NoError(t, os.RemoveAll(dir)) }() + + file := writeTempFile(t, dir, `package main +import ( + "os" + "github.com/gofiber/fiber/v2/middleware/logger" +) +var _ = logger.New(logger.Config { + Output: os.Stdout, +})`) + + var buf bytes.Buffer + cmd := newCmd(&buf) + require.NoError(t, v3.MigrateLoggerConfig(cmd, dir, nil, nil)) + + content := readFile(t, file) + assert.Contains(t, content, "Stream:") + assert.NotContains(t, content, "Output:") +} + +func Test_MigrateLoggerConfig_Alias(t *testing.T) { + t.Parallel() + + dir, err := os.MkdirTemp("", "mlogger_alias") + require.NoError(t, err) + defer func() { require.NoError(t, os.RemoveAll(dir)) }() + + file := writeTempFile(t, dir, `package main +import ( + "os" + fiberlog "github.com/gofiber/fiber/v2/middleware/logger" +) +var _ = fiberlog.New(fiberlog.Config{ + Output: os.Stdout, +})`) + + var buf bytes.Buffer + cmd := newCmd(&buf) + require.NoError(t, v3.MigrateLoggerConfig(cmd, dir, nil, nil)) + + content := readFile(t, file) + assert.Contains(t, content, "Stream:") + assert.NotContains(t, content, "Output:") +} + +func Test_MigrateLoggerConfig_SingleLine(t *testing.T) { + t.Parallel() + + dir, err := os.MkdirTemp("", "mlogger_single") + require.NoError(t, err) + defer func() { require.NoError(t, os.RemoveAll(dir)) }() + + file := writeTempFile(t, dir, `package main +import ( + "os" + "github.com/gofiber/fiber/v2/middleware/logger" +) +var _ = logger.New(logger.Config{Output: os.Stdout})`) + + var buf bytes.Buffer + cmd := newCmd(&buf) + require.NoError(t, v3.MigrateLoggerConfig(cmd, dir, nil, nil)) + + content := readFile(t, file) + assert.Contains(t, content, "Stream:") + assert.NotContains(t, content, "Output:") +}