Class: RubyWasm::Packager::FileSystem

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_wasm/packager/file_system.rb,
sig/ruby_wasm/packager.rbs

Overview

Package Ruby code into a mountable directory.

Instance Method Summary collapse

Constructor Details

#initialize(dest_dir, packager) ⇒ FileSystem

Returns a new instance of FileSystem.

Parameters:



3
4
5
6
7
# File 'lib/ruby_wasm/packager/file_system.rb', line 3

def initialize(dest_dir, packager)
  @dest_dir = dest_dir
  @packager = packager
  @ruby_root = File.join(@dest_dir, "usr", "local")
end

Instance Method Details

#bundle_dirString

Returns:

  • (String)


104
105
106
# File 'lib/ruby_wasm/packager/file_system.rb', line 104

def bundle_dir
  File.join(@dest_dir, bundle_relative_path)
end

#bundle_relative_pathString

Returns:

  • (String)


162
163
164
# File 'lib/ruby_wasm/packager/file_system.rb', line 162

def bundle_relative_path
  "bundle"
end

#each_gem_content_path {|arg0, arg1| ... } ⇒ void

This method returns an undefined value.

Yields:

Yield Parameters:

  • arg0 (String)
  • arg1 (String)

Yield Returns:

  • (void)


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/ruby_wasm/packager/file_system.rb', line 130

def each_gem_content_path(&block)
  each_gem_extension_path(&block)

  @packager.specs.each do |spec|
    next unless File.exist?(spec.full_gem_path)

    # spec.files is only valid before the gem is packaged.
    if spec.source.path?
      relative_paths = spec.files
    else
      # All files in .gem are required.
      relative_paths = Dir.children(spec.full_gem_path)
    end
    relative_paths.each do |require_path|
      source = File.expand_path(require_path, spec.full_gem_path)
      next unless File.exist?(source)
      relative =
        File.join(bundle_relative_path, "gems", spec.full_name, require_path)
      yield relative, source
    end
  end
end

#each_gem_extension_path {|arg0, arg1| ... } ⇒ void

This method returns an undefined value.

Yields:

Yield Parameters:

  • arg0 (String)
  • arg1 (String)

Yield Returns:

  • (void)


153
154
155
156
157
158
159
160
# File 'lib/ruby_wasm/packager/file_system.rb', line 153

def each_gem_extension_path
  @packager.specs.each do |spec|
    if !spec.extensions.empty? && File.exist?(spec.extension_dir)
      relative = File.join(bundle_relative_path, "extensions", spec.full_name)
      yield relative, spec.extension_dir
    end
  end
end

#each_gem_require_path {|arg0, arg1| ... } ⇒ void

This method returns an undefined value.

Iterates over each gem's require path and extension path. Yields the installation relative path and the source path.

Yields:

Yield Parameters:

  • arg0 (String)
  • arg1 (String)

Yield Returns:

  • (void)


116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/ruby_wasm/packager/file_system.rb', line 116

def each_gem_require_path(&block)
  each_gem_extension_path(&block)
  @packager.specs.each do |spec|
    # Use raw_require_paths to exclude extensions
    spec.raw_require_paths.each do |require_path|
      source = File.expand_path(require_path, spec.full_gem_path)
      next unless File.exist?(source)
      relative =
        File.join(bundle_relative_path, "gems", spec.full_name, require_path)
      yield relative, source
    end
  end
end

#package_gemsvoid

This method returns an undefined value.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ruby_wasm/packager/file_system.rb', line 57

def package_gems
  @packager.specs.each do |spec|
    RubyWasm.logger.info "Packaging gem: #{spec.full_name}"
  end
  self.each_gem_content_path do |relative, source|
    RubyWasm.logger.debug "Packaging gem file: #{relative}"
    dest = File.join(@dest_dir, relative)
    FileUtils.mkdir_p File.dirname(dest)
    FileUtils.cp_r source, dest
  end

  setup_rb_path = File.join(bundle_relative_path, "setup.rb")
  RubyWasm.logger.info "Packaging setup.rb: #{setup_rb_path}"
  full_setup_rb_path = File.join(@dest_dir, setup_rb_path)
  FileUtils.mkdir_p File.dirname(full_setup_rb_path)
  File.write(full_setup_rb_path, setup_rb_content)
end

#package_ruby_root(tarball, executor) ⇒ void

This method returns an undefined value.

Parameters:



9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/ruby_wasm/packager/file_system.rb', line 9

def package_ruby_root(tarball, executor)
  usr_dir = File.dirname(@ruby_root)
  executor.mkdir_p usr_dir
  executor.system(
    "tar",
    "-C",
    usr_dir,
    "-xzf",
    tarball,
    "--strip-components=2"
  )
end

#remove_non_runtime_files(executor) ⇒ void

This method returns an undefined value.

Parameters:



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/ruby_wasm/packager/file_system.rb', line 83

def remove_non_runtime_files(executor)
  patterns = %w[
    usr/local/lib/libruby-static.a
    usr/local/bin/ruby
    usr/local/include
  ]

  patterns << "**/*.so" unless @packager.features.support_dynamic_linking?
  patterns.each do |pattern|
    Dir
      .glob(File.join(@dest_dir, pattern))
      .each do |entry|
        RubyWasm.logger.debug do
          relative_entry = Pathname.new(entry).relative_path_from(@dest_dir)
          "Removing non-runtime file: #{relative_entry}"
        end
        executor.rm_rf entry
      end
  end
end

#remove_stdlib(executor) ⇒ void

This method returns an undefined value.

Parameters:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/ruby_wasm/packager/file_system.rb', line 22

def remove_stdlib(executor)
  # Include only rbconfig.rb
  rbconfig =
    File.join(
      @ruby_root,
      "lib",
      "ruby",
      ruby_version,
      "wasm32-wasi",
      "rbconfig.rb"
    )
  # Remove all files except rbconfig.rb
  RubyWasm.logger.info "Removing stdlib (except rbconfig.rb: #{rbconfig})"
  rbconfig_contents = File.read(rbconfig)
  executor.rm_rf @ruby_root
  executor.mkdir_p File.dirname(rbconfig)
  File.write(rbconfig, rbconfig_contents)
end

#remove_stdlib_component(executor, component) ⇒ void

This method returns an undefined value.

Parameters:



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/ruby_wasm/packager/file_system.rb', line 41

def remove_stdlib_component(executor, component)
  RubyWasm.logger.info "Removing stdlib component: #{component}"
  case component
  when "enc"
    # Remove all encodings except for encdb.so and transdb.so
    enc_dir = File.join(@ruby_root, "lib", "ruby", ruby_version, "wasm32-wasi", "enc")
    Dir.glob(File.join(enc_dir, "**/*.so")).each do |entry|
      next if entry.end_with?("encdb.so", "transdb.so")
      RubyWasm.logger.debug "Removing stdlib encoding: #{entry}"
      executor.rm_rf entry
    end
  else
    raise "Unknown stdlib component: #{component}"
  end
end

#ruby_rootstring

Returns:

  • (string)


108
109
110
# File 'lib/ruby_wasm/packager/file_system.rb', line 108

def ruby_root
  @ruby_root
end

#ruby_versionString

Returns:

  • (String)


166
167
168
169
# File 'lib/ruby_wasm/packager/file_system.rb', line 166

def ruby_version
  rubyarchdir = self.rubyarchdir
  File.basename(File.dirname(rubyarchdir))
end

#rubyarchdirString

Returns:

  • (String)


171
172
173
174
175
# File 'lib/ruby_wasm/packager/file_system.rb', line 171

def rubyarchdir
  maybe =
    Dir.glob(File.join(@ruby_root, "lib", "ruby", "*", "wasm32-wasi")).first
  maybe || raise("Cannot find rubyarchdir")
end

#setup_rb_contentString

Returns:

  • (String)


75
76
77
78
79
80
81
# File 'lib/ruby_wasm/packager/file_system.rb', line 75

def setup_rb_content
  content = ""
  self.each_gem_require_path do |relative, _|
    content << %Q[$:.unshift File.expand_path("#{File.join("/", relative)}")\n]
  end
  content
end