diff --git a/lib/schmooze/base.rb b/lib/schmooze/base.rb index ce44c17..ab9e4a8 100644 --- a/lib/schmooze/base.rb +++ b/lib/schmooze/base.rb @@ -1,6 +1,6 @@ require 'json' -require 'open3' +require 'schmooze/open3' require 'schmooze/processor_generator' module Schmooze @@ -43,7 +43,7 @@ def finalize(stdin, stdout, stderr, process_thread) def initialize(root, env={}) @_schmooze_env = env @_schmooze_root = root - @_schmooze_code = ProcessorGenerator.generate(self.class.instance_variable_get(:@_schmooze_imports) || [], self.class.instance_variable_get(:@_schmooze_methods) || []) + @_schmooze_code = ProcessorGenerator.generate(root, self.class.instance_variable_get(:@_schmooze_imports) || [], self.class.instance_variable_get(:@_schmooze_methods) || []) end def pid @@ -62,7 +62,6 @@ def spawn_process 'node', '-e', @_schmooze_code, - chdir: @_schmooze_root ) ensure_packages_are_initiated(*process_data) ObjectSpace.define_finalizer(self, self.class.send(:finalize, *process_data)) diff --git a/lib/schmooze/open3.rb b/lib/schmooze/open3.rb new file mode 100644 index 0000000..b346b5d --- /dev/null +++ b/lib/schmooze/open3.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Schmooze + module Open3 + def popen3(*cmd, **opts, &block) + in_r, in_w = IO.pipe + opts[:in] = in_r + in_w.sync = true + + out_r, out_w = IO.pipe + opts[:out] = out_w + + err_r, err_w = IO.pipe + opts[:err] = err_w + + popen_run(cmd, opts, [in_r, out_w, err_w], [in_w, out_r, err_r], &block) + end + module_function :popen3 + + def popen_run(cmd, opts, child_io, parent_io) # :nodoc: + if last = Hash.try_convert(cmd.last) + opts = opts.merge(last) + cmd.pop + end + pid = spawn(*cmd, opts) + wait_thr = Process.detach(pid) + + wait_thr.define_singleton_method(:pid) { pid } + + child_io.each {|io| io.close } + result = [*parent_io, wait_thr] + if defined? yield + begin + return yield(*result) + ensure + parent_io.each{|io| io.close unless io.closed?} + wait_thr.join + end + end + result + end + module_function :popen_run + class << self + private :popen_run + end + end +end diff --git a/lib/schmooze/processor_generator.rb b/lib/schmooze/processor_generator.rb index e1d2062..218da8f 100644 --- a/lib/schmooze/processor_generator.rb +++ b/lib/schmooze/processor_generator.rb @@ -3,8 +3,13 @@ module Schmooze class ProcessorGenerator class << self - def generate(imports, methods) -%{try { + def generate(root, imports, methods) +%{ +process.chdir(#{root.to_json}); +var path = require('path'); +module.filename = path.join(process.cwd(), '[eval]'); +module.paths = require('module')._nodeModulePaths(process.cwd()); +try { #{imports.map {|import| generate_import(import)}.join}} catch (e) { process.stdout.write(JSON.stringify(['err', e.toString()])); process.stdout.write("\\n"); diff --git a/test/schmooze_test.rb b/test/schmooze_test.rb index 4a9112c..296f9c5 100644 --- a/test/schmooze_test.rb +++ b/test/schmooze_test.rb @@ -24,7 +24,8 @@ class CoffeeSchmoozer < Schmooze::Base end def setup - @schmoozer = CoffeeSchmoozer.new(File.join(__dir__, 'fixtures', 'coffee')) + @root = File.join(__dir__, 'fixtures', 'coffee') + @schmoozer = CoffeeSchmoozer.new(@root) end def test_that_it_has_a_version_number @@ -33,6 +34,10 @@ def test_that_it_has_a_version_number def test_it_generates_code assert_equal <<-JS.strip, @schmoozer.instance_variable_get(:@_schmooze_code).strip +process.chdir(#{@root.to_json}); +var path = require('path'); +module.filename = path.join(process.cwd(), '[eval]'); +module.paths = require('module')._nodeModulePaths(process.cwd()); try { var coffee = require("coffee-script"); var compile = require("coffee-script").compile;