Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed some bug #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

type Command interface {
String() string
Start(delay time.Duration)
Start(delay time.Duration, haveBuild bool)
Terminate(wait time.Duration)
}

Expand Down Expand Up @@ -47,7 +47,7 @@ func (c *command) String() string {
return fmt.Sprintf("%s %s", c.name, strings.Join(c.args, " "))
}

func (c *command) Start(delay time.Duration) {
func (c *command) Start(delay time.Duration, haveBuild bool) {
time.Sleep(delay) // delay for a while to avoid start too frequently

c.mutex.Lock()
Expand Down Expand Up @@ -85,7 +85,11 @@ func (c *command) Start(delay time.Duration) {

cmd.Wait()
if cmd.ProcessState.Success() {
log.Println("- Done.")
if haveBuild {
log.Println("Restart application success!")
} else {
log.Println("Start application success!")
}
} else {
log.Println("- Terminated.")
}
Expand Down
16 changes: 10 additions & 6 deletions command/empty.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
package command

import "time"
import (
"time"
)

// An empty command is a command that do nothing
type empty string

func Empty() Command {
return empty("Empty command")
}

func (c empty) String() string {
return string(c)
func (e empty) String() string {
return string(e)
}

func (c empty) Start(delay time.Duration) {
func (e empty) Start(delay time.Duration, haveBuild bool) {
// Start an empty command just do nothing but delay for given duration
<-time.After(delay)
}

func (c empty) Terminate(wait time.Duration) {
func (e empty) Terminate(wait time.Duration) {
// Terminate empty command just return immediately without any error
}

// ProcessState contains information about an exited process,
// available after a call to Wait or Run.
3 changes: 3 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ package main
import (
"github.com/shanzi/wu/command"
"github.com/shanzi/wu/runner"

"log"
"os"
"os/signal"
"path/filepath"
// "wu/command"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

删除这两个注释?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个是我的失误,没有clone到github下。回头删掉

// "wu/runner"
)

func init() {
Expand Down
8 changes: 5 additions & 3 deletions runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"log"
"strings"
"time"
// "wu/command"
)

type Runner interface {
Expand Down Expand Up @@ -51,10 +52,10 @@ func (r *runner) Start() {
log.Fatal("Failed to initialize watcher:", err)
}
matched := match(changed, r.patterns)
log.Println("Start watching...")

// Run the command once at initially
r.command.Start(200 * time.Millisecond)
haveBuild := false
r.command.Start(200*time.Millisecond, haveBuild)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没看懂 haveBuild 是用来干什么的。。。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前的提示就是done 但是我想合理的提示应该是编译成功一次之后 之后就是重新启动了 你觉得呢

for fp := range matched {
files := gather(fp, matched, 500*time.Millisecond)

Expand All @@ -64,7 +65,8 @@ func (r *runner) Start() {
log.Println("File changed:", strings.Join(files, ", "))

// Run new command
r.command.Start(200 * time.Millisecond)
haveBuild = true
r.command.Start(200*time.Millisecond, haveBuild)
}
}

Expand Down
95 changes: 54 additions & 41 deletions runner/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package runner

import (
"github.com/fsnotify/fsnotify"
"io/ioutil"
"log"
"os"
"path/filepath"
Expand All @@ -15,13 +16,6 @@ func watch(path string, abort <-chan struct{}) (<-chan string, error) {
return nil, err
}

for p := range list(path) {
err = watcher.Add(p)
if err != nil {
log.Printf("Failed to watch: %s, error: %s", p, err)
}
}

out := make(chan string)
go func() {
defer close(out)
Expand All @@ -40,16 +34,36 @@ func watch(path string, abort <-chan struct{}) (<-chan string, error) {
info, err := os.Stat(fp.Name)
if err == nil && info.IsDir() {
// Add newly created sub directories to watch list
log.Printf("Add newly diectory ( %s )\n", fp.Name)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add newly created directory?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

比如新增加了一个单元文件,这里是想提示出来这个变化。

watcher.Add(fp.Name)
}
}
out <- fp.Name

if fp.Op&fsnotify.Write == fsnotify.Write || fp.Op == fsnotify.Remove || fp.Op == fsnotify.Rename {
out <- fp.Name
}

case err := <-watcher.Errors:
log.Println("Watch Error:", err)
}
}
}()

// Start watch
{
var paths []string
currpath, _ := os.Getwd()

readAppDirectories(currpath, &paths)

log.Println("Start watching...")

for _, dir := range paths {
watcher.Add(dir)
log.Printf("Directory( %s )\n", dir)
}
}

return out, nil
}

Expand All @@ -60,6 +74,13 @@ func match(in <-chan string, patterns []string) <-chan string {
defer close(out)
for fp := range in {
info, err := os.Stat(fp)

if os.IsNotExist(err) {
log.Printf("Dictory (%s) have been removed\n", fp)
log.Println("here=======here")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

删除多余的log?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个不好意思,昨晚太晚了,忘记删这个了。

continue
}

if os.IsNotExist(err) || !info.IsDir() {
_, fn := filepath.Split(fp)
for _, p := range patterns {
Expand All @@ -74,39 +95,6 @@ func match(in <-chan string, patterns []string) <-chan string {
return out
}

func list(root string) <-chan string {
out := make(chan string)

info, err := os.Stat(root)
if err != nil {
log.Fatalf("Failed to visit %s, error: %s\n", root, err)
}
if !info.IsDir() {
go func() {
defer close(out)
out <- root
}()

return out
}

go func() {
defer close(out)
filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
if err != nil {
log.Printf("Failed to visit directory: %s, error: %s", path, err)
return err
}
out <- path
}
return nil
})
}()

return out
}

// gather delays further operations for a while and gather
// all changes happened in this period
func gather(first string, changes <-chan string, delay time.Duration) []string {
Expand All @@ -132,3 +120,28 @@ loop:
sort.Strings(ret)
return ret
}

func readAppDirectories(directory string, paths *[]string) {
fileInfos, err := ioutil.ReadDir(directory)

if err != nil {
return
}

haveDir := false
for _, fileinfo := range fileInfos {
if fileinfo.IsDir() == true && fileinfo.Name() != "." && fileinfo.Name() != ".git" {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉作为一个简单的 utility 直接 ignore 掉  .git 并不好。

我觉得在使用过程中指定需要侦听的文件类型就应该够用了。对于 .git 这种需求可以做一个选项出来。直接 hard code 不好。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你这样说也可以,可以选择性的过滤一部分文件,比如说隐藏文件

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

您之前的方案,会把.git下的文件全部都监控起来,我真的不明白监控.git文件有什么特殊的用意。

readAppDirectories(directory+"/"+fileinfo.Name(), paths)
continue
}

if haveDir {
continue
}

if filepath.Ext(fileinfo.Name()) == ".go" {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm 这里 hardcode 了 go ,如果想要讲 wu 用在其他地方就没办法了吧。这么做有什么理由么?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wu 按照我的理解新的逻辑只会侦听有 Go 源文件存在的目录,也不会在新建文件和文件夹出现的时候自动加入侦听。这和以前的逻辑偏差太大。恐怕不能接受

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是不是做成配置的形式就可以接受了呢,另外监控go文件应该是合理的,如果想要监控其他的类型,比如html这就需要把这部分从配置里读取出来了。

新建文件夹会加入监听的啊。后半部分你讲的我不是太明白

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

晚上我们再联系,白天忙上班。

*paths = append(*paths, directory)
haveDir = true
}
}
}