rubocop-cask 0.0.1 → 0.1.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 +4 -4
- data/lib/rubocop-cask.rb +4 -0
- data/lib/rubocop/cask/cask_block.rb +20 -0
- data/lib/rubocop/cask/cask_header.rb +59 -0
- data/lib/rubocop/cask/cask_help.rb +32 -0
- data/lib/rubocop/cask/node_help.rb +81 -0
- data/lib/rubocop/cask/version.rb +1 -1
- data/lib/rubocop/cop/cask/no_dsl_version.rb +30 -19
- data/spec/rubocop/cop/cask/no_dsl_version_spec.rb +95 -48
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cdfd026586c969df6476b261c953b19a97c0d96
|
4
|
+
data.tar.gz: f5eec7b28ca3f9011a73505bb1caef81ccc09ed4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 087b2408052d624ca8c94b59de9314474261bdd63f728e0673763fc76a3a7e750ce4288d19580ff83d6342b722989e0bebb0dcd430692ca97efe90e117583ead
|
7
|
+
data.tar.gz: 05aed98a4ea27b6ac1060476de4aa6b0a70a52ba9e41c7c2ff12824b9fbea4ff994e93bbb9bd40a6e8d6e6a582d6b28b7b4902bda59bb43a7660e1f6c6169fb8
|
data/lib/rubocop-cask.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
module RuboCop
|
2
|
+
module Cask
|
3
|
+
# This class wraps the AST block node that represents the entire cask
|
4
|
+
# definition. It includes various helper methods to aid cops in their
|
5
|
+
# analysis.
|
6
|
+
class CaskBlock
|
7
|
+
include CaskHelp
|
8
|
+
|
9
|
+
attr_reader :block_node
|
10
|
+
|
11
|
+
def initialize(block_node)
|
12
|
+
@block_node = block_node
|
13
|
+
end
|
14
|
+
|
15
|
+
def header
|
16
|
+
@header ||= CaskHeader.new(method_node(block_node))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module RuboCop
|
2
|
+
module Cask
|
3
|
+
# This class wraps the AST method node that represents the cask header. It
|
4
|
+
# includes various helper methods to aid cops in their analysis.
|
5
|
+
class CaskHeader
|
6
|
+
include CaskHelp
|
7
|
+
|
8
|
+
attr_reader :method_node
|
9
|
+
|
10
|
+
def initialize(method_node)
|
11
|
+
@method_node = method_node
|
12
|
+
end
|
13
|
+
|
14
|
+
def dsl_version?
|
15
|
+
hash_node
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_cask?
|
19
|
+
header_method_name == :test_cask || dsl_version.to_s.include?('test')
|
20
|
+
end
|
21
|
+
|
22
|
+
def header_str
|
23
|
+
@header_str ||= source_range.source
|
24
|
+
end
|
25
|
+
|
26
|
+
def source_range
|
27
|
+
@source_range ||= method_node.loc.expression
|
28
|
+
end
|
29
|
+
|
30
|
+
def preferred_header_str
|
31
|
+
"#{preferred_header_method_name} '#{cask_token}'"
|
32
|
+
end
|
33
|
+
|
34
|
+
def preferred_header_method_name
|
35
|
+
test_cask? ? :test_cask : :cask
|
36
|
+
end
|
37
|
+
|
38
|
+
def header_method_name
|
39
|
+
@header_method_name ||= method_name(method_node)
|
40
|
+
end
|
41
|
+
|
42
|
+
def dsl_version
|
43
|
+
@dsl_version ||= key_node(pair_node).children.first
|
44
|
+
end
|
45
|
+
|
46
|
+
def cask_token
|
47
|
+
@cask_token ||= value_node(pair_node).children.first
|
48
|
+
end
|
49
|
+
|
50
|
+
def hash_node
|
51
|
+
@hash_node ||= hash_children(method_node).first
|
52
|
+
end
|
53
|
+
|
54
|
+
def pair_node
|
55
|
+
@pair_node ||= pair_children(hash_node).first
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module RuboCop
|
2
|
+
module Cask
|
3
|
+
# Common functionality for cops checking casks
|
4
|
+
module CaskHelp
|
5
|
+
include NodeHelp
|
6
|
+
|
7
|
+
CASK_METHOD_NAMES = %i(cask test_cask)
|
8
|
+
|
9
|
+
def cask?(block_node)
|
10
|
+
block?(block_node) && cask_method?(method_node(block_node))
|
11
|
+
end
|
12
|
+
|
13
|
+
def cask_method?(method_node)
|
14
|
+
CASK_METHOD_NAMES.include?(method_name(method_node))
|
15
|
+
end
|
16
|
+
|
17
|
+
def cask_children(node)
|
18
|
+
node_children(node).select { |e| cask?(e) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_block(block_node)
|
22
|
+
super if defined? super
|
23
|
+
return unless respond_to?(:on_cask)
|
24
|
+
return unless cask?(block_node)
|
25
|
+
|
26
|
+
method_node, _args, block_body = *block_node
|
27
|
+
|
28
|
+
on_cask(block_node, method_node, block_body)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module RuboCop
|
2
|
+
module Cask
|
3
|
+
# Helpers for traversing AST nodes
|
4
|
+
module NodeHelp
|
5
|
+
def root_node
|
6
|
+
processed_source.ast
|
7
|
+
end
|
8
|
+
|
9
|
+
def node?(node, type: nil)
|
10
|
+
return unless node.is_a?(Parser::AST::Node)
|
11
|
+
type ? node.type == type : true
|
12
|
+
end
|
13
|
+
|
14
|
+
def method?(node)
|
15
|
+
node?(node, type: :send)
|
16
|
+
end
|
17
|
+
|
18
|
+
def block?(node)
|
19
|
+
node?(node, type: :block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def hash?(node)
|
23
|
+
node?(node, type: :hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
def pair?(node)
|
27
|
+
node?(node, type: :pair)
|
28
|
+
end
|
29
|
+
|
30
|
+
def node_children(node, type: nil)
|
31
|
+
node.children.select { |e| node?(e, type: type) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def method_children(node)
|
35
|
+
node_children(node, type: :send)
|
36
|
+
end
|
37
|
+
|
38
|
+
def block_children(node)
|
39
|
+
node_children(node, type: :block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def hash_children(node)
|
43
|
+
node_children(node, type: :hash)
|
44
|
+
end
|
45
|
+
|
46
|
+
def pair_children(node)
|
47
|
+
node_children(node, type: :pair)
|
48
|
+
end
|
49
|
+
|
50
|
+
def method_node(block_node)
|
51
|
+
fail 'Not a block node' unless block?(block_node)
|
52
|
+
method_node, _args, _body = *block_node
|
53
|
+
method_node
|
54
|
+
end
|
55
|
+
|
56
|
+
def method_name(method_node)
|
57
|
+
fail 'Not a send node' unless method?(method_node)
|
58
|
+
_receiver, method_name, *_method_args = *method_node
|
59
|
+
method_name
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_args(method_node)
|
63
|
+
fail 'Not a send node' unless method?(method_node)
|
64
|
+
_receiver, _method_name, *method_args = *method_node
|
65
|
+
method_args
|
66
|
+
end
|
67
|
+
|
68
|
+
def key_node(pair_node)
|
69
|
+
fail 'Not a pair node' unless pair?(pair_node)
|
70
|
+
key_node, _value_node = *pair_node
|
71
|
+
key_node
|
72
|
+
end
|
73
|
+
|
74
|
+
def value_node(pair_node)
|
75
|
+
fail 'Not a pair node' unless pair?(pair_node)
|
76
|
+
_key_node, value_node = *pair_node
|
77
|
+
value_node
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/rubocop/cask/version.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module RuboCop
|
2
4
|
module Cop
|
3
5
|
module Cask
|
@@ -14,34 +16,43 @@ module RuboCop
|
|
14
16
|
# ...
|
15
17
|
# end
|
16
18
|
class NoDslVersion < Cop
|
19
|
+
extend Forwardable
|
20
|
+
include RuboCop::Cask::CaskHelp
|
21
|
+
|
17
22
|
MESSAGE = 'Use `%s` instead of `%s`'
|
18
23
|
|
19
|
-
|
24
|
+
def on_cask(_block_node, method_node, _block_body)
|
25
|
+
@cask_header = cask_header(method_node)
|
26
|
+
return unless offense?
|
27
|
+
offense
|
28
|
+
end
|
20
29
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
30
|
+
def autocorrect(method_node)
|
31
|
+
@cask_header = cask_header(method_node)
|
32
|
+
lambda do |corrector|
|
33
|
+
corrector.replace(header_range, preferred_header_str)
|
34
|
+
end
|
26
35
|
end
|
27
36
|
|
28
37
|
private
|
29
38
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
39
|
+
def_delegator :@cask_header, :source_range, :header_range
|
40
|
+
def_delegators :@cask_header, :header_str, :preferred_header_str
|
41
|
+
|
42
|
+
def cask_header(method_node)
|
43
|
+
RuboCop::Cask::CaskHeader.new(method_node)
|
44
|
+
end
|
45
|
+
|
46
|
+
def offense?
|
47
|
+
@cask_header.dsl_version?
|
48
|
+
end
|
49
|
+
|
50
|
+
def offense
|
51
|
+
add_offense(@cask_header.method_node, header_range, error_msg)
|
34
52
|
end
|
35
53
|
|
36
|
-
def
|
37
|
-
|
38
|
-
cask_token = right.children.first
|
39
|
-
dsl_version_str = left.children.first.to_s
|
40
|
-
new_method_name =
|
41
|
-
dsl_version_str.include?('test') ? :test_cask : method_name
|
42
|
-
preferred_header = "#{new_method_name} '#{cask_token}'"
|
43
|
-
actual_header = "#{method_name} #{object.loc.expression.source}"
|
44
|
-
format(MESSAGE, preferred_header, actual_header)
|
54
|
+
def error_msg
|
55
|
+
format(MESSAGE, preferred_header_str, header_str)
|
45
56
|
end
|
46
57
|
end
|
47
58
|
end
|
@@ -1,58 +1,105 @@
|
|
1
1
|
describe RuboCop::Cop::Cask::NoDslVersion do
|
2
2
|
subject(:cop) { described_class.new }
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
.to eq([":v1 => 'foo'"])
|
15
|
-
end
|
4
|
+
context 'with header method `cask`' do
|
5
|
+
context 'with no dsl version' do
|
6
|
+
it 'passes' do
|
7
|
+
inspect_source(cop, [
|
8
|
+
"cask 'foo' do",
|
9
|
+
'end'
|
10
|
+
])
|
11
|
+
expect(cop.offenses).to be_empty
|
12
|
+
end
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
15
|
+
context 'with dsl version' do
|
16
|
+
it 'fails' do
|
17
|
+
inspect_source(cop, [
|
18
|
+
"cask :v1 => 'foo' do",
|
19
|
+
'end'
|
20
|
+
])
|
21
|
+
expect(cop.offenses.size).to eq(1)
|
22
|
+
expect(cop.offenses.first.line).to eq(1)
|
23
|
+
expect(cop.messages)
|
24
|
+
.to eq(["Use `cask 'foo'` instead of `cask :v1 => 'foo'`"])
|
25
|
+
expect(cop.highlights)
|
26
|
+
.to eq(["cask :v1 => 'foo'"])
|
27
|
+
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
29
|
+
it 'autocorrects' do
|
30
|
+
new_source = autocorrect_source(cop, [
|
31
|
+
"cask :v1 => 'foo' do",
|
32
|
+
'end'
|
33
|
+
])
|
34
|
+
expect(new_source).to eq([
|
35
|
+
"cask 'foo' do",
|
36
|
+
'end'
|
37
|
+
].join("\n"))
|
38
|
+
end
|
39
|
+
end
|
37
40
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
41
|
+
context 'with dsl version containing "test"' do
|
42
|
+
it 'fails' do
|
43
|
+
inspect_source(cop, [
|
44
|
+
"cask :v1test => 'foo' do",
|
45
|
+
'end'
|
46
|
+
])
|
47
|
+
expect(cop.offenses.size).to eq(1)
|
48
|
+
expect(cop.offenses.first.line).to eq(1)
|
49
|
+
expect(cop.messages)
|
50
|
+
.to eq(["Use `test_cask 'foo'` instead of `cask :v1test => 'foo'`"])
|
51
|
+
expect(cop.highlights)
|
52
|
+
.to eq(["cask :v1test => 'foo'"])
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'autocorrects' do
|
56
|
+
new_source = autocorrect_source(cop, [
|
57
|
+
"cask :v1test => 'foo' do",
|
58
|
+
'end'
|
59
|
+
])
|
60
|
+
expect(new_source).to eq([
|
61
|
+
"test_cask 'foo' do",
|
62
|
+
'end'
|
63
|
+
].join("\n"))
|
64
|
+
end
|
65
|
+
end
|
49
66
|
end
|
50
67
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
68
|
+
context 'with header method `test_cask`' do
|
69
|
+
context 'with no dsl version' do
|
70
|
+
it 'passes' do
|
71
|
+
inspect_source(cop, [
|
72
|
+
"test_cask 'foo' do",
|
73
|
+
'end'
|
74
|
+
])
|
75
|
+
expect(cop.offenses).to be_empty
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'with dsl version' do
|
80
|
+
it 'fails' do
|
81
|
+
inspect_source(cop, [
|
82
|
+
"test_cask :v1 => 'foo' do",
|
83
|
+
'end'
|
84
|
+
])
|
85
|
+
expect(cop.offenses.size).to eq(1)
|
86
|
+
expect(cop.offenses.first.line).to eq(1)
|
87
|
+
expect(cop.messages)
|
88
|
+
.to eq(["Use `test_cask 'foo'` instead of `test_cask :v1 => 'foo'`"])
|
89
|
+
expect(cop.highlights)
|
90
|
+
.to eq(["test_cask :v1 => 'foo'"])
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'autocorrects' do
|
94
|
+
new_source = autocorrect_source(cop, [
|
95
|
+
"test_cask :v1 => 'foo' do",
|
96
|
+
'end'
|
97
|
+
])
|
98
|
+
expect(new_source).to eq([
|
99
|
+
"test_cask 'foo' do",
|
100
|
+
'end'
|
101
|
+
].join("\n"))
|
102
|
+
end
|
103
|
+
end
|
57
104
|
end
|
58
105
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-cask
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Hagins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -39,13 +39,17 @@ files:
|
|
39
39
|
- README.md
|
40
40
|
- config/default.yml
|
41
41
|
- lib/rubocop-cask.rb
|
42
|
+
- lib/rubocop/cask/cask_block.rb
|
43
|
+
- lib/rubocop/cask/cask_header.rb
|
44
|
+
- lib/rubocop/cask/cask_help.rb
|
42
45
|
- lib/rubocop/cask/inject.rb
|
46
|
+
- lib/rubocop/cask/node_help.rb
|
43
47
|
- lib/rubocop/cask/version.rb
|
44
48
|
- lib/rubocop/cop/cask/no_dsl_version.rb
|
45
49
|
- spec/project_spec.rb
|
46
50
|
- spec/rubocop/cop/cask/no_dsl_version_spec.rb
|
47
51
|
- spec/spec_helper.rb
|
48
|
-
homepage: https://github.com/
|
52
|
+
homepage: https://github.com/caskroom/rubocop-cask
|
49
53
|
licenses:
|
50
54
|
- MIT
|
51
55
|
metadata: {}
|
@@ -65,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
69
|
version: '0'
|
66
70
|
requirements: []
|
67
71
|
rubyforge_project:
|
68
|
-
rubygems_version: 2.
|
72
|
+
rubygems_version: 2.5.1
|
69
73
|
signing_key:
|
70
74
|
specification_version: 4
|
71
75
|
summary: Code style checking for Homebrew-Cask files
|