+ xfs & 更新binlog

This commit is contained in:
Max 2021-10-01 12:44:13 +08:00
parent f84136fee9
commit 274c22d2db
10 changed files with 298 additions and 44 deletions

View file

@ -5,7 +5,7 @@ VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples/)
GOFILES := $(shell find . -name "*.go")
# ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
TESTFOLDER := $(shell $(GO) list ./... | grep -E 'xiang$$|global$$|table$$|user$$' | grep -v examples)
TESTFOLDER := $(shell $(GO) list ./... | grep -E 'xiang$$|global$$|table$$|user$$|xfs$$' | grep -v examples)
TESTTAGS ?= ""
# 运行单元测试
@ -104,25 +104,24 @@ static:
rm -rf ui
mv .tmp/ui/dist ui
rm -rf .tmp/ui
# 将静态文件打包到命令工具
.PHONY: bindata
bindata:
bindata: gen-bindata fmt
# 将静态文件打包到命令工具
.PHONY: gen-bindata
gen-bindata:
rm -f data.go
mkdir -p .tmp/data
cp -r ui .tmp/data/
cp -r xiang .tmp/data/
go-bindata -fs -pkg global -o global/data.go -prefix ".tmp/data/" .tmp/data/...
go-bindata -fs -pkg data -o data/bindata.go -prefix ".tmp/data/" .tmp/data/...
rm -rf .tmp/data
# 编译可执行文件
.PHONY: xiang
xiang: bindata
if [ -f global/bindata.go ]; then \
mv global/bindata.go global/bindata.go.bak; \
fi;
if [ ! -z "${XIANG_DOMAIN}" ]; then \
mv global/vars.go global/vars.go.bak; \
sed "s/*.iqka.com/$(XIANG_DOMAIN)/g" global/vars.go.bak > global/vars.go; \
@ -135,10 +134,6 @@ xiang: bindata
mkdir -p dist/bin
mv .tmp/xiang-*-* dist/bin/
chmod +x dist/bin/xiang-*-*
rm -f global/data.go
if [ -f global/bindata.go.bak ]; then \
mv global/bindata.go.bak global/bindata.go; \
fi;
if [ ! -z "${XIANG_DOMAIN}" ]; then \
rm global/vars.go; \

View file

@ -1,4 +1,4 @@
// Code generated for package global by go-bindata DO NOT EDIT. (@generated)
// Code generated for package data by go-bindata DO NOT EDIT. (@generated)
// sources:
// .tmp/data/ui/index.html
// .tmp/data/xiang/.DS_Store
@ -14,7 +14,7 @@
// .tmp/data/xiang/models/user.json
// .tmp/data/xiang/tables/README.md
// .tmp/data/xiang/tables/user.json
package global
package data
import (
"bytes"
@ -192,7 +192,7 @@ func uiIndexHtml() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "ui/index.html", size: 14, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "ui/index.html", size: 14, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -212,7 +212,7 @@ func xiangDs_store() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/.DS_Store", size: 6148, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/.DS_Store", size: 6148, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -232,7 +232,7 @@ func xiangApisReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/apis/README.md", size: 13, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/apis/README.md", size: 13, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -252,7 +252,7 @@ func xiangApisTableHttpJson() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/apis/table.http.json", size: 2580, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/apis/table.http.json", size: 2580, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -272,7 +272,7 @@ func xiangApisUserHttpJson() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/apis/user.http.json", size: 1260, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/apis/user.http.json", size: 1260, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -292,7 +292,7 @@ func xiangApisXiangHttpJson() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/apis/xiang.http.json", size: 577, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/apis/xiang.http.json", size: 577, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -312,7 +312,7 @@ func xiangFlowsReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/flows/README.md", size: 12, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/flows/README.md", size: 12, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -332,7 +332,7 @@ func xiangFlowsMenuFlowJson() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/flows/menu.flow.json", size: 1045, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/flows/menu.flow.json", size: 1045, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -352,7 +352,7 @@ func xiangFlowsTableGetFlowJson() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/flows/table/get.flow.json", size: 541, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/flows/table/get.flow.json", size: 541, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -372,7 +372,7 @@ func xiangModelsReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/models/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/models/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -392,7 +392,7 @@ func xiangModelsMenuJson() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/models/menu.json", size: 6061, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/models/menu.json", size: 6061, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -412,7 +412,7 @@ func xiangModelsUserJson() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/models/user.json", size: 8826, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/models/user.json", size: 8826, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -432,7 +432,7 @@ func xiangTablesReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/tables/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/tables/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -452,7 +452,7 @@ func xiangTablesUserJson() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "xiang/tables/user.json", size: 1422, mode: os.FileMode(420), modTime: time.Unix(1632926333, 0)}
info := bindataFileInfo{name: "xiang/tables/user.json", size: 1422, mode: os.FileMode(420), modTime: time.Unix(1633054161, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}

19
data/data.go Normal file
View file

@ -0,0 +1,19 @@
package data
import (
"os"
assetfs "github.com/elazarl/go-bindata-assetfs"
)
// AssetFS 静态文件处理服务器
func AssetFS() *assetfs.AssetFS {
assetInfo := func(path string) (os.FileInfo, error) {
return os.Stat(path)
}
for k := range _bintree.Children {
k = "ui"
return &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, AssetInfo: assetInfo, Prefix: k, Fallback: "index.html"}
}
panic("unreachable")
}

View file

@ -11,6 +11,7 @@ import (
"github.com/yaoapp/gou"
"github.com/yaoapp/kun/exception"
"github.com/yaoapp/xiang/config"
"github.com/yaoapp/xiang/data"
"github.com/yaoapp/xiang/table"
)
@ -318,12 +319,12 @@ func getFileBaseName(root string, file string) string {
// getFilesBin 从 bindata 中读取文件列表
func getFilesBin(root string, typ string) []Script {
files := []Script{}
binfiles := AssetNames()
binfiles := data.AssetNames()
for _, path := range binfiles {
if strings.HasSuffix(path, typ) {
file := strings.TrimPrefix(path, root+"/")
name, typ := getTypeName(file)
content, err := Asset(path)
content, err := data.Asset(path)
if err != nil {
exception.Err(err, 500).Throw()
}

View file

@ -20,3 +20,8 @@ func processPing(process *gou.Process) interface{} {
}
return res
}
// processFile 返回文件内容
func processFile(process *gou.Process) interface{} {
return nil
}

View file

@ -3,12 +3,11 @@ package global
import (
"fmt"
"net/http"
"os"
"strings"
assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/yaoapp/gou"
"github.com/yaoapp/xiang/config"
"github.com/yaoapp/xiang/data"
"github.com/yaoapp/xun/capsule"
)
@ -25,7 +24,7 @@ var AllowHosts = []string{}
var Conf config.Config
// FileServer 静态服务
var FileServer http.Handler = http.FileServer(assetFS())
var FileServer http.Handler = http.FileServer(data.AssetFS())
// 初始化配置
func init() {
@ -58,14 +57,3 @@ func init() {
// 加载数据
Load(Conf)
}
func assetFS() *assetfs.AssetFS {
assetInfo := func(path string) (os.FileInfo, error) {
return os.Stat(path)
}
for k := range _bintree.Children {
k = "ui"
return &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, AssetInfo: assetInfo, Prefix: k, Fallback: "index.html"}
}
panic("unreachable")
}

1
go.mod
View file

@ -22,6 +22,7 @@ require (
github.com/mattn/go-sqlite3 v1.14.8 // indirect
github.com/mojocn/base64Captcha v1.3.5 // indirect
github.com/robertkrimen/otto v0.0.0-20210927222213-f9375a256948 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cobra v1.2.1 // indirect
github.com/stretchr/testify v1.7.0
github.com/yaoapp/gou v0.0.0-20210929143406-112eed6cdfd9 // indirect

1
go.sum
View file

@ -327,6 +327,7 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=

228
xfs/xfs.go Normal file
View file

@ -0,0 +1,228 @@
package xfs
import (
"archive/tar"
"archive/zip"
"bytes"
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"strings"
"github.com/spf13/afero"
"github.com/spf13/afero/tarfs"
"github.com/spf13/afero/zipfs"
"github.com/yaoapp/kun/exception"
)
// Xfs 文件系统
type Xfs struct {
Root string // Root
afero.Afero
}
// Fs 文件系统 Interface
type Fs interface {
afero.Fs
}
// File file fs
type File interface {
afero.File
}
// New 创建文件系统
func New(path string) Xfs {
pinfo := strings.Split(path, "://")
fs := "fs"
root := path
if len(pinfo) == 2 {
fs = pinfo[0]
root = strings.TrimPrefix(path, fmt.Sprintf("%s://", fs))
}
xfs := Xfs{
Root: root,
}
switch fs {
case "fs", "file":
xfs.Fs = afero.NewBasePathFs(afero.NewOsFs(), root)
break
case "mem", "memory":
xfs.Fs = afero.NewMemMapFs()
break
default:
exception.New("尚未支持 %s 文件系统", 500, fs).Throw()
}
exists := xfs.MustDirExists("/")
if !exists {
xfs.MustMkdirAll("/", os.ModePerm)
}
return xfs
}
// NewZip 创建Zip文件系统
func NewZip(zipfile string) Xfs {
r, err := zip.OpenReader(zipfile)
if err != nil {
exception.New("ZIP文件打开失败 %s ", 500, err).Throw()
}
return Xfs{
Root: "/",
Afero: afero.Afero{
Fs: zipfs.New(&r.Reader),
},
}
}
// NewTar tar文件系统
func NewTar(tarfile string) Xfs {
var buf bytes.Buffer
r := tar.NewReader(&buf)
return Xfs{
Root: "/",
Afero: afero.Afero{
Fs: tarfs.New(r),
},
}
}
// MustOpen 打开文件
func (xfs *Xfs) MustOpen(filename string) File {
file, err := xfs.Open(filename)
if err != nil {
exception.New("打开文件失败 %s 失败 ", 500, filename).Throw()
}
return file
}
// MustReadFile 阅读文件内容
func (xfs *Xfs) MustReadFile(filename string) []byte {
bytes, err := xfs.ReadFile(filename)
if err != nil {
exception.New("阅读文件内容失败 %s 失败 ", 500, filename).Throw()
}
return bytes
}
// MustReadDir 阅读文件夹内容
func (xfs *Xfs) MustReadDir(dirname string) []os.FileInfo {
fileinfos, err := xfs.ReadDir(dirname)
if err != nil {
exception.New("阅读文件夹失败 %s 失败 ", 500, dirname).Throw()
}
return fileinfos
}
// MustExists 检查文件是否存在
func (xfs *Xfs) MustExists(filename string) bool {
has, err := xfs.Exists(filename)
if err != nil {
exception.New("检查文件失败 %s 失败 ", 500, filename).Throw()
}
return has
}
// MustDirExists 检查文件夹是否存在
func (xfs *Xfs) MustDirExists(dirname string) bool {
res, err := xfs.DirExists(dirname)
if err != nil {
exception.New("检查文件夹 %s 失败 ", 500, dirname).Throw()
}
return res
}
// MustMkdirAll 创建文件夹及子文件夹
func (xfs *Xfs) MustMkdirAll(dirname string, pterm fs.FileMode) {
err := xfs.MkdirAll(dirname, pterm)
if err != nil {
exception.New("创建文件夹及子文件 %s 失败 ", 500, dirname).Throw()
}
}
// MustMkdir 创建文件夹
func (xfs *Xfs) MustMkdir(dirname string, pterm fs.FileMode) {
err := xfs.Mkdir(dirname, pterm)
if err != nil {
exception.New("创建文件夹 %s 失败 ", 500, dirname).Throw()
}
}
// MustIsDir 是否为文件夹
func (xfs *Xfs) MustIsDir(dirname string) bool {
isdir, err := xfs.IsDir(dirname)
if err != nil {
exception.New("创建文件夹 %s 失败 ", 500, dirname).Throw()
}
return isdir
}
// MustIsEmpty 文件是否为空
func (xfs *Xfs) MustIsEmpty(filename string) bool {
isEmpty, err := xfs.IsEmpty(filename)
if err != nil {
exception.New("检查文件是否为空 %s 失败 ", 500, filename).Throw()
}
return isEmpty
}
// GetTempDir 临时目录
func (xfs *Xfs) GetTempDir(subPath string) string {
return afero.GetTempDir(xfs.Fs, subPath)
}
//MustTempDir 创建临时文件夹
func (xfs *Xfs) MustTempDir(dirname string, prefix string) string {
name, err := xfs.TempDir(dirname, prefix)
if err != nil {
exception.New("创建文件夹 %s %s 失败 ", 500, dirname, prefix).Throw()
}
return name
}
// MustTempFile 临时文件
func (xfs *Xfs) MustTempFile(dirname, prefix string) File {
f, err := xfs.TempFile(dirname, prefix)
if err != nil {
exception.New("创建临时文件 %s %s 失败 ", 500, dirname, prefix).Throw()
}
return f
}
// MustWalk 文件夹遍历
func (xfs *Xfs) MustWalk(root string, walkFn filepath.WalkFunc) {
err := xfs.Walk(root, walkFn)
if err != nil {
exception.New("遍历文件夹 %s 失败 ", 500, root).Throw()
}
}
// MustWriteFile 写入文件
func (xfs *Xfs) MustWriteFile(filename string, data []byte, perm os.FileMode) {
err := xfs.WriteFile(filename, data, perm)
if err != nil {
exception.New("写入文件 %s 失败 ", 500, filename).Throw()
}
}
// MustFileContainsBytes 文件是否包含内容
func (xfs *Xfs) MustFileContainsBytes(filename string, subslice []byte) bool {
has, err := xfs.FileContainsBytes(filename, subslice)
if err != nil {
exception.New("检查文件是否包含内容 %s 失败 ", 500, filename).Throw()
}
return has
}
// MustSafeWriteReader 检查文件能否写入
func (xfs *Xfs) MustSafeWriteReader(filename string, r io.Reader) {
err := xfs.SafeWriteReader(filename, r)
if err != nil {
exception.New("检查文件是否可以写入 Reader %s 失败 ", 500, filename).Throw()
}
}

16
xfs/xfs_test.go Normal file
View file

@ -0,0 +1,16 @@
package xfs
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/yaoapp/xiang/config"
)
func TestOSFsMustMkdirAll(t *testing.T) {
fs := New(config.Conf.Source)
assert.NotPanics(t, func() {
fs.MustMkdirAll("/.tmp/unit-test/dir", os.ModePerm)
})
}