Files
goauto/server/cmd/migrate/server.go
T
QiuSWandClaude Opus 5 c86e98d0cb feat(#48): make one config work for both development and deployment
The repo already layered file defaults under environment overrides, on
both the backend (settings.yml < GOAUTO_*) and the frontend
(.env.production < process.env). What was missing was a translator for
production: config.yaml only ever existed for the PowerShell launchers,
so a packaged binary read none of it and had no database credentials
either — SYB was inheriting an existing gap, not creating one.

The server now reads config.yaml itself, between settings.yml and the
environment. Lookup is GOAUTO_CONFIG, then ./config.yaml, then beside the
executable, so a packaged binary works wherever it is started. An absent
file is not an error: containers supply everything through the
environment. Scalars are read by YAML type and coerced, so an unquoted
all-digit password cannot take startup down over a quoting detail.

This removed the need for a Read-SybConfig in PowerShell: the launcher
just hands over the path it already knows, rather than reimplementing a
YAML parser.

The server also serves the built frontend when dist is present, which is
what .env.production's empty VUE_APP_BASE_API already assumes. The
history fallback is restricted to non-API GETs, and is not installed at
all without dist, so development 404s stay 404s.

Precedence is mutation-tested: applying the local file after the
environment instead of before makes the layering test fail.

Not verified: the PowerShell change and any Windows deployment — both
need a run on the Windows side.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 09:28:45 +08:00

122 lines
3.0 KiB
Go

package migrate
import (
"bytes"
"fmt"
"github.com/go-admin-team/go-admin-core/sdk"
"github.com/go-admin-team/go-admin-core/sdk/pkg"
"strconv"
"text/template"
"time"
"github.com/go-admin-team/go-admin-core/config/source/file"
"github.com/spf13/cobra"
"github.com/go-admin-team/go-admin-core/sdk/config"
"go-admin/cmd/migrate/migration"
_ "go-admin/cmd/migrate/migration/version"
_ "go-admin/cmd/migrate/migration/version-local"
"go-admin/common/database"
"go-admin/common/models"
ext "go-admin/config"
)
var (
configYml string
generate bool
goAdmin bool
host string
StartCmd = &cobra.Command{
Use: "migrate",
Short: "Initialize the database",
Example: "go-admin migrate -c config/settings.yml",
Run: func(cmd *cobra.Command, args []string) {
run()
},
}
)
// fixme 在您看不见代码的时候运行迁移,我觉得是不安全的,所以编译后最好不要去执行迁移
func init() {
StartCmd.PersistentFlags().StringVarP(&configYml, "config", "c", "config/settings.yml", "Start server with provided configuration file")
StartCmd.PersistentFlags().BoolVarP(&generate, "generate", "g", false, "generate migration file")
StartCmd.PersistentFlags().BoolVarP(&goAdmin, "goAdmin", "a", false, "generate go-admin migration file")
StartCmd.PersistentFlags().StringVarP(&host, "domain", "d", "*", "select tenant host")
}
func run() {
if !generate {
fmt.Println(`start init`)
//1. 读取配置
config.Setup(
file.NewSource(file.WithPath(configYml)),
ext.ApplyLocalConfig,
ext.ApplyEnvironment,
initDB,
)
} else {
fmt.Println(`generate migration file`)
_ = genFile()
}
}
func migrateModel() error {
if host == "" {
host = "*"
}
db := sdk.Runtime.GetDbByKey(host)
if db == nil {
if len(sdk.Runtime.GetDb()) == 1 && host == "*" {
for k, v := range sdk.Runtime.GetDb() {
db = v
host = k
break
}
}
}
if db == nil {
return fmt.Errorf("未找到数据库配置")
}
if config.DatabasesConfig[host].Driver == "mysql" {
//初始化数据库时候用
db.Set("gorm:table_options", "ENGINE=InnoDB CHARSET=utf8mb4")
}
err := db.Debug().AutoMigrate(&models.Migration{})
if err != nil {
return err
}
migration.Migrate.SetDb(db.Debug())
migration.Migrate.Migrate()
return err
}
func initDB() {
//3. 初始化数据库链接
database.Setup()
//4. 数据库迁移
fmt.Println("数据库迁移开始")
_ = migrateModel()
fmt.Println(`数据库基础数据初始化成功`)
}
func genFile() error {
t1, err := template.ParseFiles("template/migrate.template")
if err != nil {
return err
}
m := map[string]string{}
m["GenerateTime"] = strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
m["Package"] = "version_local"
if goAdmin {
m["Package"] = "version"
}
var b1 bytes.Buffer
err = t1.Execute(&b1, m)
if goAdmin {
pkg.FileCreate(b1, "./cmd/migrate/migration/version/"+m["GenerateTime"]+"_migrate.go")
} else {
pkg.FileCreate(b1, "./cmd/migrate/migration/version-local/"+m["GenerateTime"]+"_migrate.go")
}
return nil
}