opal 1.7.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +12 -4
  3. data/CHANGELOG.md +29 -1
  4. data/exe/opal +5 -7
  5. data/lib/opal/builder.rb +13 -13
  6. data/lib/opal/builder_processors.rb +8 -2
  7. data/lib/opal/builder_scheduler/prefork.rb +60 -6
  8. data/lib/opal/cli.rb +59 -43
  9. data/lib/opal/cli_runners/compiler.rb +7 -6
  10. data/lib/opal/cli_runners/safari.rb +208 -0
  11. data/lib/opal/cli_runners.rb +1 -0
  12. data/lib/opal/nodes/literal.rb +16 -0
  13. data/lib/opal/version.rb +1 -1
  14. data/opal/corelib/constants.rb +2 -2
  15. data/spec/filters/platform/.keep +0 -0
  16. data/spec/filters/platform/firefox/exception.rb +8 -0
  17. data/spec/filters/platform/firefox/kernel.rb +3 -0
  18. data/spec/filters/platform/safari/exception.rb +8 -0
  19. data/spec/filters/platform/safari/float.rb +4 -0
  20. data/spec/filters/platform/safari/kernel.rb +3 -0
  21. data/spec/filters/platform/safari/literal_regexp.rb +6 -0
  22. data/spec/lib/builder_spec.rb +32 -0
  23. data/spec/lib/cli_spec.rb +18 -6
  24. data/spec/lib/fixtures/build_order/file1.js +1 -0
  25. data/spec/lib/fixtures/build_order/file2.js +1 -0
  26. data/spec/lib/fixtures/build_order/file3.js +1 -0
  27. data/spec/lib/fixtures/build_order/file4.js +1 -0
  28. data/spec/lib/fixtures/build_order/file5.rb.erb +4 -0
  29. data/spec/lib/fixtures/build_order/file51.js +1 -0
  30. data/spec/lib/fixtures/build_order/file6.rb +10 -0
  31. data/spec/lib/fixtures/build_order/file61.rb +1 -0
  32. data/spec/lib/fixtures/build_order/file62.rb +4 -0
  33. data/spec/lib/fixtures/build_order/file63.rb +4 -0
  34. data/spec/lib/fixtures/build_order/file64.rb +1 -0
  35. data/spec/lib/fixtures/build_order/file7.rb +1 -0
  36. data/spec/lib/fixtures/build_order.rb +9 -0
  37. data/spec/lib/rake_dist_spec.rb +69 -0
  38. data/spec/mspec-opal/runner.rb +1 -0
  39. data/spec/opal/core/io/read_spec.rb +12 -3
  40. data/stdlib/opal/platform.rb +1 -0
  41. data/stdlib/opal-platform.rb +3 -0
  42. data/stdlib/time.rb +21 -1
  43. data/tasks/building.rake +1 -1
  44. data/tasks/testing.rake +3 -4
  45. metadata +29 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96d55712831ec604d204ffbd2a92a5478daf36f7c24b8b58f52412fc7b2e2ca5
4
- data.tar.gz: 557869c042954fc18a1d48cf93008485471e6e1db5a936b4834ffc9700fac755
3
+ metadata.gz: 3867be8330f4fc45cb5ea9a759c3a1fd39880c5ea92e3c054cbfb2e8776d3f45
4
+ data.tar.gz: 9bae6c750966bc7e9551f5c4e6d21ce751ee66fc69862bae5b98b85299de7343
5
5
  SHA512:
6
- metadata.gz: 8747d6023e6e0e309f622c1f8ad879bd2c5ce2493662f2dc09053ab0cdbc268ad0110291a1b403c9d19272f6ceb2ebed6e15998b9673b6c5aff356898877202d
7
- data.tar.gz: 83f23a7651fd6804759f9e22e284c37eaa27aa4dce2db0ee2d9da91bd1533acf853a9b18767787af267201a0e481736f5e5694ca29d5259ebb1bc67772ec62bc
6
+ metadata.gz: 56d87d05c1c043e165b30181b26a7c761d24d9168474fdcece06ca23ee5b4133d8d58722d9e3446f63db666d15acdc2bbcaf870b237f11673d7c6d810149dd1e
7
+ data.tar.gz: c7f9ced16e1b43ca58c75d7405319c6a5c8d008fa43db6cc1281d235bae1bce090a617d21234c3807ae5d3663b9b268799a87fb4da30f2afc8587a16d5185f7d
@@ -24,12 +24,12 @@ jobs:
24
24
  - name: mspec-chrome
25
25
  ruby: '3.0'
26
26
  command: bin/rake mspec_chrome
27
- - name: minitest-firefox
27
+ - name: mspec-firefox
28
28
  env:
29
29
  # when changing version, also change it below
30
30
  MOZILLA_FIREFOX_BINARY: '/opt/hostedtoolcache/firefox/106.0.4/x64/firefox'
31
31
  ruby: '3.0'
32
- command: xvfb-run bin/rake minitest_firefox
32
+ command: xvfb-run bin/rake mspec_firefox
33
33
  - name: minitest
34
34
  ruby: '3.0'
35
35
  command: bin/rake minitest
@@ -59,13 +59,17 @@ jobs:
59
59
  command: bundle exec rake mspec_chrome
60
60
  ruby: '3.0'
61
61
  os: windows-latest
62
- - name: windows-minitest-firefox
62
+ - name: windows-mspec-firefox
63
63
  env:
64
64
  # when changing version, also change it below and above
65
65
  MOZILLA_FIREFOX_BINARY: 'C:/Program Files/Firefox_106.0.4/firefox.exe'
66
66
  ruby: '3.0'
67
- command: bundle exec rake minitest_firefox
67
+ command: bundle exec rake mspec_firefox
68
68
  os: windows-latest
69
+ - name: macos-mspec-safari
70
+ command: bundle exec rake mspec_safari
71
+ ruby: '3.0'
72
+ os: 'macos-latest'
69
73
  - name: windows-minitest
70
74
  command: bundle exec rake minitest
71
75
  ruby: '3.0'
@@ -74,6 +78,10 @@ jobs:
74
78
  command: bundle exec rake rspec
75
79
  ruby: '3.0'
76
80
  os: windows-latest
81
+ - name: macos
82
+ command: bundle exec rake rspec
83
+ ruby: '3.0'
84
+ os: 'macos-latest'
77
85
  - name: lint
78
86
  command: bin/rake lint
79
87
  ruby: '3.0'
data/CHANGELOG.md CHANGED
@@ -16,7 +16,7 @@ Changes are grouped as follows:
16
16
 
17
17
 
18
18
 
19
- ## [1.7.0](https://github.com/opal/opal/compare/v1.6.1...v1.7.0) - 2022-12-26
19
+ ## [1.7.1](https://github.com/opal/opal/compare/v1.7.0...v1.7.1) - 2023-01-06
20
20
 
21
21
 
22
22
  <!--
@@ -29,6 +29,34 @@ Changes are grouped as follows:
29
29
  ### Fixed
30
30
  -->
31
31
 
32
+
33
+ ### Added
34
+
35
+ - Add safari runner ([#2513](https://github.com/opal/opal/pull/2513))
36
+
37
+ ### Fixed
38
+
39
+ - Fix CLI file reading for macOS ([#2510](https://github.com/opal/opal/pull/2510))
40
+ - Make Date/Time.parse on Firefox more compatible with Chrome and Ruby ([#2506](https://github.com/opal/opal/pull/2506))
41
+ - Safari/WebKit can now parse code compiled with lookbehind regexps, failing at runtime instead ([#2511](https://github.com/opal/opal/pull/2511))
42
+ - Fix `--watch` ignoring some directories (e.g. `tmp`) ([#2509](https://github.com/opal/opal/pull/2509))
43
+ - Fix rake dist not generating libraries correctly for the CDN ([#2515](https://github.com/opal/opal/pull/2515))
44
+ - Prefork: output processed files in a correct, deterministic order ([#2516](https://github.com/opal/opal/pull/2516))
45
+ - Fix the handling of ARGV for the opal executable ([#2518](https://github.com/opal/opal/pull/2518))
46
+
47
+ ### Internal
48
+
49
+ - Platform specific spec filters ([#2508](https://github.com/opal/opal/pull/2508))
50
+ - Run Firefox specs by default ([#2507](https://github.com/opal/opal/pull/2507))
51
+ - Run Safari specs by default ([#2513](https://github.com/opal/opal/pull/2513))
52
+ - [mspec_opal] Avoid lookbehind Regexp for compatibility with various javascript engines ([#2512](https://github.com/opal/opal/pull/2512))
53
+
54
+
55
+
56
+
57
+ ## [1.7.0](https://github.com/opal/opal/compare/v1.6.1...v1.7.0) - 2022-12-26
58
+
59
+
32
60
  ### Added
33
61
 
34
62
  - Update benchmarking and CLI runners, added support for Deno and Firefox (#2490, #2492, #2494, #2495, #2497, #2491, #2496)
data/exe/opal CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  # Error codes are taken from /usr/include/sysexits.h
4
4
 
5
- OriginalARGV = ARGV.dup
6
-
7
5
  require 'opal/cli_options'
8
6
  options = Opal::CLIOptions.new
9
7
  begin
@@ -15,11 +13,7 @@ end
15
13
 
16
14
  require 'opal/cli'
17
15
  options_hash = options.options
18
- options_hash.merge!(
19
- file: ARGF.file,
20
- filename: ARGF.filename,
21
- argv: ARGV.dup
22
- ) unless options_hash[:lib_only]
16
+ options_hash.merge!(argv: ARGV.dup) unless options_hash[:lib_only]
23
17
  cli = Opal::CLI.new options_hash
24
18
 
25
19
  begin
@@ -28,4 +22,8 @@ begin
28
22
  rescue Opal::CliRunners::RunnerError => e
29
23
  $stderr.puts e.message
30
24
  exit 72
25
+ rescue SignalException => e
26
+ raise unless e.message == 'SIGUSR2'
27
+
28
+ exec($0, *ARGV)
31
29
  end
data/lib/opal/builder.rb CHANGED
@@ -197,6 +197,19 @@ module Opal
197
197
  processed.map(&:abs_path).compact.select { |fn| File.exist?(fn) }
198
198
  end
199
199
 
200
+ def expand_ext(path)
201
+ abs_path = path_reader.expand(path)
202
+
203
+ if abs_path
204
+ File.join(
205
+ File.dirname(path),
206
+ File.basename(abs_path)
207
+ )
208
+ else
209
+ path
210
+ end
211
+ end
212
+
200
213
  private
201
214
 
202
215
  def process_requires(rel_path, requires, autoloads, options)
@@ -261,19 +274,6 @@ module Opal
261
274
  end
262
275
  end
263
276
 
264
- def expand_ext(path)
265
- abs_path = path_reader.expand(path)
266
-
267
- if abs_path
268
- File.join(
269
- File.dirname(path),
270
- File.basename(abs_path)
271
- )
272
- else
273
- path
274
- end
275
- end
276
-
277
277
  def expand_path(path)
278
278
  return if stub?(path)
279
279
  (path_reader.expand(path) || File.expand_path(path)).to_s
@@ -148,7 +148,10 @@ module Opal
148
148
 
149
149
  def compiled
150
150
  @compiled ||= begin
151
- @source = ::ERB.new(@source.to_s).result
151
+ erb = ::ERB.new(@source.to_s)
152
+ erb.filename = @abs_path
153
+
154
+ @source = erb.result
152
155
 
153
156
  compiler = compiler_for(@source, file: @filename)
154
157
  compiler.compile
@@ -163,7 +166,10 @@ module Opal
163
166
  handles :erb
164
167
 
165
168
  def source
166
- result = ::ERB.new(@source.to_s).result
169
+ erb = ::ERB.new(@source.to_s)
170
+ erb.filename = @abs_path
171
+
172
+ result = erb.result
167
173
  module_name = ::Opal::Compiler.module_name(@filename)
168
174
  "Opal.modules[#{module_name.inspect}] = function() {#{result}};"
169
175
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'etc'
4
+ require 'set'
4
5
 
5
6
  module Opal
6
7
  class BuilderScheduler
@@ -13,12 +14,64 @@ module Opal
13
14
  io = @in_fork
14
15
  io.send(:new_requires, rel_path, requires, autoloads, options)
15
16
  else
16
- prefork_reactor(rel_path, requires, autoloads, options)
17
+ processed = prefork_reactor(rel_path, requires, autoloads, options)
18
+
19
+ processed = OrderCorrector.correct_order(processed, requires, builder)
20
+
21
+ builder.processed.append(*processed)
17
22
  end
18
23
  end
19
24
 
20
25
  private
21
26
 
27
+ # Prefork is not deterministic. This module corrects an order of processed
28
+ # files so that it would be exactly the same as if building sequentially.
29
+ # While for Ruby files it usually isn't a problem, because the real order
30
+ # stems from how `Opal.modules` array is accessed, the JavaScript files
31
+ # are executed verbatim and their order may be important. Also, having
32
+ # deterministic output is always a good thing.
33
+ module OrderCorrector
34
+ module_function
35
+
36
+ def correct_order(processed, requires, builder)
37
+ # Let's build a hash that maps a filename to an array of files it requires
38
+ requires_hash = processed.to_h do |i|
39
+ [i.filename, expand_requires(i.requires, builder)]
40
+ end
41
+ # Let's build an array with a correct order of requires
42
+ order_array = build_require_order_array(expand_requires(requires, builder), requires_hash)
43
+ # If a key is duplicated, remove the last duplicate
44
+ order_array = order_array.uniq
45
+ # Create a hash from this array: [a,b,c] => [a => 0, b => 1, c => 2]
46
+ order_hash = order_array.each_with_index.to_h
47
+ # Let's return a processed array that has elements in the order provided
48
+ processed.sort_by do |asset|
49
+ # If a filename isn't present somehow in our hash, let's put it at the end
50
+ order_hash[asset.filename] || order_array.length
51
+ end
52
+ end
53
+
54
+ # Expand a requires array, so that the requires filenames will be
55
+ # matching BuilderProcessor#. Builder needs to be passed so that
56
+ # we can access an `expand_ext` function from its context.
57
+ def expand_requires(requires, builder)
58
+ requires.map { |i| builder.expand_ext(i) }
59
+ end
60
+
61
+ def build_require_order_array(requires, requires_hash, built_for = Set.new)
62
+ array = []
63
+ requires.each do |name|
64
+ next if built_for.include?(name)
65
+ built_for << name
66
+
67
+ asset_requires = requires_hash[name]
68
+ array += build_require_order_array(asset_requires, requires_hash, built_for) if asset_requires
69
+ array << name
70
+ end
71
+ array
72
+ end
73
+ end
74
+
22
75
  class ForkSet < Array
23
76
  def initialize(count, &block)
24
77
  super([])
@@ -192,6 +245,8 @@ module Opal
192
245
  def prefork_reactor(rel_path, requires, autoloads, options)
193
246
  prefork
194
247
 
248
+ processed = []
249
+
195
250
  first = rel_path
196
251
  queue = requires.map { |i| [rel_path, i, autoloads, options] }
197
252
 
@@ -206,7 +261,7 @@ module Opal
206
261
  idles.each do |io|
207
262
  break if queue.empty?
208
263
 
209
- rel_path, req, autoloads, options = *queue.pop
264
+ rel_path, req, autoloads, options = *queue.shift
210
265
 
211
266
  next if builder.already_processed.include?(req)
212
267
  awaiting += 1
@@ -225,11 +280,8 @@ module Opal
225
280
  asset, = *args
226
281
  if !asset
227
282
  # Do nothing, we received a nil which is expected.
228
- elsif asset.filename == 'corelib/runtime.js'
229
- # Opal runtime should go first... the rest can go their way.
230
- builder.processed.unshift(asset)
231
283
  else
232
- builder.processed << asset
284
+ processed << asset
233
285
  end
234
286
  built += 1
235
287
  awaiting -= 1
@@ -252,6 +304,8 @@ module Opal
252
304
 
253
305
  break if awaiting == 0 && queue.empty?
254
306
  end
307
+
308
+ processed
255
309
  ensure
256
310
  $stderr.print "\r\e[K\r" if $stderr.tty?
257
311
  @forks.close
data/lib/opal/cli.rb CHANGED
@@ -3,18 +3,25 @@
3
3
  require 'opal/requires'
4
4
  require 'opal/builder'
5
5
  require 'opal/cli_runners'
6
+ require 'stringio'
6
7
 
7
8
  module Opal
8
9
  class CLI
9
10
  attr_reader :options, :file, :compiler_options, :evals, :load_paths, :argv,
10
11
  :output, :requires, :rbrequires, :gems, :stubs, :verbose, :runner_options,
11
- :preload, :filename, :debug, :no_exit, :lib_only, :missing_require_severity,
12
- :no_cache
12
+ :preload, :debug, :no_exit, :lib_only, :missing_require_severity,
13
+ :filename, :stdin, :no_cache
13
14
 
14
15
  class << self
15
16
  attr_accessor :stdout
16
17
  end
17
18
 
19
+ class Evals < StringIO
20
+ def to_path
21
+ '-e'
22
+ end
23
+ end
24
+
18
25
  def initialize(options = nil)
19
26
  options ||= {}
20
27
 
@@ -25,7 +32,6 @@ module Opal
25
32
  @options = options
26
33
  @sexp = options.delete(:sexp)
27
34
  @repl = options.delete(:repl)
28
- @file = options.delete(:file)
29
35
  @no_exit = options.delete(:no_exit)
30
36
  @lib_only = options.delete(:lib_only)
31
37
  @argv = options.delete(:argv) { [] }
@@ -37,10 +43,10 @@ module Opal
37
43
  @output = options.delete(:output) { self.class.stdout || $stdout }
38
44
  @verbose = options.delete(:verbose) { false }
39
45
  @debug = options.delete(:debug) { false }
40
- @filename = options.delete(:filename) { @file && @file.path }
41
46
  @requires = options.delete(:requires) { [] }
42
47
  @rbrequires = options.delete(:rbrequires) { [] }
43
48
  @no_cache = options.delete(:no_cache) { false }
49
+ @stdin = options.delete(:stdin) { $stdin }
44
50
 
45
51
  @debug_source_map = options.delete(:debug_source_map) { false }
46
52
 
@@ -55,9 +61,20 @@ module Opal
55
61
  [key, value]
56
62
  end.compact.to_h
57
63
 
58
- raise ArgumentError, 'no libraries to compile' if @lib_only && @requires.empty?
59
- raise ArgumentError, 'no runnable code provided (evals or file)' if @evals.empty? && @file.nil? && !@lib_only
60
- raise ArgumentError, "can't accept evals or file in `library only` mode" if (@evals.any? || @file) && @lib_only
64
+ if @lib_only
65
+ raise ArgumentError, 'no libraries to compile' if @requires.empty?
66
+ raise ArgumentError, "can't accept evals, file, or extra arguments in `library only` mode" if @argv.any? || @evals.any?
67
+ elsif @evals.any?
68
+ @filename = '-e'
69
+ @file = Evals.new(@evals.join("\n"))
70
+ elsif @argv.first && @argv.first != '-'
71
+ @filename = @argv.shift
72
+ @file = File.open(@filename)
73
+ else
74
+ @filename = @argv.shift || '-'
75
+ @file = @stdin
76
+ end
77
+
61
78
  raise ArgumentError, "unknown options: #{options.inspect}" unless @options.empty?
62
79
  end
63
80
 
@@ -93,7 +110,7 @@ module Opal
93
110
  require 'opal/repl'
94
111
 
95
112
  repl = REPL.new
96
- repl.run(OriginalARGV)
113
+ repl.run(argv)
97
114
  end
98
115
 
99
116
  attr_reader :exit_status
@@ -127,7 +144,8 @@ module Opal
127
144
  builder.build_str '$DEBUG = true', '(flags)', no_export: true if debug
128
145
 
129
146
  # --eval / stdin / file
130
- evals_or_file { |source, filename| builder.build_str(source, filename) }
147
+ source = evals_or_file_source
148
+ builder.build_str(source, filename) if source
131
149
 
132
150
  # --no-exit
133
151
  builder.build_str '::Kernel.exit', '(exit)', no_export: true unless no_exit
@@ -136,27 +154,27 @@ module Opal
136
154
  end
137
155
 
138
156
  def show_sexp
139
- evals_or_file do |contents, filename|
140
- buffer = ::Opal::Parser::SourceBuffer.new(filename)
141
- buffer.source = contents
142
- sexp = Opal::Parser.default_parser.parse(buffer)
143
- output.puts sexp.inspect
144
- end
157
+ source = evals_or_file_source or return # rubocop:disable Style/AndOr
158
+
159
+ buffer = ::Opal::Parser::SourceBuffer.new(filename)
160
+ buffer.source = source
161
+ sexp = Opal::Parser.default_parser.parse(buffer)
162
+ output.puts sexp.inspect
145
163
  end
146
164
 
147
165
  def debug_source_map
148
- evals_or_file do |contents, filename|
149
- compiler = Opal::Compiler.new(contents, file: filename, **compiler_options)
166
+ source = evals_or_file_source or return # rubocop:disable Style/AndOr
150
167
 
151
- compiler.compile
168
+ compiler = Opal::Compiler.new(source, file: filename, **compiler_options)
152
169
 
153
- result = compiler.result
154
- source_map = compiler.source_map.to_json
170
+ compiler.compile
155
171
 
156
- b64 = [result, source_map, contents].map { |i| Base64.strict_encode64(i) }.join(',')
172
+ result = compiler.result
173
+ source_map = compiler.source_map.to_json
157
174
 
158
- output.puts "https://sokra.github.io/source-map-visualization/#base64,#{b64}"
159
- end
175
+ b64 = [result, source_map, contents].map { |i| Base64.strict_encode64(i) }.join(',')
176
+
177
+ output.puts "https://sokra.github.io/source-map-visualization/#base64,#{b64}"
160
178
  end
161
179
 
162
180
  def compiler_option_names
@@ -177,29 +195,27 @@ module Opal
177
195
 
178
196
  # Internal: Yields a string of source code and the proper filename for either
179
197
  # evals, stdin or a filepath.
180
- def evals_or_file
181
- # --library
182
- return if lib_only
183
-
184
- if evals.any?
185
- yield evals.join("\n"), '-e'
186
- elsif file && (filename != '-' || evals.empty?)
187
- return @content if @content
188
-
189
- if file.tty?
190
- save = true
191
- else
192
- begin
193
- file.rewind
194
- rescue Errno::ESPIPE
195
- save = true
196
- end
198
+ def evals_or_file_source
199
+ return if lib_only # --library
200
+ return @cached_content if @cached_content
201
+
202
+ unless file.tty?
203
+ begin
204
+ file.rewind
205
+ can_read_again = true
206
+ rescue Errno::ESPIPE # rubocop:disable Lint/HandleExceptions
207
+ # noop
197
208
  end
209
+ end
198
210
 
199
- content = yield(file.read, filename)
200
- @content = content if save
201
- content
211
+ if @cached_content.nil? || can_read_again
212
+ # On MacOS file.read is not enough to pick up changes, probably due to some
213
+ # cache or buffer, unclear if coming from ruby or the OS.
214
+ content = File.file?(file) ? File.read(file) : file.read
202
215
  end
216
+
217
+ @cached_content ||= content unless can_read_again
218
+ content
203
219
  end
204
220
  end
205
221
  end
@@ -52,22 +52,20 @@ class Opal::CliRunners::Compiler
52
52
  end
53
53
 
54
54
  def fail_unrewindable!
55
- warn <<~ERROR
55
+ abort <<~ERROR
56
56
  You have specified --watch, but for watch to work, you must specify an
57
57
  --output file.
58
58
  ERROR
59
- exit 1
60
59
  end
61
60
 
62
61
  def fail_no_listen!
63
- warn <<~ERROR
62
+ abort <<~ERROR
64
63
  --watch mode requires the `listen` gem present. Please try to run:
65
64
 
66
65
  gem install listen
67
66
 
68
67
  Or if you are using bundler, add listen to your Gemfile.
69
68
  ERROR
70
- exit 1
71
69
  end
72
70
 
73
71
  def watch_compile
@@ -88,10 +86,13 @@ class Opal::CliRunners::Compiler
88
86
  $stderr.puts "* Opal v#{Opal::VERSION} successfully compiled your program in --watch mode"
89
87
 
90
88
  sleep
89
+ rescue Interrupt
90
+ $stderr.puts '* Stopping watcher...'
91
+ @code_listener.stop
91
92
  end
92
93
 
93
94
  def reexec
94
- system($0, *OriginalARGV) && exit
95
+ Process.kill('USR2', Process.pid)
95
96
  end
96
97
 
97
98
  def on_code_change(modified)
@@ -133,7 +134,7 @@ class Opal::CliRunners::Compiler
133
134
  def watch_files
134
135
  @directories = files_to_directories
135
136
 
136
- Listen.to(*@directories) do |modified, added, removed|
137
+ Listen.to(*@directories, ignore!: []) do |modified, added, removed|
137
138
  our_modified = @files & (modified + added + removed)
138
139
  on_code_change(our_modified) unless our_modified.empty?
139
140
  end