From 973fa055bfad1132f055b95744e8b13852edd678 Mon Sep 17 00:00:00 2001 From: Carryall Date: Thu, 16 Feb 2023 16:19:49 +0700 Subject: [PATCH 1/5] [gh-91] Move database matter to database folder --- .../bootstrap/bootstrap.go | 11 +++ .../bootstrap/database.go | 36 +--------- {{cookiecutter.app_name}}/cmd/api/main.go | 4 +- .../database/database.go | 68 +++++++++++++++++++ 4 files changed, 83 insertions(+), 36 deletions(-) create mode 100644 {{cookiecutter.app_name}}/bootstrap/bootstrap.go create mode 100644 {{cookiecutter.app_name}}/database/database.go diff --git a/{{cookiecutter.app_name}}/bootstrap/bootstrap.go b/{{cookiecutter.app_name}}/bootstrap/bootstrap.go new file mode 100644 index 0000000..6fc5fb5 --- /dev/null +++ b/{{cookiecutter.app_name}}/bootstrap/bootstrap.go @@ -0,0 +1,11 @@ +package bootstrap + +import ( + "github.com/nimblehq/{{cookiecutter.app_name}}/database" +) + +func Init() { + LoadConfig() + + InitDatabase(database.GetDatabaseURL()) +} diff --git a/{{cookiecutter.app_name}}/bootstrap/database.go b/{{cookiecutter.app_name}}/bootstrap/database.go index 91943e0..b12177d 100644 --- a/{{cookiecutter.app_name}}/bootstrap/database.go +++ b/{{cookiecutter.app_name}}/bootstrap/database.go @@ -1,39 +1,9 @@ package bootstrap import ( - "fmt" - "strings" - {% if cookiecutter.use_logrus == "no" %}"log" - {% endif %} - "github.com/nimblehq/{{cookiecutter.app_name}}/helpers" - {% if cookiecutter.use_logrus == "yes" %}"github.com/nimblehq/{{cookiecutter.app_name}}/helpers/log" - {% endif %} - "github.com/gin-gonic/gin" - "github.com/spf13/viper" - "gorm.io/driver/postgres" - "gorm.io/gorm" + "github.com/nimblehq/{{cookiecutter.app_name}}/database" ) -func InitDatabase() { - db, err := gorm.Open(postgres.Open(getDatabaseURL()), &gorm.Config{}) - if err != nil { - log.Fatalf("Failed to connect to %v database: %v", gin.Mode(), err) - } else { - viper.Set("database", db) - log.Println(strings.Title(gin.Mode()) + " database connected successfully.") - } -} - -func getDatabaseURL() string { - if gin.Mode() == gin.ReleaseMode { - return viper.GetString("DATABASE_URL") - } - - return fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable", - viper.GetString("db_username"), - viper.GetString("db_password"), - viper.GetString("db_host"), - helpers.GetStringConfig("db_port"), - helpers.GetStringConfig("db_name"), - ) +func InitDatabase(databaseURL string) { + database.InitDatabase(databaseURL) } diff --git a/{{cookiecutter.app_name}}/cmd/api/main.go b/{{cookiecutter.app_name}}/cmd/api/main.go index 40a2d47..852fe62 100644 --- a/{{cookiecutter.app_name}}/cmd/api/main.go +++ b/{{cookiecutter.app_name}}/cmd/api/main.go @@ -12,9 +12,7 @@ import ( ) func main() { - bootstrap.LoadConfig() - - bootstrap.InitDatabase() + bootstrap.Init() r := bootstrap.SetupRouter() diff --git a/{{cookiecutter.app_name}}/database/database.go b/{{cookiecutter.app_name}}/database/database.go new file mode 100644 index 0000000..0d141a3 --- /dev/null +++ b/{{cookiecutter.app_name}}/database/database.go @@ -0,0 +1,68 @@ +package database + +import ( + "fmt" + "strings" + {% if cookiecutter.use_logrus == "no" %}"log" + {% endif %} + + "github.com/nimblehq/{{cookiecutter.app_name}}/helpers" + {% if cookiecutter.use_logrus == "yes" %}"github.com/nimblehq/{{cookiecutter.app_name}}/helpers/log" + {% endif %} + + "github.com/gin-gonic/gin" + "github.com/pressly/goose/v3" + "github.com/spf13/viper" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +var database *gorm.DB + +func InitDatabase(databaseURL string) { + db, err := gorm.Open(postgres.Open(databaseURL), &gorm.Config{}) + if err != nil { + log.Fatalf("Failed to connect to %v database: %v", gin.Mode(), err) + } else { + viper.Set("database", db) + log.Println(strings.Title(gin.Mode()) + " database connected successfully.") + } + + migrateDB(db) +} + +func migrateDB(db *gorm.DB) { + sqlDB, err := db.DB() + if err != nil { + log.Fatalf("Failed to convert gormDB to sqlDB: %v", err) + } + + err = goose.Up(sqlDB, "database/migrations", goose.WithAllowMissing()) + if err != nil { + log.Fatalf("Failed to migrate database: %v", err) + } + + log.Println("Migrated database successfully.") +} + +func GetDB() *gorm.DB { + if database == nil { + InitDatabase(GetDatabaseURL()) + } + + return database +} + +func GetDatabaseURL() string { + if gin.Mode() == gin.ReleaseMode { + return viper.GetString("DATABASE_URL") + } + + return fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable", + viper.GetString("db_username"), + viper.GetString("db_password"), + viper.GetString("db_host"), + helpers.GetStringConfig("db_port"), + helpers.GetStringConfig("db_name"), + ) +} From c91172ed0fc90049621e8982d0e8d556e0396b82 Mon Sep 17 00:00:00 2001 From: Carryall Date: Thu, 16 Feb 2023 16:25:15 +0700 Subject: [PATCH 2/5] [gh-91] Remove migration run on start --- {{cookiecutter.app_name}}/Dockerfile | 8 -------- {{cookiecutter.app_name}}/Makefile | 8 ++++---- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/{{cookiecutter.app_name}}/Dockerfile b/{{cookiecutter.app_name}}/Dockerfile index 8aca7d6..e763244 100644 --- a/{{cookiecutter.app_name}}/Dockerfile +++ b/{{cookiecutter.app_name}}/Dockerfile @@ -1,7 +1,5 @@ FROM golang:1.18-buster -ARG DATABASE_URL - ENV GIN_MODE=release WORKDIR /app @@ -10,15 +8,9 @@ WORKDIR /app COPY go.mod go.sum ./ RUN go mod download -# Install goose for migration -RUN go get github.com/pressly/goose/cmd/goose - # Copy codebase COPY . . -# Run the migration -RUN goose -dir database/migrations -table "migration_versions" postgres "$DATABASE_URL" up - # Build go application RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main ./cmd/api diff --git a/{{cookiecutter.app_name}}/Makefile b/{{cookiecutter.app_name}}/Makefile index cb0ae14..56ff4fe 100644 --- a/{{cookiecutter.app_name}}/Makefile +++ b/{{cookiecutter.app_name}}/Makefile @@ -34,15 +34,15 @@ dev: forego start -f Procfile.dev install-dependencies: - go get github.com/cosmtrek/air@v1.15.1 - go get github.com/pressly/goose/cmd/goose - go get github.com/ddollar/forego + go install github.com/cosmtrek/air@v1.41.1 + go install github.com/pressly/goose/v3/cmd/goose@v3.9.0 + go install github.com/ddollar/forego@latest go mod tidy {% if cookiecutter._web_variant == "yes" %}npm install{% endif %} test: docker-compose -f docker-compose.test.yml up -d - ENV=test make db/migrate + make wait-for-postgres go test -v -p 1 -count=1 ./... docker-compose -f docker-compose.test.yml down From 50450a53324664d144d67dd6e0a99a1bc30a588f Mon Sep 17 00:00:00 2001 From: Carryall Date: Tue, 21 Feb 2023 16:21:10 +0700 Subject: [PATCH 3/5] [gh-91] Fix test --- cmd/create_test.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/cmd/create_test.go b/cmd/create_test.go index 390672f..41a5541 100644 --- a/cmd/create_test.go +++ b/cmd/create_test.go @@ -125,13 +125,13 @@ var _ = Describe("Create template", func() { }) Context("given bootstrap/database.go", func() { - It("contains project name at helpers import", func() { + It("contains project name at database import", func() { cookiecutter := tests.Cookiecutter{AppName: "test-gin-templates"} cookiecutter.CreateProjectFromGinTemplate(currentTemplatePath) content := tests.ReadFile("bootstrap/database.go") - expectedContent := `"github.com/nimblehq/test-gin-templates/helpers"` + expectedContent := `"github.com/nimblehq/test-gin-templates/database"` Expect(content).To(ContainSubstring(expectedContent)) }) @@ -296,7 +296,7 @@ var _ = Describe("Create template", func() { cookiecutter.CreateProjectFromGinTemplate(currentTemplatePath) content := tests.ReadFile("go.mod") - expectedContent := "github.com/sirupsen/logrus v1.8.1" + expectedContent := "github.com/sirupsen/logrus" Expect(content).To(ContainSubstring(expectedContent)) }) @@ -314,13 +314,26 @@ var _ = Describe("Create template", func() { Expect(content).To(ContainSubstring(expectedContent)) }) - It("contains logrus package import in bootstrap/database.go", func() { + Context("given database/database.go", func() { + It("contains project name at helpers import", func() { + cookiecutter := tests.Cookiecutter{AppName: "test-gin-templates"} + cookiecutter.CreateProjectFromGinTemplate(currentTemplatePath) + + content := tests.ReadFile("database/database.go") + + expectedContent := `"github.com/nimblehq/test-gin-templates/helpers"` + + Expect(content).To(ContainSubstring(expectedContent)) + }) + }) + + It("contains logrus package import in database/database.go", func() { cookiecutter := tests.Cookiecutter{ AppName: "test-gin-templates", UseLogrus: tests.Yes, } cookiecutter.CreateProjectFromGinTemplate(currentTemplatePath) - content := tests.ReadFile("bootstrap/database.go") + content := tests.ReadFile("database/database.go") expectedContent := "github.com/nimblehq/test-gin-templates/helpers/log" From b08976fbe8cb4e0b622631a4a872bbe727afcaf6 Mon Sep 17 00:00:00 2001 From: Carryall Date: Tue, 21 Feb 2023 16:21:20 +0700 Subject: [PATCH 4/5] [gh-91] Update code blocks in readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e28cc0b..17646d6 100644 --- a/README.md +++ b/README.md @@ -26,19 +26,19 @@ Check this [wiki](https://github.com/nimblehq/gin-templates/wiki/Directories) fo - Download **latest** version of gin-templates. - ``` + ```sh go get github.com/nimblehq/gin-templates ``` - Build the binary file. - ``` + ```sh go build -o $GOPATH/bin/nimble-gin github.com/nimblehq/gin-templates ``` - Create the project using gin-templates. Note that the **main** branch is being used by default. Refer to [this wiki page](https://github.com/nimblehq/gin-templates/wiki/Commands) for instructions on how to use a different branch. - ``` + ```sh nimble-gin create ``` From f7141b184b10e645547b6c103985d82857e9d3e8 Mon Sep 17 00:00:00 2001 From: Carryall Date: Tue, 7 Mar 2023 15:20:30 +0700 Subject: [PATCH 5/5] [gh-91] Add Alex and Best --- .github/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8accb7e..e49d5e6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,6 @@ # Team -# @junan is the Team Lead and the others are team members -* @junan @carryall @hoangmirs @Lahphim @malparty +# @carryall is the Team Lead and the others are team members +* @carryall @hoangmirs @malparty @Nihisil @suphanatjarukulgowit # Engineering Leads CODEOWNERS @nimblehq/engineering-leads