Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 65 additions & 2 deletions lib/wasify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,73 @@
require 'erb'
require_relative 'wasify/cmd_runner'
require_relative 'wasify/deps_manager'

# wrapper for Wasify
class Wasify
DEFAULT_WASM_VERSION = "2.5.0"
DEFAULT_RUBY_VERSION = "3.3"

# Anything before 2.1.0 doesn't have a browser.umd.js in CDN
#RUBY_WASM_VERSIONS = [ "2.1.0", "2.2.0", "2.3.0", "2.4.0", "2.4.1" ]

def self.download_filename
return @ruby_wasm_filename if @ruby_wasm_filename

wasm_version = ENV["WS_RUBY_WASM_VERSION"] ? ENV["WS_RUBY_WASM_VERSION"] : DEFAULT_WASM_VERSION

sep = "."
if wasm_version[0..2] < "2.4"
# Before 2.4, used an underscore separator.
sep = "_"
end

# Grab the Ruby version (3.2 or 3.3) and parse out the major and minor numbers
rv = gems_ruby_version
maj = gems_ruby_version[0]
min = gems_ruby_version[2]

@ruby_wasm_filename = "ruby-#{maj}#{sep}#{min}-wasm32-unknown-wasi-full-js-debug"
end

def self.dir_filename
return @ruby_dir_filename if @ruby_dir_filename

wasm_version = ENV["WS_RUBY_WASM_VERSION"] ? ENV["WS_RUBY_WASM_VERSION"] : DEFAULT_WASM_VERSION
if wasm_version[0..2] < "2.4"
@ruby_dir_filename = download_filename
else
@ruby_dir_filename = download_filename.delete_prefix("ruby-")
end
end

def self.gems_ruby_version
return @ruby_version if @ruby_version

ruby_short_version = ENV["WS_RUBY_VERSION"] ? ENV["WS_RUBY_VERSION"] : DEFAULT_RUBY_VERSION

if ruby_short_version == "3.3"
@ruby_version = "3.3.0"
elsif ruby_short_version == "3.2"
@ruby_version = "3.2.0"
else
raise "Unrecognized ENV WS_RUBY_VERSION value: should be 3.2 or 3.3!"
end
end

# This is the version of ruby/ruby.wasm being used
def self.wasi_version
return @wasi_version if @wasi_version

@wasi_version = ENV["WS_RUBY_WASM_VERSION"] || DEFAULT_WASM_VERSION

@wasi_version
end

# TODO: control the wasi-vfs version in the same way

def self.prepack
CMDRunner.download_binary unless File.exist?('ruby-3_2-wasm32-unknown-wasi-full-js.tar.gz')
CMDRunner.unzip_binary unless Dir.exist?('ruby-3_2-wasm32-unknown-wasi-full-js')
CMDRunner.download_binary unless File.exist?(self.download_filename + '.tar.gz')
CMDRunner.unzip_binary unless Dir.exist?(self.dir_filename)
CMDRunner.move_binary unless File.exist?('ruby.wasm')
CMDRunner.fix_lockfile
CMDRunner.copy_gemfile
Expand All @@ -34,6 +96,7 @@ def self.pack

def self.generate_html(entrypoint)
entrypoint_txt = DepsManager.add_entrypoint(entrypoint)
wasm_wasi_version = wasi_version
template = 'wasify/template.erb'
html = ERB.new(File.read(File.join(__dir__, template))).result(binding)
File.rename('index.html', 'index.html.bak') if File.exist?('index.html')
Expand Down
28 changes: 17 additions & 11 deletions lib/wasify/cmd_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,42 @@
class Wasify
# methods interacting with the command line
class CMDRunner
def self.run_or_fail(cmd)
system(cmd) || raise("Failed with #{$?.exitstatus} running cmd: #{cmd.inspect} in dir #{Dir.pwd.inspect}")
end

def self.download_binary
system('curl -LO https://github.com/ruby/ruby.wasm/releases/latest/download/ruby-3_2-wasm32-unknown-wasi-full-js.tar.gz')
version = Wasify.wasi_version
url = "https://github.com/ruby/ruby.wasm/releases/download/#{version}/#{Wasify.download_filename}.tar.gz"
run_or_fail("curl -LO #{url}")
end

def self.unzip_binary
system('tar xfz ruby-3_2-wasm32-unknown-wasi-full-js.tar.gz')
system('chmod -R u+rw 3_2-wasm32-unknown-wasi-full-js')
run_or_fail("tar xfz #{Wasify.download_filename}.tar.gz")
run_or_fail("chmod -R u+rw #{Wasify.dir_filename}")
end

def self.move_binary
system('mv 3_2-wasm32-unknown-wasi-full-js/usr/local/bin/ruby ruby.wasm')
run_or_fail("mv #{Wasify.dir_filename}/usr/local/bin/ruby ruby.wasm")
end

def self.copy_gemfile
system('mkdir -p deps && cp -r Gemfile deps/Gemfile && cp -r Gemfile.lock deps/Gemfile.lock')
run_or_fail('mkdir -p deps && cp -r Gemfile deps/Gemfile && cp -r Gemfile.lock deps/Gemfile.lock')
end

def self.fix_lockfile
system('bundle lock --add-platform wasm32-unknown')
run_or_fail('bundle lock --add-platform wasm32-unknown')
end

def self.run_vfs
system('wasi-vfs pack ruby.wasm --mapdir /src::./src --mapdir /usr::./3_2-wasm32-unknown-wasi-full-js/usr --mapdir /deps::./deps -o packed_ruby.wasm')
run_or_fail("wasi-vfs pack ruby.wasm --mapdir /src::./src --mapdir /usr::./#{Wasify.dir_filename}/usr --mapdir /deps::./deps -o packed_ruby.wasm")
end

def self.cleanup
system('rm -rf 3_2-wasm32-unknown-wasi-full-js')
system('rm ruby-3_2-wasm32-unknown-wasi-full-js.tar.gz')
system('rm ruby.wasm')
system('rm -rf deps')
run_or_fail("rm -rf #{Wasify.dir_filename}")
run_or_fail("rm #{Wasify.download_filename}.tar.gz")
run_or_fail('rm ruby.wasm')
run_or_fail('rm -rf deps')
end
end
end
6 changes: 3 additions & 3 deletions lib/wasify/deps_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def self.get_deps

def self.copy_deps
get_deps.each do |gem_name, dep|
dest_dir = "./3_2-wasm32-unknown-wasi-full-js/usr/local/lib/ruby/gems/3.2.0/gems/#{gem_name}"
dest_dir = "./#{Wasify.dir_filename}/usr/local/lib/ruby/gems/#{Wasify.gems_ruby_version}/gems/#{gem_name}"
if dep[:files] == :all
FileUtils.cp_r dep[:root], dest_dir
elsif dep[:files].respond_to?(:each)
Expand All @@ -84,9 +84,9 @@ def self.copy_deps
def self.copy_specs
deps = get_deps
specs = get_specs(deps)
FileUtils.mkdir_p "./3_2-wasm32-unknown-wasi-full-js/usr/local/lib/ruby/gems/3.2.0/specifications/"
FileUtils.mkdir_p "./#{Wasify.dir_filename}/usr/local/lib/ruby/gems/#{Wasify.gems_ruby_version}/specifications/"
specs.each do |name, contents|
File.write("./3_2-wasm32-unknown-wasi-full-js/usr/local/lib/ruby/gems/3.2.0/specifications/#{name}", contents)
File.write("./#{Wasify.dir_filename}/usr/local/lib/ruby/gems/#{Wasify.gems_ruby_version}/specifications/#{name}", contents)
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/wasify/template.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<html>
<script src="https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@latest/dist/browser.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@<%= wasm_wasi_version || "latest" %>/dist/browser.umd.js"></script>
<script>
const { DefaultRubyVM } = window["ruby-wasm-wasi"];
const main = async () => {
Expand Down