songzhibin97
4 years ago
3 changed files with 248 additions and 0 deletions
@ -0,0 +1,47 @@ |
|||
/* |
|||
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 ( |
|||
"github.com/spf13/cobra" |
|||
) |
|||
|
|||
// 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) { |
|||
// todo 未实现
|
|||
}, |
|||
} |
|||
|
|||
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,83 @@ |
|||
package utils |
|||
|
|||
import ( |
|||
"os" |
|||
"os/exec" |
|||
"strings" |
|||
"sync" |
|||
) |
|||
|
|||
type RunTask interface { |
|||
AddTask() |
|||
RunTask() |
|||
} |
|||
|
|||
// T: Task任务
|
|||
type T struct { |
|||
sync.Mutex |
|||
|
|||
// ch: 获取时间channel
|
|||
ch chan struct{} |
|||
|
|||
// 记录pid 用于kill
|
|||
pid int |
|||
|
|||
// 执行shell命令
|
|||
exec.Cmd |
|||
} |
|||
|
|||
// NewT: 实例化方法
|
|||
func NewT(path string, args []string, environment ...[]string) *T { |
|||
env := os.Environ() |
|||
if len(environment) > 0 { |
|||
for k, v := range environment[0] { |
|||
env[k] = v |
|||
} |
|||
} |
|||
t := &T{ |
|||
Mutex: sync.Mutex{}, |
|||
ch: make(chan struct{}), |
|||
Cmd: exec.Cmd{ |
|||
Path: path, |
|||
Args: []string{path}, |
|||
Env: env, |
|||
Stdin: os.Stdin, |
|||
Stdout: os.Stdout, |
|||
Stderr: os.Stderr, |
|||
ExtraFiles: make([]*os.File, 0), |
|||
}, |
|||
pid: os.Getpid(), |
|||
} |
|||
t.Dir, _ = os.Getwd() |
|||
if len(args) > 0 { |
|||
// Exclude of current binary path.
|
|||
start := 0 |
|||
if strings.EqualFold(path, args[0]) { |
|||
start = 1 |
|||
} |
|||
t.Args = append(t.Args, args[start:]...) |
|||
} |
|||
return t |
|||
} |
|||
|
|||
func (t *T) AddTask() { |
|||
t.Lock() |
|||
defer t.Unlock() |
|||
if len(t.ch) == 1 { |
|||
// 代表已经有任务了
|
|||
// 直接丢弃这次任务
|
|||
return |
|||
} |
|||
t.ch <- struct{}{} |
|||
} |
|||
|
|||
func (t *T) RunTask() { |
|||
for { |
|||
_, ok := <-t.ch |
|||
if !ok { |
|||
return |
|||
} |
|||
// todo 执行任务
|
|||
|
|||
} |
|||
} |
@ -0,0 +1,118 @@ |
|||
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) 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) |
|||
_ = w.Add(even.Name) |
|||
case even.Op&fsnotify.Write == fsnotify.Write: |
|||
fmt.Println("修改 : ", even.Name) |
|||
case even.Op&fsnotify.Remove == fsnotify.Remove: |
|||
fmt.Println("删除 : ", even.Name) |
|||
_ = w.Remove(even.Name) |
|||
case even.Op&fsnotify.Rename == fsnotify.Rename: |
|||
fmt.Println("重命名 : ", even.Name) |
|||
_ = w.Remove(even.Name) |
|||
} |
|||
case err = <-w.Errors: |
|||
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