Class: RuboCop::Cop::Rake::DuplicateTask

Inherits:
Base
  • Object
show all
Includes:
Helper::OnTask
Defined in:
lib/rubocop/cop/rake/duplicate_task.rb

Overview

If tasks are defined with the same name, Rake executes the both tasks in definition order. It is misleading sometimes. You should squash them into one definition. This cop detects it.

Examples:

# bad
task :foo do
  p 'foo 1'
end
task :foo do
  p 'foo 2'
end

# good
task :foo do
  p 'foo 1'
  p 'foo 2'
end

Constant Summary collapse

MSG =
'Task `%<task>s` is defined at both %<previous>s and %<current>s.'

Instance Method Summary collapse

Methods included from Helper::OnTask

#on_send

Constructor Details

#initializeDuplicateTask

Returns a new instance of DuplicateTask.



31
32
33
34
# File 'lib/rubocop/cop/rake/duplicate_task.rb', line 31

def initialize(*)
  super
  @tasks = {}
end

Instance Method Details

#message_for_dup(previous:, current:, task_name:) ⇒ Object



66
67
68
69
70
71
72
73
# File 'lib/rubocop/cop/rake/duplicate_task.rb', line 66

def message_for_dup(previous:, current:, task_name:)
  format(
    MSG,
    task: task_name,
    previous: source_location(previous),
    current: source_location(current),
  )
end

#namespaces(node) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rubocop/cop/rake/duplicate_task.rb', line 52

def namespaces(node)
  ns = []

  node.each_ancestor(:block) do |block_node|
    send_node = block_node.send_node
    next unless send_node.method?(:namespace)

    name = Helper::TaskName.task_name(send_node)
    ns << name
  end

  ns
end

#on_task(node) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/rubocop/cop/rake/duplicate_task.rb', line 36

def on_task(node)
  namespaces = namespaces(node)
  return if namespaces.include?(nil)

  task_name = Helper::TaskName.task_name(node)
  return unless task_name

  full_name = [*namespaces.reverse, task_name].join(':')
  if (previous = @tasks[full_name])
    message = message_for_dup(previous: previous, current: node, task_name: full_name)
    add_offense(node, message: message)
  else
    @tasks[full_name] = node
  end
end

#source_location(node) ⇒ Object



75
76
77
78
79
# File 'lib/rubocop/cop/rake/duplicate_task.rb', line 75

def source_location(node)
  range = node.location.expression
  path = smart_path(range.source_buffer.name)
  "#{path}:#{range.line}"
end