Class: Wasify::DepsManager

Inherits:
Object
  • Object
show all
Defined in:
lib/wasify/deps_manager.rb

Overview

methods finding and copying dependecies

Class Method Summary collapse

Class Method Details

.add_entrypoint(entrypoint) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/wasify/deps_manager.rb', line 93

def self.add_entrypoint(entrypoint)
  entrypoint = entrypoint[4..-1] if entrypoint.start_with?("src/") && !File.exist?("src/#{entrypoint}")

  raise 'Invalid entrypoint! Entrypoint must be a Ruby script' unless entrypoint.include?('.rb')
  raise 'Entrypoint does not exist! All scripts must be in the src folder.' unless File.exist?("src/#{entrypoint}")

  entrypoint = entrypoint.delete_suffix('.rb')
  "    require \"bundler/setup\"\n    require_relative \"/src/\#{entrypoint}\"\n  HTML\nend\n"

.copy_depsObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/wasify/deps_manager.rb', line 65

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}"
    if dep[:files] == :all
      FileUtils.cp_r dep[:root], dest_dir
    elsif dep[:files].respond_to?(:each)
      dep[:files].each do |file|
        src = "#{dep[:root]}/#{file}"
        dest = "#{dest_dir}/#{file}"
        FileUtils.mkdir_p File.dirname(dest)
        #STDERR.puts "cp: #{src.inspect} #{dest.inspect}"
        FileUtils.cp src, dest
      end
    else
      raise "Unexpected file list object!"
    end
  end
end

.copy_specsObject



84
85
86
87
88
89
90
91
# File 'lib/wasify/deps_manager.rb', line 84

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/"
  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)
  end
end

.get_depsObject



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/wasify/deps_manager.rb', line 31

def self.get_deps
  return @all_gems if @all_gems

  @all_gems = {}

  # We don't want to copy random files (e.g. .git directories, .bundle) in a path: or git: gem dir.
  # But also, Bundler has multiple kinds of specs. Installed baked specs often omit the file list
  # or cut it down to just executables and top-level README-type files. So we have to do things
  # differently for installed and non-installed specs :-(
  specs = Bundler.load.requested_specs.to_a
  specs.each do |spec|
    root_path = File.expand_path spec.full_gem_path # Pretty sure the expand is unneeded

    files = case spec
    when Gem::Specification
      #puts "#{spec.full_name} is a git: or path: gem"
      spec.files
    when Bundler::StubSpecification
      # The specification file is wrong, but there should be only the right files already installed...
      #puts "#{spec.full_name} is locally installed"
      files = :all
    else
      raise "Not implemented! Figure out how to get Bundler data from a #{spec.class}!"
    end

    @all_gems[spec.full_name] = {
      root: root_path,
      files: files,
    }
  end

  @all_gems
end

.get_specs(deps) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/wasify/deps_manager.rb', line 8

def self.get_specs(deps)
  # Bundler internals are annoying to look through. And mostly undocumented.
  # It's amazing what you can find via "bundle exec irb" and then "Bundler.load".
  bundler_specs = Bundler.load.requested_specs.to_a

  # By default, Bundler only "installs" git: gems and path: gems partway.
  # The specification remains dynamic. So if you require "lib/scarpe/version"
  # in the gemspec, it breaks when vendored, because the specification is
  # separated from the gem source (like lib/scarpe/version.rb). When
  # a gem is built and installed, the gemspec is "baked" to a static version,
  # either Ruby or YAML. But git: and path: gems don't do that. So we
  # need to bake them ourselves using spec.to_ruby.
  # (Thanks to Benedikt Deicke, who pointed out to_ruby.)

  spec_contents = {}
  bundler_specs.each do |spec|
    next if ["bundler", "wasify"].include?(spec.name)

    spec_contents["#{spec.full_name}.gemspec"] = spec.to_ruby
  end
  spec_contents
end