opal 1.7.0 → 1.7.1
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/.github/workflows/build.yml +12 -4
- data/CHANGELOG.md +29 -1
- data/exe/opal +5 -7
- data/lib/opal/builder.rb +13 -13
- data/lib/opal/builder_processors.rb +8 -2
- data/lib/opal/builder_scheduler/prefork.rb +60 -6
- data/lib/opal/cli.rb +59 -43
- data/lib/opal/cli_runners/compiler.rb +7 -6
- data/lib/opal/cli_runners/safari.rb +208 -0
- data/lib/opal/cli_runners.rb +1 -0
- data/lib/opal/nodes/literal.rb +16 -0
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/constants.rb +2 -2
- data/spec/filters/platform/.keep +0 -0
- data/spec/filters/platform/firefox/exception.rb +8 -0
- data/spec/filters/platform/firefox/kernel.rb +3 -0
- data/spec/filters/platform/safari/exception.rb +8 -0
- data/spec/filters/platform/safari/float.rb +4 -0
- data/spec/filters/platform/safari/kernel.rb +3 -0
- data/spec/filters/platform/safari/literal_regexp.rb +6 -0
- data/spec/lib/builder_spec.rb +32 -0
- data/spec/lib/cli_spec.rb +18 -6
- data/spec/lib/fixtures/build_order/file1.js +1 -0
- data/spec/lib/fixtures/build_order/file2.js +1 -0
- data/spec/lib/fixtures/build_order/file3.js +1 -0
- data/spec/lib/fixtures/build_order/file4.js +1 -0
- data/spec/lib/fixtures/build_order/file5.rb.erb +4 -0
- data/spec/lib/fixtures/build_order/file51.js +1 -0
- data/spec/lib/fixtures/build_order/file6.rb +10 -0
- data/spec/lib/fixtures/build_order/file61.rb +1 -0
- data/spec/lib/fixtures/build_order/file62.rb +4 -0
- data/spec/lib/fixtures/build_order/file63.rb +4 -0
- data/spec/lib/fixtures/build_order/file64.rb +1 -0
- data/spec/lib/fixtures/build_order/file7.rb +1 -0
- data/spec/lib/fixtures/build_order.rb +9 -0
- data/spec/lib/rake_dist_spec.rb +69 -0
- data/spec/mspec-opal/runner.rb +1 -0
- data/spec/opal/core/io/read_spec.rb +12 -3
- data/stdlib/opal/platform.rb +1 -0
- data/stdlib/opal-platform.rb +3 -0
- data/stdlib/time.rb +21 -1
- data/tasks/building.rake +1 -1
- data/tasks/testing.rake +3 -4
- metadata +29 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3867be8330f4fc45cb5ea9a759c3a1fd39880c5ea92e3c054cbfb2e8776d3f45
|
4
|
+
data.tar.gz: 9bae6c750966bc7e9551f5c4e6d21ce751ee66fc69862bae5b98b85299de7343
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56d87d05c1c043e165b30181b26a7c761d24d9168474fdcece06ca23ee5b4133d8d58722d9e3446f63db666d15acdc2bbcaf870b237f11673d7c6d810149dd1e
|
7
|
+
data.tar.gz: c7f9ced16e1b43ca58c75d7405319c6a5c8d008fa43db6cc1281d235bae1bce090a617d21234c3807ae5d3663b9b268799a87fb4da30f2afc8587a16d5185f7d
|
data/.github/workflows/build.yml
CHANGED
@@ -24,12 +24,12 @@ jobs:
|
|
24
24
|
- name: mspec-chrome
|
25
25
|
ruby: '3.0'
|
26
26
|
command: bin/rake mspec_chrome
|
27
|
-
- name:
|
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
|
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-
|
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
|
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.
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
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, :
|
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
|
-
|
59
|
-
|
60
|
-
|
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(
|
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
|
-
|
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
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
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
|
-
|
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
|
-
|
168
|
+
compiler = Opal::Compiler.new(source, file: filename, **compiler_options)
|
152
169
|
|
153
|
-
|
154
|
-
source_map = compiler.source_map.to_json
|
170
|
+
compiler.compile
|
155
171
|
|
156
|
-
|
172
|
+
result = compiler.result
|
173
|
+
source_map = compiler.source_map.to_json
|
157
174
|
|
158
|
-
|
159
|
-
|
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
|
181
|
-
# --library
|
182
|
-
return if
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
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
|
-
|
200
|
-
|
201
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|