ruby_wasm 2.5.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.clang-format +8 -0
  3. data/CONTRIBUTING.md +124 -0
  4. data/Cargo.lock +2452 -0
  5. data/Cargo.toml +7 -0
  6. data/Gemfile +17 -0
  7. data/LICENSE +21 -0
  8. data/NOTICE +1293 -0
  9. data/README.md +161 -0
  10. data/Rakefile +164 -0
  11. data/Steepfile +24 -0
  12. data/benchmarks/vm_deep_call.rb +55 -0
  13. data/builders/wasm32-unknown-emscripten/Dockerfile +43 -0
  14. data/builders/wasm32-unknown-emscripten/entrypoint.sh +7 -0
  15. data/builders/wasm32-unknown-wasi/Dockerfile +47 -0
  16. data/builders/wasm32-unknown-wasi/entrypoint.sh +7 -0
  17. data/docs/api.md +2 -0
  18. data/docs/cheat_sheet.md +195 -0
  19. data/docs/faq.md +25 -0
  20. data/exe/rbwasm +7 -0
  21. data/ext/.gitignore +2 -0
  22. data/ext/README.md +11 -0
  23. data/ext/extinit.c.erb +32 -0
  24. data/ext/ruby_wasm/Cargo.toml +17 -0
  25. data/ext/ruby_wasm/extconf.rb +6 -0
  26. data/ext/ruby_wasm/src/lib.rs +69 -0
  27. data/lib/ruby_wasm/build/build_params.rb +3 -0
  28. data/lib/ruby_wasm/build/downloader.rb +18 -0
  29. data/lib/ruby_wasm/build/executor.rb +187 -0
  30. data/lib/ruby_wasm/build/product/baseruby.rb +37 -0
  31. data/lib/ruby_wasm/build/product/crossruby.rb +326 -0
  32. data/lib/ruby_wasm/build/product/libyaml.rb +68 -0
  33. data/lib/ruby_wasm/build/product/openssl.rb +88 -0
  34. data/lib/ruby_wasm/build/product/product.rb +39 -0
  35. data/lib/ruby_wasm/build/product/ruby_source.rb +103 -0
  36. data/lib/ruby_wasm/build/product/wasi_vfs.rb +83 -0
  37. data/lib/ruby_wasm/build/product/zlib.rb +68 -0
  38. data/lib/ruby_wasm/build/product.rb +8 -0
  39. data/lib/ruby_wasm/build/toolchain/wit_bindgen.rb +31 -0
  40. data/lib/ruby_wasm/build/toolchain.rb +193 -0
  41. data/lib/ruby_wasm/build.rb +88 -0
  42. data/lib/ruby_wasm/cli.rb +195 -0
  43. data/lib/ruby_wasm/packager/core.rb +156 -0
  44. data/lib/ruby_wasm/packager/file_system.rb +157 -0
  45. data/lib/ruby_wasm/packager.rb +159 -0
  46. data/lib/ruby_wasm/rake_task.rb +58 -0
  47. data/lib/ruby_wasm/util.rb +15 -0
  48. data/lib/ruby_wasm/version.rb +3 -0
  49. data/lib/ruby_wasm.rb +33 -0
  50. data/package-lock.json +9500 -0
  51. data/package.json +12 -0
  52. data/ruby_wasm.gemspec +32 -0
  53. data/sig/open_uri.rbs +4 -0
  54. data/sig/ruby_wasm/build.rbs +322 -0
  55. data/sig/ruby_wasm/cli.rbs +24 -0
  56. data/sig/ruby_wasm/ext.rbs +11 -0
  57. data/sig/ruby_wasm/packager.rbs +91 -0
  58. data/sig/ruby_wasm/util.rbs +5 -0
  59. data/tasks/check.rake +37 -0
  60. data/tasks/ci.rake +152 -0
  61. data/tasks/doc.rake +24 -0
  62. data/tasks/format.rake +34 -0
  63. data/tasks/gem.rake +19 -0
  64. data/tasks/packaging.rake +148 -0
  65. data/tasks/version.rake +38 -0
  66. data/tools/clang-format-diff.sh +18 -0
  67. data/tools/exe/rbminify +12 -0
  68. data/tools/lib/syntax_tree/minify_ruby.rb +63 -0
  69. metadata +115 -0
data/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # ruby.wasm
2
+
3
+ [![Build ruby.wasm](https://github.com/ruby/ruby.wasm/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/ruby/ruby.wasm/actions/workflows/build.yml)
4
+
5
+ ruby.wasm is a collection of WebAssembly ports of the [CRuby](https://github.com/ruby/ruby).
6
+ It enables running Ruby application on browsers, WASI compatible WebAssembly runtimes, and Edge Computing platforms.
7
+
8
+ ## Try ruby.wasm (no installation needed)
9
+
10
+ Try ruby.wasm in [TryRuby](https://try.ruby-lang.org/playground#code=puts+RUBY_DESCRIPTION&engine=cruby-3.2.0dev) in your browser.
11
+
12
+ ## Quick Links
13
+
14
+ - [Cheat Sheet](https://github.com/ruby/ruby.wasm/blob/main/docs/cheat_sheet.md)
15
+ - [FAQ](https://github.com/ruby/ruby.wasm/blob/main/docs/faq.md)
16
+ - [API Reference](https://github.com/ruby/ruby.wasm/blob/main/docs/api.md)
17
+ - [Complete Examples](https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-wasm-wasi/example)
18
+ - [Community Showcase](https://github.com/ruby/ruby.wasm/wiki/Showcase)
19
+
20
+ ## Quick Example: Ruby on browser
21
+
22
+ Create and save `index.html` page with the following contents:
23
+
24
+ ```html
25
+ <html>
26
+ <script src="https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.4.1/dist/browser.script.iife.js"></script>
27
+ <script type="text/ruby">
28
+ require "js"
29
+
30
+ puts RUBY_VERSION # => Hello, world! (printed to the browser console)
31
+ JS.global[:document].write "Hello, world!"
32
+ </script>
33
+ </html>
34
+ ```
35
+
36
+ ## Quick Example: How to package your Ruby application as a WASI application
37
+
38
+ Dependencies: [wasi-vfs](https://github.com/kateinoigakukun/wasi-vfs), [wasmtime](https://github.com/bytecodealliance/wasmtime)
39
+
40
+ ```console
41
+ # Download a prebuilt Ruby release
42
+ $ curl -LO https://github.com/ruby/ruby.wasm/releases/latest/download/ruby-3.2-wasm32-unknown-wasi-full.tar.gz
43
+ $ tar xfz ruby-3.2-wasm32-unknown-wasi-full.tar.gz
44
+
45
+ # Extract ruby binary not to pack itself
46
+ $ mv 3.2-wasm32-unknown-wasi-full/usr/local/bin/ruby ruby.wasm
47
+
48
+ # Put your app code
49
+ $ mkdir src
50
+ $ echo "puts 'Hello'" > src/my_app.rb
51
+
52
+ # Pack the whole directory under /usr and your app dir
53
+ $ wasi-vfs pack ruby.wasm --mapdir /src::./src --mapdir /usr::./3.2-wasm32-unknown-wasi-full/usr -o my-ruby-app.wasm
54
+
55
+ # Run the packed scripts
56
+ $ wasmtime my-ruby-app.wasm -- /src/my_app.rb
57
+ Hello
58
+ ```
59
+
60
+ ## npm packages (for JavaScript host environments)
61
+
62
+ See the `README.md` of each package for more detail and its usage.
63
+
64
+ <table>
65
+ <thead>
66
+ <tr>
67
+ <th>Package</th>
68
+ <th>Description</th>
69
+ <th>npm</th>
70
+ </tr>
71
+ </thead>
72
+ <tbody>
73
+ <tr>
74
+ <td><a href="/packages/npm-packages/ruby-3.3-wasm-wasi">@ruby/3.3-wasm-wasi</a></td>
75
+ <td>CRuby 3.3 built on WASI with JS interop support</td>
76
+ <td><a href="https://www.npmjs.com/package/@ruby/3.3-wasm-wasi" rel="nofollow"><img src="https://badge.fury.io/js/@ruby%2F3.3-wasm-wasi.svg" alt="npm version" style="max-width: 100%;"></a></td>
77
+ </tr>
78
+ <tr>
79
+ <td><a href="/packages/npm-packages/ruby-3.2-wasm-wasi">@ruby/3.2-wasm-wasi</a></td>
80
+ <td>CRuby 3.2 built on WASI with JS interop support</td>
81
+ <td><a href="https://www.npmjs.com/package/@ruby/3.2-wasm-wasi" rel="nofollow"><img src="https://badge.fury.io/js/@ruby%2F3.2-wasm-wasi.svg" alt="npm version" style="max-width: 100%;"></a></td>
82
+ </tr>
83
+ <tr>
84
+ <td><a href="/packages/npm-packages/ruby-head-wasm-wasi">@ruby/head-wasm-wasi</a></td>
85
+ <td>HEAD CRuby built on WASI with JS interop support</td>
86
+ <td><a href="https://www.npmjs.com/package/@ruby/head-wasm-wasi" rel="nofollow"><img src="https://badge.fury.io/js/@ruby%2Fhead-wasm-wasi.svg" alt="npm version" style="max-width: 100%;"></a></td>
87
+ </tr>
88
+ <tr>
89
+ <td><a href="/packages/npm-packages/ruby-head-wasm-emscripten">@ruby/head-wasm-emscripten</a></td>
90
+ <td>HEAD CRuby built on Emscripten (not well tested)</td>
91
+ <td><a href="https://www.npmjs.com/package/@ruby/head-wasm-emscripten" rel="nofollow"><img src="https://badge.fury.io/js/@ruby%2Fhead-wasm-emscripten.svg" alt="npm version" style="max-width: 100%;"></a></td>
92
+ </tr>
93
+ </tbody>
94
+ </table>
95
+
96
+ ## Prebuilt binaries
97
+
98
+ This project distributes [prebuilt Ruby binaries in GitHub Releases](https://github.com/ruby/ruby.wasm/releases).
99
+ A _build_ is a combination of ruby version, _profile_, and _target_.
100
+
101
+ ### Supported Target Triples
102
+
103
+ <table>
104
+ <thead>
105
+ <tr>
106
+ <th>Triple</th>
107
+ <th>Description</th>
108
+ </tr>
109
+ </thead>
110
+ <tbody>
111
+ <tr>
112
+ <td><code>wasm32-unknown-wasi</code></td>
113
+ <td>Targeting WASI-compatible environments (e.g. Node.js, browsers with polyfill, <a href="https://github.com/bytecodealliance/wasmtime">wasmtime</a>, and so on)</td>
114
+ </tr>
115
+ <tr>
116
+ <td><code>wasm32-unknown-emscripten</code></td>
117
+ <td>Targeting JavaScript environments including Node.js and browsers</td>
118
+ </tr>
119
+ </tbody>
120
+ </table>
121
+
122
+ ### Profiles
123
+
124
+ <table>
125
+ <thead>
126
+ <tr>
127
+ <th>Profile</th>
128
+ <th>Description</th>
129
+ </tr>
130
+ </thead>
131
+ <tbody>
132
+ <tr>
133
+ <td><code>minimal</code></td>
134
+ <td>No standard extension libraries (like <code>json</code>, <code>yaml</code>, or <code>stringio</code>)</td>
135
+ </tr>
136
+ <tr>
137
+ <td><code>full</code></td>
138
+ <td>All standard extension libraries</td>
139
+ </tr>
140
+ <tr>
141
+ <td><code>*-js</code></td>
142
+ <td>Enabled JS interoperability, only usable with npm package</td>
143
+ </tr>
144
+ <tr>
145
+ <td><code>*-debug</code></td>
146
+ <td>With DWARF info and <a href="https://webassembly.github.io/spec/core/appendix/custom.html#name-section" rel="nofollow"><code>name</code> section</a> for debugging</td>
147
+ </tr>
148
+ </tbody>
149
+ </table>
150
+
151
+ ## Notable Limitations
152
+
153
+ The current WASI target build does not yet support `Thread` related APIs. Specifically, WASI does not yet have an API for creating and managing threads yet.
154
+
155
+ Also there is no support for networking. It is one of the goal of WASI to support networking in the future, but it is not yet implemented.
156
+
157
+
158
+ ## Contributing
159
+
160
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to build and test, and how to contribute to this project.
161
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/ruby.wasm
data/Rakefile ADDED
@@ -0,0 +1,164 @@
1
+ require "rake"
2
+ require "json"
3
+ require "open-uri"
4
+
5
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "lib")
6
+
7
+ require "bundler/gem_tasks"
8
+ require "ruby_wasm/rake_task"
9
+ require "ruby_wasm/packager"
10
+
11
+ Dir.glob("tasks/**.rake").each { |f| import f }
12
+
13
+ BUILD_SOURCES = %w[3.3 3.2 head]
14
+ BUILD_PROFILES = %w[full minimal]
15
+
16
+ BUILDS =
17
+ BUILD_SOURCES
18
+ .product(BUILD_PROFILES)
19
+ .map { |src, profile| [src, "wasm32-unknown-wasi", profile] } +
20
+ BUILD_SOURCES.map { |src| [src, "wasm32-unknown-emscripten", "full"] }
21
+
22
+ NPM_PACKAGES = [
23
+ {
24
+ name: "ruby-head-wasm-emscripten",
25
+ ruby_version: "head",
26
+ gemfile: nil,
27
+ target: "wasm32-unknown-emscripten"
28
+ },
29
+ {
30
+ name: "ruby-head-wasm-wasi",
31
+ ruby_version: "head",
32
+ gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
33
+ target: "wasm32-unknown-wasi"
34
+ },
35
+ {
36
+ name: "ruby-3.3-wasm-wasi",
37
+ ruby_version: "3.3",
38
+ gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
39
+ target: "wasm32-unknown-wasi"
40
+ },
41
+ {
42
+ name: "ruby-3.2-wasm-wasi",
43
+ ruby_version: "3.2",
44
+ gemfile: "packages/npm-packages/ruby-wasm-wasi/Gemfile",
45
+ target: "wasm32-unknown-wasi"
46
+ }
47
+ ]
48
+
49
+ STANDALONE_PACKAGES = [
50
+ { name: "ruby", build: "head-wasm32-unknown-wasi-full" },
51
+ { name: "irb", build: "head-wasm32-unknown-wasi-full" }
52
+ ]
53
+
54
+ LIB_ROOT = File.dirname(__FILE__)
55
+
56
+ TOOLCHAINS = {}
57
+ BUILDS
58
+ .map { |_, target, _| target }
59
+ .uniq
60
+ .each do |target|
61
+ build_dir = File.join(LIB_ROOT, "build")
62
+ toolchain = RubyWasm::Toolchain.get(target, build_dir)
63
+ TOOLCHAINS[toolchain.name] = toolchain
64
+ end
65
+
66
+ class BuildTask < Struct.new(:name, :target, :build_command)
67
+ def ruby_cache_key
68
+ return @key if @key
69
+ require "open3"
70
+ cmd = build_command + ["--print-ruby-cache-key"]
71
+ stdout, status = Open3.capture2(*cmd)
72
+ unless status.success?
73
+ raise "Command failed with status (#{status.exitstatus}): #{cmd.join ""}"
74
+ end
75
+ require "json"
76
+ @key = JSON.parse(stdout)
77
+ end
78
+
79
+ def hexdigest
80
+ ruby_cache_key["hexdigest"]
81
+ end
82
+ def artifact
83
+ ruby_cache_key["artifact"]
84
+ end
85
+ end
86
+
87
+ namespace :build do
88
+ BUILD_TASKS =
89
+ BUILDS.map do |src, target, profile|
90
+ name = "#{src}-#{target}-#{profile}"
91
+
92
+ build_command = [
93
+ "exe/rbwasm",
94
+ "build",
95
+ "--ruby-version",
96
+ src,
97
+ "--target",
98
+ target,
99
+ "--build-profile",
100
+ profile,
101
+ "--disable-gems",
102
+ "-o",
103
+ "/dev/null"
104
+ ]
105
+ desc "Cross-build Ruby for #{target}"
106
+ task name do
107
+ sh *build_command
108
+ end
109
+ namespace name do
110
+ task :remake do
111
+ sh *build_command, "--remake"
112
+ end
113
+ task :reconfigure do
114
+ sh *build_command, "--reconfigure"
115
+ end
116
+ task :clean do
117
+ sh *build_command, "--clean"
118
+ end
119
+ end
120
+
121
+ BuildTask.new(name, target, build_command)
122
+ end
123
+
124
+ desc "Clean build directories"
125
+ task :clean do
126
+ rm_rf "./build"
127
+ rm_rf "./rubies"
128
+ end
129
+
130
+ desc "Download prebuilt Ruby"
131
+ task :download_prebuilt, :tag do |t, args|
132
+ require "ruby_wasm/build/downloader"
133
+
134
+ release =
135
+ if args[:tag]
136
+ url =
137
+ "https://api.github.com/repos/ruby/ruby.wasm/releases/tags/#{args[:tag]}"
138
+ OpenURI.open_uri(url) { |f| JSON.load(f.read) }
139
+ else
140
+ url = "https://api.github.com/repos/ruby/ruby.wasm/releases?per_page=1"
141
+ OpenURI.open_uri(url) { |f| JSON.load(f.read)[0] }
142
+ end
143
+
144
+ puts "Downloading from release \"#{release["tag_name"]}\""
145
+
146
+ rubies_dir = "./rubies"
147
+ downloader = RubyWasm::Downloader.new
148
+ rm_rf rubies_dir
149
+ mkdir_p rubies_dir
150
+
151
+ assets = release["assets"].select { |a| a["name"].end_with? ".tar.gz" }
152
+ assets.each_with_index do |asset, i|
153
+ url = asset["browser_download_url"]
154
+ tarball = File.join("rubies", asset["name"])
155
+ rm_rf tarball, verbose: false
156
+ downloader.download(
157
+ url,
158
+ tarball,
159
+ "[%2d/%2d] Downloading #{File.basename(url)}" % [i + 1, assets.size]
160
+ )
161
+ sh "tar xzf #{tarball} -C ./rubies"
162
+ end
163
+ end
164
+ end
data/Steepfile ADDED
@@ -0,0 +1,24 @@
1
+ D = Steep::Diagnostic
2
+
3
+ target :lib do
4
+ signature "sig"
5
+
6
+ check "lib"
7
+ # RBS's stdlib signatures don't have rake signatures yet.
8
+ ignore "lib/ruby_wasm/rake_task.rb"
9
+
10
+ library "digest"
11
+ library "tmpdir"
12
+ library "fileutils"
13
+ library "open-uri"
14
+ library "uri"
15
+ library "shellwords"
16
+ library "io-console"
17
+ library "optparse"
18
+ library "json"
19
+ library "logger"
20
+ library "pathname"
21
+ library "forwardable"
22
+
23
+ configure_code_diagnostics(D::Ruby.default)
24
+ end
@@ -0,0 +1,55 @@
1
+ # This script checks the max number of call frames under WebAssembly restriction
2
+ #
3
+ # Example runs
4
+ # $ ruby vm_deep_call.rb
5
+ # $ RUBY_EXE="wasmtime run --mapdir /::/ head-wasm32-unknown-wasi-minimal/usr/local/bin/ruby --" ruby vm_deep_call.rb
6
+ # $ RUBY_EXE="wasmtime run --env RUBY_FIBER_MACHINE_STACK_SIZE=20971520 --mapdir /::/ head-wasm32-unknown-wasi-minimal/usr/local/bin/ruby --" ruby vm_deep_call.rb
7
+
8
+ def vm_rec n
9
+ vm_rec n - 1 if n > 0
10
+ end
11
+
12
+ def vm_c_rec n
13
+ 1.times do
14
+ vm_c_rec n - 1 if n > 0
15
+ end
16
+ end
17
+
18
+ def vm_rec_fiber n
19
+ Fiber.new { vm_rec n }.resume
20
+ end
21
+
22
+ def vm_c_rec_fiber n
23
+ Fiber.new { vm_c_rec n }.resume
24
+ end
25
+
26
+ def check(ruby_exe, target, n)
27
+ cmd = %Q(#{ruby_exe} -r #{File.expand_path(__FILE__)} -e "#{target}(#{n})")
28
+ Kernel.system(cmd, err: File::NULL)
29
+ end
30
+
31
+ def bisect(ruby_exe, target)
32
+ min = 0
33
+ max = 15000
34
+ while min < max
35
+ mid = (min + max) / 2
36
+ ok = check(ruby_exe, target, mid)
37
+ if ok
38
+ min = mid + 1
39
+ else
40
+ max = mid
41
+ end
42
+ end
43
+ min
44
+ end
45
+
46
+ def main
47
+ ruby_exe = ENV['RUBY_EXE'] || 'ruby'
48
+ puts "How deep the call stack can be"
49
+ puts " with only VM calls: " + bisect(ruby_exe, "vm_rec").to_s
50
+ puts " with only VM calls in Fiber: " + bisect(ruby_exe, "vm_rec_fiber").to_s
51
+ puts " with VM and C calls: " + bisect(ruby_exe, "vm_c_rec").to_s
52
+ puts " with VM and C calls in Fiber: " + bisect(ruby_exe, "vm_c_rec_fiber").to_s
53
+ end
54
+
55
+ main if $0 == __FILE__
@@ -0,0 +1,43 @@
1
+ FROM emscripten/emsdk:3.1.31
2
+
3
+ ARG NODE_MAJOR_VERSION=20
4
+
5
+ RUN set -eux; \
6
+ apt-get update; \
7
+ apt-get install -y ca-certificates curl gnupg; \
8
+ mkdir -p /etc/apt/keyrings; \
9
+ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg; \
10
+ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR_VERSION.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list; \
11
+ apt-get update; \
12
+ apt-get install ruby ruby-dev ruby-bundler nodejs \
13
+ bison make autoconf git curl build-essential \
14
+ libyaml-dev zlib1g-dev gosu \
15
+ libclang-13-dev -y; \
16
+ apt-get clean; \
17
+ rm -r /var/lib/apt/lists/*
18
+
19
+ # Prefer apt-installed nodejs instead of emsdk's old one.
20
+ ENV PATH=/usr/bin:$PATH
21
+
22
+ ENV RUSTUP_HOME=/usr/local/rustup \
23
+ CARGO_HOME=/usr/local/cargo \
24
+ PATH=/usr/local/cargo/bin:$PATH \
25
+ RUST_VERSION=1.74
26
+
27
+ RUN set -eux pipefail; \
28
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
29
+ sh -s -- -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION; \
30
+ chmod -R a+w $RUSTUP_HOME $CARGO_HOME
31
+
32
+ ENV BUNDLE_PATH=/usr/local/gems
33
+ RUN set -eux; \
34
+ mkdir -p $BUNDLE_PATH; \
35
+ chmod -R 777 $BUNDLE_PATH
36
+
37
+ COPY entrypoint.sh /usr/local/bin/entrypoint.sh
38
+ RUN chmod +x /usr/local/bin/entrypoint.sh
39
+ ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
40
+ # Build with non-root user because `@npmcli/promise-spawn` sets `uid` and `gid` to cwd owner when the current user is root.
41
+ # This permission demotion results in EACCES error at reading `$HOME/.node_modules` in `resolve` package, which is used by `@rollup/plugin-node-resolve`.
42
+ # * https://github.com/npm/cli/blob/32336f6efe06bd52de1dc67c0f812d4705533ef2/node_modules/%40npmcli/promise-spawn/lib/index.js#L13
43
+ RUN adduser --disabled-password --gecos '' me
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ [ ! -z "${RUBYWASM_UID+x}" ] && usermod --uid "$RUBYWASM_UID" --non-unique me
6
+ [ ! -z "${RUBYWASM_GID+x}" ] && groupmod --gid "$RUBYWASM_GID" --non-unique me
7
+ exec gosu me "$@"
@@ -0,0 +1,47 @@
1
+ FROM debian:bullseye
2
+
3
+ ARG WASI_PRESET_ARGS_VERSION=0.1.1
4
+ ARG NODE_MAJOR_VERSION=20
5
+
6
+ RUN set -eux; \
7
+ apt-get update; \
8
+ apt-get install -y ca-certificates curl gnupg; \
9
+ mkdir -p /etc/apt/keyrings; \
10
+ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg; \
11
+ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR_VERSION.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list; \
12
+ apt-get update; \
13
+ apt-get install ruby ruby-dev ruby-bundler nodejs \
14
+ bison make autoconf git curl build-essential \
15
+ libyaml-dev zlib1g-dev gosu \
16
+ libclang-13-dev -y; \
17
+ apt-get clean; \
18
+ rm -r /var/lib/apt/lists/*
19
+
20
+ RUN set -eux pipefail; \
21
+ wasi_preset_args_url="https://github.com/kateinoigakukun/wasi-preset-args/releases/download/v${WASI_PRESET_ARGS_VERSION}/wasi-preset-args-x86_64-unknown-linux-gnu.zip"; \
22
+ curl -LO "$wasi_preset_args_url"; \
23
+ unzip wasi-preset-args-x86_64-unknown-linux-gnu.zip; \
24
+ mv wasi-preset-args /usr/local/bin/wasi-preset-args
25
+
26
+ ENV RUSTUP_HOME=/usr/local/rustup \
27
+ CARGO_HOME=/usr/local/cargo \
28
+ PATH=/usr/local/cargo/bin:$PATH \
29
+ RUST_VERSION=1.74
30
+
31
+ RUN set -eux pipefail; \
32
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
33
+ sh -s -- -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION; \
34
+ chmod -R a+w $RUSTUP_HOME $CARGO_HOME
35
+
36
+ ENV BUNDLE_PATH=/usr/local/gems
37
+ RUN set -eux; \
38
+ mkdir -p $BUNDLE_PATH; \
39
+ chmod -R 777 $BUNDLE_PATH
40
+
41
+ COPY entrypoint.sh /usr/local/bin/entrypoint.sh
42
+ RUN chmod +x /usr/local/bin/entrypoint.sh
43
+ ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
44
+ # Build with non-root user because `@npmcli/promise-spawn` sets `uid` and `gid` to cwd owner when the current user is root.
45
+ # This permission demotion results in EACCES error at reading `$HOME/.node_modules` in `resolve` package, which is used by `@rollup/plugin-node-resolve`.
46
+ # * https://github.com/npm/cli/blob/32336f6efe06bd52de1dc67c0f812d4705533ef2/node_modules/%40npmcli/promise-spawn/lib/index.js#L13
47
+ RUN adduser --disabled-password --gecos '' me
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ [ ! -z "${RUBYWASM_UID+x}" ] && usermod --uid "$RUBYWASM_UID" --non-unique me
6
+ [ ! -z "${RUBYWASM_GID+x}" ] && groupmod --gid "$RUBYWASM_GID" --non-unique me
7
+ exec gosu me "$@"
data/docs/api.md ADDED
@@ -0,0 +1,2 @@
1
+ - [Ruby API](https://ruby.github.io/ruby.wasm/JS.html)
2
+ - [JavaScript API](https://github.com/ruby/ruby.wasm/blob/main/packages/npm-packages/ruby-wasm-wasi/README.md#API)