Class: Opal::CLI

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

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)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
# File 'opal/lib/opal/cli.rb', line 16

def initialize options = nil
  options ||= {}

  # Runner
  @runner_type = options.delete(:runner)     || :nodejs
  @port        = options.delete(:port)       || 3000

  @options     = options
  @compile     = !!options.delete(:compile)
  @sexp        = options.delete(:sexp)
  @file        = options.delete(:file)
  @map         = options.delete(:map)
  @no_exit     = options.delete(:no_exit)
  @lib_only    = options.delete(:lib_only)
  @argv        = options.delete(:argv)       || []
  @evals       = options.delete(:evals)      || []
  @load_paths  = options.delete(:load_paths) || []
  @gems        = options.delete(:gems)       || []
  @stubs       = options.delete(:stubs)      || []
  @preload     = options.delete(:preload)    || []
  @output      = options.delete(:output)     || self.class.stdout || $stdout
  @verbose     = options.fetch(:verbose, false); options.delete(:verbose)
  @debug       = options.fetch(:debug, false);   options.delete(:debug)
  @filename    = options.fetch(:filename) { @file && @file.path }; options.delete(:filename)

  @requires    = options.delete(:requires)   || []

  @missing_require_severity = options.delete(:missing_require_severity) { Opal::Config.missing_require_severity }

  @requires.unshift('opal') unless options.delete(:skip_opal_require)

  @compiler_options = Hash[
    *compiler_option_names.map do |option|
      key = option.to_sym
      next unless options.has_key? key
      value = options.delete(key)
      [key, value]
    end.compact.flatten
  ]

  raise ArgumentError, "no libraries to compile" if @lib_only and @requires.length == 0
  raise ArgumentError, "no runnable code provided (evals or file)" if @evals.empty? and @file.nil? and not(@lib_only)
  raise ArgumentError, "can't accept evals or file in `library only` mode" if (@evals.any? or @file) and @lib_only
  raise ArgumentError, "unknown options: #{options.inspect}" unless @options.empty?
end

Class Attribute Details

.stdoutObject

Returns the value of attribute stdout



13
14
15
# File 'opal/lib/opal/cli.rb', line 13

def stdout
  @stdout
end

Instance Attribute Details

#argvObject (readonly)

Returns the value of attribute argv



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

def argv
  @argv
end

#compiler_optionsObject (readonly)

Returns the value of attribute compiler_options



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

def compiler_options
  @compiler_options
end

#debugObject (readonly)

Returns the value of attribute debug



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

def debug
  @debug
end

#evalsObject (readonly)

Returns the value of attribute evals



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

def evals
  @evals
end

#exit_statusObject (readonly)

Returns the value of attribute exit_status



84
85
86
# File 'opal/lib/opal/cli.rb', line 84

def exit_status
  @exit_status
end

#fileObject (readonly)

Returns the value of attribute file



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

def file
  @file
end

#filenameObject (readonly)

Returns the value of attribute filename



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

def filename
  @filename
end

#gemsObject (readonly)

Returns the value of attribute gems



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

def gems
  @gems
end

#lib_onlyObject (readonly)

Returns the value of attribute lib_only



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

def lib_only
  @lib_only
end

#load_pathsObject (readonly)

Returns the value of attribute load_paths



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

def load_paths
  @load_paths
end

#missing_require_severityObject (readonly)

Returns the value of attribute missing_require_severity



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

def missing_require_severity
  @missing_require_severity
end

#no_exitObject (readonly)

Returns the value of attribute no_exit



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

def no_exit
  @no_exit
end

#optionsObject (readonly)

Returns the value of attribute options



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

def options
  @options
end

#outputObject (readonly)

Returns the value of attribute output



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

def output
  @output
end

#portObject (readonly)

Returns the value of attribute port



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

def port
  @port
end

#preloadObject (readonly)

Returns the value of attribute preload



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

def preload
  @preload
end

#requiresObject (readonly)

Returns the value of attribute requires



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

def requires
  @requires
end

#stubsObject (readonly)

Returns the value of attribute stubs



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

def stubs
  @stubs
end

#verboseObject (readonly)

Returns the value of attribute verbose



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

def verbose
  @verbose
end

Instance Method Details

#builderObject



86
87
88
# File 'opal/lib/opal/cli.rb', line 86

def builder
  @builder ||= create_builder
end

#compiler_option_namesObject



133
134
135
136
137
138
139
140
141
142
143
144
# File 'opal/lib/opal/cli.rb', line 133

def compiler_option_names
  %w[
    method_missing
    arity_check
    dynamic_require_severity
    source_map_enabled
    irb_enabled
    inline_operators
    enable_source_location
    parse_comments
  ]
end

#create_builderObject



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'opal/lib/opal/cli.rb', line 90

def create_builder
  builder = Opal::Builder.new(
    stubs: stubs,
    compiler_options: compiler_options,
    missing_require_severity: missing_require_severity,
  )

  # --include
  builder.append_paths(*load_paths)

  # --gem
  gems.each { |gem_name| builder.use_gem gem_name }

  # --require
  requires.each { |required| builder.build(required) }

  # --preload
  preload.each { |path| builder.build_require(path) }

  # --verbose
  builder.build_str '$VERBOSE = true', '(flags)' if verbose

  # --debug
  builder.build_str '$DEBUG = true', '(flags)' if debug

  # --eval / stdin / file
  evals_or_file { |source, filename| builder.build_str(source, filename) }

  # --no-exit
  builder.build_str 'Kernel.exit', '(exit)' unless no_exit

  builder
end

#evals_or_fileObject

Internal: Yields a string of source code and the proper filename for either evals, stdin or a filepath.



148
149
150
151
152
153
154
155
156
157
158
159
# File 'opal/lib/opal/cli.rb', line 148

def evals_or_file
  # --library
  return if lib_only

  if evals.any?
    yield evals.join("\n"), '-e'
  else
    if file and (filename != '-' or evals.empty?)
      yield file.read, filename
    end
  end
end

#puts(*args) ⇒ Object



161
162
163
# File 'opal/lib/opal/cli.rb', line 161

def puts(*args)
  output.puts(*args)
end

#runObject



62
63
64
65
66
67
68
69
70
71
72
73
# File 'opal/lib/opal/cli.rb', line 62

def run
  return show_sexp if @sexp

  compiled_source = builder.to_s

  File.write @map, builder.source_map if @map

  return puts compiled_source if @compile

  runner.run(compiled_source, argv)
  @exit_status = runner.exit_status
end

#runnerObject



75
76
77
78
79
80
81
82
# File 'opal/lib/opal/cli.rb', line 75

def runner
  @runner ||= begin
    const_name = @runner_type.to_s.capitalize
    CliRunners.const_defined?(const_name) or
      raise ArgumentError, "unknown runner: #{@runner_type.inspect}"
    CliRunners.const_get(const_name).new(output: output, port: port)
  end
end

#show_sexpObject



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

def show_sexp
  evals_or_file do |contents, filename|
    buffer = ::Opal::Source::Buffer.new(filename)
    buffer.source = contents
    sexp = Opal::Parser.default_parser.parse(buffer)
    puts sexp.inspect
  end
end