Browse Source
Merge branch 'gva_gormv2_dev' of https://github.com/flipped-aurora/gin-vue-admin into gva_gormv2_dev
main
Merge branch 'gva_gormv2_dev' of https://github.com/flipped-aurora/gin-vue-admin into gva_gormv2_dev
main
1319612909
4 years ago
12 changed files with 412 additions and 91 deletions
-
12server/api/v1/sys_authority.go
-
50server/api/v1/sys_auto_code.go
-
2server/api/v1/sys_system.go
-
2server/api/v1/sys_user.go
-
53server/cmd/gva/run.go
-
2server/go.mod
-
6server/model/sys_base_menu.go
-
22server/service/sys_api.go
-
63server/service/sys_auto_code.go
-
24server/service/sys_base_menu.go
-
140server/utils/cmd_Task.go
-
127server/utils/cmd_monitor.go
@ -0,0 +1,53 @@ |
|||
/* |
|||
Copyright © 2020 NAME HERE <EMAIL ADDRESS> |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); |
|||
you may not use this file except in compliance with the License. |
|||
You may obtain a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0
|
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
See the License for the specific language governing permissions and |
|||
limitations under the License. |
|||
*/ |
|||
package gva |
|||
|
|||
import ( |
|||
"gin-vue-admin/utils" |
|||
"github.com/spf13/cobra" |
|||
"os" |
|||
) |
|||
|
|||
// runCmd represents the run command
|
|||
var runCmd = &cobra.Command{ |
|||
Use: "run", |
|||
Short: "running go codes with hot-compiled-like feature", |
|||
Long: ` |
|||
The "run" command is used for running go codes with hot-compiled-like feature, |
|||
which compiles and runs the go codes asynchronously when codes change. |
|||
`, |
|||
Run: func(cmd *cobra.Command, args []string) { |
|||
w := utils.NewWatch() |
|||
t := utils.NewT() |
|||
path, _ := os.Getwd() |
|||
go w.Watch(path, t) |
|||
t.RunTask() |
|||
}, |
|||
} |
|||
|
|||
func init() { |
|||
rootCmd.AddCommand(runCmd) |
|||
|
|||
// Here you will define your flags and configuration settings.
|
|||
|
|||
// Cobra supports Persistent Flags which will work for this command
|
|||
// and all subcommands, e.g.:
|
|||
// runCmd.PersistentFlags().String("foo", "", "A help for foo")
|
|||
|
|||
// Cobra supports local flags which will only run when this command
|
|||
// is called directly, e.g.:
|
|||
// runCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
|||
} |
@ -0,0 +1,140 @@ |
|||
package utils |
|||
|
|||
import ( |
|||
"fmt" |
|||
"os" |
|||
"os/exec" |
|||
"path/filepath" |
|||
"runtime" |
|||
"sync" |
|||
) |
|||
|
|||
type RunTask interface { |
|||
AddTask() |
|||
RunTask() |
|||
} |
|||
|
|||
// T: Task任务
|
|||
type T struct { |
|||
sync.Mutex |
|||
|
|||
// ch: 获取事件channel
|
|||
ch chan struct{} |
|||
|
|||
closeChan chan struct{} |
|||
|
|||
// 记录process对象
|
|||
p *os.Process |
|||
|
|||
// f: 执行任务
|
|||
f func(chan struct{}) error |
|||
} |
|||
|
|||
// NewT: 实例化方法
|
|||
func NewT() *T { |
|||
return newT(nil) |
|||
} |
|||
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 |
|||
} |
|||
|
|||
func (t *T) AddTask() { |
|||
t.Lock() |
|||
defer t.Unlock() |
|||
if len(t.ch) == 1 { |
|||
// 代表已经有任务了
|
|||
// 直接丢弃这次任务
|
|||
return |
|||
} |
|||
t.ch <- struct{}{} |
|||
} |
|||
|
|||
func (t *T) RunTask() { |
|||
fmt.Println("进入") |
|||
// 这里做的make 是用于关闭上一个执行的任务
|
|||
ch := make(chan struct{}) |
|||
// 先run服务
|
|||
go t.f(ch) |
|||
for { |
|||
_, ok := <-t.ch |
|||
ch <- struct{}{} |
|||
if !ok { |
|||
return |
|||
} |
|||
// 等待上一个关闭
|
|||
<-t.closeChan |
|||
go t.f(ch) |
|||
} |
|||
|
|||
} |
|||
|
|||
// DefaultF: 默认的StartFunction
|
|||
func (t *T) DefaultF(ch chan struct{}) error { |
|||
|
|||
var buildCmd *exec.Cmd |
|||
var cmd *exec.Cmd |
|||
|
|||
// 判断是否有makefile
|
|||
_, err := os.Stat(filepath.Join("Makefile")) |
|||
if runtime.GOOS != "windows" && err != nil { |
|||
_, err := exec.LookPath("make") |
|||
if err == nil { |
|||
cmd = exec.Command("makefile") |
|||
goto makefile |
|||
} |
|||
} |
|||
// 检测系统是否有编译环境
|
|||
_, err = exec.LookPath("go") |
|||
if err != nil { |
|||
return err |
|||
} |
|||
// build
|
|||
|
|||
switch runtime.GOOS { |
|||
case "windows": |
|||
buildCmd = exec.Command("go", "build", "-o", "gva.exe", "main.go") |
|||
default: |
|||
buildCmd = exec.Command("go", "build", "-o", "gva", "main.go") |
|||
} |
|||
|
|||
err = buildCmd.Run() |
|||
fmt.Println("build 执行完成") |
|||
if err != nil { |
|||
return err |
|||
} |
|||
// 执行
|
|||
|
|||
switch runtime.GOOS { |
|||
case "windows": |
|||
cmd = exec.Command("gva.exe") |
|||
default: |
|||
cmd = exec.Command("./gva") |
|||
} |
|||
makefile: |
|||
// 开始执行任务
|
|||
err = cmd.Start() |
|||
if err != nil { |
|||
return err |
|||
} |
|||
t.p = cmd.Process |
|||
fmt.Println("pid", t.p.Pid) |
|||
go func() { |
|||
err = cmd.Wait() |
|||
}() |
|||
<-ch |
|||
// 回收资源
|
|||
err = cmd.Process.Kill() |
|||
fmt.Println("kill err", err) |
|||
// 发送关闭完成信号
|
|||
t.closeChan <- struct{}{} |
|||
return err |
|||
} |
@ -0,0 +1,127 @@ |
|||
package utils |
|||
|
|||
import ( |
|||
"errors" |
|||
"fmt" |
|||
"github.com/fsnotify/fsnotify" |
|||
"io/ioutil" |
|||
"os" |
|||
"path/filepath" |
|||
) |
|||
|
|||
// Watch: 监控对象
|
|||
type Watch struct { |
|||
*fsnotify.Watcher |
|||
} |
|||
|
|||
func NewWatch() *Watch { |
|||
obj, _ := fsnotify.NewWatcher() |
|||
return &Watch{obj} |
|||
} |
|||
|
|||
// Watch: 监控对象
|
|||
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 |
|||
} |
|||
// 判断时间
|
|||
fmt.Println("even", even) |
|||
switch { |
|||
// todo 待处理
|
|||
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) |
|||
fmt.Println(filepath.Ext(even.Name)) |
|||
if filepath.Ext(even.Name) == ".go" { |
|||
fmt.Println("send addtask:", even.Name) |
|||
t.AddTask() |
|||
} |
|||
case even.Op&fsnotify.Remove == fsnotify.Remove: |
|||
fmt.Println("删除 : ", even.Name) |
|||
//t.AddTask()
|
|||
_ = w.Remove(even.Name) |
|||
case even.Op&fsnotify.Rename == fsnotify.Rename: |
|||
fmt.Println("重命名 : ", even.Name) |
|||
//t.AddTask()
|
|||
_ = w.Remove(even.Name) |
|||
} |
|||
case err = <-w.Errors: |
|||
fmt.Println("79", err) |
|||
c <- err |
|||
return |
|||
} |
|||
} |
|||
}() |
|||
return <-c |
|||
|
|||
} |
|||
|
|||
// watchDir: 处理监控目录
|
|||
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() { |
|||
// todo 这里加一些条件筛选添加监控的内容
|
|||
err = w.watchFile(fPath) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
} else { |
|||
err := w.watchDir(fPath) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
} |
|||
} |
|||
return err |
|||
} |
|||
|
|||
// watchDir: 处理监控单文件
|
|||
func (w *Watch) watchFile(path string) error { |
|||
return w.Add(path) |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue