Class: Steep::CLI

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

Defined Under Namespace

Classes: SignatureOptions

Constant Summary collapse

BUILTIN_PATH =
Pathname(__dir__).join("../../stdlib").realpath

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stdout:, stdin:, stderr:, argv:) ⇒ CLI

Returns a new instance of CLI.



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

def initialize(stdout:, stdin:, stderr:, argv:)
  @stdout = stdout
  @stdin = stdin
  @stderr = stderr
  @argv = argv
end

Instance Attribute Details

#argvObject (readonly)

Returns the value of attribute argv.



121
122
123
# File 'lib/steep/cli.rb', line 121

def argv
  @argv
end

#commandObject (readonly)

Returns the value of attribute command.



125
126
127
# File 'lib/steep/cli.rb', line 125

def command
  @command
end

#stderrObject (readonly)

Returns the value of attribute stderr.



124
125
126
# File 'lib/steep/cli.rb', line 124

def stderr
  @stderr
end

#stdinObject (readonly)

Returns the value of attribute stdin.



123
124
125
# File 'lib/steep/cli.rb', line 123

def stdin
  @stdin
end

#stdoutObject (readonly)

Returns the value of attribute stdout.



122
123
124
# File 'lib/steep/cli.rb', line 122

def stdout
  @stdout
end

Class Method Details

.available_commandsObject



134
135
136
# File 'lib/steep/cli.rb', line 134

def self.available_commands
  [:check, :validate, :annotations, :scaffold, :interface, :version, :paths, :watch, :langserver]
end

Instance Method Details

#handle_dir_options(opts, options) ⇒ Object



191
192
193
194
195
196
# File 'lib/steep/cli.rb', line 191

def handle_dir_options(opts, options)
  opts.on("-I [PATH]") {|path| options << Pathname(path) }
  opts.on("-G [GEM]") {|gem| options << gem }
  opts.on("--no-builtin") { options.no_builtin! }
  opts.on("--no-bundler") { options.no_bundler! }
end

#handle_logging_options(opts) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/steep/cli.rb', line 169

def handle_logging_options(opts)
  opts.on("--verbose") do
    Steep.logger.level = Logger::DEBUG
  end

  opts.on("--log-level=[debug,info,warn,error,fatal]") do |level|
    lv = {
      "debug" => Logger::DEBUG,
      "info" => Logger::INFO,
      "warn" => Logger::WARN,
      "error" => Logger::ERROR,
      "fatal" => Logger::FATAL
    }[level.downcase] or raise "Unknown error level: #{level}"

    Steep.logger.level = lv
  end

  opts.on("--log-output=[PATH]") do |file|
    Steep.log_output = file
  end
end

#process_annotationsObject



246
247
248
249
250
251
252
253
# File 'lib/steep/cli.rb', line 246

def process_annotations
  OptionParser.new do |opts|
    handle_logging_options opts
  end.parse!(argv)

  source_paths = argv.map {|file| Pathname(file) }
  Drivers::Annotations.new(source_paths: source_paths, stdout: stdout, stderr: stderr).run
end

#process_checkObject



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/steep/cli.rb', line 208

def process_check
  with_signature_options do |signature_options|
    dump_all_types = false
    fallback_any_is_error = false
    strict = false

    OptionParser.new do |opts|
      handle_logging_options opts
      handle_dir_options opts, signature_options
      opts.on("--dump-all-types") { dump_all_types = true }
      opts.on("--strict") { strict = true }
      opts.on("--fallback-any-is-error") { fallback_any_is_error = true }
    end.parse!(argv)

    source_paths = argv.map {|path| Pathname(path) }
    if source_paths.empty?
      source_paths << Pathname(".")
    end

    Drivers::Check.new(source_paths: source_paths, signature_dirs: signature_options.paths, stdout: stdout, stderr: stderr).tap do |check|
      check.dump_all_types = dump_all_types
      check.fallback_any_is_error = fallback_any_is_error || strict
      check.allow_missing_definitions = false if strict
    end.run
  end
end

#process_global_optionsObject



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/steep/cli.rb', line 138

def process_global_options
  OptionParser.new do |opts|
    opts.on("--version") do
      process_version
      exit 0
    end

    handle_logging_options(opts)
  end.order!(argv)

  true
end

#process_interfaceObject



264
265
266
267
268
269
270
271
272
273
# File 'lib/steep/cli.rb', line 264

def process_interface
  with_signature_options do |signature_options|
    OptionParser.new do |opts|
      handle_logging_options opts
      handle_dir_options opts, signature_options
    end.parse!(argv)

    Drivers::PrintInterface.new(type_name: argv.first, signature_dirs: signature_options.paths, stdout: stdout, stderr: stderr).run
  end
end

#process_langserverObject



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/steep/cli.rb', line 301

def process_langserver
  with_signature_options do |signature_options|
    strict = false
    fallback_any_is_error = false

    OptionParser.new do |opts|
      handle_logging_options opts
      handle_dir_options opts, signature_options
      opts.on("--strict") { strict = true }
      opts.on("--fallback-any-is-error") { fallback_any_is_error = true }
    end.parse!(argv)

    source_dirs = argv.map { |path| Pathname(path) }
    if source_dirs.empty?
      source_dirs << Pathname(".")
    end

    Drivers::Langserver.new(source_dirs: source_dirs, signature_dirs: signature_options.paths).tap do |driver|
      driver.options.fallback_any_is_error = fallback_any_is_error || strict
      driver.options.allow_missing_definitions = false if strict
    end.run

    0
  end
end

#process_pathsObject



332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/steep/cli.rb', line 332

def process_paths
  with_signature_options do |signature_options|
    OptionParser.new do |opts|
      handle_logging_options opts
      handle_dir_options opts, signature_options
    end.parse!(argv)

    signature_options.paths.each do |path|
      stdout.puts path
    end

    0
  end
end

#process_scaffoldObject



255
256
257
258
259
260
261
262
# File 'lib/steep/cli.rb', line 255

def process_scaffold
  OptionParser.new do |opts|
    handle_logging_options opts
  end.parse!(argv)

  source_paths = argv.map {|file| Pathname(file) }
  Drivers::Scaffold.new(source_paths: source_paths, stdout: stdout, stderr: stderr).run
end

#process_validateObject



235
236
237
238
239
240
241
242
243
244
# File 'lib/steep/cli.rb', line 235

def process_validate
  with_signature_options do |signature_options|
    OptionParser.new do |opts|
      handle_logging_options opts
      handle_dir_options opts, signature_options
    end.parse!(argv)

    Drivers::Validate.new(signature_dirs: signature_options.paths, stdout: stdout, stderr: stderr).run
  end
end

#process_versionObject



327
328
329
330
# File 'lib/steep/cli.rb', line 327

def process_version
  stdout.puts Steep::VERSION
  0
end

#process_watchObject



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/steep/cli.rb', line 275

def process_watch
  with_signature_options do |signature_options|
    strict = false
    fallback_any_is_error = false

    OptionParser.new do |opts|
      handle_logging_options opts
      handle_dir_options opts, signature_options
      opts.on("--strict") { strict = true }
      opts.on("--fallback-any-is-error") { fallback_any_is_error = true }
    end.parse!(argv)

    source_dirs = argv.map {|path| Pathname(path) }
    if source_dirs.empty?
      source_dirs << Pathname(".")
    end

    Drivers::Watch.new(source_dirs: source_dirs, signature_dirs: signature_options.paths, stdout: stdout, stderr: stderr).tap do |driver|
      driver.options.fallback_any_is_error = fallback_any_is_error || strict
      driver.options.allow_missing_definitions = false if strict
    end.run

    0
  end
end

#runObject



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

def run
  process_global_options or return 1
  setup_command or return 1

  __send__(:"process_#{command}")
end

#setup_commandObject



151
152
153
154
155
156
157
158
159
160
# File 'lib/steep/cli.rb', line 151

def setup_command
  @command = argv.shift&.to_sym
  if CLI.available_commands.include?(@command)
    true
  else
    stderr.puts "Unknown command: #{command}"
    stderr.puts "  available commands: #{CLI.available_commands.join(', ')}"
    false
  end
end

#with_signature_optionsObject



198
199
200
201
202
203
204
205
206
# File 'lib/steep/cli.rb', line 198

def with_signature_options
  yield SignatureOptions.new
rescue SignatureOptions::MissingGemError => exn
  stderr.puts Rainbow("Gem not found: name=#{exn.name}, version=#{exn.version}").red
  1
rescue SignatureOptions::NoTypeDefinitionFromGemError => exn
  stderr.puts Rainbow("Type definition directory not found: #{exn.gemspec.name} (#{exn.gemspec.version})").red
  1
end