opal 1.7.0 → 1.7.2
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 +39 -1
- data/UNRELEASED.md +1 -0
- data/docs/cdp_common.md +1 -1
- data/docs/compiler.md +1 -1
- data/docs/releasing.md +24 -8
- 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 +64 -9
- data/lib/opal/cli.rb +60 -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 +3 -3
- 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 +28 -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/lib/spec_helper.rb +2 -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/releasing.rake +46 -0
- data/tasks/testing.rake +3 -4
- metadata +30 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3221ae5854f26b0d0722ddf2689773633648086a616add372e8fdd617b31d7c0
|
4
|
+
data.tar.gz: b6b4a65b1905bddb6c1fd2310b13c03600ef4bb8fb416fff54e5499bfae8616c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a009bcca000c8fef3d73cda99453023b2860615e4c4c7176e328448cd12d5f26bbf6d2809ca040f064e64af7b04ddb94857b35ac36486a0c7996be28a63230b
|
7
|
+
data.tar.gz: d9154247ad9e90fbc770d647524db30fc8132b3fb77f8c5115abb67a3507fe66c0f7306a2965f1aca11bc790b2f6b7308d7db7bda7e9c3443b54bce42a957bab
|
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.2](https://github.com/opal/opal/compare/v1.7.1...v1.7.2) - 2023-01-20
|
20
20
|
|
21
21
|
|
22
22
|
<!--
|
@@ -29,6 +29,44 @@ Changes are grouped as follows:
|
|
29
29
|
### Fixed
|
30
30
|
-->
|
31
31
|
|
32
|
+
### Fixed
|
33
|
+
|
34
|
+
- Fix the `--debug-source-map` CLI option ([#2520](https://github.com/opal/opal/pull/2520))
|
35
|
+
- Fix links in `docs/compiler.md` ([#2519](https://github.com/opal/opal/pull/2519))
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
## [1.7.1](https://github.com/opal/opal/compare/v1.7.0...v1.7.1) - 2023-01-05
|
41
|
+
|
42
|
+
|
43
|
+
### Added
|
44
|
+
|
45
|
+
- Add safari runner ([#2513](https://github.com/opal/opal/pull/2513))
|
46
|
+
|
47
|
+
### Fixed
|
48
|
+
|
49
|
+
- Fix CLI file reading for macOS ([#2510](https://github.com/opal/opal/pull/2510))
|
50
|
+
- Make Date/Time.parse on Firefox more compatible with Chrome and Ruby ([#2506](https://github.com/opal/opal/pull/2506))
|
51
|
+
- Safari/WebKit can now parse code compiled with lookbehind regexps, failing at runtime instead ([#2511](https://github.com/opal/opal/pull/2511))
|
52
|
+
- Fix `--watch` ignoring some directories (e.g. `tmp`) ([#2509](https://github.com/opal/opal/pull/2509))
|
53
|
+
- Fix rake dist not generating libraries correctly for the CDN ([#2515](https://github.com/opal/opal/pull/2515))
|
54
|
+
- Prefork: output processed files in a correct, deterministic order ([#2516](https://github.com/opal/opal/pull/2516))
|
55
|
+
- Fix the handling of ARGV for the opal executable ([#2518](https://github.com/opal/opal/pull/2518))
|
56
|
+
|
57
|
+
### Internal
|
58
|
+
|
59
|
+
- Platform specific spec filters ([#2508](https://github.com/opal/opal/pull/2508))
|
60
|
+
- Run Firefox specs by default ([#2507](https://github.com/opal/opal/pull/2507))
|
61
|
+
- Run Safari specs by default ([#2513](https://github.com/opal/opal/pull/2513))
|
62
|
+
- [mspec_opal] Avoid lookbehind Regexp for compatibility with various javascript engines ([#2512](https://github.com/opal/opal/pull/2512))
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
## [1.7.0](https://github.com/opal/opal/compare/v1.6.1...v1.7.0) - 2022-12-26
|
68
|
+
|
69
|
+
|
32
70
|
### Added
|
33
71
|
|
34
72
|
- Update benchmarking and CLI runners, added support for Deno and Firefox (#2490, #2492, #2494, #2495, #2497, #2491, #2496)
|
data/UNRELEASED.md
CHANGED
data/docs/cdp_common.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# Common CDP of Chrome, Firefox, Node and Deno
|
2
2
|
|
3
3
|
cdp_common.json documents a subset of the common CDP as reported by Chrome, version 107 and Firefox, version 106.
|
4
4
|
All entries that where marked as "experimental" or "deprecated" have been removed.
|
data/docs/compiler.md
CHANGED
@@ -27,7 +27,7 @@ code as well as a reference back to the original sexp which is useful for
|
|
27
27
|
generating source maps afterwards.
|
28
28
|
|
29
29
|
|
30
|
-
[
|
30
|
+
[parser]: https://github.com/opal/opal/tree/master/lib/opal/parser.rb
|
31
31
|
[compiler]: https://github.com/opal/opal/tree/master/lib/opal/compiler.rb
|
32
32
|
[fragments]: https://github.com/opal/opal/tree/master/lib/opal/fragment.rb
|
33
33
|
[base-node]: https://github.com/opal/opal/tree/master/lib/opal/nodes/base.rb
|
data/docs/releasing.md
CHANGED
@@ -2,40 +2,56 @@
|
|
2
2
|
|
3
3
|
_This guide is a work-in-progress._
|
4
4
|
|
5
|
-
|
5
|
+
---
|
6
|
+
|
7
|
+
## Before the release
|
8
|
+
|
9
|
+
All of the following is now covered by `bin/rake release:prepare VERSION=v1.2.3`
|
10
|
+
|
11
|
+
### Updating the version
|
6
12
|
|
7
13
|
- Update `lib/opal/version.rb`
|
8
14
|
- Update `opal/corelib/constants.rb` with the same version number along with release dates
|
9
15
|
|
10
|
-
|
16
|
+
### Updating the changelog
|
11
17
|
|
12
18
|
- Ensure all the unreleased changes are documented in UNRELEASED.md
|
13
19
|
- [skip for pre-releases] Run `bin/rake changelog VERSION=v1.2.3` specifying the version number you're about to release
|
14
20
|
- [skip for pre-releases] Empty UNRELEASED.md
|
15
21
|
|
16
|
-
|
22
|
+
### The commit
|
17
23
|
|
18
24
|
- Commit the updated changelog along with the version bump using this commit message:
|
19
25
|
"Release v1.2.3"
|
20
|
-
|
26
|
+
|
27
|
+
---
|
28
|
+
|
29
|
+
## Release!
|
30
|
+
|
31
|
+
- Push the commit to `master`
|
32
|
+
- Run `bin/rake release` to release the new version to Rubygems
|
21
33
|
- Go to GitHub releases and create a new release from the latest tag pasting the contents from CHANGELOG.md (or UNRELEASED.md for pre-releases)
|
22
34
|
|
23
|
-
|
35
|
+
---
|
36
|
+
|
37
|
+
## After the release
|
38
|
+
|
39
|
+
### Opal docs
|
24
40
|
|
25
41
|
- Open `opal-docs` and run `bin/build v1.2.3`
|
26
42
|
- Then run `bin/deploy`
|
27
43
|
|
28
|
-
|
44
|
+
### [skip for pre-releases] Opal site
|
29
45
|
|
30
46
|
- Open `opal.github.io` and update the opal version in the `Gemfile`
|
31
47
|
- run `bin/build`
|
32
48
|
- `git push` the latest changes
|
33
49
|
|
34
|
-
|
50
|
+
### Opal CDN
|
35
51
|
|
36
52
|
- Run `bin/release v1.2.3`
|
37
53
|
|
38
|
-
|
54
|
+
### [skip for minor-releases] Prepare for the next release
|
39
55
|
|
40
56
|
- Create a new pull request that:
|
41
57
|
- Updates a version to `v1.x.0.dev` in both `lib/opal/version.rb` and `opal/corelib/constants.rb`
|
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,13 +245,16 @@ 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
|
|
198
253
|
awaiting = 0
|
199
254
|
built = 0
|
255
|
+
should_log = $stderr.tty? && !ENV['OPAL_DISABLE_PREFORK_LOGS']
|
200
256
|
|
201
|
-
$stderr.print "\r\e[K" if
|
257
|
+
$stderr.print "\r\e[K" if should_log
|
202
258
|
|
203
259
|
loop do
|
204
260
|
events, idles = @forks.get_events(queue.length)
|
@@ -206,7 +262,7 @@ module Opal
|
|
206
262
|
idles.each do |io|
|
207
263
|
break if queue.empty?
|
208
264
|
|
209
|
-
rel_path, req, autoloads, options = *queue.
|
265
|
+
rel_path, req, autoloads, options = *queue.shift
|
210
266
|
|
211
267
|
next if builder.already_processed.include?(req)
|
212
268
|
awaiting += 1
|
@@ -225,11 +281,8 @@ module Opal
|
|
225
281
|
asset, = *args
|
226
282
|
if !asset
|
227
283
|
# 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
284
|
else
|
232
|
-
|
285
|
+
processed << asset
|
233
286
|
end
|
234
287
|
built += 1
|
235
288
|
awaiting -= 1
|
@@ -244,7 +297,7 @@ module Opal
|
|
244
297
|
end
|
245
298
|
end
|
246
299
|
|
247
|
-
if
|
300
|
+
if should_log
|
248
301
|
percent = (100.0 * built / (awaiting + built)).round(1)
|
249
302
|
str = format("[opal/builder] Building %<first>s... (%<percent>4.3g%%)\r", first: first, percent: percent)
|
250
303
|
$stderr.print str
|
@@ -252,8 +305,10 @@ module Opal
|
|
252
305
|
|
253
306
|
break if awaiting == 0 && queue.empty?
|
254
307
|
end
|
308
|
+
|
309
|
+
processed
|
255
310
|
ensure
|
256
|
-
$stderr.print "\r\e[K\r" if
|
311
|
+
$stderr.print "\r\e[K\r" if should_log
|
257
312
|
@forks.close
|
258
313
|
@forks.wait
|
259
314
|
end
|
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,28 @@ 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
|
+
b64 = [
|
173
|
+
compiler.result,
|
174
|
+
compiler.source_map.to_json,
|
175
|
+
evals_or_file_source,
|
176
|
+
].map { |i| Base64.strict_encode64(i) }.join(',')
|
157
177
|
|
158
|
-
|
159
|
-
end
|
178
|
+
output.puts "https://sokra.github.io/source-map-visualization/#base64,#{b64}"
|
160
179
|
end
|
161
180
|
|
162
181
|
def compiler_option_names
|
@@ -177,29 +196,27 @@ module Opal
|
|
177
196
|
|
178
197
|
# Internal: Yields a string of source code and the proper filename for either
|
179
198
|
# 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
|
199
|
+
def evals_or_file_source
|
200
|
+
return if lib_only # --library
|
201
|
+
return @cached_content if @cached_content
|
202
|
+
|
203
|
+
unless file.tty?
|
204
|
+
begin
|
205
|
+
file.rewind
|
206
|
+
can_read_again = true
|
207
|
+
rescue Errno::ESPIPE # rubocop:disable Lint/HandleExceptions
|
208
|
+
# noop
|
197
209
|
end
|
210
|
+
end
|
198
211
|
|
199
|
-
|
200
|
-
|
201
|
-
|
212
|
+
if @cached_content.nil? || can_read_again
|
213
|
+
# On MacOS file.read is not enough to pick up changes, probably due to some
|
214
|
+
# cache or buffer, unclear if coming from ruby or the OS.
|
215
|
+
content = File.file?(file) ? File.read(file) : file.read
|
202
216
|
end
|
217
|
+
|
218
|
+
@cached_content ||= content unless can_read_again
|
219
|
+
content
|
203
220
|
end
|
204
221
|
end
|
205
222
|
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
|