filewatcher-cli 1.0.0.beta1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a7885738bc63e99bd2be26af12b8ec536f29ec6e117e191dc507b973b152f3b
4
- data.tar.gz: e46bb7b473ec6cc0943cb71aa3d0d63047d8ac989e866fcd5c2d47b2ab3b0ad5
3
+ metadata.gz: ecc2b0f16f8b65900310497d4ba3ed44681a24955cbba174bb49bd46816096a1
4
+ data.tar.gz: b4a02f994d6c7f25c2c390baac9ec4593bfd21e98a42b1217932eb251de3f486
5
5
  SHA512:
6
- metadata.gz: 00c729fb158d7cc1f49bf09c53117e8b6f284b3c922ef741e1202725d494111a8ccaa9d3d36687c66f35d85e8a8fa422504e30346357d5c8bb697868e25dffbc
7
- data.tar.gz: d02829a6821d3f7b7aeb537299199062fba11025a5e71b6755cc83db6eb41e9dd27e2c19a397ccb0d9843e73623c42e80e0956fdadb04a217d4e99160fc44afe
6
+ metadata.gz: a0b6b45cac67c1ca798bf95ce79cb27af25f46d0005c27594477e5ea9ff8b26bbda2e8e69c8d87de6f85aeff1b5dc2626a2e902b071727613daa767500fc8e99
7
+ data.tar.gz: 99ef03d27a90356182d01e5871830894a06a7ceaf30c378383d173f6b015e576bf5c536ab9aa3277f76ebe5948c171fb5ec846fad068a88b604746e393cf85e8
data/CHANGELOG.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Changelog
2
2
 
3
- ## master (unreleased)
3
+ ## Unreleased
4
4
 
5
- ## 1.0.0.beta1 (2020-09-19)
5
+ ## 1.0.0 (2022-09-09)
6
6
 
7
7
  * Initial release.
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # Filewatcher CLI
2
2
 
3
3
  [![Cirrus CI - Base Branch Build Status](https://img.shields.io/cirrus/github/filewatcher/filewatcher-cli?style=flat-square)](https://cirrus-ci.com/github/filewatcher/filewatcher-cli)
4
- [![Codecov branch](https://img.shields.io/codecov/c/github/filewatcher/filewatcher-cli/master.svg?style=flat-square)](https://codecov.io/gh/filewatcher/filewatcher-cli)
4
+ [![Codecov branch](https://img.shields.io/codecov/c/github/filewatcher/filewatcher-cli/main.svg?style=flat-square)](https://codecov.io/gh/filewatcher/filewatcher-cli)
5
5
  [![Code Climate](https://img.shields.io/codeclimate/maintainability/filewatcher/filewatcher-cli.svg?style=flat-square)](https://codeclimate.com/github/filewatcher/filewatcher-cli)
6
6
  [![Depfu](https://img.shields.io/depfu/filewatcher/filewatcher-cli?style=flat-square)](https://depfu.com/repos/github/filewatcher/filewatcher-cli)
7
- [![Inline docs](https://inch-ci.org/github/filewatcher/filewatcher-cli.svg?branch=master)](https://inch-ci.org/github/filewatcher/filewatcher-cli)
7
+ [![Inline docs](https://inch-ci.org/github/filewatcher/filewatcher-cli.svg?branch=main)](https://inch-ci.org/github/filewatcher/filewatcher-cli)
8
8
  [![License](https://img.shields.io/github/license/filewatcher/filewatcher-cli.svg?style=flat-square)](LICENSE.txt)
9
- [![Gem](https://img.shields.io/gem/v/filewatcher-cli.svg?style=flat-square)](https://rubygems.org/gems/filewatcher-cli)
9
+ [![Gem](https://img.shields.io/gem/v/filewatcher-cli.svg?include_prereleases&style=flat-square)](https://rubygems.org/gems/filewatcher-cli)
10
10
 
11
11
  CLI for [Filewatcher](https://github.com/filewatcher/filewatcher).
12
12
 
@@ -112,6 +112,10 @@ via `--restart-signal` option:
112
112
  $ filewatcher --restart --restart-signal=KILL "**/*.rb" "rake test"
113
113
  ```
114
114
 
115
+ Due to [problems with signals on Windows](https://bugs.ruby-lang.org/issues/17820),
116
+ the default value of restart signal is `KILL` on Windows (while on Unix-like is `TERM`),
117
+ which is a single one supported at the current moment, so use other values carefully.
118
+
115
119
  The `--immediate/-I` option starts the command on startup without waiting for file system updates. To start a web server and have it automatically restart when HTML files are updated:
116
120
 
117
121
  ```sh
@@ -17,8 +17,10 @@ class Filewatcher
17
17
  option %w[-r --restart --fork], :flag, 'restart process when file system is updated',
18
18
  default: false
19
19
 
20
+ ## Signal don't work on Windows for some reason:
21
+ ## https://bugs.ruby-lang.org/issues/17820
20
22
  option '--restart-signal', 'VALUE', 'termination signal for `restart` option',
21
- default: 'TERM'
23
+ default: Gem.win_platform? ? 'KILL' : 'TERM'
22
24
 
23
25
  option %w[-l --list], :flag, 'print name of files being watched',
24
26
  default: false
@@ -30,7 +32,7 @@ class Filewatcher
30
32
  default: File.join('**', '*')
31
33
 
32
34
  option '--exclude', 'GLOB', 'exclude file(s) matching', default: nil do |string|
33
- split_files_void_escaped_whitespace string.split(' ') unless string.to_s.empty?
35
+ split_files_void_escaped_whitespace string.split unless string.to_s.empty?
34
36
  end
35
37
 
36
38
  option %w[-i --interval], 'SECONDS', 'interval to scan file system', default: 0.5 do |string|
@@ -22,6 +22,12 @@ class Filewatcher
22
22
 
23
23
  parameter '[COMMAND]', 'shell command to execute when file changes'
24
24
 
25
+ option ['-v', '--version'], :flag, 'Print versions' do
26
+ Filewatcher.print_version
27
+ puts "Filewatcher CLI #{Filewatcher::CLI::VERSION}"
28
+ exit 0
29
+ end
30
+
25
31
  def execute
26
32
  @child_pid = nil
27
33
 
@@ -42,9 +48,9 @@ class Filewatcher
42
48
  @filewatcher = Filewatcher.new(
43
49
  files,
44
50
  ## https://github.com/mdub/clamp/issues/105
45
- self.class.declared_options.map do |option|
51
+ self.class.declared_options.to_h do |option|
46
52
  [option.attribute_name.to_sym, public_send(option.read_method)]
47
- end.to_h
53
+ end
48
54
  )
49
55
  end
50
56
 
@@ -93,10 +99,23 @@ class Filewatcher
93
99
  end
94
100
  end
95
101
 
102
+ WINDOWS_SIGNALS_WARNING = <<~WARN
103
+ WARNING: Signals don't work on Windows properly: https://bugs.ruby-lang.org/issues/17820
104
+ It's recommended to use only the `KILL` (default `restart-signal` on Windows).
105
+ WARN
106
+ private_constant :WINDOWS_SIGNALS_WARNING
107
+
96
108
  def restart(pid, restart_signal, env, command)
97
109
  begin
98
110
  raise Errno::ESRCH unless pid
99
111
 
112
+ ## Signals don't work on Windows for some reason:
113
+ ## https://cirrus-ci.com/task/5706760947236864?logs=test#L346
114
+ ## https://bugs.ruby-lang.org/issues/17820
115
+ ## https://blog.simplificator.com/2016/01/18/how-to-kill-processes-on-windows-using-ruby/
116
+ ## But `KILL` works.
117
+ warn WINDOWS_SIGNALS_WARNING if Gem.win_platform? && restart_signal != 'KILL'
118
+
100
119
  Process.kill(restart_signal, pid)
101
120
  Process.wait(pid)
102
121
  rescue Errno::ESRCH
@@ -4,6 +4,6 @@ class Filewatcher
4
4
  module CLI
5
5
  BINDIR = 'exe'
6
6
 
7
- VERSION = '1.0.0.beta1'
7
+ VERSION = '1.0.0'
8
8
  end
9
9
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'shell_watch_run'
4
+
5
+ def dump_to_file(content)
6
+ File.write File.join(Filewatcher::CLI::SpecHelper::ShellWatchRun::DUMP_FILE), content
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../dump_to_file'
4
+
5
+ dump_to_file(
6
+ %w[
7
+ FILENAME BASENAME EVENT DIRNAME ABSOLUTE_FILENAME RELATIVE_FILENAME
8
+ ].map { |var| ENV.fetch(var) }.join(', ')
9
+ )
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../dump_to_file'
4
+
5
+ signal = ARGV.first
6
+ Signal.trap(signal) do
7
+ dump_to_file signal
8
+ exit
9
+ end
10
+
11
+ Filewatcher::CLI::SpecHelper.wait seconds: 60
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../dump_to_file'
4
+
5
+ dump_to_file 'watched'
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../constants'
4
+ require_relative '../spec_helper'
5
+
6
+ class Filewatcher
7
+ module CLI
8
+ module SpecHelper
9
+ ## Watch runner for calls from shell
10
+ class ShellWatchRun
11
+ include Filewatcher::SpecHelper::WatchRun
12
+ include CLI::SpecHelper
13
+
14
+ executable_path = File.realpath "#{__dir__}/../../../../#{CLI::BINDIR}/filewatcher"
15
+ EXECUTABLE = "#{'ruby ' if Gem.win_platform?}#{executable_path}" \
16
+
17
+ DUMP_FILE = File.join(TMP_DIR, 'dump')
18
+
19
+ def initialize(options:, dumper:, dumper_args:, **rest_args)
20
+ super(**rest_args)
21
+ @options = options
22
+ @options[:interval] ||= 0.2
23
+ debug "options = #{options_string}"
24
+ @dumper = dumper
25
+ debug "dumper = #{@dumper}"
26
+ @dumper_args = dumper_args.join(' ')
27
+ end
28
+
29
+ def start
30
+ super
31
+
32
+ spawn_filewatcher
33
+
34
+ wait
35
+
36
+ wait seconds: 3 do
37
+ debug "pid state = #{pid_state.inspect}"
38
+ dump_file_exists = File.exist?(DUMP_FILE)
39
+ debug "#{__method__}: File.exist?(DUMP_FILE) = #{dump_file_exists}"
40
+ pid_ready? && (!@options[:immediate] || dump_file_exists)
41
+ end
42
+
43
+ ## Dump file can exists with `--immediate` option, but Filewatcher can not have time
44
+ ## to initialize `@last_snapshot` in main cycle.
45
+ wait
46
+ end
47
+
48
+ def stop
49
+ kill_filewatcher
50
+
51
+ wait do
52
+ pid_state.nil?
53
+ end
54
+
55
+ super
56
+ end
57
+
58
+ private
59
+
60
+ def options_string
61
+ @options_string ||=
62
+ @options
63
+ .map { |key, value| value.is_a?(TrueClass) ? "--#{key}" : "--#{key}=#{value}" }
64
+ .join(' ')
65
+ end
66
+
67
+ SPAWN_OPTIONS = Gem.win_platform? ? {} : { pgroup: true }
68
+
69
+ def spawn_filewatcher
70
+ dumper_full_command = "#{__dir__}/dumpers/#{@dumper}_dumper.rb #{@dumper_args}"
71
+ spawn_command =
72
+ "#{EXECUTABLE} #{options_string} \"#{@filename}\" \"ruby #{dumper_full_command}\""
73
+ debug "spawn_command = #{spawn_command}"
74
+ @pid = spawn spawn_command, **SPAWN_OPTIONS
75
+
76
+ debug "@pid = #{@pid}"
77
+
78
+ debug Process.detach(@pid)
79
+ end
80
+
81
+ def make_changes
82
+ super
83
+
84
+ wait seconds: 3 do
85
+ dump_file_exists = File.exist?(DUMP_FILE)
86
+ debug "#{__method__}: File.exist?(DUMP_FILE) = #{dump_file_exists}"
87
+ debug "#{__method__}: DUMP_FILE content = #{File.read(DUMP_FILE)}" if dump_file_exists
88
+ dump_file_exists
89
+ end
90
+ end
91
+
92
+ def kill_filewatcher
93
+ # debug __method__
94
+ if Gem.win_platform?
95
+ Process.kill('KILL', @pid)
96
+ else
97
+ ## Problems: https://github.com/thomasfl/filewatcher/pull/83
98
+ ## Solution: https://stackoverflow.com/a/45032252/2630849
99
+ Process.kill('TERM', -Process.getpgid(@pid))
100
+ Process.waitall
101
+ end
102
+ rescue Errno::ESRCH
103
+ nil ## already killed
104
+ ensure
105
+ wait
106
+ end
107
+
108
+ def pid_state
109
+ if Gem.win_platform?
110
+ match = `tasklist /FI "PID eq #{@pid}" /FO "LIST" /V`.match(/Status:\s+(\w+)/)
111
+ return unless match
112
+
113
+ match[1]
114
+ else
115
+ ## For macOS output:
116
+ ## https://travis-ci.org/thomasfl/filewatcher/jobs/304433538
117
+ state = `ps -ho state -p #{@pid}`.sub('STAT', '').strip
118
+ ## Return `nil` for consistency with Windows
119
+ state.empty? ? nil : state
120
+ end
121
+ end
122
+
123
+ def pid_ready?
124
+ ps = pid_state
125
+
126
+ return if ps.nil?
127
+
128
+ ps == (Gem.win_platform? ? 'Running' : 'S')
129
+ end
130
+
131
+ def wait(seconds: 1)
132
+ super seconds: seconds, interval: @options[:interval]
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -2,22 +2,36 @@
2
2
 
3
3
  require 'filewatcher/spec_helper'
4
4
 
5
+ require_relative 'spec_helper/dump_to_file'
6
+
5
7
  class Filewatcher
6
8
  module CLI
7
9
  ## Helper for CLI specs
8
10
  module SpecHelper
9
11
  include Filewatcher::SpecHelper
10
12
 
13
+ ENVIRONMENT_SPECS_COEFFICIENTS = {
14
+ lambda do
15
+ RUBY_ENGINE == 'jruby' &&
16
+ is_a?(Filewatcher::CLI::SpecHelper::ShellWatchRun)
17
+ end => 2,
18
+ lambda do
19
+ RUBY_ENGINE == 'jruby' &&
20
+ ENV.fetch('CI', false) &&
21
+ is_a?(Filewatcher::CLI::SpecHelper::ShellWatchRun)
22
+ end => 1.5,
23
+ lambda do
24
+ RUBY_ENGINE == 'truffleruby' &&
25
+ ENV.fetch('CI', false) &&
26
+ is_a?(Filewatcher::CLI::SpecHelper::ShellWatchRun)
27
+ end => 3
28
+ }.freeze
29
+
11
30
  def environment_specs_coefficients
12
- super.merge(
13
- ## https://cirrus-ci.com/build/6442339705028608
14
- lambda do
15
- RUBY_PLATFORM == 'java' && ENV['CI'] && is_a?(Filewatcher::Spec::ShellWatchRun)
16
- end => 2
17
- )
31
+ @environment_specs_coefficients ||= super.merge ENVIRONMENT_SPECS_COEFFICIENTS
18
32
  end
19
33
 
20
- ## https://github.com/rubocop-hq/ruby-style-guide/issues/556#issuecomment-691274359
34
+ ## https://github.com/rubocop/ruby-style-guide/issues/556#issuecomment-828672008
21
35
  # rubocop:disable Style/ModuleFunction
22
36
  extend self
23
37
  # rubocop:enable Style/ModuleFunction
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'filewatcher'
4
4
 
5
- require_relative 'cli/constants'
5
+ require_relative 'cli/command'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filewatcher-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Flemming
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-09-18 00:00:00.000000000 Z
12
+ date: 2022-09-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: clamp
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 2.0.0.beta1
34
+ version: '2.0'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 2.0.0.beta1
41
+ version: '2.0'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: pry-byebug
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -67,48 +67,62 @@ dependencies:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '2.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: bundler-audit
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: 0.9.0
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 0.9.0
70
84
  - !ruby/object:Gem::Dependency
71
85
  name: gem_toys
72
86
  requirement: !ruby/object:Gem::Requirement
73
87
  requirements:
74
88
  - - "~>"
75
89
  - !ruby/object:Gem::Version
76
- version: 0.3.0
90
+ version: 0.12.1
77
91
  type: :development
78
92
  prerelease: false
79
93
  version_requirements: !ruby/object:Gem::Requirement
80
94
  requirements:
81
95
  - - "~>"
82
96
  - !ruby/object:Gem::Version
83
- version: 0.3.0
97
+ version: 0.12.1
84
98
  - !ruby/object:Gem::Dependency
85
99
  name: toys
86
100
  requirement: !ruby/object:Gem::Requirement
87
101
  requirements:
88
102
  - - "~>"
89
103
  - !ruby/object:Gem::Version
90
- version: 0.11.0
104
+ version: 0.13.1
91
105
  type: :development
92
106
  prerelease: false
93
107
  version_requirements: !ruby/object:Gem::Requirement
94
108
  requirements:
95
109
  - - "~>"
96
110
  - !ruby/object:Gem::Version
97
- version: 0.11.0
111
+ version: 0.13.1
98
112
  - !ruby/object:Gem::Dependency
99
113
  name: codecov
100
114
  requirement: !ruby/object:Gem::Requirement
101
115
  requirements:
102
116
  - - "~>"
103
117
  - !ruby/object:Gem::Version
104
- version: 0.2.1
118
+ version: 0.6.0
105
119
  type: :development
106
120
  prerelease: false
107
121
  version_requirements: !ruby/object:Gem::Requirement
108
122
  requirements:
109
123
  - - "~>"
110
124
  - !ruby/object:Gem::Version
111
- version: 0.2.1
125
+ version: 0.6.0
112
126
  - !ruby/object:Gem::Dependency
113
127
  name: rspec
114
128
  requirement: !ruby/object:Gem::Requirement
@@ -129,28 +143,28 @@ dependencies:
129
143
  requirements:
130
144
  - - "~>"
131
145
  - !ruby/object:Gem::Version
132
- version: 0.18.0
146
+ version: 0.21.2
133
147
  type: :development
134
148
  prerelease: false
135
149
  version_requirements: !ruby/object:Gem::Requirement
136
150
  requirements:
137
151
  - - "~>"
138
152
  - !ruby/object:Gem::Version
139
- version: 0.18.0
153
+ version: 0.21.2
140
154
  - !ruby/object:Gem::Dependency
141
155
  name: rubocop
142
156
  requirement: !ruby/object:Gem::Requirement
143
157
  requirements:
144
158
  - - "~>"
145
159
  - !ruby/object:Gem::Version
146
- version: 0.89.0
160
+ version: 1.36.0
147
161
  type: :development
148
162
  prerelease: false
149
163
  version_requirements: !ruby/object:Gem::Requirement
150
164
  requirements:
151
165
  - - "~>"
152
166
  - !ruby/object:Gem::Version
153
- version: 0.89.0
167
+ version: 1.36.0
154
168
  - !ruby/object:Gem::Dependency
155
169
  name: rubocop-performance
156
170
  requirement: !ruby/object:Gem::Requirement
@@ -171,14 +185,14 @@ dependencies:
171
185
  requirements:
172
186
  - - "~>"
173
187
  - !ruby/object:Gem::Version
174
- version: '1.43'
188
+ version: '2.0'
175
189
  type: :development
176
190
  prerelease: false
177
191
  version_requirements: !ruby/object:Gem::Requirement
178
192
  requirements:
179
193
  - - "~>"
180
194
  - !ruby/object:Gem::Version
181
- version: '1.43'
195
+ version: '2.0'
182
196
  description: 'CLI for Filewatcher.
183
197
 
184
198
  '
@@ -201,13 +215,19 @@ files:
201
215
  - lib/filewatcher/cli/env.rb
202
216
  - lib/filewatcher/cli/runner.rb
203
217
  - lib/filewatcher/cli/spec_helper.rb
218
+ - lib/filewatcher/cli/spec_helper/dump_to_file.rb
219
+ - lib/filewatcher/cli/spec_helper/dumpers/env_dumper.rb
220
+ - lib/filewatcher/cli/spec_helper/dumpers/signal_dumper.rb
221
+ - lib/filewatcher/cli/spec_helper/dumpers/watched_dumper.rb
222
+ - lib/filewatcher/cli/spec_helper/shell_watch_run.rb
204
223
  homepage: https://github.com/filewatcher/filewatcher-cli
205
224
  licenses:
206
225
  - MIT
207
226
  metadata:
208
227
  source_code_uri: https://github.com/filewatcher/filewatcher-cli
209
228
  homepage_uri: https://github.com/filewatcher/filewatcher-cli
210
- changelog_uri: https://github.com/filewatcher/filewatcher-cli/blob/master/CHANGELOG.md
229
+ changelog_uri: https://github.com/filewatcher/filewatcher-cli/blob/main/CHANGELOG.md
230
+ rubygems_mfa_required: 'true'
211
231
  post_install_message:
212
232
  rdoc_options: []
213
233
  require_paths:
@@ -216,14 +236,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
216
236
  requirements:
217
237
  - - ">="
218
238
  - !ruby/object:Gem::Version
219
- version: '2.4'
239
+ version: '2.6'
240
+ - - "<"
241
+ - !ruby/object:Gem::Version
242
+ version: '4'
220
243
  required_rubygems_version: !ruby/object:Gem::Requirement
221
244
  requirements:
222
- - - ">"
245
+ - - ">="
223
246
  - !ruby/object:Gem::Version
224
- version: 1.3.1
247
+ version: '0'
225
248
  requirements: []
226
- rubygems_version: 3.1.2
249
+ rubygems_version: 3.3.7
227
250
  signing_key:
228
251
  specification_version: 4
229
252
  summary: CLI for Filewatcher