rubocop-cask 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|