Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Framework #12

Merged
merged 9 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 3 additions & 23 deletions .github/workflows/build-and-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,6 @@ on:
branches: [ "main" ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19

- name: Build Service
run: go build -o bin/user_service -v user-service/application.go
test:
runs-on: ubuntu-latest
steps:
Expand All @@ -27,16 +15,8 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19

- name: Build SQL & Redis Service
run: docker-compose up -d

- name: SQL Migration
run: |
go build -o bin/migrate -v migration/migrate_user.go
./bin/migrate packages/config/ini/test.ini
go-version: 1.20.5

- name: Test
- name: Test All
run: |
go test -cover -v ./...
make test
5 changes: 4 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
// need to find another elegant way for operating & debug with redis
// "cweijan.vscode-redis-client",
"ms-azuretools.vscode-docker",
"ms-vscode.makefile-tools"
"ms-vscode.makefile-tools",
"tamasfe.even-better-toml",
"pkief.material-icon-theme",
"ckolkman.vscode-postgres"
],
}
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"material-icon-theme.folders.associations": {
"application": "core",
"mapper": "database",
"migration": "import",
"user-service": "server",
}
}
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
OS := $(shell uname -s)

.PHONY: build
build:
@echo "Building on $(OS)"
go mod tidy
go build -o bin/migrate_user migration/migrate_user.go
go build -o bin/user_service user-service/application.go

.PHONY: setup-db
setup-db: build
docker-compose up -d
@echo "Wait 10 seconds for db setup"
sleep 10s
./bin/migrate_user

.PHONY: check
check:
go vet ./...

.PHONY: test
test: build check setup-db
go test -cover -v ./...
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ You will need to run the migration script before you can use the service.

## Development

🌟 Accept VSCode extension recommandation for complete experience 🌟

For service development, we don't want to make it too complex.
Using VSCode on either Win/*nix System are avaliabe, try using the Makefile/Dockerfile in the repository.
13 changes: 11 additions & 2 deletions config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,14 @@
level = "debug"

[database]
type = "postgres"
user = "postgres"
dsn = "user=postgres password=development host=127.0.0.1 port=5432 dbname=oj_lab sslmode=disable TimeZone=Asia/Shanghai"

[jwt]
secret = "example_secret"
duration = "24h"

[service]
auth_on = true
port = ":8080"
cookie.age = "24h"
mode = "debug"
10 changes: 10 additions & 0 deletions config/override.example.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# By default, you can override the config by creating a file named in `override` in the config directory.
#
# If you want to override the using config, instead the file name of `override`,
# you need to set env `OJ_LAB_OVERRIDE_CONFIG_NAME` to the name of the config file you want to use.
#
# In this example, setting `OJ_LAB_OVERRIDE_CONFIG_NAME` to `override.example`
# will override the log level to `info`.

[log]
level = "info"
2 changes: 0 additions & 2 deletions config/override.toml

This file was deleted.

1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ services:
restart: always
environment:
POSTGRES_PASSWORD: development
POSTGRES_DB: oj_lab
ports:
- 5432:5432

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ go 1.20
require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/viper v1.16.0
gopkg.in/ini.v1 v1.67.0
gorm.io/driver/postgres v1.5.2
gorm.io/gorm v1.25.4
)
Expand All @@ -31,6 +30,7 @@ require (
github.com/subosito/gotenv v1.6.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
golang.org/x/arch v0.4.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

Expand Down
7 changes: 0 additions & 7 deletions makefile

This file was deleted.

22 changes: 5 additions & 17 deletions migration/migrate_user.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,16 @@
package main

import (
"os"

"github.com/OJ-lab/oj-lab-services/packages/config"
"github.com/OJ-lab/oj-lab-services/packages/application"
"github.com/OJ-lab/oj-lab-services/packages/model"
"github.com/OJ-lab/oj-lab-services/packages/utils"
"github.com/sirupsen/logrus"
)

func main() {
var configPath string
if len(os.Args) > 1 {
configPath = os.Args[1]
} else {
configPath = "packages/config/ini/test.ini"
}
dataBaseSettings, err := config.GetDatabaseSettings(configPath)
if err != nil {
panic("failed to get database settings")
}
utils.MustCreateDatabase(*dataBaseSettings)
db := utils.MustGetDBConnection(*dataBaseSettings)
err = db.AutoMigrate(&model.UserTable{})
db := application.GetDefaultDB()
err := db.AutoMigrate(&model.UserTable{})
if err != nil {
panic("failed to migrate database")
}
logrus.Info("migrate user table success")
}
50 changes: 46 additions & 4 deletions packages/application/config.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package app
package application

import (
"os"
"path"

"github.com/spf13/viper"
)

const SERVICE_ENV_KEY = "OJ_LAB_SERVICE_ENV"
const OVERRIDE_CONFIG_NAME = "override"
const PROJECT_ROOT_ENV_KEY = "OJ_LAB_PROJECT_ROOT"
const OVERRIDE_CONFIG_NAME_ENV_KEY = "OJ_LAB_OVERRIDE_CONFIG_NAME"

const DEFAULT_OVERRIDE_CONFIG_NAME = "override"
const DEFAULT_PROJECT_ROOT = "oj-lab-services"

type ServiceEnv string

Expand All @@ -17,6 +22,7 @@ const (
)

var serviceEnv ServiceEnv
var AppConfig *viper.Viper

func (se ServiceEnv) isValid() bool {
if se == DEV_SERVICE_ENV || se == PRD_SERVICE_ENV {
Expand All @@ -29,26 +35,62 @@ func IsDevEnv() bool {
return serviceEnv == DEV_SERVICE_ENV
}

func LoadConfig(basePath string) error {
func loadConfig(basePath string) error {
viper.AddConfigPath(basePath)

serviceEnv = DEV_SERVICE_ENV
env := os.Getenv(SERVICE_ENV_KEY)
if ServiceEnv(env).isValid() {
serviceEnv = ServiceEnv(env)
}
println("Env:", serviceEnv)
viper.SetConfigName(string(serviceEnv))

err := viper.ReadInConfig()
if err != nil {
return err
}

viper.SetConfigName(OVERRIDE_CONFIG_NAME)
overrideConfigName := os.Getenv(OVERRIDE_CONFIG_NAME_ENV_KEY)
if overrideConfigName == "" {
overrideConfigName = DEFAULT_OVERRIDE_CONFIG_NAME
}
println("Set override config name:", overrideConfigName)

viper.SetConfigName(overrideConfigName)
err = viper.MergeInConfig()
if err == nil {
println("Found override config, merged")
}

AppConfig = viper.GetViper()
return nil
}

func GetProjectRoot() string {
projectRoot := os.Getenv(PROJECT_ROOT_ENV_KEY)
if projectRoot == "" {
projectRoot = DEFAULT_PROJECT_ROOT
}

wd, err := os.Getwd()
if err != nil {
panic("Cannot find working dir")
}
isRoot := path.Base(wd) == DEFAULT_PROJECT_ROOT
for !isRoot && wd != "" {
wd = path.Dir(wd)
isRoot = path.Base(wd) == DEFAULT_PROJECT_ROOT
}
if wd == "" {
panic("Cannot find project root folder")
}
return wd
}

func init() {
projectRoot := GetProjectRoot()
println("Initing config with project root:", projectRoot)
loadConfig(path.Join(projectRoot, "config"))
setupLog()
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
package database
package application

import (
"github.com/spf13/viper"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)

const dsnProp = "database.dsn"

var db *gorm.DB

var dsn string

func init() {
dsn = AppConfig.GetString(dsnProp)
if dsn == "" {
panic("database dsn is not set")
}
}

func GetDefaultDB() *gorm.DB {
if db == nil {
var err error
Expand All @@ -24,7 +32,3 @@ func GetDefaultDB() *gorm.DB {

return db
}

func init() {
dsn = viper.GetString("database.dsn")
}
20 changes: 4 additions & 16 deletions packages/application/init_test.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
package app
package application

import (
"testing"

"github.com/sirupsen/logrus"
"github.com/spf13/viper"
)

func TestInit(T *testing.T) {
err := LoadConfig("../../config")
if err != nil {
T.Fatal(err)
logLevel := viper.GetString(logLevelProp)
if logLevel != "debug" {
T.Errorf("log level is not debug but %s", logLevel)
}

databaseType := viper.GetString("database.type")
databaseUser := viper.GetString("database.user")
println(databaseType, databaseUser)
if len(databaseType) == 0 {
T.Fatal("databaseType not loaded")
}

SetupLog()

logrus.Error("debug")
}
11 changes: 6 additions & 5 deletions packages/application/log.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package app
package application

import (
"os"

"github.com/sirupsen/logrus"
"github.com/spf13/viper"
)

const LOG_LEVEL_PROP = "log.level"
const logLevelProp = "log.level"

func SetupLog() {
func setupLog() {
logrus.SetOutput(os.Stdout)

logrus.SetLevel(logrus.DebugLevel)
logLevel, err := logrus.ParseLevel(viper.GetString(LOG_LEVEL_PROP))
lvl := AppConfig.GetString(logLevelProp)
logLevel, err := logrus.ParseLevel(lvl)
if err == nil {
println("log level:", lvl)
logrus.SetLevel(logLevel)
}
}
Loading