mirror of
https://github.com/flipped-aurora/gin-vue-admin.git
synced 2026-09-21 12:32:25 +00:00
自动初始化数据库功能后端部分完成
This commit is contained in:
@@ -1,199 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"sync"
|
||||
)
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@interface_name: RunTask
|
||||
//@description: Task接口
|
||||
|
||||
type RunTask interface {
|
||||
AddTask()
|
||||
RunTask()
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@struct_name: T
|
||||
//@description: Task任务
|
||||
|
||||
type T struct {
|
||||
sync.Mutex
|
||||
|
||||
// 获取事件channel
|
||||
ch chan struct{}
|
||||
|
||||
closeChan chan struct{}
|
||||
|
||||
// 记录process对象
|
||||
p *os.Process
|
||||
|
||||
// 执行任务
|
||||
f func(chan struct{}) error
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@function: NewT
|
||||
//@description: T的实例化方法
|
||||
//@return: *T
|
||||
|
||||
func NewT() *T {
|
||||
return newT(nil)
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@function: newT
|
||||
//@description:
|
||||
//@param: f func(chan struct{}) error
|
||||
//@return: *T
|
||||
|
||||
func newT(f func(chan struct{}) error) *T {
|
||||
t := &T{
|
||||
Mutex: sync.Mutex{},
|
||||
ch: make(chan struct{}, 1),
|
||||
closeChan: make(chan struct{}),
|
||||
f: f,
|
||||
}
|
||||
if f == nil {
|
||||
t.f = t.DefaultF
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@object: *T
|
||||
//@function: AddTask
|
||||
//@description: 添加任务
|
||||
|
||||
func (t *T) AddTask() {
|
||||
select {
|
||||
case t.ch <- struct{}{}:
|
||||
default:
|
||||
// 代表已经有任务了
|
||||
// 直接丢弃这次任务
|
||||
}
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@object: *T
|
||||
//@function: RunTask
|
||||
//@description: 启动任务
|
||||
|
||||
func (t *T) RunTask() {
|
||||
fmt.Println("进入")
|
||||
// 这里做的make 是用于关闭上一个执行的任务
|
||||
ch := make(chan struct{})
|
||||
// 先run服务
|
||||
go t.f(ch)
|
||||
for {
|
||||
_, ok := <-t.ch
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
ch <- struct{}{}
|
||||
// 等待上一个关闭
|
||||
<-t.closeChan
|
||||
go t.f(ch)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@object: t *T
|
||||
//@function: DefaultF
|
||||
//@description: 默认的StartFunction
|
||||
//@param: ch chan struct{}
|
||||
//@return: error
|
||||
|
||||
func (t *T) DefaultF(ch chan struct{}) error {
|
||||
var buildCmd *exec.Cmd
|
||||
var cmd *exec.Cmd
|
||||
|
||||
// 检测系统是否有编译环境
|
||||
_, err := exec.LookPath("go")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// build
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
buildCmd = exec.Command("go", "build", "-o", "server.exe", "main.go")
|
||||
default:
|
||||
buildCmd = exec.Command("go", "build", "-o", "server", "main.go")
|
||||
}
|
||||
//cmd = exec.Command("go", "run", "main.go")
|
||||
err = buildCmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("build 执行完成")
|
||||
// 执行
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
cmd = exec.Command("server.exe")
|
||||
default:
|
||||
cmd = exec.Command("./server")
|
||||
}
|
||||
|
||||
// 开始执行任务
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
err = t.echo(cmd, ctx)
|
||||
<-ch
|
||||
// 回收资源
|
||||
fmt.Println("pid:", t.p.Pid, "->Kill")
|
||||
err = t.p.Kill()
|
||||
cancel()
|
||||
// 发送关闭完成信号
|
||||
t.closeChan <- struct{}{}
|
||||
return err
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@object: t *T
|
||||
//@function: echo
|
||||
//@description: 封装回显
|
||||
//@param: cmd *exec.Cmd, ctx context.Context
|
||||
//@return: error
|
||||
|
||||
func (t *T) echo(cmd *exec.Cmd, ctx context.Context) error {
|
||||
var stdoutBuf bytes.Buffer
|
||||
stdoutIn, _ := cmd.StdoutPipe()
|
||||
var errStdout error
|
||||
stdout := io.MultiWriter(os.Stdout, &stdoutBuf)
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func(ctx context.Context) {
|
||||
_, errStdout = io.Copy(stdout, stdoutIn)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
}(ctx)
|
||||
t.p = cmd.Process
|
||||
fmt.Println("pid", t.p.Pid)
|
||||
go func() {
|
||||
_ = cmd.Wait()
|
||||
if errStdout != nil {
|
||||
fmt.Printf("failed to capture stdout or stderr\n")
|
||||
}
|
||||
fmt.Printf("%s\n", string(stdoutBuf.Bytes()))
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
//_ = os.Stdout.Close()
|
||||
return
|
||||
default:
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@struct_name: Watch
|
||||
//@description: 监控对象
|
||||
|
||||
type Watch struct {
|
||||
*fsnotify.Watcher
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@function: NewWatch
|
||||
//@description: Watch的实例化方法
|
||||
//@return: *Watch
|
||||
|
||||
func NewWatch() *Watch {
|
||||
obj, _ := fsnotify.NewWatcher()
|
||||
return &Watch{obj}
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@object: w *Watch
|
||||
//@function: Watch
|
||||
//@description: 监控对象
|
||||
//@param: path string, t *T
|
||||
//@return: error
|
||||
|
||||
func (w *Watch) Watch(path string, t *T) error {
|
||||
// 先转化为绝对路径
|
||||
path, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 判断是单个文件还是目录文件
|
||||
fileInfo, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 判断是否是目录 添加监控
|
||||
if fileInfo.IsDir() {
|
||||
// dir
|
||||
err = w.watchDir(path)
|
||||
|
||||
} else {
|
||||
err = w.watchFile(path)
|
||||
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c := make(chan error)
|
||||
// 启动监控
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case even, ok := <-w.Events:
|
||||
if !ok {
|
||||
// close
|
||||
fmt.Println("Errors close")
|
||||
c <- errors.New("errors close")
|
||||
return
|
||||
}
|
||||
// 判断事件
|
||||
switch {
|
||||
case even.Op&fsnotify.Create == fsnotify.Create:
|
||||
//这里获取新创建文件的信息,如果是目录,则加入监控中
|
||||
fmt.Println("创建文件 : ", even.Name)
|
||||
//t.AddTask()
|
||||
_ = w.Add(even.Name)
|
||||
case even.Op&fsnotify.Write == fsnotify.Write:
|
||||
fmt.Println("修改文件 : ", even.Name)
|
||||
w.addTask(t, even.Name)
|
||||
case even.Op&fsnotify.Remove == fsnotify.Remove || even.Op&fsnotify.Rename == fsnotify.Rename:
|
||||
fmt.Println("删除或重命名文件 : ", even.Name)
|
||||
_ = w.Remove(even.Name)
|
||||
w.addTask(t, even.Name)
|
||||
}
|
||||
case err = <-w.Errors:
|
||||
fmt.Println("even Error:", err)
|
||||
c <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return <-c
|
||||
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@object: w *Watch
|
||||
//@function: watchDir
|
||||
//@description: 处理监控目录
|
||||
//@param: path string
|
||||
//@return: error
|
||||
|
||||
func (w *Watch) watchDir(path string) error {
|
||||
// 先将自己添加到监控
|
||||
err := w.Add(path)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileSlice, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range fileSlice {
|
||||
fPath := filepath.Join(path, f.Name())
|
||||
if !f.IsDir() {
|
||||
// 判断是否可监控的文件
|
||||
if chickPower(fPath) {
|
||||
err = w.watchFile(fPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err := w.watchDir(fPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@object: w *Watch
|
||||
//@function: watchDir
|
||||
//@description: 处理监控单文件
|
||||
//@param: path string
|
||||
//@return: error
|
||||
|
||||
func (w *Watch) watchFile(path string) error {
|
||||
var err error
|
||||
if chickPower(path) {
|
||||
err = w.Add(path)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@function: chickPower
|
||||
//@description: 判断是否在可控范围内
|
||||
//@param: path string
|
||||
//@return: error
|
||||
|
||||
func chickPower(name string) bool {
|
||||
name = filepath.Ext(name)
|
||||
return name == ".go" || name == ".yaml"
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@object: w *Watch
|
||||
//@function: addTask
|
||||
//@description: 偏函数 简化发送任务
|
||||
//@param: path string
|
||||
//@return: error
|
||||
|
||||
func (w *Watch) addTask(t *T, name string) {
|
||||
if chickPower(name) {
|
||||
fmt.Println("Add Task->>>>>>")
|
||||
t.AddTask()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user