Class: Opal::CLI

Inherits:
Object show all
Defined in:
opal/lib/opal/cli.rb

Defined Under Namespace

Classes: MissingNode, PathFinder

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = nil) ⇒ CLI

Returns a new instance of CLI

Raises:

  • (ArgumentError)


13
14
15
16
17
18
19
20
21
22
# File 'opal/lib/opal/cli.rb', line 13

def initialize options = nil
  options ||= {}
  @options    = options
  @evals      = options[:evals] || []
  @requires   = options[:requires] || []
  @filename   = options[:filename]
  @load_paths = options[:load_paths] || []
  @output     = options[:output] || self.class.stdout || $stdout
  raise ArgumentError if @evals.empty? and @filename.nil?
end

Class Attribute Details

.stdoutObject

Returns the value of attribute stdout



10
11
12
# File 'opal/lib/opal/cli.rb', line 10

def stdout
  @stdout
end

Instance Attribute Details

#evalsObject (readonly)

Returns the value of attribute evals



7
8
9
# File 'opal/lib/opal/cli.rb', line 7

def evals
  @evals
end

#filenameObject (readonly)

Returns the value of attribute filename



6
7
8
# File 'opal/lib/opal/cli.rb', line 6

def filename
  @filename
end

#load_pathsObject (readonly)

Returns the value of attribute load_paths



7
8
9
# File 'opal/lib/opal/cli.rb', line 7

def load_paths
  @load_paths
end

#optionsObject (readonly)

Returns the value of attribute options



6
7
8
# File 'opal/lib/opal/cli.rb', line 6

def options
  @options
end

#outputObject (readonly)

Returns the value of attribute output



7
8
9
# File 'opal/lib/opal/cli.rb', line 7

def output
  @output
end

#requiresObject (readonly)

Returns the value of attribute requires



7
8
9
# File 'opal/lib/opal/cli.rb', line 7

def requires
  @requires
end

Instance Method Details

#evals_sourceObject

EVALS



194
195
196
# File 'opal/lib/opal/cli.rb', line 194

def evals_source
  evals.inject('', &:<<)
end

#mapObject



134
135
136
137
138
# File 'opal/lib/opal/cli.rb', line 134

def map
  compiler = Opal::Compiler.new
  compiler.compile(filename, options)
  compiler.source_map
end

#prepare_eval_codeObject



198
199
200
201
202
203
204
205
206
207
208
209
# File 'opal/lib/opal/cli.rb', line 198

def prepare_eval_code
  if evals.any?
    require 'tmpdir'
    path = File.join(Dir.mktmpdir,"opal-#{$$}.js.rb")
    File.open(path, 'w') do |tempfile|
      load_paths << File.dirname(path)
      tempfile.puts 'require "opal"'
      tempfile.puts evals_source
    end
    @filename = File.basename(path)
  end
end

#processor_optionsObject



144
145
146
147
148
149
150
151
152
153
# File 'opal/lib/opal/cli.rb', line 144

def processor_options
  %w[
    method_missing_enabled
    arity_check_enabled
    const_missing_enabled
    dynamic_require_severity
    source_map_enabled
    irb_enabled
  ]
end

#puts(*args) ⇒ Object

OUTPUT



187
188
189
# File 'opal/lib/opal/cli.rb', line 187

def puts *args
  output.puts *args
end

#require_opal_sprocketsObject



172
173
174
175
176
177
178
179
180
181
182
# File 'opal/lib/opal/cli.rb', line 172

def require_opal_sprockets
  begin
    require 'opal-sprockets'
  rescue LoadError
    $stderr.puts 'Opal executable requires opal-sprockets to be fully functional.'
    $stderr.puts 'You can install it with rubygems:'
    $stderr.puts ''
    $stderr.puts '    gem install opal-sprockets'
    exit -1
  end
end

#runObject



24
25
26
27
28
29
30
31
32
33
# File 'opal/lib/opal/cli.rb', line 24

def run
  set_processor_options

  case
  when options[:sexp];    prepare_eval_code; show_sexp
  when options[:compile]; prepare_eval_code; show_compiled_source
  when options[:server];  prepare_eval_code; start_server
  else                    run_code
  end
end

#run_codeObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'opal/lib/opal/cli.rb', line 51

def run_code
  Opal.paths.concat load_paths
  path_finder = PathFinder.new(Opal.paths)
  builder = Opal::Builder.new
  full_source = builder.build('opal')

  require 'pathname'
  requires.each do |path|
    path   = Pathname(path)
    path   = Pathname(path_finder.find(path)) unless path.absolute?
    full_source << builder.build_str(path.read, :file => path.to_s)
  end

  evals.each_with_index do |code, index|
    full_source << builder.build_str(code, :file => "(eval #{index+1})")
  end

  file = Pathname(filename.to_s)
  full_source << builder.build_str(file.read, :file => file.to_s) if file.exist?

  run_with_node(full_source)
end

#run_with_node(code) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'opal/lib/opal/cli.rb', line 74

def run_with_node(code)
  require 'open3'
  begin
    stdin, stdout, stderr = Open3.popen3('node')
  rescue Errno::ENOENT
    raise MissingNode, 'Please install Node.js to be able to run Opal scripts.'
  end

  stdin.write code
  stdin.close

  [stdout, stderr].each do |io|
    str = io.read
    puts str unless str.empty?
  end
end

#serverObject



162
163
164
165
166
167
168
169
170
# File 'opal/lib/opal/cli.rb', line 162

def server
  require_opal_sprockets
  @server ||= Opal::Server.new do |s|
    load_paths.each do |path|
      s.append_path path
    end
    s.main = File.basename(filename, '.rb')
  end
end

#set_processor_optionsObject

PROCESSOR



125
126
127
128
129
130
131
132
# File 'opal/lib/opal/cli.rb', line 125

def set_processor_options
  require_opal_sprockets
  processor_options.each do |option|
    key = option.to_sym
    next unless options.has_key? key
    Opal::Processor.send("#{option}=", options[key])
  end
end

#sexpObject

SOURCE



214
215
216
# File 'opal/lib/opal/cli.rb', line 214

def sexp
  Opal::Parser.new.parse(source)
end

#show_compiled_sourceObject



107
108
109
110
111
112
113
114
115
# File 'opal/lib/opal/cli.rb', line 107

def show_compiled_source
  if sprockets[filename]
    puts sprockets[filename].to_a.last
  elsif File.exist?(filename)
    puts Opal.compile File.read(filename), options
  else
    puts Opal.compile(filename, options)
  end
end

#show_sexpObject



117
118
119
# File 'opal/lib/opal/cli.rb', line 117

def show_sexp
  puts sexp.inspect
end

#sourceObject



140
141
142
# File 'opal/lib/opal/cli.rb', line 140

def source
  File.exist?(filename) ? File.read(filename) : filename
end

#sprocketsObject

SPROCKETS



158
159
160
# File 'opal/lib/opal/cli.rb', line 158

def sprockets
  server.sprockets
end

#start_serverObject



94
95
96
97
98
99
100
101
102
103
104
105
# File 'opal/lib/opal/cli.rb', line 94

def start_server
  require 'rack'
  require 'webrick'
  require 'logger'

  Rack::Server.start(
    :app       => server,
    :Port      => options[:port] || 3000,
    :AccessLog => [],
    :Logger    => Logger.new($stdout)
  )
end