go-godo / godo

golang build tool in the spirt of rake, gulp
MIT License
535 stars 31 forks source link

How to kill processing tree when using Start and watch? #21

Closed txchen closed 9 years ago

txchen commented 9 years ago
p.Task("server", W{"**/*.go"}, Debounce(500), func() {
    // rebuilds and restarts the process when a watched file changes
    Start("go run goweb.go", In{"."})
})

Here is my task example. When I run godo watch --watch and trigger some file changes, it would kill the go run goweb.go process, but that one's child, the actual working process, is not killed. Then the port is still taken by it, the 2nd process cannot start correctly. Basically, watch mode cannot work correctly in my case.

The reason I am using go run is because for small projects that only has main package, I don't place them in my $GOPATH, so it cannot run go install.

How should I change my task? Thanks!

mgutz commented 9 years ago

I run projects outside of $GOPATH. I just ran godo server -w inside a temp directory containing these files. Does this simple example work for you?

Also you may have to kill zombie processes since you used go run and it errored. Try ps | grep go run

goweb.go

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

tasks/Godofile.go

package main

import . "gopkg.in/godo.v1"

func tasks(p *Project) {
    p.Task("server", W{"**/*.go"}, Debounce(500), func() {
        Start("goweb.go")
    })
}

func main() {
    Godo(tasks)
}
txchen commented 9 years ago

@mgutz thanks! however seems this does not work for me.

> godo server --w
go install: no install location for directory /Users/txchen/localcode/goweb outside GOPATH
server 64ms
server watching . ...

It could not go install, and the server is not launched.

txchen commented 9 years ago
package main

import . "gopkg.in/godo.v1"

func Tasks(p *Project) {
    p.Task("server", W{"**/*.go"}, Debounce(500), func() {
        // rebuilds and restarts the process when a watched file changes
        Run("go build goweb.go")
        Start("./goweb")
    })
}

func main() {
    Godo(Tasks)
}

I use this, and it can work. The only issue is it would generate the binary inside the project folder. It would be nice if Start("goweb.go") can just work like what @mgutz mentioned.

txchen commented 9 years ago

Another issue I found is; if I use Run("go build *.go") or Run("go run *.go"), it would complain stat *.go: no such file or directory

If my temp project has multiple .go files, I cannot figure out how to watch and build automatically.

mgutz commented 9 years ago

You cannot use "go build .go" because that uses Go's built-in exec.Command(). Wildcards are handled by the shell. You should use `Bash("go build go")` for shell commands.

txchen commented 9 years ago

Thanks, I didn't know * is handled by shell.

Yeah Bash("go run *.go") can work, but Bash cannot async, it cannot work in watch mode.

Could you try to figure out why you can do Start("goweb.go") outside $GOPATH? If it invokes go install, I don't think it can work...

mgutz commented 9 years ago

As for the binary being built inside the folder, there is no way around it. Go's tools are meant to work inside $GOPATH. go run spawns a child process, as you have seen, which I cannot kill. The work around is to go install which builds everything correctly. go build caches object files.

I just add a .gitignore entry for the generated file. In your example you don't need Run, just Start.

txchen commented 9 years ago

:smile: I wish just Start can work, but as I mentioned, I am getting go install: no install location for directory /Users/txchen/localcode/goweb outside GOPATH

I am closing this since I have found a workaround.

Anyway, thank you so much for your help, @mgutz

mgutz commented 9 years ago

OK, some people say that error is sometimes caused by $GOPATH missing directories. It should have $GOPATH/{bin,pkg,src}

txchen commented 9 years ago

I am pretty sure I have a correct and working $GOPATH :) Otherwise, godo itself cannot work after go get.

mgutz commented 9 years ago

I'm stumped. Sorry I couldn't help.