Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: opal/opal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: cf3c410a9abe
Choose a base ref
...
head repository: opal/opal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d88ebcf41e52
Choose a head ref
  • 6 commits
  • 8 files changed
  • 2 contributors

Commits on May 15, 2015

  1. Extract Opal.use_gem for use inside Opal::Builder

    This allows you to use gems for specific builders instead of
    modifying global state. In order to do so, it moves use_gem
    from being a singleton method on Opal to being a module that
    extends Opal, and including that module in Opal::Builder.
    
    To unify the Opal singleton API and Opal::Builder instance
    API, add append_paths methods to both, with Opal just using
    appending to the global paths, and Opal::Builder appending
    the paths to the underlying file_finder inside the path_reader.
    jeremyevans committed May 15, 2015
    Copy the full SHA
    d927b50 View commit details
  2. Make Opal::CLI not modify global state

    Instead, only modify the state of the generated builder. In order
    to test this, add a CLI#build method that returns the builder
    object.
    jeremyevans committed May 15, 2015
    Copy the full SHA
    6223ce1 View commit details
  3. Make Opal::Builder#dup work correctly

    Previously this did not duplicate internal structures, causing the
    objects to not be independent.
    jeremyevans committed May 15, 2015
    Copy the full SHA
    93a9681 View commit details
  4. Allow tilt/opal to use Opal::Builder with :build or :builder options

    If :build option is used, the Opal::Builder defaults are used.
    If :builder option is used, you can pass in your own custom
    builder, which could have per-build stubs, append_paths, and
    use_gems to change building without modifying global state.
    
    Using this, it's possible to build arbitrary opal projects that
    require other files using tilt without sprockets.
    jeremyevans committed May 15, 2015

    Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    5de0340 View commit details

Commits on May 16, 2015

  1. Copy the full SHA
    6c0e370 View commit details

Commits on May 17, 2015

  1. Merge pull request #864 from jeremyevans/tilt_build

    Allow tilt/opal to use Opal::Builder with :build or :builder options
    elia committed May 17, 2015
    Copy the full SHA
    d88ebcf View commit details
Showing with 94 additions and 34 deletions.
  1. +17 −0 lib/opal/builder.rb
  2. +8 −5 lib/opal/cli.rb
  3. +3 −0 lib/opal/path_reader.rb
  4. +23 −16 lib/opal/paths.rb
  5. +11 −5 lib/tilt/opal.rb
  6. +12 −6 spec/lib/builder_spec.rb
  7. +2 −2 spec/lib/cli_spec.rb
  8. +18 −0 spec/lib/tilt/opal_spec.rb
17 changes: 17 additions & 0 deletions lib/opal/builder.rb
Original file line number Diff line number Diff line change
@@ -50,6 +50,17 @@ def build_require(path, options = {})
process_require(path, options)
end

def initialize_copy(other)
super
@stubs = other.stubs.dup
@preload = other.preload.dup
@processors = other.processors.dup
@path_reader = other.path_reader.dup
@prerequired = other.prerequired.dup
@compiler_options = other.compiler_options.dup
@processed = other.processed.dup
end

def to_s
processed.map(&:to_s).join("\n")
end
@@ -58,6 +69,12 @@ def source_map
processed.map(&:source_map).reduce(:+).as_json.to_json
end

def append_paths(*paths)
path_reader.append_paths(*paths)
end

include UseGem

attr_reader :processed

attr_accessor :processors, :default_processor, :path_reader,
13 changes: 8 additions & 5 deletions lib/opal/cli.rb
Original file line number Diff line number Diff line change
@@ -87,11 +87,10 @@ def run_code

attr_reader :exit_status

def compiled_source
Opal.paths.concat load_paths
gems.each { |gem_name| Opal.use_gem gem_name }

def build
builder = Opal::Builder.new stubs: stubs, compiler_options: compiler_options
builder.append_paths(*load_paths)
gems.each { |gem_name| builder.use_gem gem_name }

builder.build 'opal' unless skip_opal_require?

@@ -116,7 +115,11 @@ def compiled_source

builder.build_str 'Kernel.exit', '(exit)' unless no_exit

builder.to_s
builder
end

def compiled_source
build.to_s
end

def show_compiled_source
3 changes: 3 additions & 0 deletions lib/opal/path_reader.rb
Original file line number Diff line number Diff line change
@@ -24,6 +24,9 @@ def paths
file_finder.paths
end

def append_paths(*paths)
file_finder.append_paths(*paths)
end

private

39 changes: 23 additions & 16 deletions lib/opal/paths.rb
Original file line number Diff line number Diff line change
@@ -16,31 +16,38 @@ def self.std_dir
# here should only be paths which contain code targeted at being compiled by
# Opal.
def self.append_path(path)
paths << path
append_paths(path)
end
def self.append_paths(*paths)
self.paths.concat(paths)
end

def self.use_gem(gem_name, include_dependencies = true)
require_paths_for_gem(gem_name, include_dependencies).each do |path|
append_path path
module UseGem
def use_gem(gem_name, include_dependencies = true)
append_paths(*require_paths_for_gem(gem_name, include_dependencies))
end
end

private

def self.require_paths_for_gem(gem_name, include_dependencies)
paths = []
spec = Gem::Specification.find_by_name(gem_name)
def require_paths_for_gem(gem_name, include_dependencies)
paths = []
spec = Gem::Specification.find_by_name(gem_name)

spec.runtime_dependencies.each do |dependency|
paths += require_paths_for_gem(dependency.name, include_dependencies)
end if include_dependencies
spec.runtime_dependencies.each do |dependency|
paths += require_paths_for_gem(dependency.name, include_dependencies)
end if include_dependencies

gem_dir = spec.gem_dir
spec.require_paths.map do |path|
paths << File.join(gem_dir, path)
end
gem_dir = spec.gem_dir
spec.require_paths.map do |path|
paths << File.join(gem_dir, path)
end

paths
paths
end
end

extend UseGem

# Private, don't add to these directly (use .append_path instead).
def self.paths
@paths ||= [core_dir.untaint, std_dir.untaint, gem_dir.untaint]
16 changes: 11 additions & 5 deletions lib/tilt/opal.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require 'tilt'
require 'opal/compiler'
require 'opal/builder'
require 'opal/config'
require 'opal/version'

@@ -32,10 +32,16 @@ def initialize_engine
def prepare
end

def evaluate(context, locals, &block)
compiler_options = Opal::Config.compiler_options.merge(file: file)
compiler = Compiler.new(data, compiler_options)
compiler.compile.to_s
def evaluate(_, _, &block)
if builder = @options[:builder]
builder.dup.build(file).to_s
elsif @options[:build]
Opal::Builder.build(file).to_s
else
compiler_options = (compiler_options || {}).merge!(file: file)
compiler = Compiler.new(data, compiler_options)
compiler.compile.to_s
end
end

def compiler_options
18 changes: 12 additions & 6 deletions spec/lib/builder_spec.rb
Original file line number Diff line number Diff line change
@@ -11,12 +11,8 @@
end

it 'respect #require_tree calls' do
begin
Opal.append_path(File.expand_path('..', __FILE__))
expect(builder.build('fixtures/require_tree_test').to_s).to include('Opal.modules["fixtures/required_tree_test/required_file1"]')
ensure
Opal.instance_variable_set('@paths', nil)
end
builder.append_paths(File.expand_path('..', __FILE__))
expect(builder.build('fixtures/require_tree_test').to_s).to include('Opal.modules["fixtures/required_tree_test/required_file1"]')
end

describe ':stubs' do
@@ -52,6 +48,16 @@
end
end

describe 'dup' do
it 'duplicates internal structures' do
b2 = builder.dup
b2.should_not equal(builder)
[:stubs, :preload, :processors, :path_reader, :prerequired, :compiler_options, :processed].each do |m|
b2.send(m).should_not equal(builder.send(m))
end
end
end

describe 'requiring a native .js file' do
it 'can be required without specifying extension' do
builder.build_str('require "corelib/runtime"', 'foo')
4 changes: 2 additions & 2 deletions spec/lib/cli_spec.rb
Original file line number Diff line number Diff line change
@@ -82,12 +82,12 @@
let(:options) { {:gems => [gem_name], :evals => ['']} }

it "adds the gem's lib paths to Opal.path" do
cli.run
builder = cli.build

spec = Gem::Specification.find_by_name(gem_name)
spec.require_paths.each do |require_path|
require_path = File.join(spec.gem_dir, require_path)
expect(Opal.paths).to include(require_path)
expect(builder.path_reader.send(:file_finder).paths).to include(require_path)
end
end
end
18 changes: 18 additions & 0 deletions spec/lib/tilt/opal_spec.rb
Original file line number Diff line number Diff line change
@@ -16,4 +16,22 @@
end
end
end

it "support :build option" do
template = described_class.new('./spec/lib/fixtures/opal_file.rb', :build=>true)
output = template.render
expect(output).to include('"hi from opal!"')
expect(output).to include('self.$require("corelib/runtime");')
end

it "support :builder option" do
builder = Opal::Builder.new(:stubs=>['opal'])
template = described_class.new('./spec/lib/fixtures/opal_file.rb', :builder=>builder)

2.times do
output = template.render
expect(output.scan(/hi from opal!/).length).to eql(1)
expect(output).not_to include('self.$require("corelib/runtime");')
end
end
end