Class: Opal::CLI

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

Defined Under Namespace

Classes: MissingNodeJS, 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



180
181
182
# File 'opal/lib/opal/cli.rb', line 180

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

#mapObject



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

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

#prepare_eval_codeObject



184
185
186
187
188
189
190
191
192
193
194
195
# File 'opal/lib/opal/cli.rb', line 184

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



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

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



173
174
175
# File 'opal/lib/opal/cli.rb', line 173

def puts(*args)
  output.puts(*args)
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 MissingNodeJS, '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



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

def server
  @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
# File 'opal/lib/opal/cli.rb', line 125

def set_processor_options
  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



200
201
202
# File 'opal/lib/opal/cli.rb', line 200

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



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

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

#sprocketsObject

SPROCKETS



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

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