rubocop-rake 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73d51636442d4cfdeb17f8f0001b51ead2a0628f2e79d8ebeb995ea2b8955915
4
- data.tar.gz: cd0b14eeef0a9cd88caa7f98eb7cff6127bea2e81e16490191591fc68ba0ed6a
3
+ metadata.gz: 14304d50b67b9946c5962a7d4a120f924b1fa12f0236e51dab8b58d106b4a81c
4
+ data.tar.gz: d827d6b122b63d7ce6e012551d389f9e3ee34597d99e9d7b6739e533243d8fe7
5
5
  SHA512:
6
- metadata.gz: 02406d1e2fb8f97db3db0312288e5a5b52a745d5a71eba48a042787e51d8f2040dae6f58243f261acb51d7d53f395038cf0b62904b46bd1d8adcb9def07c7c9d
7
- data.tar.gz: 2b995b622090f8cb82ffdc91674ed54d022349f477ac7334fd75692a70baa03ad87178cad9475352905e8afdcd04d90830bdf24c27d910df0196af62959e1b1b
6
+ metadata.gz: 1079f85fad77e44350769a85a5d925d4ca46c249952d3903f6b0e4804ed22b8435a4e27f0a717296bf024389413852ee89f45ae36cad44c4106560914fe97f1e
7
+ data.tar.gz: f32b18ca6c6db87e80b6ee71bb754717aab1750fc4596949a6e4b2d001034319a5843d5b9771171e332ec9b9ff2e86a7af2ddbbfded90e6c35659d7ef5d7f078
@@ -33,6 +33,9 @@ Style/PercentLiteralDelimiters:
33
33
  Exclude:
34
34
  - '*.gemspec'
35
35
 
36
+ Style/TrailingCommaInArguments:
37
+ EnforcedStyleForMultiline: comma
38
+
36
39
  RSpec/ExampleLength:
37
40
  Enabled: false
38
41
 
@@ -2,12 +2,6 @@
2
2
 
3
3
  ## master (unreleased)
4
4
 
5
- ## 0.3.1 (2019-10-06)
6
-
7
- ### Bug fixes
8
-
9
- * [#17](https://github.com/rubocop-hq/rubocop-rake/pull/17): Filter target files for Rake/ClassDefinitionInTask cop. ([@pocke][])
10
-
11
5
  <!--
12
6
 
13
7
  ### New features
@@ -18,6 +12,18 @@
18
12
 
19
13
  -->
20
14
 
15
+ ## 0.4.0 (2019-10-13)
16
+
17
+ ### New features
18
+
19
+ * [#13](https://github.com/rubocop-hq/rubocop-rake/issues/13): Add Rake/DuplicateTask cop. ([@pocke][])
20
+
21
+ ## 0.3.1 (2019-10-06)
22
+
23
+ ### Bug fixes
24
+
25
+ * [#17](https://github.com/rubocop-hq/rubocop-rake/pull/17): Filter target files for Rake/ClassDefinitionInTask cop. ([@pocke][])
26
+
21
27
  ## 0.3.0 (2019-09-25)
22
28
 
23
29
  ### New features
@@ -1,23 +1,24 @@
1
+ Rake:
2
+ Include:
3
+ - 'Rakefile'
4
+ - '**/*.rake'
5
+
1
6
  Rake/ClassDefinitionInTask:
2
7
  Description: 'Do not define a class or module in rake task, because it will be defined to the top level.'
3
8
  Enabled: true
4
9
  VersionAdded: '0.3.0'
5
- Include:
6
- - 'Rakefile'
7
- - '**/*.rake'
8
10
 
9
11
  Rake/Desc:
10
12
  Description: 'Describe the task with `desc` method.'
11
13
  Enabled: true
12
14
  VersionAdded: '0.1.0'
13
- Include:
14
- - 'Rakefile'
15
- - '**/*.rake'
15
+
16
+ Rake/DuplicateTask:
17
+ Description: 'Do not define tasks with the same name'
18
+ Enabled: true
19
+ VersionAdded: '0.4.0'
16
20
 
17
21
  Rake/MethodDefinitionInTask:
18
22
  Description: 'Do not define a method in rake task, because it will be defined to the top level.'
19
23
  Enabled: true
20
24
  VersionAdded: '0.2.0'
21
- Include:
22
- - 'Rakefile'
23
- - '**/*.rake'
@@ -9,5 +9,7 @@ require_relative 'rubocop/rake/inject'
9
9
  RuboCop::Rake::Inject.defaults!
10
10
 
11
11
  require_relative 'rubocop/cop/rake/helper/class_definition'
12
+ require_relative 'rubocop/cop/rake/helper/on_task'
12
13
  require_relative 'rubocop/cop/rake/helper/task_definition'
14
+ require_relative 'rubocop/cop/rake/helper/task_name'
13
15
  require_relative 'rubocop/cop/rake_cops'
@@ -28,16 +28,13 @@ module RuboCop
28
28
  # end
29
29
  #
30
30
  class Desc < Cop
31
- MSG = 'Describe the task with `desc` method.'
31
+ include Helper::OnTask
32
32
 
33
- def_node_matcher :task?, <<~PATTERN
34
- (send nil? :task ...)
35
- PATTERN
33
+ MSG = 'Describe the task with `desc` method.'
36
34
 
37
- def on_send(node)
38
- return unless task?(node)
35
+ def on_task(node)
39
36
  return if task_with_desc?(node)
40
- return if task_name(node) == :default
37
+ return if Helper::TaskName.task_name(node) == :default
41
38
 
42
39
  add_offense(node)
43
40
  end
@@ -53,23 +50,6 @@ module RuboCop
53
50
  desc_candidate.send_type? && desc_candidate.method_name == :desc
54
51
  end
55
52
 
56
- private def task_name(node)
57
- first_arg = node.arguments[0]
58
- case first_arg&.type
59
- when :sym, :str
60
- return first_arg.value.to_sym
61
- when :hash
62
- return nil if first_arg.children.size != 1
63
-
64
- pair = first_arg.children.first
65
- key = pair.children.first
66
- case key.type
67
- when :sym, :str
68
- key.value.to_sym
69
- end
70
- end
71
- end
72
-
73
53
  private def parent_and_task(task_node)
74
54
  parent = task_node.parent
75
55
  return nil, task_node unless parent
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rake
6
+ # If tasks are defined with the same name, Rake executes the both tasks
7
+ # in definition order.
8
+ # It is misleading sometimes. You should squash them into one definition.
9
+ # This cop detects it.
10
+ #
11
+ # @example
12
+ # # bad
13
+ # task :foo do
14
+ # p 'foo 1'
15
+ # end
16
+ # task :foo do
17
+ # p 'foo 2'
18
+ # end
19
+ #
20
+ # # good
21
+ # task :foo do
22
+ # p 'foo 1'
23
+ # p 'foo 2'
24
+ # end
25
+ #
26
+ class DuplicateTask < Cop
27
+ include Helper::OnTask
28
+
29
+ MSG = 'Task `%<task>s` is defined at both %<previous>s and %<current>s.'
30
+
31
+ def initialize(*)
32
+ super
33
+ @tasks = {}
34
+ end
35
+
36
+ def on_task(node)
37
+ namespaces = namespaces(node)
38
+ return if namespaces.include?(nil)
39
+
40
+ task_name = Helper::TaskName.task_name(node)
41
+ return unless task_name
42
+
43
+ full_name = [*namespaces.reverse, task_name].join(':')
44
+ if (previous = @tasks[full_name])
45
+ message = message_for_dup(previous: previous, current: node, task_name: full_name)
46
+ add_offense(node, message: message)
47
+ else
48
+ @tasks[full_name] = node
49
+ end
50
+ end
51
+
52
+ def namespaces(node)
53
+ ns = []
54
+
55
+ node.each_ancestor(:block) do |block_node|
56
+ send_node = block_node.send_node
57
+ next unless send_node.method_name == :namespace
58
+
59
+ name = Helper::TaskName.task_name(send_node)
60
+ ns << name
61
+ end
62
+
63
+ ns
64
+ end
65
+
66
+ def message_for_dup(previous:, current:, task_name:)
67
+ format(
68
+ MSG,
69
+ task: task_name,
70
+ previous: source_location(previous),
71
+ current: source_location(current),
72
+ )
73
+ end
74
+
75
+ def source_location(node)
76
+ range = node.location.expression
77
+ path = smart_path(range.source_buffer.name)
78
+ "#{path}:#{range.line}"
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rake
6
+ module Helper
7
+ module OnTask
8
+ extend NodePattern::Macros
9
+
10
+ def_node_matcher :task?, <<~PATTERN
11
+ (send nil? :task ...)
12
+ PATTERN
13
+
14
+ def on_send(node)
15
+ return unless task?(node)
16
+
17
+ on_task(node)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rake
6
+ module Helper
7
+ module TaskName
8
+ extend self
9
+
10
+ def task_name(node)
11
+ first_arg = node.arguments[0]
12
+ case first_arg&.type
13
+ when :sym, :str
14
+ return first_arg.value.to_sym
15
+ when :hash
16
+ return nil if first_arg.children.size != 1
17
+
18
+ pair = first_arg.children.first
19
+ key = pair.children.first
20
+ case key.type
21
+ when :sym, :str
22
+ key.value.to_sym
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -2,4 +2,5 @@
2
2
 
3
3
  require_relative 'rake/class_definition_in_task'
4
4
  require_relative 'rake/desc'
5
+ require_relative 'rake/duplicate_task'
5
6
  require_relative 'rake/method_definition_in_task'
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module Rake
5
- VERSION = "0.3.1"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masataka Pocke Kuwabara
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-05 00:00:00.000000000 Z
11
+ date: 2019-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -47,8 +47,11 @@ files:
47
47
  - lib/rubocop-rake.rb
48
48
  - lib/rubocop/cop/rake/class_definition_in_task.rb
49
49
  - lib/rubocop/cop/rake/desc.rb
50
+ - lib/rubocop/cop/rake/duplicate_task.rb
50
51
  - lib/rubocop/cop/rake/helper/class_definition.rb
52
+ - lib/rubocop/cop/rake/helper/on_task.rb
51
53
  - lib/rubocop/cop/rake/helper/task_definition.rb
54
+ - lib/rubocop/cop/rake/helper/task_name.rb
52
55
  - lib/rubocop/cop/rake/method_definition_in_task.rb
53
56
  - lib/rubocop/cop/rake_cops.rb
54
57
  - lib/rubocop/rake.rb