Class: RuboCop::Cop::Rake::DuplicateNamespace

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

Overview

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

Examples:

# bad
namespace :foo do
  task :bar do
  end
end
namespace :foo do
  task :hoge do
  end
end

# good
namespace :foo do
  task :bar do
  end
  task :hoge do
  end
end

Constant Summary collapse

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

Instance Method Summary collapse

Methods included from Helper::OnNamespace

#on_send

Constructor Details

#initializeDuplicateNamespace

Returns a new instance of DuplicateNamespace.



35
36
37
38
# File 'lib/rubocop/cop/rake/duplicate_namespace.rb', line 35

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

Instance Method Details

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



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

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

#namespaces(node) ⇒ Object



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

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_namespace(node) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rubocop/cop/rake/duplicate_namespace.rb', line 40

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

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

#source_location(node) ⇒ Object



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

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