Module: SyntaxTree::CLI

Defined in:
lib/syntax_tree/cli.rb

Overview

Syntax Tree ships with the ‘stree` CLI, which can be used to inspect and manipulate Ruby code. This module is responsible for powering that CLI.

Defined Under Namespace

Classes: AST, Action, Check, Color, ConfigFile, Debug, Doc, FileItem, Format, Json, Match, Options, ScriptItem, Write

Constant Summary collapse

HELP =

The help message displayed if the input arguments are not correctly ordered or formatted.

<<~HELP
  #{Color.bold("stree ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE")}
    Print out the AST corresponding to the given files

  #{Color.bold("stree check [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE")}
    Check that the given files are formatted as syntax tree would format them

  #{Color.bold("stree debug [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE")}
    Check that the given files can be formatted idempotently

  #{Color.bold("stree doc [--plugins=...] [-e SCRIPT] FILE")}
    Print out the doc tree that would be used to format the given files

  #{Color.bold("stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE")}
    Print out the formatted version of the given files

  #{Color.bold("stree json [--plugins=...] [-e SCRIPT] FILE")}
    Print out the JSON representation of the given files

  #{Color.bold("stree match [--plugins=...] [-e SCRIPT] FILE")}
    Print out a pattern-matching Ruby expression that would match the given files

  #{Color.bold("stree help")}
    Display this help message

  #{Color.bold("stree lsp [--plugins=...] [--print-width=NUMBER]")}
    Run syntax tree in language server mode

  #{Color.bold("stree version")}
    Output the current version of syntax tree

  #{Color.bold("stree write [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE")}
    Read, format, and write back the source of the given files

  --plugins=...
    A comma-separated list of plugins to load.

  --print-width=NUMBER
    The maximum line width to use when formatting.

  -e SCRIPT
    Parse an inline Ruby string.
HELP

Class Method Summary collapse

Class Method Details

.run(argv) ⇒ Object

Run the CLI over the given array of strings that make up the arguments passed to the invocation.



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
# File 'lib/syntax_tree/cli.rb', line 347

def run(argv)
  name, *arguments = argv

  config_file = ConfigFile.new
  arguments.unshift(*config_file.arguments)

  options = Options.new
  options.parse(arguments)

  action =
    case name
    when "a", "ast"
      AST.new(options)
    when "c", "check"
      Check.new(options)
    when "debug"
      Debug.new(options)
    when "doc"
      Doc.new(options)
    when "help"
      puts HELP
      return 0
    when "j", "json"
      Json.new(options)
    when "lsp"
      require "syntax_tree/language_server"
      LanguageServer.new(print_width: options.print_width).run
      return 0
    when "m", "match"
      Match.new(options)
    when "f", "format"
      Format.new(options)
    when "version"
      puts SyntaxTree::VERSION
      return 0
    when "w", "write"
      Write.new(options)
    else
      warn(HELP)
      return 1
    end

  # If we're not reading from stdin and the user didn't supply and
  # filepaths to be read, then we exit with the usage message.
  if $stdin.tty? && arguments.empty? && options.scripts.empty?
    warn(HELP)
    return 1
  end

  # We're going to build up a queue of items to process.
  queue = Queue.new

  # If we're reading from stdin, then we'll just add the stdin object to
  # the queue. Otherwise, we'll add each of the filepaths to the queue.
  if $stdin.tty? && (arguments.any? || options.scripts.any?)
    arguments.each do |pattern|
      Dir
        .glob(pattern)
        .each do |filepath|
          queue << FileItem.new(filepath) if File.file?(filepath)
        end
    end
    options.scripts.each { |script| queue << ScriptItem.new(script) }
  else
    queue << ScriptItem.new($stdin.read)
  end

  # At the end, we're going to return whether or not this worker ever
  # encountered an error.
  if process_queue(queue, action)
    action.failure
    1
  else
    action.success
    0
  end
end