feat: add independent platform modules and multi-provider storage

This commit is contained in:
2026-09-23 14:51:14 +08:00
parent f91034477b
commit 208a9c3fbd
57 changed files with 4890 additions and 48 deletions

View File

@@ -17,6 +17,11 @@ func main() {
}
switch os.Args[1] {
case "migrate":
if err := runMigrate(os.Args[2:]); err != nil {
fmt.Fprintln(os.Stderr, "go-omni migrate:", err)
os.Exit(1)
}
case "add":
if err := runAdd(os.Args[2:]); err != nil {
fmt.Fprintln(os.Stderr, "go-omni add:", err)
@@ -108,6 +113,7 @@ func usage() {
fmt.Fprintln(os.Stderr, "GoOmni project tool")
fmt.Fprintln(os.Stderr, "")
fmt.Fprintln(os.Stderr, "Usage:")
fmt.Fprintln(os.Stderr, " go-omni migrate [--dir migrations] [--apply] [--dsn-env GO_OMNI_DB_DSN]")
fmt.Fprintln(os.Stderr, " go-omni new [--module <module>] [--force] <directory>")
fmt.Fprintln(os.Stderr, " go-omni add <name> [--dir <project>] Generate an isolated business module")
fmt.Fprintln(os.Stderr, " --framework-version <version> Pin a remote framework version (defaults to CLI version)")

60
cmd/go-omni/migrate.go Normal file
View File

@@ -0,0 +1,60 @@
package main
import (
"context"
"encoding/json"
"errors"
"flag"
"fmt"
migration "git.yuntuo.hk/k2safe/go-omni/database/migrate"
"io"
"os"
"os/signal"
"syscall"
)
func runMigrate(args []string) error {
flags := flag.NewFlagSet("migrate", flag.ContinueOnError)
flags.SetOutput(io.Discard)
directory := flags.String("dir", "migrations", "SQL directory")
dsnEnv := flags.String("dsn-env", "GO_OMNI_DB_DSN", "DSN environment variable")
apply := flags.Bool("apply", false, "apply pending up migrations")
if err := flags.Parse(args); err != nil {
return err
}
if flags.NArg() != 0 {
return errors.New("migrate: unexpected argument")
}
_, manifest, err := migration.Snapshot(os.DirFS(*directory), ".")
if err != nil {
return err
}
if !*apply {
data, err := json.MarshalIndent(manifest, "", " ")
if err != nil {
return err
}
fmt.Println(string(data))
return nil
}
dsn := os.Getenv(*dsnEnv)
if dsn == "" {
return errors.New("migrate: DSN environment variable is empty")
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
runner, err := migration.NewMySQL(ctx, dsn, os.DirFS(*directory), ".")
if err != nil {
return err
}
defer runner.Close()
if err = runner.Up(ctx); err != nil {
return err
}
version, dirty, err := runner.Version()
if err != nil {
return err
}
fmt.Printf("migration version=%d dirty=%t\n", version, dirty)
return nil
}

View File

@@ -0,0 +1,25 @@
package main
import (
"os"
"path/filepath"
"testing"
)
func TestMigrationPreviewDoesNotConnect(t *testing.T) {
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, "0001_createItems.up.sql"), []byte("CREATE TABLE testItems(id BIGINT);"), 0600); err != nil {
t.Fatal(err)
}
t.Setenv("GO_OMNI_DB_DSN", "not a DSN")
if err := runMigrate([]string{"--dir", dir}); err != nil {
t.Fatal("preview tried to connect", err)
}
t.Setenv("GO_OMNI_DB_DSN", "")
if err := runMigrate([]string{"--dir", dir, "--apply"}); err == nil {
t.Fatal("missing DSN accepted")
}
if err := runMigrate([]string{"--dir", dir, "--force"}); err == nil {
t.Fatal("unsafe unknown flag accepted")
}
}