watchcat 0.3.0-x86_64-linux → 0.5.0-x86_64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +5 -1
- data/README.md +81 -2
- data/cli_example.yml +14 -0
- data/exe/watchcat +14 -0
- data/lib/watchcat/3.1/watchcat.so +0 -0
- data/lib/watchcat/3.2/watchcat.so +0 -0
- data/lib/watchcat/3.3/watchcat.so +0 -0
- data/lib/watchcat/3.4/watchcat.so +0 -0
- data/lib/watchcat/cli/action_executor.rb +43 -0
- data/lib/watchcat/cli/config.rb +72 -0
- data/lib/watchcat/cli/watcher.rb +85 -0
- data/lib/watchcat/cli.rb +52 -0
- data/lib/watchcat/debouncer.rb +41 -0
- data/lib/watchcat/executor.rb +16 -13
- data/lib/watchcat/version.rb +1 -1
- data/lib/watchcat.rb +3 -4
- metadata +38 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 06645aee84876dac8c231d425b846d54aacfbbfc56082d615327c059d796205e
|
|
4
|
+
data.tar.gz: 59ed59a908d0b8e270540aa7dbd4abe520ea94dcfbcf300b86b78706d45e291b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c68fee7c1b1a61c58d451aa9663bf558bc2ee18fd26b0bb921258a3ec9fd1434d4d9cf308dd2c364f9fcede3e988197fff07ae66fa904b2b944246f08349dca1
|
|
7
|
+
data.tar.gz: 392b34865e7e958a8abecca656d2c721cbd85439f1f7ea229e561f607c6e6cf9ebd5bc3c6b9b29248d23aa9c6694366f61f152ba9304c00adc5e97efbe37ab35
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
watchcat (0.
|
|
4
|
+
watchcat (0.5.0)
|
|
5
|
+
psych
|
|
5
6
|
rb_sys
|
|
6
7
|
|
|
7
8
|
GEM
|
|
@@ -27,6 +28,8 @@ GEM
|
|
|
27
28
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
28
29
|
rb-inotify (~> 0.9, >= 0.9.10)
|
|
29
30
|
minitest (5.25.5)
|
|
31
|
+
minitest-fail-fast (0.1.0)
|
|
32
|
+
minitest (~> 5)
|
|
30
33
|
minitest-retry (0.2.5)
|
|
31
34
|
minitest (>= 5.0)
|
|
32
35
|
nokogiri (1.18.1-arm64-darwin)
|
|
@@ -74,6 +77,7 @@ DEPENDENCIES
|
|
|
74
77
|
debug
|
|
75
78
|
listen
|
|
76
79
|
minitest
|
|
80
|
+
minitest-fail-fast
|
|
77
81
|
minitest-retry
|
|
78
82
|
rake
|
|
79
83
|
rake-compiler
|
data/README.md
CHANGED
|
@@ -8,7 +8,7 @@ This gem uses [Notify](https://github.com/notify-rs/notify) to get notifications
|
|
|
8
8
|
|
|
9
9
|
## Platforms
|
|
10
10
|
|
|
11
|
-
This gem supports Linux
|
|
11
|
+
This gem supports Linux, macOS and Windows.
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
@@ -84,7 +84,6 @@ sleep
|
|
|
84
84
|
|
|
85
85
|
**CAUTION** The `watchcat` doesn't normalize the events. So the result might change per the platform.
|
|
86
86
|
|
|
87
|
-
|
|
88
87
|
### Options
|
|
89
88
|
|
|
90
89
|
| Name | Description | Default |
|
|
@@ -94,6 +93,86 @@ sleep
|
|
|
94
93
|
| **debounce** | Debounce events for the same file. | `-1` |
|
|
95
94
|
|
|
96
95
|
|
|
96
|
+
### Filters Option
|
|
97
|
+
|
|
98
|
+
You can use the `filters` option to ignore specific event types:
|
|
99
|
+
|
|
100
|
+
| Key | Description |
|
|
101
|
+
|-----------------|-----------------------------------|
|
|
102
|
+
| ignore_remove | Ignore remove (delete) events |
|
|
103
|
+
| ignore_access | Ignore access events |
|
|
104
|
+
| ignore_create | Ignore create events |
|
|
105
|
+
| ignore_modify | Ignore modify events |
|
|
106
|
+
|
|
107
|
+
Example usage:
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
Watchcat.watch("/tmp/test", filters: { ignore_remove: true, ignore_access: true }) do |e|
|
|
111
|
+
pp e.paths, e.kind
|
|
112
|
+
end
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
## CLI
|
|
117
|
+
|
|
118
|
+
`watchcat` comes with a command-line interface that allows you to watch files and execute commands when changes occur.
|
|
119
|
+
|
|
120
|
+
### Usage
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
# Run watchcat with a config file
|
|
124
|
+
$ watchcat -C config.yml
|
|
125
|
+
|
|
126
|
+
# Generate a template config file
|
|
127
|
+
$ watchcat --init config.yml
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Configuration File
|
|
131
|
+
|
|
132
|
+
The configuration file should be in YAML format. Here's an example:
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
watches:
|
|
136
|
+
- path: "./lib"
|
|
137
|
+
recursive: true
|
|
138
|
+
debounce: 300
|
|
139
|
+
filters:
|
|
140
|
+
ignore_access: true
|
|
141
|
+
patterns:
|
|
142
|
+
- "*.rb"
|
|
143
|
+
- "*.yml"
|
|
144
|
+
actions:
|
|
145
|
+
- command: "echo 'Ruby/YAML file changed: {{file_name}}'"
|
|
146
|
+
- command: "rubocop {{file_path}}"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Configuration Options
|
|
150
|
+
|
|
151
|
+
Each watch entry supports the following options:
|
|
152
|
+
|
|
153
|
+
| Option | Description | Default |
|
|
154
|
+
|-------------|--------------------------------------------------------|---------|
|
|
155
|
+
| path | Directory or file path to watch (required) | - |
|
|
156
|
+
| recursive | Watch a directory recursively or not | `true` |
|
|
157
|
+
| debounce | Debounce events for the same file (in milliseconds) | `-1` |
|
|
158
|
+
| filters | Event filters (same as library filters option) | `{}` |
|
|
159
|
+
| patterns | File patterns to match (using File.fnmatch) | `[]` |
|
|
160
|
+
| actions | Commands to execute when files change | `[]` |
|
|
161
|
+
|
|
162
|
+
### Available Variables for Commands
|
|
163
|
+
|
|
164
|
+
When specifying commands, you can use the following variables:
|
|
165
|
+
|
|
166
|
+
| Variable | Description | Example |
|
|
167
|
+
|---------------|------------------------------------------|------------------------|
|
|
168
|
+
| {{file_path}} | Full path of the changed file | `/home/user/app/file.rb` |
|
|
169
|
+
| {{file_dir}} | Directory containing the file | `/home/user/app` |
|
|
170
|
+
| {{file_name}} | File name with extension | `file.rb` |
|
|
171
|
+
| {{file_base}} | File name without extension | `file` |
|
|
172
|
+
| {{file_ext}} | File extension | `.rb` |
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
97
176
|
## Contributing
|
|
98
177
|
|
|
99
178
|
Bug reports and pull requests are welcome on GitHub at https://github.com/y-yagi/watchcat.
|
data/cli_example.yml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Watchcat Configuration File
|
|
2
|
+
|
|
3
|
+
watches:
|
|
4
|
+
- path: "./lib"
|
|
5
|
+
recursive: true
|
|
6
|
+
debounce: 300
|
|
7
|
+
filters:
|
|
8
|
+
ignore_access: true
|
|
9
|
+
patterns:
|
|
10
|
+
- "*.rb"
|
|
11
|
+
- "*.yml"
|
|
12
|
+
actions:
|
|
13
|
+
- command: "echo 'Ruby/YAML file changed: {{file_name}}'"
|
|
14
|
+
- command: "rubocop {{file_path}}"
|
data/exe/watchcat
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Watchcat
|
|
2
|
+
module CLI
|
|
3
|
+
class ActionExecutor
|
|
4
|
+
def initialize(file_path, event)
|
|
5
|
+
@file_path = file_path
|
|
6
|
+
@event = event
|
|
7
|
+
@file_dir = File.dirname(file_path)
|
|
8
|
+
@file_name = File.basename(file_path)
|
|
9
|
+
@file_ext = File.extname(file_path)
|
|
10
|
+
@file_base = File.basename(file_path, @file_ext)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def execute(action)
|
|
14
|
+
execute_command(action)
|
|
15
|
+
rescue => e
|
|
16
|
+
puts "Error executing action #{action}: #{e.message}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def execute_command(action)
|
|
22
|
+
command = substitute_variables(action["command"])
|
|
23
|
+
puts "Executing: #{command}"
|
|
24
|
+
|
|
25
|
+
success = system(command)
|
|
26
|
+
unless success
|
|
27
|
+
puts "Command failed with exit code: #{$?.exitstatus}"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def substitute_variables(template)
|
|
32
|
+
return template unless template.is_a?(String)
|
|
33
|
+
|
|
34
|
+
template
|
|
35
|
+
.gsub("{{file_path}}", @file_path)
|
|
36
|
+
.gsub("{{file_dir}}", @file_dir)
|
|
37
|
+
.gsub("{{file_name}}", @file_name)
|
|
38
|
+
.gsub("{{file_base}}", @file_base)
|
|
39
|
+
.gsub("{{file_ext}}", @file_ext)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require "psych"
|
|
2
|
+
|
|
3
|
+
module Watchcat
|
|
4
|
+
module CLI
|
|
5
|
+
class Config
|
|
6
|
+
attr_reader :watches
|
|
7
|
+
|
|
8
|
+
def initialize(data)
|
|
9
|
+
@watches = parse_watches(data["watches"] || [])
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.load(file_path)
|
|
13
|
+
unless File.exist?(file_path)
|
|
14
|
+
raise Error, "Configuration file not found: #{file_path}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
begin
|
|
18
|
+
data = Psych.load_file(file_path)
|
|
19
|
+
new(data)
|
|
20
|
+
rescue Psych::SyntaxError => e
|
|
21
|
+
raise Error, "Invalid YAML syntax in #{file_path}: #{e.message}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.generate_template(file_path)
|
|
26
|
+
template = <<~YAML
|
|
27
|
+
# Watchcat Configuration File
|
|
28
|
+
|
|
29
|
+
watches:
|
|
30
|
+
- path: "./src"
|
|
31
|
+
recursive: true
|
|
32
|
+
debounce: 300
|
|
33
|
+
patterns:
|
|
34
|
+
- "*.js"
|
|
35
|
+
- "*.ts"
|
|
36
|
+
- "*.css"
|
|
37
|
+
actions:
|
|
38
|
+
- command: "echo 'File changed: {{file_path}}'"
|
|
39
|
+
|
|
40
|
+
- path: "./docs"
|
|
41
|
+
recursive: true
|
|
42
|
+
patterns:
|
|
43
|
+
- "*.md"
|
|
44
|
+
actions:
|
|
45
|
+
- command: "echo 'Documentation updated: {{file_name}}'"
|
|
46
|
+
YAML
|
|
47
|
+
|
|
48
|
+
if File.exist?(file_path)
|
|
49
|
+
raise Error, "File already exists: #{file_path}. Won't overwrite."
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
File.write(file_path, template)
|
|
53
|
+
puts "Config template generated at #{file_path}"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def parse_watches(watches_data)
|
|
59
|
+
watches_data.map do |watch_config|
|
|
60
|
+
{
|
|
61
|
+
path: watch_config["path"],
|
|
62
|
+
recursive: watch_config.fetch("recursive", true),
|
|
63
|
+
patterns: watch_config["patterns"] || [],
|
|
64
|
+
actions: watch_config["actions"] || [],
|
|
65
|
+
debounce: watch_config.fetch("debounce", -1),
|
|
66
|
+
filters: watch_config["filters"]&.transform_keys(&:to_sym) || {},
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module Watchcat
|
|
2
|
+
module CLI
|
|
3
|
+
class Watcher
|
|
4
|
+
def initialize(config)
|
|
5
|
+
@config = config
|
|
6
|
+
@watchers = []
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def start
|
|
10
|
+
puts "Starting Watchcat file watcher..."
|
|
11
|
+
|
|
12
|
+
@config.watches.each do |watch_config|
|
|
13
|
+
start_watching_path(watch_config)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
puts "Watchcat is now watching for file changes. Press Ctrl+C to stop."
|
|
17
|
+
|
|
18
|
+
# Keep the main thread alive
|
|
19
|
+
begin
|
|
20
|
+
sleep
|
|
21
|
+
rescue Interrupt
|
|
22
|
+
puts "\nStopping Watchcat..."
|
|
23
|
+
stop
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def stop
|
|
28
|
+
@watchers.each(&:stop)
|
|
29
|
+
@watchers.clear
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def start_watching_path(watch_config)
|
|
35
|
+
path = watch_config[:path]
|
|
36
|
+
|
|
37
|
+
unless File.exist?(path)
|
|
38
|
+
puts "Warning: Path does not exist: #{path}"
|
|
39
|
+
return
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
puts "Watching: #{path} (recursive: #{watch_config[:recursive]}, debounce: #{watch_config[:debounce]}ms)"
|
|
43
|
+
|
|
44
|
+
watcher = Watchcat.watch(
|
|
45
|
+
path,
|
|
46
|
+
recursive: watch_config[:recursive],
|
|
47
|
+
filters: watch_config[:filters],
|
|
48
|
+
debounce: watch_config[:debounce],
|
|
49
|
+
) do |event|
|
|
50
|
+
handle_file_event(event, watch_config)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
@watchers << watcher
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def handle_file_event(event, watch_config)
|
|
57
|
+
return if event.kind.access?
|
|
58
|
+
|
|
59
|
+
event.paths.each do |file_path|
|
|
60
|
+
next unless should_process_file?(file_path, watch_config[:patterns])
|
|
61
|
+
|
|
62
|
+
puts "File changed: #{file_path}"
|
|
63
|
+
execute_actions(file_path, event, watch_config[:actions])
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def should_process_file?(file_path, patterns)
|
|
68
|
+
return true if patterns.empty?
|
|
69
|
+
|
|
70
|
+
patterns.any? do |pattern|
|
|
71
|
+
File.fnmatch?(pattern, File.basename(file_path)) ||
|
|
72
|
+
File.fnmatch?(pattern, file_path)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def execute_actions(file_path, event, actions)
|
|
77
|
+
executor = ActionExecutor.new(file_path, event)
|
|
78
|
+
|
|
79
|
+
actions.each do |action|
|
|
80
|
+
executor.execute(action)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
data/lib/watchcat/cli.rb
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require "optparse"
|
|
2
|
+
require_relative "cli/watcher"
|
|
3
|
+
require_relative "cli/config"
|
|
4
|
+
require_relative "cli/action_executor"
|
|
5
|
+
|
|
6
|
+
module Watchcat
|
|
7
|
+
module CLI
|
|
8
|
+
class Error < StandardError; end
|
|
9
|
+
class << self
|
|
10
|
+
def start(argv)
|
|
11
|
+
options = parse(argv)
|
|
12
|
+
|
|
13
|
+
if options[:init]
|
|
14
|
+
Config.generate_template(options[:init])
|
|
15
|
+
return
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
config = Config.load(options[:config])
|
|
19
|
+
watcher = Watcher.new(config)
|
|
20
|
+
watcher.start
|
|
21
|
+
rescue => e
|
|
22
|
+
raise Error, "Failed to start Watchcat: #{e.message}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def parse(argv)
|
|
26
|
+
options = { config: 'watchcat.yml' }
|
|
27
|
+
OptionParser.new do |opts|
|
|
28
|
+
opts.banner = "Usage: watchcat [options]"
|
|
29
|
+
|
|
30
|
+
opts.on("-C", "--config PATH", "Path to the config file. Default is 'watchcat.yml'.") do |v|
|
|
31
|
+
options[:config] = v
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
opts.on("--init PATH", "Generate a template config file at the specified path") do |v|
|
|
35
|
+
options[:init] = v
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
opts.on("-h", "--help", "Show this help message") do
|
|
39
|
+
puts opts
|
|
40
|
+
exit
|
|
41
|
+
end
|
|
42
|
+
end.parse!(argv)
|
|
43
|
+
|
|
44
|
+
if !options[:init] && options[:config].nil?
|
|
45
|
+
raise OptionParser::MissingArgument.new("-C")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
options
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Watchcat
|
|
2
|
+
class Debouncer
|
|
3
|
+
def initialize
|
|
4
|
+
@timers = {}
|
|
5
|
+
@mutex = Mutex.new
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def debounce(key, delay_ms, &block)
|
|
9
|
+
@mutex.synchronize do
|
|
10
|
+
# Cancel existing timer for this key
|
|
11
|
+
if @timers[key]
|
|
12
|
+
@timers[key].kill
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Create new timer
|
|
16
|
+
@timers[key] = Thread.new do
|
|
17
|
+
sleep(delay_ms / 1000.0) # Convert ms to seconds
|
|
18
|
+
|
|
19
|
+
@mutex.synchronize do
|
|
20
|
+
@timers.delete(key)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
block.call
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def clear
|
|
29
|
+
@mutex.synchronize do
|
|
30
|
+
@timers.each_value(&:kill)
|
|
31
|
+
@timers.clear
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def pending_count
|
|
36
|
+
@mutex.synchronize do
|
|
37
|
+
@timers.size
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/watchcat/executor.rb
CHANGED
|
@@ -2,14 +2,14 @@ require_relative "event"
|
|
|
2
2
|
|
|
3
3
|
module Watchcat
|
|
4
4
|
class Executor
|
|
5
|
-
def initialize(paths, recursive:, force_polling:, poll_interval:,
|
|
5
|
+
def initialize(paths, recursive:, force_polling:, poll_interval:, filters:, debounce:, block:)
|
|
6
6
|
@paths = paths
|
|
7
7
|
@recursive = recursive
|
|
8
8
|
@force_polling = force_polling
|
|
9
9
|
@poll_interval = poll_interval
|
|
10
|
-
@
|
|
11
|
-
@ignore_remove = ignore_remove
|
|
10
|
+
@filters = filters || {}
|
|
12
11
|
@debounce = debounce
|
|
12
|
+
@debouncer = Debouncer.new if @debounce > 0
|
|
13
13
|
@block = block
|
|
14
14
|
@watcher = Watchcat::Watcher.new
|
|
15
15
|
@watch_thread = nil
|
|
@@ -23,11 +23,6 @@ module Watchcat
|
|
|
23
23
|
start_watching
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# If wait_until_startup is true, give the thread a moment to start
|
|
27
|
-
if @wait_until_startup
|
|
28
|
-
sleep 0.1
|
|
29
|
-
end
|
|
30
|
-
|
|
31
26
|
at_exit do
|
|
32
27
|
stop
|
|
33
28
|
end
|
|
@@ -49,14 +44,22 @@ module Watchcat
|
|
|
49
44
|
recursive: @recursive,
|
|
50
45
|
force_polling: @force_polling,
|
|
51
46
|
poll_interval: @poll_interval,
|
|
52
|
-
ignore_remove: @ignore_remove,
|
|
53
|
-
|
|
47
|
+
ignore_remove: @filters[:ignore_remove],
|
|
48
|
+
ignore_access: @filters[:ignore_access],
|
|
49
|
+
ignore_create: @filters[:ignore_create],
|
|
50
|
+
ignore_modify: @filters[:ignore_modify]
|
|
54
51
|
) do |kind, paths, raw_kind|
|
|
55
52
|
break if @stop_requested
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
if @debounce > 0 && paths.size == 1
|
|
55
|
+
@debouncer.debounce(paths[0], @debounce) do
|
|
56
|
+
event = Watchcat::Event.new(kind, paths, raw_kind)
|
|
57
|
+
@block.call(event)
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
event = Watchcat::Event.new(kind, paths, raw_kind)
|
|
61
|
+
@block.call(event)
|
|
62
|
+
end
|
|
60
63
|
end
|
|
61
64
|
end
|
|
62
65
|
end
|
data/lib/watchcat/version.rb
CHANGED
data/lib/watchcat.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative "watchcat/version"
|
|
2
2
|
require_relative "watchcat/executor"
|
|
3
|
+
require_relative "watchcat/debouncer"
|
|
3
4
|
|
|
4
5
|
begin
|
|
5
6
|
require "watchcat/#{RUBY_VERSION.to_f}/watchcat"
|
|
@@ -14,8 +15,7 @@ module Watchcat
|
|
|
14
15
|
recursive: true,
|
|
15
16
|
force_polling: false,
|
|
16
17
|
poll_interval: nil,
|
|
17
|
-
|
|
18
|
-
ignore_remove: false,
|
|
18
|
+
filters: {},
|
|
19
19
|
debounce: -1,
|
|
20
20
|
&block
|
|
21
21
|
)
|
|
@@ -25,8 +25,7 @@ module Watchcat
|
|
|
25
25
|
recursive: recursive,
|
|
26
26
|
force_polling: force_polling,
|
|
27
27
|
poll_interval: poll_interval,
|
|
28
|
-
|
|
29
|
-
ignore_remove: ignore_remove,
|
|
28
|
+
filters: filters,
|
|
30
29
|
debounce: debounce,
|
|
31
30
|
block: block
|
|
32
31
|
)
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: watchcat
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: x86_64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Yuji Yaginuma
|
|
8
8
|
autorequire:
|
|
9
|
-
bindir:
|
|
9
|
+
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-09-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: psych
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: debug
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -52,6 +66,20 @@ dependencies:
|
|
|
52
66
|
- - ">="
|
|
53
67
|
- !ruby/object:Gem::Version
|
|
54
68
|
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: minitest-fail-fast
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
55
83
|
- !ruby/object:Gem::Dependency
|
|
56
84
|
name: rake
|
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -121,12 +149,19 @@ files:
|
|
|
121
149
|
- LICENSE.txt
|
|
122
150
|
- README.md
|
|
123
151
|
- Rakefile
|
|
152
|
+
- cli_example.yml
|
|
153
|
+
- exe/watchcat
|
|
124
154
|
- ext/watchcat/.gitignore
|
|
125
155
|
- lib/watchcat.rb
|
|
126
156
|
- lib/watchcat/3.1/watchcat.so
|
|
127
157
|
- lib/watchcat/3.2/watchcat.so
|
|
128
158
|
- lib/watchcat/3.3/watchcat.so
|
|
129
159
|
- lib/watchcat/3.4/watchcat.so
|
|
160
|
+
- lib/watchcat/cli.rb
|
|
161
|
+
- lib/watchcat/cli/action_executor.rb
|
|
162
|
+
- lib/watchcat/cli/config.rb
|
|
163
|
+
- lib/watchcat/cli/watcher.rb
|
|
164
|
+
- lib/watchcat/debouncer.rb
|
|
130
165
|
- lib/watchcat/event.rb
|
|
131
166
|
- lib/watchcat/executor.rb
|
|
132
167
|
- lib/watchcat/kind.rb
|