class TodoLint::Todo

Todo represents a todo/fixme/etc comment within your source code

Constants

PATTERN

The regular expression that identifies todo comments

Attributes

config[R]

What is the configuration for this code base's todo_lint setup?

@return [Hash] @api private

line[R]

The content of the line of source code containing the todo comment @example

todo.line #=> "# TODO: refactor me"

@api public @return [String]

line_number[R]

The 1-indexed line on which the todo was discovered @example

todo.line_number #=> 4

@api public @return [Fixnum]

path[R]

The absolute path to the file where we found this todo @example

todo.path #=> "/Users/max/src/layabout/Gemfile"

@api public @return [String]

Public Class Methods

new(line, line_number: RequiredArg.new(:line_number), path: RequiredArg.new(:path), config: RequiredArg.new(:config)) click to toggle source

A new Todo must know a few things @example

Todo.new("#TODO: get a boat", line_number: 4)

@api public

# File lib/todo_lint/todo.rb, line 66
def initialize(line,
               line_number: RequiredArg.new(:line_number),
               path: RequiredArg.new(:path),
               config: RequiredArg.new(:config))
  absent_todo!(line) unless self.class.present_in?(line)
  @line = line
  @line_number = line_number
  @path = path
  @config = config
end
present_in?(line) click to toggle source

Does this line contain a todo? @example

Todo.present_in?("hello") #=> false
Todo.present_in?("TODO") #=> true

@return [Boolean] @api public

# File lib/todo_lint/todo.rb, line 36
def self.present_in?(line)
  line =~ PATTERN
end
within(file, config: RequiredArg.new(:config)) click to toggle source

Search a file for all of the todo/fixme/etc comments within it @example

Todo.within(File.open("app.rb"))

@api public @return [Array<Todo>]

# File lib/todo_lint/todo.rb, line 18
def self.within(file, config: RequiredArg.new(:config))
  file.each_line.with_index.map do |line, line_number|
    next unless present_in?(line)
    new(
      line,
      :line_number => line_number + 1,
      :path => file.path,
      :config => config
    )
  end.compact
end

Public Instance Methods

<=>(other) click to toggle source

Which todo is due sooner?

@example

[todo_one, todo_two].sort # this implicitly calls <=>

@return [Fixnum] @api public

# File lib/todo_lint/todo.rb, line 168
def <=>(other)
  due_date_for_sorting <=> other.due_date_for_sorting
end
annotated?() click to toggle source

Was this todo annotated with a due date? @example

annotated_todo.line #=> "# TODO(2013-05-24): learn to fly"
annotated_todo.annotated? #=> true

not_annotated_todo.line #=> "# TODO: read a poem"
not_annotated_todo.annotated? #=> false"

@return [Boolean] @api public

# File lib/todo_lint/todo.rb, line 86
def annotated?
  !match[:due_date].nil? || !match[:tag].nil?
end
character_number() click to toggle source

The 1-indexed character at which the todo comment is found @example

todo.character_number #=> 4

@return [Fixnum] @api public

# File lib/todo_lint/todo.rb, line 134
def character_number
  (line =~ PATTERN) + 1
end
due_date() click to toggle source

When this todo is due @example

due_todo.line #=> "# TODO(2015-05-24): go to the beach"
due_todo.due_date.to_date #=> #<Date: 2015-05-24>
not_due_todo.line #=> "# TODO: become a fish"
not_due_todo.due_date #=> nil

@return [DueDate] if there is a due date @return [NilClass] if there is no due date @api public

# File lib/todo_lint/todo.rb, line 110
def due_date
  return unless annotated?
  return @due_date if defined?(@due_date)
  @due_date = if match[:due_date]
                DueDate.from_annotation(match[:due_date])
              elsif match[:tag]
                lookup_tag_due_date
              end
end
flag() click to toggle source

What did the developer write to get our attention? @example

todo.flag #=> "TODO"

@return [String] @api public

# File lib/todo_lint/todo.rb, line 125
def flag
  match[:flag]
end
relative_path() click to toggle source

The relative path to the file where this todo was found

@example

todo.relative #=> "spec/spec_helper.rb"

@return [String] @api public

# File lib/todo_lint/todo.rb, line 179
def relative_path
  current_dir = Pathname.new(File.expand_path("./"))
  Pathname.new(path).relative_path_from(current_dir).to_s
end
tag() click to toggle source

What tag does this todo use?

@example

todo.tag #=> "#shipit"
todo.tag #=> nil

@return [String] if the Todo has a tag @return [NilClass] if the Todo has no tag @api public

# File lib/todo_lint/todo.rb, line 157
def tag
  match[:tag]
end
tag?() click to toggle source

Was this todo using a tag (as opposed to a direct due date)?

@example

todo.tag? #=> true

@return [Boolean] @api public

# File lib/todo_lint/todo.rb, line 144
def tag?
  !match[:tag].nil?
end
task() click to toggle source

What is the actual task associated with this todo?

@example

todo.task #=> "Wash the car"

@return [String] @api public

# File lib/todo_lint/todo.rb, line 97
def task
  match[:task].lstrip
end

Protected Instance Methods

due_date_for_sorting() click to toggle source

Helper for sorting todos

@example

todo.due_date_for_sorting #=> #<Date: 2016-02-06>

@return [Date] @api semipublic

# File lib/todo_lint/todo.rb, line 193
def due_date_for_sorting
  # Date.new is like the beginning of time
  due_date ? due_date.to_date : Date.new
end

Private Instance Methods

absent_todo!(line) click to toggle source

complain that this line isn't even a todo, so nothing will work anyway @return Does not return @api private

# File lib/todo_lint/todo.rb, line 216
def absent_todo!(line)
  raise ArgumentError, "Not even a todo: #{line.inspect}"
end
lookup_tag_due_date() click to toggle source

A tag was referenced, so let's see when that's due @return [DueDate] @raise [KeyError] if the tag does not reference a due date in the config @api private

# File lib/todo_lint/todo.rb, line 224
def lookup_tag_due_date
  config.fetch(:tags).fetch(match[:tag])
rescue KeyError
  msg = "#{match[:tag]} tag not defined in config file"
  raise KeyError, msg
end
match() click to toggle source

Analyze the line to help identify when the todo is due @return [MatchData] @api private

# File lib/todo_lint/todo.rb, line 209
def match
  @match ||= PATTERN.match(line)
end