Watches for changes in a directory tree and reruns a command in an acme win or just on the terminal.

Watch

Usage: Watch [-v] [-t] [-p <path>] [-x <regexp>] <command>

Watches for changes in a directory tree, and runs a command when something changed. By default, the output goes to an acme win.

-t sends the output to the terminal instead of acme

-v enables verbose debugging output

-p specifies the path to watch (if it is a directory then it watches recursively)

-x specifies a regexp used to exclude files and directories from the watcher.

Comments
  • Avoid syscalls

    Avoid syscalls

    These aren't covered by the Go compatibility promise and are questionably portable. I at least want to get rid of the Wait4 polling, because it's orthogonal to the race described in #14 (which was due to global PID flim-flammery).

  • Watch uses tons of cpu time

    Watch uses tons of cpu time

    Hiya, a few days ago I finally got around to checking out Watch and its a fantastic addition to the workflow, so thanks!

    Today I noticed my laptop was getting hot though, and sure enough top revealed my four Watch instances consuming 70-80% cpu between them, despite no action on the filesystem.

    These instances had been open for several days through several sleep/resume cycles which may or may not be related. A newly spawned Watch instance does not use excessive CPU.

    Not sure if this will actually turn out to be a bug in Watch, as kill -ABRT on one of the instances showed only these two goroutines active:

    goroutine 0 [idle]:
    runtime.futex(0x6d2e38, 0x0, 0x0, 0x0, 0x0, 0x6d27c0, 0x1, 0x41198f, 0x411bae, 0x6d2e38, ...)
        /usr/lib/go/src/runtime/sys_linux_amd64.s:277 +0x21
    runtime.futexsleep(0x6d2e38, 0x0, 0xffffffffffffffff)
        /usr/lib/go/src/runtime/os_linux.c:49 +0x47
    runtime.notesleep(0x6d2e38)
        /usr/lib/go/src/runtime/lock_futex.go:145 +0xae
    stopm()
        /usr/lib/go/src/runtime/proc.c:1178 +0x119
    findrunnable(0xc208012000)
        /usr/lib/go/src/runtime/proc.c:1487 +0x562
    schedule()
        /usr/lib/go/src/runtime/proc.c:1575 +0x151
    exitsyscall0(0xc208000a20)
        /usr/lib/go/src/runtime/proc.c:2021 +0xdd
    runtime.mcall(0x435cc4)
        /usr/lib/go/src/runtime/asm_amd64.s:186 +0x5a
    
    goroutine 7 [syscall]:
    syscall.Syscall6(0xe8, 0x6, 0xc2080a9cb4, 0x7, 0xffffffffffffffff, 0x0, 0x0, 0x8, 0xc20802a2e8, 0x7f84169fc8f0)
        /usr/lib/go/src/syscall/asm_linux_amd64.s:46 +0x5
    syscall.EpollWait(0x6, 0xc2080a9cb4, 0x7, 0x7, 0xffffffffffffffff, 0xc20802a2e8, 0x0, 0x0)
        /usr/lib/go/src/syscall/zsyscall_linux_amd64.go:376 +0x93
    github.com/go-fsnotify/fsnotify.(*fdPoller).wait(0xc20801e2c0, 0xc208052700, 0x0, 0x0)
        /d/go/src/github.com/go-fsnotify/fsnotify/inotify_poller.go:85 +0xc7
    github.com/go-fsnotify/fsnotify.(*Watcher).readEvents(0xc20800a370)
        /d/go/src/github.com/go-fsnotify/fsnotify/inotify.go:179 +0x16f
    created by github.com/go-fsnotify/fsnotify.NewWatcher
        /d/go/src/github.com/go-fsnotify/fsnotify/inotify.go:58 +0x32b
    

    (the other four goroutines had been blocked for 28 minutes)

    I realise this report is probably not sufficient to solve/understand the issue. At some point I'll dig into the Watch/fsnotify code to try and gather more information, but if someone beats me to it I'm not going to complain ;)

    go version go1.4.2 linux/amd64

  • Get should cancel running commands.

    Get should cancel running commands.

    The acme win should have a Cancel that would cancel the current execution, for when you spot a bug but are already running an eggrigerously long build.

  • -x only works for directories

    -x only works for directories

    eg. with no exclusions, Watch -v -t echo build

    touch .git/newfile => causes build touch .gitignore => causes build

    Now try Watch -v -t -x '.git.*' echo build Debug output says:

    2015/08/27 14:15:36 DEBUG: excluding .git
    2015/08/27 14:15:36 DEBUG: excluding .gitignore
    

    but then:

    touch .gitignore => causes build

    touch .git/newfile is however correctly ignored.

  • Fix goroutine leaks.

    Fix goroutine leaks.

    The wait function was leaking a goroutine via time.Tick.

    Also—and I'm not sure this was an actual problem—Cmd.Start appers to create goroutines to be cleaned up by Cmd.Wait. Since we never called Cmd.Wait, these will be leaked too. So, we just call cmd.Wait as a dummy after Wait4.

    Fixes #20.

  • Fix clumsy race in run/kill

    Fix clumsy race in run/kill

    In retrospect, this is obviously fixed by using a channel: Run selects between the kill channel and a default case with a non-blocking wait. If it gets kill once, SIGTERM; twice, SIGKILL (there you go, Steve) and nil the kill channel to stop this case. When killed, Wait will fire. No more race. No need for global pid, no "lock vomit." But we will need the shared channel.

  • Option to pass changes to subprocess

    Option to pass changes to subprocess

    Something like -w to invoke the command with what has changed. E.g. (details omitted):

    % Watch -t -w echo &
    % touch hi
    hi
    % touch hi blop
    hi blop
    %
    
  • Watching inside git repo = too many open files

    Watching inside git repo = too many open files

    Hi

    When running inside a Git repo it attempts to watch all the files the .git directory, this results in too many open file errors.

    Solution would be to allow the user to create a .watch file in which you can write exclude or include regex rules.

    Here is my debug outout from OSX.

    ↳ Watch -t -d go test
    2014/01/21 09:30:34 DEBUG: Watching .git/hooks
    2014/01/21 09:30:34 DEBUG: Watching .git/info
    2014/01/21 09:30:34 DEBUG: Watching .git/logs/refs/heads
    2014/01/21 09:30:34 DEBUG: Watching .git/logs/refs/remotes/origin
    2014/01/21 09:30:34 DEBUG: Watching .git/logs/refs/remotes
    2014/01/21 09:30:34 DEBUG: Watching .git/logs/refs
    2014/01/21 09:30:34 DEBUG: Watching .git/logs
    2014/01/21 09:30:34 DEBUG: Watching .git/objects/02
    2014/01/21 09:30:34 DEBUG: Watching .git/objects/03
    ...
    lots of git files
    ...
    2014/01/21 09:30:34 DEBUG: Watching .git
    2014/01/21 09:30:34 DEBUG: Watching .
    go test
    fork/exec /usr/local/go/bin/go: too many open files
    2014-01-21 09:30:34.391614237 +0000 GMT
    

    Chris

  • Fix -x not working for plain files

    Fix -x not working for plain files

    Since changing a file also results in a change to the containing directory, excluding files from the watch list is not sufficient. The exclusion filter must also be applied when processing events.

    Closes #25.

  • Doesn't built on Windows

    Doesn't built on Windows

    d:\>go get github.com/eaburns/Watch \# github.com/eaburns/Watch d:\src\github.com\eaburns\Watch\main.go:158: undefined: syscall.Kill d:\src\github.com\eaburns\Watch\main.go:161: undefined: syscall.Kill d:\src\github.com\eaburns\Watch\main.go:168: undefined: syscall.Wait4 d:\src\github.com\eaburns\Watch\main.go:168: undefined: syscall.WNOHANG

  • Restart running command

    Restart running command

    Any thoughts on a mode where Watch restarts the command whenever a change is detected? This goes deep into the process management hell, so I understand if you'd rather punt this to some other utility.

  • No synchronization between writing stdout and writing

    No synchronization between writing stdout and writing "exit status" and end time message

    The exit status and end time often get interleaved with the writing of stdout/stderr. Instead, we should write stdout and stderr in our own go routine, wait for it to finish, and only then write these trailing messages.

Related tags
A modern and intuitive terminal-based text editor
A modern and intuitive terminal-based text editor

micro is a terminal-based text editor that aims to be easy to use and intuitive, while also taking advantage of the capabilities of modern terminals.

Dec 30, 2022
A terminal based game that teaches you how to use Vim.
A terminal based game that teaches you how to use Vim.

VimMan Learn how to use Vim in its natural environment, the Terminal! About VimMan is terminal program that's a semi editor and a semi game. The purpo

Dec 5, 2022
A Golang plugin collection for SublimeText 3, providing code completion and other IDE-like features.

GoSublime Intro GoSublime is an IDE-like plugin for Sublime Text 3 mainly, but not limited to, providing integration for most of your Go/Golang develo

Jan 4, 2023
watch for file changes (matching a suffix whitelist) in a directory tree and run a command when they change

watchspawn what is it? Watches for file creates and writes in and below the current directory and when any of them (matching a suffix list) change, ru

Jan 16, 2022
Watcher - A simple command line app to watch files in a directory for changes and run a command when files change!

Watcher - Develop your programs easily Watcher watches all the files present in the directory it is run from of the directory that is specified while

Mar 27, 2022
Watches container registries for new and changed tags and creates an RSS feed for detected changes.

Tagwatch Watches container registries for new and changed tags and creates an RSS feed for detected changes. Configuration Tagwatch is configured thro

Jan 7, 2022
Ghdl - A much more convenient way to download GitHub release binaries on the command line, works on Win & Unix-like systems

ghdl Memorize ghdl as github download ghdl is a fast and simple program (and als

Oct 12, 2022
A cross platform desktop service that watches custom folders for file changes and updates the corresponding database in Notion.

A cross platform desktop service that watches custom folders for file changes and updates the corresponding database in Notion. Perfect for tracking reading lists

Mar 12, 2022
ChangeTower is intended to help you watch changes in webpages and get notified of any changes written in Go

ChangeTower is intended to help you watch changes in webpages and get notified of any changes written in Go

Nov 17, 2022
Tree style (files) explorer for p9p acme.

xplor, a tree-style (file) explorer for (plan9port) Acme screenshot, regular screenshot, monospaced Xplor is written for Acme, the Plan 9 text editing

Nov 25, 2021
Turn .mp3 files in current directory to a podcast feed just one command.

dir2cast Turn .mp3 files in current directory to a podcast feed just one command. Then you can subscribe to it with your favorite podcast client, down

Jun 27, 2022
apicompat checks recent changes to a Go project for backwards incompatible changes

Introduction apicompat is a tool to check for the introduction of backwards incompatible changes. apicompat: Guarantees that all consumers of a librar

Dec 24, 2022
Simple and lightweight SSH git hosting with just a directory.

go-gitdir This project makes it incredibly easy to host a secure git server with a config that can be easily rolled back. It aims to solve a number of

Dec 20, 2022
Tool for printing a directory tree and indicating the space it occupies.

Tool for printing a directory tree and indicating the space it occupies.

Nov 6, 2021
Simple code just to try out and Binary Tree on Golang.

Character counter | ▮▮▮▮▮▮▮▮ Simple code just to try out and Binary Tree on Golang. Count characters to train openning a file and reading it, as well

May 17, 2022
FSManager - Tree view Simple util to displays the directory structure of a path or of the disk in a drive graphically.

FSManager - Tree view Simple util to displays the directory structure of a path or of the disk in a drive graphically. If you don't specify a drive or

Oct 9, 2021
Just an itsy bitsy b-tree in Go

tinybtree Just an itsy bitsy b-tree. Usage Keys are strings, values are interfaces. Functions Get(key string) (value interface{}, gotten bool) Set(key

Dec 25, 2022
Exp-tree: go library for parsing expression tree

Vinshop expression tree Exp-tree is go library for parsing expression tree Installation go get -u github.com/vinshop/exp-tree Quick start Format Expre

May 11, 2022