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, CTags, Check, Color, ConfigFile, Debug, Doc, Expr, FileItem, Format, Json, Match, Options, STDINItem, ScriptItem, Search, 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 ctags [-e SCRIPT] FILE")}
    Print out a ctags-compatible index of the given files

  #{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 expr [-e SCRIPT] FILE")}
    Print out a pattern-matching Ruby expression that would match the first
    expression of 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 search PATTERN [-e SCRIPT] FILE")}
    Search for the given pattern in the given files

  #{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.



565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
# File 'lib/syntax_tree/cli.rb', line 565

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 "ctags"
      CTags.new(options)
    when "debug"
      Debug.new(options)
    when "doc"
      Doc.new(options)
    when "e", "expr"
      Expr.new(options)
    when "f", "format"
      Format.new(options)
    when "help"
      puts HELP
      return 0
    when "j", "json"
      Json.new(options)
    when "lsp"
      LanguageServer.new(print_width: options.print_width).run
      return 0
    when "m", "match"
      Match.new(options)
    when "s", "search"
      Search.new(arguments.shift)
    when "version"
      puts SyntaxTree::VERSION
      return 0
    when "w", "write"
      Write.new(options)
    else
      warn(HELP)
      return 1
    end

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

  # If there are any arguments or scripts, then we'll add those to the
  # queue. Otherwise we'll read the content off STDIN.
  if arguments.any? || options.scripts.any?
    arguments.each do |pattern|
      Dir
        .glob(pattern)
        .each do |filepath|
          # Skip past invalid filepaths by default.
          next unless File.readable?(filepath)

          # Skip past any ignored filepaths.
          next if options.ignore_files.any? { File.fnmatch(_1, filepath) }

          # Otherwise, a new file item for the given filepath to the list.
          queue << FileItem.new(filepath)
        end
    end

    options.scripts.each { |script| queue << ScriptItem.new(script) }
  else
    queue << STDINItem.new
  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