Skip to content

Commit

Permalink
Merge pull request #5 from MohamedAlosaili/enhancement
Browse files Browse the repository at this point in the history
feat: enhance project structure and configuratio
  • Loading branch information
malosayli authored Dec 10, 2024
2 parents 8119156 + 5ce0f52 commit 27c8992
Show file tree
Hide file tree
Showing 44 changed files with 784 additions and 305 deletions.
20 changes: 0 additions & 20 deletions cmd/gog/new/_template/.env.example

This file was deleted.

4 changes: 3 additions & 1 deletion cmd/gog/new/_template/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
bin/
.env
config.yaml

__debug*
17 changes: 17 additions & 0 deletions cmd/gog/new/_template/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}",
"envFile": "${workspaceFolder}/.env",
"args": ["serve"]
}
]
}
16 changes: 10 additions & 6 deletions cmd/gog/new/_template/cmd/migrate/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func newMigrationDown() *cobra.Command {
return &cobra.Command{
cmd := &cobra.Command{
Use: "down [version]",
Short: "Rollback migrations",
Long: `Rollback migrations
Expand All @@ -19,20 +19,24 @@ migrate down 0 - Rollback all migrations`,
Example: "migrate down\nmigrate down 20241108133703\nmigrate down 0",
RunE: runMigrationDown,
}

cmd.Flags().StringP("config", "c", "config.yaml", "config file")

return cmd
}

func runMigrationDown(cmd *cobra.Command, args []string) error {
cfg, db, err := setupMigration()
cfg, db, err := setupMigration(cmd)
if err != nil {
return fmt.Errorf("❌ Failed to setup migration: %v", err)
}
defer db.Close()

goose.SetTableName(cfg.DatabaseMigrateTable)
fmt.Printf("🔄 Rolling back migrations from directory: %s\n", cfg.DatabaseMigrationsDir)
goose.SetTableName(cfg.Database.MigrateTable)
fmt.Printf("🔄 Rolling back migrations from directory: %s\n", cfg.Database.MigrationsDir)

if len(args) == 0 {
if err := goose.Down(db, cfg.DatabaseMigrationsDir); err != nil {
if err := goose.Down(db, cfg.Database.MigrationsDir); err != nil {
return fmt.Errorf("❌ Rolling back failed: %v", err)
}
} else {
Expand All @@ -41,7 +45,7 @@ func runMigrationDown(cmd *cobra.Command, args []string) error {
return fmt.Errorf("❌ Invalid migration version: %v", err)
}

if err := goose.DownTo(db, cfg.DatabaseMigrationsDir, to); err != nil {
if err := goose.DownTo(db, cfg.Database.MigrationsDir, to); err != nil {
return fmt.Errorf("❌ Rolling back failed: %v", err)
}
}
Expand Down
15 changes: 10 additions & 5 deletions cmd/gog/new/_template/cmd/migrate/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,27 @@ func NewMigrateCmd() *cobra.Command {
}

// setupMigration handles common migration setup tasks
func setupMigration() (*config.Config, *sql.DB, error) {
cfg, err := config.Load()
func setupMigration(cmd *cobra.Command) (*config.Config, *sql.DB, error) {
configFile, err := cmd.Flags().GetString("config")
if err != nil {
return nil, nil, fmt.Errorf("❌ Failed to get config file: %v", err)
}

cfg, err := config.Load(configFile)
if err != nil {
return nil, nil, fmt.Errorf("❌ Failed to load configuration: %v", err)
}

fmt.Println("🔄 Connecting to database...")

dbString := fmt.Sprintf("user=%s password=%s dbname=%s host=%s port=%d sslmode=%s", cfg.DatabaseUsername, cfg.DatabasePassword, cfg.DatabaseName, cfg.DatabaseHost, cfg.DatabasePort, cfg.DatabaseSSLMode)
db, err := sql.Open(cfg.DatabaseDriver, dbString)
dbString := fmt.Sprintf("user=%s password=%s dbname=%s host=%s port=%d sslmode=%s", cfg.Database.Username, cfg.Database.Password, cfg.Database.Name, cfg.Database.Host, cfg.Database.Port, cfg.Database.SSLMode)
db, err := sql.Open(cfg.Database.Driver, dbString)
if err != nil {
return nil, nil, fmt.Errorf("❌ Failed to connect to database: %v", err)
}

fmt.Println("✅ Database connection established")
goose.SetTableName(cfg.DatabaseMigrateTable)
goose.SetTableName(cfg.Database.MigrateTable)

return cfg, db, nil
}
15 changes: 12 additions & 3 deletions cmd/gog/new/_template/cmd/migrate/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func newMigrationNew() *cobra.Command {
return &cobra.Command{
cmd := &cobra.Command{
Use: "new [name]",
Short: "Create a new migration",
DisableFlagsInUseLine: true,
Expand All @@ -18,18 +18,27 @@ func newMigrationNew() *cobra.Command {
return fmt.Errorf("❌ name is missing")
}

cfg, err := config.Load()
configFile, err := cmd.Flags().GetString("config")
if err != nil {
return fmt.Errorf("❌ Failed to get config file: %v", err)
}

cfg, err := config.Load(configFile)
if err != nil {
return fmt.Errorf("❌ Failed to load configuration")
}

fmt.Println("🔄 Creating new migration...")
if err := goose.Create(nil, cfg.DatabaseMigrationsDir, args[0], "sql"); err != nil {
if err := goose.Create(nil, cfg.Database.MigrationsDir, args[0], "sql"); err != nil {
return fmt.Errorf("❌ Failed to create migration: %v", err)
}
fmt.Println("✅ Migration created successfully")

return nil
},
}

cmd.Flags().StringP("config", "c", "config.yaml", "config file")

return cmd
}
10 changes: 7 additions & 3 deletions cmd/gog/new/_template/cmd/migrate/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,28 @@ import (
)

func newMigrationStatus() *cobra.Command {
return &cobra.Command{
cmd := &cobra.Command{
Use: "status",
Short: "Show the status of the migrations",
DisableFlagsInUseLine: true,
RunE: runMigrationStatus,
}

cmd.Flags().StringP("config", "c", "config.yaml", "config file")

return cmd
}

func runMigrationStatus(cmd *cobra.Command, args []string) error {
fmt.Println("🔄 Getting migration status...")

cfg, db, err := setupMigration()
cfg, db, err := setupMigration(cmd)
if err != nil {
return fmt.Errorf("❌ Failed to setup migration: %v", err)
}
defer db.Close()

if err := goose.Status(db, cfg.DatabaseMigrationsDir); err != nil {
if err := goose.Status(db, cfg.Database.MigrationsDir); err != nil {
return fmt.Errorf("❌ Migration failed: %v", err)
}
fmt.Println("✅ Migration status retrieved successfully")
Expand Down
14 changes: 9 additions & 5 deletions cmd/gog/new/_template/cmd/migrate/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,28 @@ import (
)

func newMigrationUp() *cobra.Command {
return &cobra.Command{
cmd := &cobra.Command{
Use: "up",
Short: "Run pending migrations",
DisableFlagsInUseLine: true,
RunE: runMigrationUp,
}

cmd.Flags().StringP("config", "c", "config.yaml", "config file")

return cmd
}

func runMigrationUp(cmd *cobra.Command, args []string) error {
cfg, db, err := setupMigration()
cfg, db, err := setupMigration(cmd)
if err != nil {
return fmt.Errorf("❌ Failed to setup migration: %v", err)
}
defer db.Close()

goose.SetTableName(cfg.DatabaseMigrateTable)
fmt.Printf("🔄 Running migrations from directory: %s\n", cfg.DatabaseMigrationsDir)
if err := goose.Up(db, cfg.DatabaseMigrationsDir); err != nil {
goose.SetTableName(cfg.Database.MigrateTable)
fmt.Printf("🔄 Running migrations from directory: %s\n", cfg.Database.MigrationsDir)
if err := goose.Up(db, cfg.Database.MigrationsDir); err != nil {
return fmt.Errorf("❌ Migration failed: %v", err)
}
fmt.Println("✅ Migrations completed successfully")
Expand Down
41 changes: 24 additions & 17 deletions cmd/gog/new/_template/cmd/serve/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,32 @@ import (
)

func NewServeCmd() *cobra.Command {
return &cobra.Command{
cmd := &cobra.Command{
Use: "serve",
Short: "Start the server",
RunE: Run,
}

cmd.Flags().StringP("config", "c", "config.yaml", "config file")

return cmd
}

// @title PROJECT_NAME
// @version 1.0
// @description Your API Description
// @host localhost:3000
// @Title PROJECT_NAME
// @Version 1.0
// @Description API for PROJECT_NAME
// @BasePath /api
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description JWT Authorization header using the Bearer scheme. Example: "Bearer {token}"
// @security Bearer
// @SecurityDefinitions.apikey ApiKey
// @In header
// @Name X-API-KEY
// @Description API key for authentication
func Run(cmd *cobra.Command, args []string) error {
cfg, err := config.Load()
configFile, err := cmd.Flags().GetString("config")
if err != nil {
return fmt.Errorf("❌ Failed to get config file: %v", err)
}

cfg, err := config.Load(configFile)
if err != nil {
return fmt.Errorf("❌ Failed to load configuration: %v", err)
}
Expand All @@ -56,7 +63,7 @@ func Run(cmd *cobra.Command, args []string) error {

// Start server in a goroutine
go func() {
if err := app.Listen(fmt.Sprintf(":%d", cfg.Port)); err != nil {
if err := app.Listen(fmt.Sprintf(":%d", cfg.App.Port)); err != nil {
serverErr <- err
}
}()
Expand Down Expand Up @@ -100,11 +107,11 @@ func Run(cmd *cobra.Command, args []string) error {

func NewApp(cfg *config.Config, r *registry.Registry) *fiber.App {
return fiber.New(fiber.Config{
AppName: cfg.AppName,
AppName: cfg.App.Name,
ErrorHandler: r.ErrorHandler().Handle,
// Handle timeouts
ReadTimeout: time.Duration(cfg.ReadTimeout) * time.Second,
WriteTimeout: time.Duration(cfg.WriteTimeout) * time.Second,
ReadTimeout: time.Duration(cfg.App.ReadTimeout) * time.Second,
WriteTimeout: time.Duration(cfg.App.WriteTimeout) * time.Second,

// print all routes with their method, path and handler
EnablePrintRoutes: true,
Expand All @@ -113,13 +120,13 @@ func NewApp(cfg *config.Config, r *registry.Registry) *fiber.App {

func NewSwagger(cfg *config.Config) fiber.Handler {
cacheAge := 0
if cfg.Env == "development" {
if cfg.App.Env == "development" {
cacheAge = 0
}

return swagger.New(swagger.Config{
BasePath: "/api",
Title: cfg.AppName,
Title: cfg.App.Name,
Path: "docs",
FilePath: "./docs/swagger.json",
CacheAge: cacheAge,
Expand Down
23 changes: 23 additions & 0 deletions cmd/gog/new/_template/config.yaml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Environment Variables

app:
name: PROJECT_NAME
env: production
port: 3022
log_level: info
read_timeout: 60
write_timeout: 60

api:
key: my-api-key

database:
host: localhost
port: 5460
name: mydatabase
username: myusername
password: mypassword
synchronize: false
ssl: false
migrations_dir: migrations
driver: postgres
Loading

0 comments on commit 27c8992

Please sign in to comment.