commit ed42db709f6fed53f4365d042b0dd18e3d29d374 Author: fancl Date: Thu Dec 12 11:45:03 2024 +0800 整合数据库组件 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..556957c --- /dev/null +++ b/.gitignore @@ -0,0 +1,60 @@ +bin/ + +.svn/ +.godeps +./build +.cover/ +dist +_site +_posts +*.dat +.vscode +vendor + +# Go.gitignore + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test +storage +.idea + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.local +.DS_Store + +profile + +# vim stuff +*.sw[op] + + +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +.vscode/* +!.vscode/extensions.json + +node_modules \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..89d136d --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# 模版 + diff --git a/api.go b/api.go new file mode 100644 index 0000000..60629a3 --- /dev/null +++ b/api.go @@ -0,0 +1,5 @@ +package moto + +func (svr *Server) routes() { + +} diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..2ec5e25 --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "flag" + "fmt" + "git.nobla.cn/golang/kos" + "git.nobla.cn/golang/moto" + "git.nobla.cn/golang/moto/config" + "git.nobla.cn/golang/moto/version" + yaml "gopkg.in/yaml.v3" + "os" +) + +var ( + configFlag = flag.String("config", "", "Config filename") +) + +func main() { + var ( + buf []byte + err error + ) + flag.Parse() + cfg := config.New() + if *configFlag != "" { + if buf, err = os.ReadFile(*configFlag); err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + if err = yaml.Unmarshal(buf, cfg); err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + } + svr := kos.Init( + kos.WithName("git.nobla.cn/golang/"+version.ProductName, version.Version), + kos.WithServer(moto.New(cfg)), + ) + if err = svr.Run(); err != nil { + fmt.Println(err) + os.Exit(1) + } + +} diff --git a/common/db/db.go b/common/db/db.go new file mode 100644 index 0000000..bb1a67e --- /dev/null +++ b/common/db/db.go @@ -0,0 +1,58 @@ +package db + +import ( + "context" + "git.nobla.cn/golang/moto/config" + "git.nobla.cn/golang/rest/types" + "github.com/go-sql-driver/mysql" + mysqlDriver "gorm.io/driver/mysql" + "gorm.io/gorm" + "time" +) + +var ( + db *gorm.DB +) + +func Init(ctx context.Context, cfg config.Database, plugins ...gorm.Plugin) (err error) { + dbCfg := &mysql.Config{ + Net: "tcp", + Addr: cfg.Address, + User: cfg.Username, + Passwd: cfg.Password, + DBName: cfg.Database, + AllowNativePasswords: true, + AllowOldPasswords: true, + Collation: "utf8mb4_unicode_ci", + Loc: time.Local, + CheckConnLiveness: true, + Params: make(map[string]string), + ParseTime: true, + MaxAllowedPacket: 4 << 20, + } + dbCfg.Params["charset"] = "utf8mb4" + if db, err = gorm.Open(mysqlDriver.Open(dbCfg.FormatDSN())); err != nil { + return + } + db = db.WithContext(ctx) + for _, plugin := range plugins { + if err = db.Use(plugin); err != nil { + return + } + } + if err = db.AutoMigrate(&types.Schema{}); err != nil { + return + } + return +} + +func DB() *gorm.DB { + if db == nil { + panic("database component not initialized") + } + return db +} + +func WithContext(ctx context.Context) *gorm.DB { + return DB().WithContext(ctx) +} diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..4390bfc --- /dev/null +++ b/config/config.go @@ -0,0 +1,17 @@ +package config + +type Database struct { + Address string `json:"address" yaml:"address"` + Username string `json:"username" yaml:"username"` + Password string `json:"password" yaml:"password"` + Database string `json:"database" yaml:"database"` +} + +type Config struct { + Database Database `json:"database" yaml:"database"` +} + +func New() *Config { + cfg := &Config{} + return cfg +} diff --git a/config/config.yaml b/config/config.yaml new file mode 100644 index 0000000..7afde6e --- /dev/null +++ b/config/config.yaml @@ -0,0 +1,5 @@ +database: + address: "192.168.9.199:3306" + username: "root" + password: "root" + database: "test2" \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e769a48 --- /dev/null +++ b/go.mod @@ -0,0 +1,33 @@ +module git.nobla.cn/golang/moto + +go 1.22.9 + +require ( + git.nobla.cn/golang/kos v0.1.32 + git.nobla.cn/golang/rest v0.0.1 + github.com/go-sql-driver/mysql v1.8.1 + gopkg.in/yaml.v3 v3.0.1 + gorm.io/driver/mysql v1.5.7 + gorm.io/gorm v1.25.12 +) + +require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-runewidth v0.0.3 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/peterh/liner v1.2.2 // indirect + github.com/rs/xid v1.6.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..c675e54 --- /dev/null +++ b/go.sum @@ -0,0 +1,67 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +git.nobla.cn/golang/kos v0.1.32 h1:sFVCA7vKc8dPUd0cxzwExOSPX2mmMh2IuwL6cYS1pBc= +git.nobla.cn/golang/kos v0.1.32/go.mod h1:35Z070+5oB39WcVrh5DDlnVeftL/Ccmscw2MZFe9fUg= +git.nobla.cn/golang/rest v0.0.1 h1:atEF73F7NuzYGWzO4+H2qHwgtwV+omG1paEj1DJ5RN8= +git.nobla.cn/golang/rest v0.0.1/go.mod h1:tGDOul2GGJtxk6fAeu+YLpMt/Up/TsBonTkygymN/wE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4= +github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw= +github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= +gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= +gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8= +gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= diff --git a/models/department.go b/models/department.go new file mode 100644 index 0000000..7619ed9 --- /dev/null +++ b/models/department.go @@ -0,0 +1,18 @@ +package models + +import "gorm.io/gorm" + +type Department struct { + ID string `json:"id" gorm:"primaryKey;size:20" comment:"ID" scenarios:"view;export"` + CreatedAt int64 `json:"created_at" gorm:"autoCreateTime" comment:"创建时间" scenarios:"list;view;export"` + UpdatedAt int64 `json:"updated_at" gorm:"autoUpdateTime" comment:"更新时间" scenarios:"list;view;export"` + DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index" comment:"删除时间"` + Parent string `json:"parent" gorm:"index;size:20;not null;default:''" props:"match:exactly" comment:"归属" format:"department" scenarios:"search;list;create;update;view;export" live:"type:dropdown;url:/organize/department-types" position:"3"` + Name string `json:"name" gorm:"size:60;not null;default:''" rule:"required" comment:"名称" scenarios:"search;list;create;update;view;export" position:"2"` + Description string `json:"description" gorm:"size:500;not null;default:''" format:"textarea" comment:"备注" scenarios:"create;update;view;export"` + Position int `json:"position" gorm:"not null;default:0" comment:"排序" scenarios:""` +} + +func (model *Department) TableName() string { + return "departments" +} diff --git a/models/role.go b/models/role.go new file mode 100644 index 0000000..e59bae0 --- /dev/null +++ b/models/role.go @@ -0,0 +1,18 @@ +package models + +import "gorm.io/gorm" + +type Role struct { + ID string `json:"id" gorm:"primaryKey;size:20" comment:"ID" scenarios:"view;export"` + CreatedAt int64 `json:"created_at" gorm:"autoCreateTime" comment:"创建时间" scenarios:"list;view;export"` + UpdatedAt int64 `json:"updated_at" gorm:"autoUpdateTime" comment:"更新时间" scenarios:"list;view;export"` + DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index" comment:"删除时间"` + Name string `json:"name" gorm:"size:60;not null;default:''" rule:"required" comment:"名称" scenarios:"search;list;create;update;view;export" position:"2"` + Description string `json:"description" gorm:"size:500;not null;default:''" format:"textarea" comment:"备注" scenarios:"create;update;view;export"` + Permissions string `json:"permissions" gorm:"size:10240;not null;default:''" comment:"权限" scenarios:"create;update"` + Position int `json:"position" gorm:"not null;default:0" comment:"排序" scenarios:""` +} + +func (model *Role) TableName() string { + return "roles" +} diff --git a/models/user.go b/models/user.go new file mode 100644 index 0000000..4a59fc1 --- /dev/null +++ b/models/user.go @@ -0,0 +1,27 @@ +package models + +import ( + "gorm.io/gorm" +) + +type User struct { + ID string `json:"id" gorm:"primaryKey;size:20" comment:"ID" scenarios:"view;export"` + CreatedAt int64 `json:"created_at,omitempty" gorm:"autoCreateTime" comment:"创建时间" scenarios:"view;export"` + UpdatedAt int64 `json:"updated_at,omitempty" gorm:"autoUpdateTime" comment:"更新时间" scenarios:"view;export"` + DeletedAt gorm.DeletedAt `json:"deleted_at,omitempty" gorm:"index" comment:"删除时间"` + UID string `json:"uid" gorm:"column:uid;index;size:20;not null;default:''" rule:"required;unique;regexp:^[a-zA-Z0-9]{3,8}$;" props:"readonly:update" comment:"账号" scenarios:"search;list;create;view;export"` + Department string `json:"department,omitempty" gorm:"index;size:20;not null;default:''" rule:"required" comment:"部门" scenarios:"search;list;create;update;view;export" live:"type:dropdown;url:/organize/department-types"` + Role string `json:"role,omitempty" gorm:"index;size:20;not null;default:''" rule:"required" comment:"角色" scenarios:"search;list;create;update;view;export" live:"type:dropdown;url:/organize/role-types"` + Username string `json:"username" gorm:"index;size:36;not null;default:''" rule:"required" comment:"用户名" scenarios:"search;list;create;update;view;export"` + Tag string `json:"tag" gorm:"index;size:60;not null;default:''" comment:"标签" dropdown:"created;filterable;default_first" live:"type:dropdown;url:/organize/user-tags" scenarios:"list;search;create;update;view;export"` + Password string `json:"password,omitempty" gorm:"size:60;not null;default:''" rule:"required" comment:"密码" scenarios:"create"` + Avatar string `json:"avatar" gorm:"size:1024;not null;default:''" comment:"头像" scenarios:"view"` + Email string `json:"email" gorm:"size:120;not null;default:''" comment:"邮箱" scenarios:"search;list;create;update;view;export"` + Phone string `json:"phone" gorm:"size:36;not null;default:''" comment:"手机" scenarios:"search;list;create;update;view;export"` + Gender string `json:"gender,omitempty" gorm:"default:man" comment:"性别" scenarios:"list;create;update;view;export" enum:"man:男;woman:女;other:其他"` + Description string `json:"description,omitempty" gorm:"size:250;not null;default:''" format:"textarea" comment:"备注" scenarios:"create;update;view;export"` +} + +func (model *User) TableName() string { + return "users" +} diff --git a/server.go b/server.go new file mode 100644 index 0000000..60f88a2 --- /dev/null +++ b/server.go @@ -0,0 +1,69 @@ +package moto + +import ( + "context" + "git.nobla.cn/golang/kos" + httpkg "git.nobla.cn/golang/kos/entry/http" + "git.nobla.cn/golang/moto/common/db" + "git.nobla.cn/golang/moto/config" + "git.nobla.cn/golang/moto/models" + "git.nobla.cn/golang/moto/version" + "git.nobla.cn/golang/rest" + "io" + "net/http" +) + +type Server struct { + cfg *config.Config + ctx context.Context + cancelFunc context.CancelCauseFunc +} + +func (svr *Server) prepare() (err error) { + if err = db.Init(svr.ctx, svr.cfg.Database); err != nil { + return + } + values := []any{ + &models.User{}, + &models.Role{}, + &models.Department{}, + } + for _, item := range values { + if err = db.DB().AutoMigrate(item); err != nil { + return + } + if err = rest.AutoMigrate(svr.ctx, db.DB(), item, rest.WithoutDomain(), rest.WithModuleName(version.ProductName)); err != nil { + return + } + } + rest.SetHttpRouter(svr) + return +} + +func (svr *Server) Handle(method string, uri string, handler http.HandlerFunc) { + kos.Http().Handle(method, uri, func(ctx *httpkg.Context) (err error) { + handler(ctx.Response(), ctx.Request()) + return + }) +} + +func (svr *Server) Start(ctx context.Context) (err error) { + svr.ctx, svr.cancelFunc = context.WithCancelCause(ctx) + if err = svr.prepare(); err != nil { + return + } + svr.routes() + return +} + +func (svr *Server) Stop() (err error) { + svr.cancelFunc(io.ErrClosedPipe) + return +} + +func New(cfg *config.Config) *Server { + svr := &Server{ + cfg: cfg, + } + return svr +} diff --git a/version/version.go b/version/version.go new file mode 100644 index 0000000..5c4f8fd --- /dev/null +++ b/version/version.go @@ -0,0 +1,6 @@ +package version + +var ( + ProductName = "moto" + Version = "0.0.1" +)