From 236d1f78602e0d686b07094a67386eae80a450ab Mon Sep 17 00:00:00 2001 From: Gajendra Malviya Date: Thu, 30 Oct 2025 20:45:41 +0530 Subject: [PATCH] fixed migration name into camel case --- migration/migrate.go | 39 +++++++++++++++++++++++++++++++++---- migration/migration_test.go | 31 +++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 migration/migration_test.go diff --git a/migration/migrate.go b/migration/migrate.go index 835dcf6..b02cbf7 100644 --- a/migration/migrate.go +++ b/migration/migrate.go @@ -68,7 +68,9 @@ func Migrate(ctx *gofr.Context) (any, error) { return nil, errNameEmpty } - if err := createMigrationFile(ctx, migName); err != nil { + camelCasedMigName := toCamelCase(migName) + + if err := createMigrationFile(ctx, camelCasedMigName); err != nil { return nil, fmt.Errorf("error while creating migration file, err: %w", err) } @@ -76,7 +78,7 @@ func Migrate(ctx *gofr.Context) (any, error) { return nil, fmt.Errorf("error while creating all.go file, err: %w", err) } - return fmt.Sprintf("Successfully created migration %v", migName), nil + return fmt.Sprintf("Successfully created migration %v", camelCasedMigName), nil } func createMigrationFile(ctx *gofr.Context, migrationName string) error { @@ -182,9 +184,38 @@ func findMigrations(files []os.DirEntry) map[string]string { if len(fileParts) < 2 || file.Name() == allFile || fileParts[len(fileParts)-1] == "test.go" { continue } - - existingMig[fileParts[0]] = strings.TrimSuffix(strings.Join(fileParts[1:], "_"), ".go") + // convert second part (function) to camelCase, since migration files are now generated using camelCase + existingMig[fileParts[0]] = toCamelCase(strings.TrimSuffix(strings.Join(fileParts[1:], "_"), ".go")) } return existingMig } + +// toCamelCase converts snake_case or kebab-case to camelCase. If input has no delimiters, +// it preserves existing casing except lowercasing the first letter. +func toCamelCase(migrationName string) string { + if migrationName == "" { + return migrationName + } + // If no delimiters, assume it's already camel/Pascal case or a single word; just lowercase first rune + if !strings.Contains(migrationName, "_") && !strings.Contains(migrationName, "-") { + return strings.ToLower(migrationName[:1]) + migrationName[1:] + } + + migrationName = strings.ReplaceAll(migrationName, "-", "_") + parts := strings.FieldsFunc(migrationName, func(r rune) bool { return r == '_' || r == '-' }) + + if len(parts) == 0 { + return "" + } + + result := strings.ToLower(parts[0]) + + for _, part := range parts[1:] { + if part != "" { + result += strings.ToUpper(part[:1]) + strings.ToLower(part[1:]) + } + } + + return result +} diff --git a/migration/migration_test.go b/migration/migration_test.go new file mode 100644 index 0000000..f2358d1 --- /dev/null +++ b/migration/migration_test.go @@ -0,0 +1,31 @@ +package migration + +import "testing" + +func TestToCamelCase(t *testing.T) { + tests := []struct { + name string + in string + out string + }{ + {name: "snake_case", in: "create_employee_table", out: "createEmployeeTable"}, + {name: "kebab_case", in: "create-employee-table", out: "createEmployeeTable"}, + {name: "mixed_caps_snake", in: "Create_Employee_Table", out: "createEmployeeTable"}, + {name: "single_word_lower", in: "employee", out: "employee"}, + {name: "single_word_upper_first", in: "Employee", out: "employee"}, + {name: "no_delimiters_lower", in: "createemployeetable", out: "createemployeetable"}, + {name: "no_delimiters_camel", in: "CreateEmployeeTable", out: "createEmployeeTable"}, + {name: "empty", in: "", out: ""}, + {name: "leading_trailing_delims", in: "_create__employee_table_", out: "createEmployeeTable"}, + {name: "multiple_delims", in: "create---employee___table", out: "createEmployeeTable"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := toCamelCase(tt.in) + if got != tt.out { + t.Fatalf("toCamelCase(%q) = %q; want %q", tt.in, got, tt.out) + } + }) + } +}