Watcher
by Peter.
In doing Python development I’ve found that pyflakes is a great tool to catch stupid errors before I’m halfway through a long run and it fails. However, it only runs once. Inspired by sbt’s ~ option, I whipped up a generic Python program to call another program whenever one or more of the given files change. The only requirements are Growl and growl-py, which can easily be removed.
#!/usr/bin/env python import sys import os import subprocess import sched import time from Growl import GrowlNotifier def run(): if (len(sys.argv) < 3): print 'Usage: watcher files command' return False relative_files = sys.argv[1:-1] command = sys.argv[-1] # subtract 1 from the timestamps so that the script is called on the initial versions of the files files = [{'file': f, 'ts': os.path.getmtime(f) - 1} for f in relative_files] # Growl growl = GrowlNotifier(applicationName='watcher', notifications=['File(s) changed']) growl.register() interval = 1.0 s = sched.scheduler(time.time, time.sleep) def doWork(sc): modified_files = [] command_list = [command] for k, v in enumerate(files): f = files[k]['file'] ts = os.path.getmtime(f) if (files[k]['ts'] < ts): modified_files.append(f) files[k]['ts'] = ts if len(modified_files) > 0: command_list.extend(modified_files) print '-' * 10 output = subprocess.Popen(command_list, stdout=subprocess.PIPE).communicate()[0].strip() if output: print output growl.notify('File(s) changed', 'Watcher', 'There are problems in one or more of %d file(s).' % len(modified_files)) else: print 'OK' growl.notify('File(s) changed', 'Watcher', 'Problems fixed.') sc.enter(interval, 1, doWork, (sc,)) s.enter(interval, 1, doWork, (s,)) s.run() if __name__ == '__main__': sys.exit(run()) |
I also added the following alias to my ~/.profile
:
alias watcher="python /Users/peter/watcher.py" |
I use the script like so:
watcher *.py *.tac pyflakes |