Skip to content

Commit

Permalink
added --dontwait and --restart options
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasfl committed Feb 6, 2015
1 parent 5172c69 commit ae25791
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 10 deletions.
9 changes: 8 additions & 1 deletion README.md
Expand Up @@ -84,6 +84,13 @@ filesystem gets updated:

$ filewatcher "src test" "ruby test/test_suite.rb"

Automatic restart of processes
------------------------------

The `--restart` option restarts the command when changes happens on the file system. The `--dontwait` starts the command when filewatcher is started. To start a webserver and have it automatically restart when html files are updated:

$ filewatcher --dontwait --restart "*.html" "python -m SimpleHTTPServer"

Available enviroment variables
------------------------------

Expand Down Expand Up @@ -209,4 +216,4 @@ Note on Patches/Pull Requests
Copyright
---------

Copyright (c) 2011 - 2014 Thomas Flemming. See LICENSE for details.
Copyright (c) 2011 - 2015 Thomas Flemming. See LICENSE for details.
2 changes: 2 additions & 0 deletions Rakefile
Expand Up @@ -3,6 +3,8 @@ require 'rake'
require 'rake/testtask'

task :default => :test

desc "Run tests"
task :test do
sh "bacon -Ilib -Itest --automatic --quiet"
end
68 changes: 62 additions & 6 deletions bin/filewatcher
Expand Up @@ -3,9 +3,10 @@ require 'rubygems'
require 'filewatcher'
require 'trollop'
require 'pathname'
require 'thread'

options = Trollop::options do
version "filewatcher, version #{FileWatcher.VERSION} by Thomas Flemming 2014"
version "filewatcher, version #{FileWatcher.VERSION} by Thomas Flemming 2015"
banner <<-EOS
Filewatcher scans the filesystem and executes shell commands when files changes.
Expand All @@ -22,11 +23,13 @@ Examples:
Options:
EOS

opt :interval, "Interval to scan filesystem. Defaults to 0.5 seconds.", :short => 'i', :type => :float, :default => 0.5
opt :dontwait, "Do not wait for filesystem updates before running", :short => 'd', :type => :boolean, :default => false
opt :restart, "Restart process when filesystem is updated", :short => 'r', :type => :boolean, :default => false
opt :list, "Print name of files being watched"
opt :exec, "Execute file as a script when file is updated.", :short => 'e', :type => :boolean, :default => false
opt :include, "Include files", :type => :string, :default => "*"
opt :exclude, "Exclude file(s) matching", :type => :string, :default => ""
opt :list, "Print name of files being watched"
opt :interval, "Interval to scan filesystem. Defaults to 0.5 seconds.", :short => 'i', :type => :float, :default => 0.5
end

Trollop::die "must have at least one argument" if(ARGV.size == 0)
Expand Down Expand Up @@ -56,7 +59,45 @@ end

files = split_files_void_escaped_whitespace(files)

FileWatcher.new(files, options[:list]).watch(options[:interval]) do |filename, event|
def fork_process(env, cmd)
pipe_read, pipe_write = IO.pipe
fork do
pipe_read.close
pipe_write.write Process.spawn(env,cmd).to_s
exit
end

Kernel.sleep 1
pipe_write.close
child_pid = pipe_read.read.to_i
pipe_read.close
return child_pid
end

def kill_process(child_pid)
still_running = true
begin
Process.kill(1, child_pid)
rescue Errno::ESRCH
still_running = false
end
while still_running do
begin
Process.getpgid( child_pid)
still_running = true
rescue Errno::ESRCH
still_running = false
end
Kernel.sleep 0.1
end
end

if(options[:restart])
rd, wr = IO.pipe
child_pid = nil
end

FileWatcher.new(files, options[:list], options[:dontwait]).watch(options[:interval]) do |filename, event|
cmd = nil
if(options[:exec] and File.exist?(filename))
extension = filename[/(\.[^\.]*)$/,0]
Expand Down Expand Up @@ -91,8 +132,23 @@ FileWatcher.new(files, options[:list]).watch(options[:interval]) do |filename, e
if(event != :delete)
ENV['FILEPATH'] = path.realpath.to_s
end
pid = Process.spawn(env, cmd);
pid = Process.wait();

if(options[:restart])
if(child_pid == nil)
child_pid = fork_process(env, cmd)
else
kill_process(child_pid)
child_pid = fork_process(env, cmd)
end
else
begin
pid = Process.spawn(env, cmd)
Process.wait()
rescue SystemExit, Interrupt
exit(0)
end
end

else
case(event)
when :changed
Expand Down
9 changes: 6 additions & 3 deletions lib/filewatcher.rb
Expand Up @@ -6,14 +6,14 @@ class FileWatcher
attr_accessor :filenames

def self.VERSION
return '0.3.6'
return '0.4.0'
end

def initialize(unexpanded_filenames, print_filelist=false)
def initialize(unexpanded_filenames, print_filelist=false, dontwait=false)
@unexpanded_filenames = unexpanded_filenames
@last_mtimes = { }
@filenames = expand_directories(@unexpanded_filenames)

@dontwait = dontwait
puts 'Watching:' if print_filelist
@filenames.each do |filename|
raise 'File does not exist' unless File.exist?(filename)
Expand All @@ -23,6 +23,9 @@ def initialize(unexpanded_filenames, print_filelist=false)
end

def watch(sleep=1, &on_update)
if(@dontwait)
yield '',''
end
loop do
begin
Kernel.sleep sleep until filesystem_updated?
Expand Down

0 comments on commit ae25791

Please sign in to comment.