diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..17ce774 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,5 @@ +# Repository Guidelines + +- Use the Makefile commands for common tasks (e.g., `make lint`, `make test`) +- Always run `make lint` +- Always run `make test` diff --git a/Makefile b/Makefile index cdf459d..ad57fea 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +TOOLCHAIN ?= go1.25.0 + ## help: 💡 Display available commands .PHONY: help help: @@ -37,7 +39,7 @@ markdown: ## lint: 🚨 Run lint checks .PHONY: lint lint: - go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 run ./... + GOTOOLCHAIN=$(TOOLCHAIN) go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 run ./... ## test: 🚦 Execute all tests .PHONY: test diff --git a/cmd/internal/migrations/lists.go b/cmd/internal/migrations/lists.go index c63ec26..3076c45 100644 --- a/cmd/internal/migrations/lists.go +++ b/cmd/internal/migrations/lists.go @@ -73,7 +73,7 @@ var Migrations = []Migration{ // DoMigration runs all migrations // It will run all migrations that match the current and target version -func DoMigration(cmd *cobra.Command, cwd string, curr, target *semver.Version, skipGoMod bool) error { +func DoMigration(cmd *cobra.Command, cwd string, curr, target *semver.Version, skipGoMod, verbose bool) error { for _, m := range Migrations { toC, err := semver.NewConstraint(m.To) if err != nil { @@ -90,7 +90,7 @@ func DoMigration(cmd *cobra.Command, cwd string, curr, target *semver.Version, s return err } } - } else { + } else if verbose { cmd.Printf("Skipping migration from %s to %s\n", m.From, m.To) } } diff --git a/cmd/internal/migrations/lists_test.go b/cmd/internal/migrations/lists_test.go new file mode 100644 index 0000000..d0b00a1 --- /dev/null +++ b/cmd/internal/migrations/lists_test.go @@ -0,0 +1,42 @@ +package migrations_test + +import ( + "bytes" + "testing" + + semver "github.com/Masterminds/semver/v3" + "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/gofiber/cli/cmd/internal/migrations" +) + +func Test_DoMigration_Verbose(t *testing.T) { + t.Parallel() + dir := t.TempDir() + curr := semver.MustParse("0.0.0") + target := semver.MustParse("0.1.0") + + t.Run("silent", func(t *testing.T) { + t.Parallel() + + var buf bytes.Buffer + cmd := &cobra.Command{} + cmd.SetOut(&buf) + require.NoError(t, migrations.DoMigration(cmd, dir, curr, target, true, false)) + assert.Equal(t, "", buf.String()) + }) + + t.Run("verbose", func(t *testing.T) { + t.Parallel() + + var buf bytes.Buffer + cmd := &cobra.Command{} + cmd.SetOut(&buf) + require.NoError(t, migrations.DoMigration(cmd, dir, curr, target, true, true)) + out := buf.String() + assert.Contains(t, out, "Skipping migration from >=1.0.0 to >=0.0.0-0") + assert.Contains(t, out, "Skipping migration from >=2.0.0 to <4.0.0-0") + }) +} diff --git a/cmd/migrate.go b/cmd/migrate.go index f5485a2..3a96e56 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -16,23 +16,17 @@ func newMigrateCmd() *cobra.Command { var targetVersionS string var force bool var skipGoMod bool + var verbose bool cmd := &cobra.Command{ Use: "migrate", Short: "Migrate Fiber project version to a newer version", } - latestFiberVersion, err := LatestFiberVersion() - if err != nil { - latestFiberVersion = "" - } - - cmd.Flags().StringVarP(&targetVersionS, "to", "t", "", "Migrate to a specific version e.g:"+latestFiberVersion+" Format: X.Y.Z") - if err := cmd.MarkFlagRequired("to"); err != nil { - panic(err) - } + cmd.Flags().StringVarP(&targetVersionS, "to", "t", "", "Migrate to a specific version. Default: latest") cmd.Flags().BoolVarP(&force, "force", "f", false, "Force migration even if already on version") cmd.Flags().BoolVarP(&skipGoMod, "skip_go_mod", "s", false, "Skip running go mod tidy, download and vendor") + cmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output") cmd.RunE = func(cmd *cobra.Command, _ []string) error { return migrateRunE(cmd, MigrateOptions{ @@ -40,6 +34,7 @@ func newMigrateCmd() *cobra.Command { TargetVersionS: targetVersionS, Force: force, SkipGoMod: skipGoMod, + Verbose: verbose, }) } @@ -53,6 +48,7 @@ type MigrateOptions struct { TargetVersionS string Force bool SkipGoMod bool + Verbose bool } func migrateRunE(cmd *cobra.Command, opts MigrateOptions) error { @@ -63,6 +59,12 @@ func migrateRunE(cmd *cobra.Command, opts MigrateOptions) error { currentVersionS = strings.TrimPrefix(currentVersionS, "v") currentVersion := semver.MustParse(currentVersionS) + if opts.TargetVersionS == "" { + opts.TargetVersionS, err = LatestFiberVersion() + if err != nil { + return fmt.Errorf("failed to determine latest fiber version: %w", err) + } + } opts.TargetVersionS = strings.TrimPrefix(opts.TargetVersionS, "v") targetVersion, err := semver.NewVersion(opts.TargetVersionS) if err != nil { @@ -89,7 +91,7 @@ func migrateRunE(cmd *cobra.Command, opts MigrateOptions) error { migrateFromS = migrateFrom.String() } - err = migrations.DoMigration(cmd, wd, migrateFrom, targetVersion, opts.SkipGoMod) + err = migrations.DoMigration(cmd, wd, migrateFrom, targetVersion, opts.SkipGoMod, opts.Verbose) if err != nil { return fmt.Errorf("migration failed %w", err) } diff --git a/cmd/migrate_test.go b/cmd/migrate_test.go index 808b711..d58f8f2 100644 --- a/cmd/migrate_test.go +++ b/cmd/migrate_test.go @@ -1,11 +1,13 @@ package cmd import ( + "net/http" "os" "os/exec" "path/filepath" "testing" + "github.com/jarcoal/httpmock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -111,6 +113,47 @@ func main() { assert.Equal(t, content, content2) } +func Test_Migrate_DefaultTarget(t *testing.T) { + dir, err := os.MkdirTemp("", "migrate_default") + require.NoError(t, err) + defer func() { require.NoError(t, os.RemoveAll(dir)) }() + + gomod := `module example.com/demo + +go 1.20 + +require github.com/gofiber/fiber/v2 v2.0.6 +` + require.NoError(t, os.WriteFile(filepath.Join(dir, "go.mod"), []byte(gomod), 0o600)) + + main := `package main +import "github.com/gofiber/fiber/v2" +func main() { + _ = fiber.New() +}` + require.NoError(t, os.WriteFile(filepath.Join(dir, "main.go"), []byte(main), 0o600)) + + cwd, err := os.Getwd() + require.NoError(t, err) + require.NoError(t, os.Chdir(dir)) + defer func() { require.NoError(t, os.Chdir(cwd)) }() + + setupCmd() + defer teardownCmd() + + httpmock.Activate() + defer httpmock.DeactivateAndReset() + httpmock.RegisterResponder(http.MethodGet, "https://api.github.com/repos/gofiber/fiber/releases/latest", httpmock.NewBytesResponder(200, []byte(`{"name":"v3.0.0"}`))) + + cmd := newMigrateCmd() + out, err := runCobraCmd(cmd) + require.NoError(t, err) + assert.Contains(t, out, "Migration from Fiber 2.0.6 to 3.0.0") + + content := readFileTB(t, filepath.Join(dir, "go.mod")) + assert.Contains(t, content, "github.com/gofiber/fiber/v3 v3.0.0") +} + func Test_RunGoMod(t *testing.T) { dir := t.TempDir() diff --git a/cmd/tester_test.go b/cmd/tester_test.go index 98e8d6f..140c1e0 100644 --- a/cmd/tester_test.go +++ b/cmd/tester_test.go @@ -121,7 +121,11 @@ func runCobraCmd(cmd *cobra.Command, args ...string) (string, error) { parent.SilenceErrors = origSilence }() } else { - cmd.SetArgs(args) + if len(args) == 0 { + cmd.SetArgs([]string{}) + } else { + cmd.SetArgs(args) + } } err := cmd.Execute()