Skip to content

Commit 388fff5

Browse files
authored
Merge pull request #691 from bashly-framework/change/filewatcher
Switch from `filewatcher` to `listen`
2 parents 343e63e + 1de90c6 commit 388fff5

File tree

21 files changed

+173
-58
lines changed

21 files changed

+173
-58
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
LC_ALL: en_US.UTF-8
1515

1616
strategy:
17-
matrix: { ruby: ['3.2', '3.3', '3.4'] }
17+
matrix: { ruby: ['3.2', '3.3', '3.4', '4.0'] }
1818

1919
steps:
2020
- name: Checkout code

bashly.gemspec

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,17 @@ Gem::Specification.new do |s|
1717

1818
s.add_dependency 'colsole', '~> 1.0'
1919
s.add_dependency 'completely', '~> 0.7.0'
20-
s.add_dependency 'filewatcher', '~> 2.0'
2120
s.add_dependency 'gtx', '~> 0.1.1'
21+
s.add_dependency 'listen', '~> 3.9'
2222
s.add_dependency 'lp', '~> 0.2.0'
23-
s.add_dependency 'mister_bin', '~> 0.8.1'
23+
s.add_dependency 'mister_bin', '~> 0.9.0'
2424
s.add_dependency 'requires', '~> 1.1'
2525
s.add_dependency 'tty-markdown', '~> 0.7.2'
2626

27-
# Sub-dependenceis (Ruby 3.3.5 warnings)
28-
s.add_dependency 'logger', '>= 1', '< 3' # required by filewatcher
29-
s.add_dependency 'ostruct', '>= 0', '< 2' # required by json
27+
# Missing sub-dependencies
28+
# logger: required and not bundled by `listen` 3.9.0
29+
# ref: https://github.com/guard/listen/issues/591
30+
s.add_dependency 'logger', '~> 1.7'
3031

3132
s.metadata = {
3233
'bug_tracker_uri' => 'https://github.com/bashly-framework/bashly/issues',

examples/render-mandoc/docs/download.1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.\" Automatically generated by Pandoc 3.2
22
.\"
3-
.TH "download" "1" "December 2025" "Version 0.1.0" "Sample application"
3+
.TH "download" "1" "January 2026" "Version 0.1.0" "Sample application"
44
.SH NAME
55
\f[B]download\f[R] \- Sample application
66
.SH SYNOPSIS

examples/render-mandoc/docs/download.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
% download(1) Version 0.1.0 | Sample application
22
% Lana Lang
3-
% December 2025
3+
% January 2026
44

55
NAME
66
==================================================

lib/bashly.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module Bashly
1212

1313
autoloads 'bashly', %i[
1414
CLI Config ConfigValidator Library LibrarySource LibrarySourceConfig
15-
MessageStrings RenderContext RenderSource Settings VERSION
15+
MessageStrings RenderContext RenderSource Settings VERSION Watch
1616
]
1717

1818
autoloads 'bashly/concerns', %i[

lib/bashly/commands/generate.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
require 'filewatcher'
2-
31
module Bashly
42
module Commands
53
class Generate < Base
@@ -41,7 +39,7 @@ def run
4139
def watch
4240
quiet_say "g`watching` #{Settings.source_dir}\n"
4341

44-
Filewatcher.new([Settings.source_dir]).watch do
42+
Watch.new(Settings.source_dir).on_change do
4543
reset
4644
generate
4745
rescue Bashly::ConfigurationError => e

lib/bashly/commands/render.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
require 'filewatcher'
21
require 'tty-markdown'
32

43
module Bashly
@@ -75,7 +74,7 @@ def render
7574
def watch
7675
say "g`watching`\n"
7776

78-
Filewatcher.new(watchables).watch do
77+
Watch.new(*watchables).on_change do
7978
render
8079
say "g`waiting`\n"
8180
end

lib/bashly/watch.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
require 'listen'
2+
3+
module Bashly
4+
# File system watcher - an ergonomic wrapper around the Listen gem
5+
class Watch
6+
attr_reader :dirs, :options
7+
8+
DEFAULT_OPTIONS = {
9+
force_polling: true,
10+
latency: 1.0,
11+
}.freeze
12+
13+
def initialize(*dirs, **options)
14+
@options = DEFAULT_OPTIONS.merge(options).freeze
15+
@dirs = dirs.empty? ? ['.'] : dirs
16+
end
17+
18+
def on_change(&)
19+
start(&)
20+
wait
21+
ensure
22+
stop
23+
end
24+
25+
private
26+
27+
def build_listener
28+
listen.to(*dirs, **options) do |modified, added, removed|
29+
yield changes(modified, added, removed)
30+
end
31+
end
32+
33+
def start(&block)
34+
raise ArgumentError, 'block required' unless block
35+
36+
@listener = build_listener(&block)
37+
@listener.start
38+
end
39+
40+
def stop
41+
@listener&.stop
42+
@listener = nil
43+
end
44+
45+
def changes(modified, added, removed)
46+
{ modified:, added:, removed: }
47+
end
48+
49+
def listen = Listen
50+
def wait = sleep
51+
end
52+
end

spec/approvals/examples/dependencies-alt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ args: none
2424
deps:
2525
- ${deps[git]} = /usr/bin/git
2626
- ${deps[http_client]} = /usr/bin/curl
27-
- ${deps[ruby]} = /home/vagrant/.rbenv/versions/3.4.1/bin/ruby
27+
- ${deps[ruby]} = /home/vagrant/.rbenv/versions/4.0.0/bin/ruby

spec/bashly/commands/generate_spec.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,20 +229,20 @@
229229

230230
let(:bashly_config_path) { "#{source_dir}/bashly.yml" }
231231
let(:bashly_config) { YAML.load_file bashly_config_path }
232-
let(:watcher_double) { instance_double Filewatcher, watch: nil }
232+
let(:watch_double) { instance_double Watch, on_change: nil }
233233

234234
it 'generates immediately and on change' do
235-
allow(Filewatcher).to receive(:new).and_return(watcher_double)
236-
allow(watcher_double).to receive(:watch).and_yield
235+
allow(Watch).to receive(:new).and_return(watch_double)
236+
allow(watch_double).to receive(:on_change).and_yield
237237

238238
expect { subject.execute %w[generate --watch] }
239239
.to output_approval('cli/generate/watch')
240240
end
241241

242242
context 'when ConfigurationError is raised during watch' do
243243
it 'shows the error gracefully and continues to watch' do
244-
allow(Filewatcher).to receive(:new).and_return(watcher_double)
245-
allow(watcher_double).to receive(:watch) do |&block|
244+
allow(Watch).to receive(:new).and_return(watch_double)
245+
allow(watch_double).to receive(:on_change) do |&block|
246246
bashly_config['invalid_option'] = 'error this'
247247
File.write bashly_config_path, bashly_config.to_yaml
248248
block.call

0 commit comments

Comments
 (0)