Class: SmartTodo::CLI

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

Overview

This class is the entrypoint of the SmartTodo library and is responsible to retrieve the command line options as well as iterating over each files/directories to run the CommentParser on.

Instance Method Summary collapse

Constructor Details

#initialize(dispatcher = nil) ⇒ CLI

Returns a new instance of CLI.



11
12
13
14
15
# File 'lib/smart_todo/cli.rb', line 11

def initialize(dispatcher = nil)
  @options = {}
  @errors = []
  @dispatcher = dispatcher
end

Instance Method Details

#define_optionsOptionParser

Returns an instance of OptionParser.

Returns:

  • (OptionParser)

    an instance of OptionParser



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/smart_todo/cli.rb', line 57

def define_options
  OptionParser.new do |opts|
    opts.banner = "Usage: smart_todo [options] file_or_path1 file_or_path2 ..."
    opts.on("--slack_token TOKEN") do |token|
      @options[:slack_token] = token
    end
    opts.on("--fallback_channel CHANNEL") do |channel|
      @options[:fallback_channel] = channel
    end
    opts.on("--dispatcher DISPATCHER") do |dispatcher|
      @options[:dispatcher] = dispatcher
    end
  end
end

#dispatcherClass

Returns a Dispatchers::Base subclass.

Returns:

  • (Class)

    a Dispatchers::Base subclass



73
74
75
# File 'lib/smart_todo/cli.rb', line 73

def dispatcher
  @dispatcher ||= Dispatchers::Base.class_for(@options[:dispatcher])
end

#normalize_path(path) ⇒ Array<String>

Returns all the directories the parser should run on.

Parameters:

  • path (String)

    a path to a file or directory

Returns:

  • (Array<String>)

    all the directories the parser should run on



79
80
81
82
83
84
85
# File 'lib/smart_todo/cli.rb', line 79

def normalize_path(path)
  if File.file?(path)
    [path]
  else
    Dir["#{path}/**/*.rb"]
  end
end

#process_dispatches(dispatches) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/smart_todo/cli.rb', line 112

def process_dispatches(dispatches)
  queue = Queue.new
  dispatches.each { |dispatch| queue << dispatch }

  thread_count = Etc.nprocessors
  thread_count.times { queue << nil }

  threads =
    thread_count.times.map do
      Thread.new do
        Thread.current.abort_on_exception = true

        loop do
          dispatch = queue.pop
          break if dispatch.nil?

          (event_message, todo) = dispatch
          dispatcher.new(event_message, todo, todo.filepath, @options).dispatch
        end
      end
    end

  threads.each(&:join)
end

#process_todos(todos) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/smart_todo/cli.rb', line 87

def process_todos(todos)
  events = Events.new
  dispatches = []

  todos.each do |todo|
    event_message = nil
    event_met = todo.events.find do |event|
      event_message = events.public_send(event.method_name, *event.arguments)
    rescue => e
      message = "Error while parsing #{todo.filepath} on event `#{event.method_name}` " \
        "with arguments #{event.arguments.map(&:inspect)}: " \
        "#{e.message}"

      @errors << message

      nil
    end

    @errors.concat(todo.errors)
    dispatches << [event_message, todo] if event_met
  end

  dispatches
end

#run(args = ARGV) ⇒ Object

Parameters:

  • args (Array<String>) (defaults to: ARGV)


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
# File 'lib/smart_todo/cli.rb', line 18

def run(args = ARGV)
  paths = define_options.parse!(args)
  validate_options!

  paths << "." if paths.empty?

  comment_parser = CommentParser.new
  paths.each do |path|
    normalize_path(path).each do |filepath|
      comment_parser.parse_file(filepath)

      $stdout.print(".")
      $stdout.flush
    end
  end

  process_dispatches(process_todos(comment_parser.todos))

  if @errors.empty?
    0
  else
    $stderr.puts "There were errors while checking for TODOs:\n"

    @errors.each do |error|
      $stderr.puts error
    end

    1
  end
end

#validate_options!void

This method returns an undefined value.

Raises:

  • (ArgumentError)

    In case an option needed by a dispatcher wasn’t provided.



52
53
54
# File 'lib/smart_todo/cli.rb', line 52

def validate_options!
  dispatcher.validate_options!(@options)
end