From 0caa4c93a00362b3b36e340d2cc541e6f39f7aec Mon Sep 17 00:00:00 2001 From: Patrick Hogan Date: Wed, 22 May 2024 14:45:36 -0500 Subject: [PATCH] Add an option (--filter) to allow filtering change events to modified, added and/or removed --- lib/rerun/options.rb | 5 +++++ lib/rerun/watcher.rb | 23 ++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/rerun/options.rb b/lib/rerun/options.rb index 9707603..639f58b 100644 --- a/lib/rerun/options.rb +++ b/lib/rerun/options.rb @@ -29,6 +29,7 @@ class Options :signal => (windows? ? "TERM,KILL" : "TERM,INT,KILL"), :verbose => false, :wait => 2, + :filter => [:modified, :added, :removed] } def self.parse args: ARGV, config_file: nil @@ -68,6 +69,10 @@ def self.parse args: ARGV, config_file: nil options[:ignore] += [pattern] end + o.on("-f changes", "--filter", "changes to respond to, default = #{DEFAULTS[:filter].join(",")}") do |value| + options[:filter] = value.strip.split(/\s*,\s*/).reject(&:empty?).map(&:to_sym) + end + o.on("--[no-]ignore-dotfiles", "by default, file globs do not match files that begin with a dot. Setting --no-ignore-dotfiles allows you to monitor a relevant file like .env, but you may also have to explicitly --ignore more dotfiles and dotdirs.") do |value| options[:ignore_dotfiles] = value end diff --git a/lib/rerun/watcher.rb b/lib/rerun/watcher.rb index f6eb83f..b09e5b5 100644 --- a/lib/rerun/watcher.rb +++ b/lib/rerun/watcher.rb @@ -32,6 +32,7 @@ def initialize(options = {}, &client_callback) options = { :directory => ".", :pattern => "**/*", + :filter => [:modified, :added, :removed], :priority => 0, :ignore_dotfiles => true, }.merge(options) @@ -39,6 +40,7 @@ def initialize(options = {}, &client_callback) @pattern = options[:pattern] @directories = options[:directory] @directories = sanitize_dirs(@directories) + @filter = options[:filter] @priority = options[:priority] @force_polling = options[:force_polling] @ignore = [options[:ignore]].flatten.compact @@ -57,6 +59,21 @@ def sanitize_dirs(dirs) end end + def filter_changes(modified, added, removed) + changes = { modified: [], added: [], removed: [] } + @filter.each do |change| + case change + when :modified + changes[:modified] = modified + when :added + changes[:added] = added + when :removed + changes[:removed] = removed + end + end + changes + end + def start if @thread then raise RuntimeError, "already started" @@ -64,9 +81,9 @@ def start @thread = Thread.new do @listener = Listen.to(*@directories, only: watching, ignore: ignoring, wait_for_delay: 1, force_polling: @force_polling) do |modified, added, removed| - count = modified.size + added.size + removed.size - if count > 0 - @client_callback.call(:modified => modified, :added => added, :removed => removed) + changes = filter_changes(modified, added, removed) + if changes.each_value.map(&:size).sum > 0 + @client_callback.call(**changes) end end @listener.start