diff --git a/lib/builder.go b/lib/builder.go index 345337c..8237c76 100644 --- a/lib/builder.go +++ b/lib/builder.go @@ -3,9 +3,9 @@ package gin import ( "fmt" "os/exec" - "path/filepath" "runtime" "strings" + "sync" ) type Builder interface { @@ -19,11 +19,11 @@ type builder struct { binary string errors string useGodep bool - wd string buildArgs []string + mutex *sync.Mutex } -func NewBuilder(dir string, bin string, useGodep bool, wd string, buildArgs []string) Builder { +func NewBuilder(dir string, bin string, useGodep bool, buildArgs []string) Builder { if len(bin) == 0 { bin = "bin" } @@ -35,7 +35,9 @@ func NewBuilder(dir string, bin string, useGodep bool, wd string, buildArgs []st } } - return &builder{dir: dir, binary: bin, useGodep: useGodep, wd: wd, buildArgs: buildArgs} + m := &sync.Mutex{} + + return &builder{dir: dir, binary: bin, useGodep: useGodep, buildArgs: buildArgs, mutex: m} } func (b *builder) Binary() string { @@ -47,13 +49,15 @@ func (b *builder) Errors() string { } func (b *builder) Build() error { - args := append([]string{"go", "build", "-o", filepath.Join(b.wd, b.binary)}, b.buildArgs...) + args := append([]string{"go", "build", "-o", b.binary}, b.buildArgs...) var command *exec.Cmd if b.useGodep { args = append([]string{"godep"}, args...) } + b.mutex.Lock() command = exec.Command(args[0], args[1:]...) + b.mutex.Unlock() command.Dir = b.dir diff --git a/main.go b/main.go index 2da9b60..58d2c82 100644 --- a/main.go +++ b/main.go @@ -3,21 +3,21 @@ package main import ( "errors" "fmt" - - "github.com/codegangsta/envy/lib" - "github.com/codegangsta/gin/lib" - shellwords "github.com/mattn/go-shellwords" - "gopkg.in/urfave/cli.v1" - - "github.com/0xAX/notificator" "log" "os" "os/signal" "path/filepath" "strconv" "strings" + "sync" "syscall" "time" + + "github.com/0xAX/notificator" + envy "github.com/codegangsta/envy/lib" + gin "github.com/ezoic/gin/lib" + "github.com/mattn/go-shellwords" + "gopkg.in/urfave/cli.v1" ) var ( @@ -60,19 +60,19 @@ func main() { Name: "bin,b", Value: "gin-bin", EnvVar: "GIN_BIN", - Usage: "name of generated binary file", + Usage: "path to generated binary file, defaults to current working directory", }, - cli.StringFlag{ + cli.StringSliceFlag{ Name: "path,t", - Value: ".", + Value: &cli.StringSlice{}, EnvVar: "GIN_PATH", - Usage: "Path to watch files from", + Usage: "Paths to watch files from", }, cli.StringFlag{ Name: "build,d", Value: "", EnvVar: "GIN_BUILD", - Usage: "Path to build files from (defaults to same value as --path)", + Usage: "Path to build files from (defaults to first value of --path)", }, cli.StringSliceFlag{ Name: "excludeDir,x", @@ -169,12 +169,22 @@ func MainAction(c *cli.Context) { logger.Fatal(err) } + bin := c.GlobalString("bin") + if strings.HasPrefix(bin, string(filepath.Separator)) == false { + bin = filepath.Join(wd, bin) + } + + watchPaths := c.GlobalStringSlice("path") + if len(watchPaths) == 0 { + watchPaths = []string{"."} + } + buildPath := c.GlobalString("build") if buildPath == "" { - buildPath = c.GlobalString("path") + buildPath = watchPaths[0] } - builder := gin.NewBuilder(buildPath, c.GlobalString("bin"), c.GlobalBool("godep"), wd, buildArgs) - runner := gin.NewRunner(filepath.Join(wd, builder.Binary()), c.Args()...) + builder := gin.NewBuilder(buildPath, bin, c.GlobalBool("godep"), buildArgs) + runner := gin.NewRunner(bin, c.Args()...) runner.SetWriter(os.Stdout) proxy := gin.NewProxy(builder, runner) @@ -203,7 +213,7 @@ func MainAction(c *cli.Context) { build(builder, runner, logger) // scan for changes - scanChanges(c.GlobalString("path"), c.GlobalStringSlice("excludeDir"), all, func(path string) { + scanChangesForPaths(watchPaths, c.GlobalStringSlice("excludeDir"), all, func(path string) { runner.Kill() build(builder, runner, logger) }) @@ -260,6 +270,15 @@ func build(builder gin.Builder, runner gin.Runner, logger *log.Logger) { type scanCallback func(path string) +func scanChangesForPaths(watchPaths, excludeDirs []string, allFiles bool, cb scanCallback) { + wg := sync.WaitGroup{} + wg.Add(1) + for _, p := range watchPaths { + go scanChanges(p, excludeDirs, allFiles, cb) + } + wg.Wait() +} + func scanChanges(watchPath string, excludeDirs []string, allFiles bool, cb scanCallback) { for { filepath.Walk(watchPath, func(path string, info os.FileInfo, err error) error {