module SyntaxTree::CLI

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.

Constants

HELP

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

Public Class Methods

run(argv) click to toggle source

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

# 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