Esempio n. 1
0
func rerun(buildpath string, args []string) (err error) {
	log.Printf("setting up %s %v", buildpath, args)

	pkg, err := build.Import(buildpath, "", 0)
	if err != nil {
		return
	}

	if pkg.Name != "main" {
		err = errors.New(fmt.Sprintf("expected package %q, got %q", "main", pkg.Name))
		return
	}

	_, binName := path.Split(buildpath)
	binPath := filepath.Join(pkg.BinDir, binName)

	runch := run(binName, binPath, args)

	var errorOutput string
	_, errorOutput, ierr := install(buildpath, errorOutput)
	if ierr == nil {
		runch <- true
	}

	var watcher *fsnotify.Watcher
	watcher, err = getWatcher(buildpath)
	if err != nil {
		return
	}

	for {
		we, _ := <-watcher.Event
		var installed bool
		installed, errorOutput, _ = install(buildpath, errorOutput)
		if installed {
			log.Print(we.Name)
			runch <- true
			watcher.Close()
			/* empty the buffer */
			go func(events chan *fsnotify.FileEvent) {
				for _ = range events {

				}
			}(watcher.Event)
			go func(errors chan error) {
				for _ = range errors {

				}
			}(watcher.Error)
			/* rescan */
			log.Println("rescanning")
			watcher, err = getWatcher(buildpath)
			if err != nil {
				return
			}
		}
	}
	return
}
Esempio n. 2
0
func (t *InotifyTracker) CloseWatcher(w *fsnotify.Watcher) (err error) {
	t.mux.Lock()
	defer t.mux.Unlock()
	if _, ok := t.watchers[w]; ok {
		err = w.Close()
		delete(t.watchers, w)
	}
	return
}
Esempio n. 3
0
func main() {

	var (
		err            error
		watcher        *fsnotify.Watcher
		done           chan bool
		includePattern string
		include        *regexp.Regexp
		watchedFile    string
	)

	flag.StringVar(&watchedFile, "watch", "none", `Directory to watch for modification events`)
	flag.StringVar(&includePattern, "include", "", `Filename pattern to include (regex)`)
	flag.Parse()

	include = nil
	if includePattern != "" {
		include = regexp.MustCompile(includePattern)
	}

	watcher, err = fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}

	done = make(chan bool)

	go func(include *regexp.Regexp, hdlr modifyHandler) {
		for {
			select {
			case ev := <-watcher.Event:
				// log.Println("event:", ev)
				if include == nil || include.MatchString(ev.Name) {
					if ev.IsModify() || ev.IsCreate() {
						log.Printf("Calling handler\n")
						hdlr(ev.Name, "make")
					}
				}
			case err := <-watcher.Error:
				log.Println("error:", err)
			}
		}
	}(include, triggerCmd)

	err = watcher.Watch(watchedFile)
	if err != nil {
		fmt.Printf("%s: %v\n", watchedFile, err)
		os.Exit(1)
	}

	<-done

	watcher.Close()
}
Esempio n. 4
0
func (db *DB) watchEvents(watcher *fsnotify.Watcher) {
	for {
		select {
		case ev := <-watcher.Event:
			if ev.Name == db.file && (ev.IsCreate() || ev.IsModify()) {
				db.openFile()
			}
		case <-watcher.Error:
		case <-db.notifyQuit:
			watcher.Close()
			return
		}
		time.Sleep(time.Second) // Suppress high-rate events.
	}
}
Esempio n. 5
0
func watch(watcher *fsnotify.Watcher, dir string, handler func(name string)) {
	defer watcher.Close()

	err := recursive(watcher, dir)

	if err != nil {
		return
	}

	for {
		select {
		case ev := <-watcher.Event:
			if ev.IsCreate() {
				recursive(watcher, ev.Name)
			}

			handler(ev.Name)
		case <-watcher.Error:
			// nothing to do for now
		}
	}
}
Esempio n. 6
0
func rerun(buildpath string, args []string) (err error) {
	log.Printf("setting up %s %v", buildpath, args)

	pkg, err := build.Import(buildpath, "", 0)
	if err != nil {
		return
	}

	if pkg.Name != "main" {
		err = errors.New(fmt.Sprintf("expected package %q, got %q", "main", pkg.Name))
		return
	}

	_, binName := path.Split(buildpath)
	var binPath string

	if *outfile != "" {
		if *outfile == "getwd" {
			p, err := os.Getwd()
			if err == nil {
				binPath = filepath.Join(p, binName)
			} else {
				panic("Can't usw getwd: " + err.Error())
			}
		} else {
			p, err := filepath.Abs(*outfile)
			if err == nil {
				binPath = filepath.Join(p, binName)
			} else {
				panic("Can't usw abs: " + err.Error())
			}
		}
	} else {
		if gobin := os.Getenv("GOBIN"); gobin != "" {
			binPath = filepath.Join(gobin, binName)
		} else {
			binPath = filepath.Join(pkg.BinDir, binName)
		}
	}

	var runch chan bool
	if !(*never_run) {
		runch = run(binName, binPath, args)
	}

	no_run := false
	if *do_tests {
		passed, _ := test(buildpath)
		if !passed {
			no_run = true
		}
	}

	if *do_build && !no_run {
		gobuild(buildpath)
	}

	var errorOutput string
	_, errorOutput, ierr := install(buildpath, errorOutput)
	if !no_run && !(*never_run) && ierr == nil {
		runch <- true
	}

	var watcher *fsnotify.Watcher
	watcher, err = getWatcher(buildpath)
	if err != nil {
		return
	}

	for {
		// read event from the watcher
		we, _ := <-watcher.Event
		// other files in the directory don't count - we watch the whole thing in case new .go files appear.
		if filepath.Ext(we.Name) != ".go" {
			continue
		}

		log.Print(we.Name)

		// close the watcher
		watcher.Close()
		// to clean things up: read events from the watcher until events chan is closed.
		go func(events chan *fsnotify.FileEvent) {
			for _ = range events {

			}
		}(watcher.Event)
		// create a new watcher
		log.Println("rescanning")
		watcher, err = getWatcher(buildpath)
		if err != nil {
			return
		}

		// we don't need the errors from the new watcher.
		// we continiously discard them from the channel to avoid a deadlock.
		go func(errors chan error) {
			for _ = range errors {

			}
		}(watcher.Error)

		var installed bool
		// rebuild
		installed, errorOutput, _ = install(buildpath, errorOutput)
		if !installed {
			continue
		}

		if *do_tests {
			passed, _ := test(buildpath)
			if !passed {
				continue
			}
		}

		if *do_build {
			gobuild(buildpath)
		}

		// rerun. if we're only testing, sending
		if !(*never_run) {
			runch <- true
		}
	}
	return
}
Esempio n. 7
0
func watch(command, importable, bin, exts string, dobuild, watchbuild, withdir bool, args []string) error {
	log.Printf("Command: %s %s %s %t", command, importable, bin, dobuild)

	extcls := multispaces.ReplaceAllString(exts, " ")
	extens := multispaces.Split(extcls, -1)

	if len(extens) == 1 && extens[0] == "" {
		extens = extens[:0]
	}

	var buildName string
	var ubin string

	var buildHandler = func() error {
		var pkgs *build.Package
		var err error
		pkgs, err = build.Import(importable, "", 0)

		if err != nil {
			return err
		}

		_, buildName = path.Split(pkgs.ImportPath)
		// _, buildName := path.Split("./")

		wd, _ := os.Getwd()
		if bin != "" {
			ubin = filepath.ToSlash(filepath.Join(wd, bin))
		} else {
			ubin = pkgs.BinDir
		}

		// lets install
		_, err = goDeps("./")

		if err != nil {
			log.Printf("go.install.err: %s", err.Error())
			// return err
		}

		log.Printf("Building Pkg %s \nBin: %s \nUsing name: %s", pkgs.ImportPath, ubin, buildName)

		done, err := gobuild(ubin, buildName)

		if err != nil {
			return err
		}

		_ = done
		return nil
	}

	var buildWatch = func() (*fsnotify.Watcher, error) {
		var err error
		var watch *fsnotify.Watcher

		added := make(map[string]bool)

		if watchbuild {
			log.Printf("Watch import Path enabled")
			watch, err = buildPkgWatcher(importable, added)
		} else {
			if !added["./"] {
				watch, err = buildWatcher("./")
			}
		}

		//lets watch the current directory also if allowed
		if withdir && err == nil {
			wod, ex := os.Getwd()

			if ex == nil && wod != "" {
				watchDir(watch, wod, added, []string{ubin})
			}
		}

		return watch, err
	}

	var err error
	var watch *fsnotify.Watcher
	var binRun bool
	var binChan chan bool

	//lets build if we are allowed
	if dobuild {
		if err = buildHandler(); err != nil {
			return err
		}

		binChan = runBin(ubin, buildName, args)
		binRun = true
		binChan <- true
	}

	log.Printf("Building dir watchers.....")
	watch, err = buildWatch()

	if err != nil {
		log.Printf("Unable to build err %s", err.Error())
		return err
	}

	for {

		//should we watch
		we, _ := <-watch.Event

		exo := filepath.Ext(we.Name)

		//if its a .git directory skip it
		if strings.Contains(filepath.ToSlash(we.Name), ".git") {
			continue
		}

		//if its our bin directory skip it
		if filepath.ToSlash(we.Name) == filepath.ToSlash(ubin) {
			continue
		}

		log.Printf("Watch: %s -> %s with extensions: %s", exo, we.Name, extens)

		if len(extens) > 0 {
			var found bool
			for _, mo := range extens {
				if exo == mo {
					found = true
					break
				}
			}

			if !found {
				continue
			}
		}

		log.Printf("Watcher notified change: %s", we.Name)

		watch.Close()

		go func(evs chan *fsnotify.FileEvent) {
			for _ = range evs {
			}
		}(watch.Event)

		log.Printf("Re-initiating watch scans .....")

		if command != "" {
			log.Printf("Running cmd '%s' with result: '%s'", command, goRun(command))
		}

		if dobuild {
			if err = buildHandler(); err != nil {
				return err
			}

			if binRun {
				binChan <- true
			}
		}

		watch, err = buildWatch()

		if err != nil {
			return err
		}

		go func(errors chan error) {
			for _ = range errors {
			}
		}(watch.Error)

	}
}
Esempio n. 8
0
func rerun(buildpath string, args []string) (err error) {
	log.Printf("setting up %s %v", buildpath, args)

	pkg, err := build.Import(buildpath, "", 0)
	if err != nil {
		return
	}

	if pkg.Name != "main" {
		err = errors.New(fmt.Sprintf("expected package %q, got %q", "main", pkg.Name))
		return
	}

	_, binName := path.Split(buildpath)
	var binPath string
	if gobin := os.Getenv("GOBIN"); gobin != "" {
		binPath = filepath.Join(gobin, binName)
	} else {
		binPath = filepath.Join(pkg.BinDir, binName)
	}

	runch := run(binName, binPath, args)

	var errorOutput string
	_, errorOutput, ierr := install(buildpath, errorOutput)
	if ierr == nil {
		runch <- true
	}

	var watcher *fsnotify.Watcher
	watcher, err = getWatcher(buildpath)
	if err != nil {
		return
	}

	for {
		// read event from the watcher
		we, _ := <-watcher.Event
		var installed bool
		installed, errorOutput, _ = install(buildpath, errorOutput)
		if installed {
			log.Print(we.Name)
			// re-build and re-run the application
			runch <- true
			// close the watcher
			watcher.Close()
			// to clean things up: read events from the watcher until events chan is closed.
			go func(events chan *fsnotify.FileEvent) {
				for _ = range events {

				}
			}(watcher.Event)
			// create a new watcher
			log.Println("rescanning")
			watcher, err = getWatcher(buildpath)
			if err != nil {
				return
			}
			// we don't need the errors from the new watcher.
			// therfore we continiously discard them from the channel to avoid a deadlock.
			go func(errors chan error) {
				for _ = range errors {

				}
			}(watcher.Error)
		}
	}
	return
}