Skip to content

Instantly share code, notes, and snippets.

@ahoward
Created January 5, 2012 22:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahoward/1567682 to your computer and use it in GitHub Desktop.
Save ahoward/1567682 to your computer and use it in GitHub Desktop.
runs an arbitrary commands when files change
#! /usr/bin/env ruby
## rego command to run -- files to watch
#
# rego command_to_run on @ -- {lib/*,test/*}
#
require 'time'
require 'pathname'
require 'rubygems'
pos = ARGV.index('--')
if pos
command = ARGV[0...pos].join(' ')
paths = ARGV[pos + 1 .. -1]
else
command = ARGV[0..-1].join(' ')
paths = []
end
command = 'echo @' if paths.empty?
paths = %w[.] if paths.empty?
paths.map!{|path| test(?d, path) ? [path, Dir.glob(File.join(path, '**/**'))] : path}
paths.flatten!
paths.compact!
paths.uniq!
paths.map! do |path|
Pathname.new(path).realpath.to_s
end
##
#
require 'yaml'
#STDERR.puts({command => paths}.to_yaml)
#STDERR.puts
puts "## #{ command }"
puts "#"
puts paths.join("\n")
puts
##
#
directories = []
files = []
paths.each do |path|
if test(?d, path)
directories.push(path)
else
files.push(path)
directories.push(File.dirname(path))
end
end
directories.uniq!
files.uniq!
stats = {}
files.each do |file|
begin
stats[file] = File.stat(file)
rescue
nil
end
end
require 'rb-fsevent'
fsevent = FSEvent.new
n = '0'
line = '#' * 42
$running = false
rego = proc do |*args|
entry = args.shift
cmd = entry ? command.gsub(/@/, entry) : command
puts line
puts "# rego.#{ n } @ #{ Time.now.strftime('%H:%M:%S') } - #{ cmd }"
puts
system(cmd)
puts
puts "# rego.#{ n } @ #{ Time.now.strftime('%H:%M:%S') } - #{ $?.exitstatus }"
puts
n.succ!
end
rego[ false ]
fsevent.watch(directories) do |*args|
unless $running
$running = true
args.flatten.each do |dir|
glob = File.join(dir, '**/**')
entries = Dir.glob(glob)
entries.each do |entry|
entry = File.expand_path(entry)
next unless stats.has_key?(entry)
begin
stats[entry] ||= File.stat(entry)
before = stats[entry]
after = File.stat(entry)
rescue
next
end
unless before.mtime == after.mtime
stats[entry] = after
rego[ entry ]
end
end
end
end
$running = false
end
fsevent.run
=begin
require 'rb-inotify'
notifier = INotify::Notifier.new
notifier.watch(paths, :modify) {puts "foo.txt was modified!"}
#notifier.watch("path/to/bar", :moved_to, :create) do |event|
#puts "#{event.name} is now in path/to/bar!"
#end
notifier.run
=end
#exit
=begin
require 'directory_watcher'
dw = DirectoryWatcher.new(paths, :scanner => :rev)
dw.add_observer do |*args|
args.each{|event| puts event}
end
dw.start
trap('INT'){ exit! }
sleep
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment