rubocop-cask 0.2.2 → 0.3.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/README.md +1 -1
- data/config/default.yml +8 -4
- data/lib/rubocop-cask.rb +1 -0
- data/lib/rubocop/cask/ast/cask_block.rb +3 -4
- data/lib/rubocop/cask/version.rb +1 -1
- data/lib/rubocop/cop/cask/license_unknown_comment.rb +74 -0
- data/lib/rubocop/cop/cask/stanza_order.rb +4 -4
- data/spec/rubocop/cop/cask/license_unknown_comment_spec.rb +87 -0
- data/spec/rubocop/cop/cask/no_dsl_version_spec.rb +22 -28
- data/spec/rubocop/cop/cask/stanza_grouping_spec.rb +32 -39
- data/spec/rubocop/cop/cask/stanza_order_spec.rb +38 -46
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb51eac3550f067eca7d72c40f8e328b22b5025c
|
4
|
+
data.tar.gz: 47d413dba32958d1ac635d8b2c6fbdd56408cef7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c35ec1f44568927cdd99ebbab3fb0905dffa3452a6e8d3d29fee49cdea1f6480fa8dd86c4ba60686e6e46f294e816a1ea1bf2e5c45cab341faece793defedbc
|
7
|
+
data.tar.gz: 4abb51a80d7d1a24a1ae4fd300779da7bed220b539381e8a2b84c51ddfa63361d89798be085d300a39965a451ed9e22650819e3e94db975d18e71b6806559c82
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
[](https://codeclimate.com/github/caskroom/rubocop-cask)
|
8
8
|
[](http://inch-ci.org/github/caskroom/rubocop-cask)
|
9
9
|
|
10
|
-
Cask-specific analysis for your Homebrew-Cask taps, as an extension to
|
10
|
+
Cask-specific analysis for your [Homebrew-Cask](https://github.com/caskroom/homebrew-cask) taps, as an extension to
|
11
11
|
[RuboCop](https://github.com/bbatsov/rubocop). Heavily inspired by [`rubocop-rspec`](https://github.com/nevir/rubocop-rspec).
|
12
12
|
|
13
13
|
|
data/config/default.yml
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
-
Cask/
|
2
|
-
Description: '
|
1
|
+
Cask/LicenseUnknownComment:
|
2
|
+
Description: 'Always follow `license :unknown` with the machine-generated TODO comment.'
|
3
3
|
Enabled: true
|
4
4
|
|
5
|
-
Cask/
|
6
|
-
Description: '
|
5
|
+
Cask/NoDslVersion:
|
6
|
+
Description: 'Do not use the deprecated DSL version syntax in your cask header.'
|
7
7
|
Enabled: true
|
8
8
|
|
9
9
|
Cask/StanzaGrouping:
|
10
10
|
Description: 'Ensure that cask stanzas are grouped correctly. More info at https://github.com/caskroom/homebrew-cask/blob/master/CONTRIBUTING.md#stanza-order'
|
11
11
|
Enabled: true
|
12
|
+
|
13
|
+
Cask/StanzaOrder:
|
14
|
+
Description: 'Ensure that cask stanzas are sorted correctly. More info at https://github.com/caskroom/homebrew-cask/blob/master/CONTRIBUTING.md#stanza-order'
|
15
|
+
Enabled: true
|
data/lib/rubocop-cask.rb
CHANGED
@@ -12,6 +12,7 @@ require 'rubocop/cask/inject'
|
|
12
12
|
RuboCop::Cask::Inject.defaults!
|
13
13
|
|
14
14
|
require 'rubocop/cop/cask/mixin/cask_help'
|
15
|
+
require 'rubocop/cop/cask/license_unknown_comment'
|
15
16
|
require 'rubocop/cop/cask/no_dsl_version'
|
16
17
|
require 'rubocop/cop/cask/stanza_order'
|
17
18
|
require 'rubocop/cop/cask/stanza_grouping'
|
@@ -18,16 +18,15 @@ module RuboCop
|
|
18
18
|
|
19
19
|
alias_method :cask_node, :block_node
|
20
20
|
|
21
|
-
|
22
|
-
cask_node.block_body
|
23
|
-
end
|
21
|
+
def_delegator :cask_node, :block_body, :cask_body
|
24
22
|
|
25
23
|
def header
|
26
24
|
@header ||= CaskHeader.new(cask_node.method_node)
|
27
25
|
end
|
28
26
|
|
29
27
|
def stanzas
|
30
|
-
|
28
|
+
return [] unless cask_body
|
29
|
+
@stanzas ||= cask_body.each_node
|
31
30
|
.select(&:stanza?)
|
32
31
|
.map { |node| Stanza.new(node, stanza_comments(node)) }
|
33
32
|
end
|
data/lib/rubocop/cask/version.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'pry'
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Cask
|
6
|
+
# This cop checks that if a cask uses `license :unknown`, it is followed
|
7
|
+
# on the same line by the machine-generated TODO comment.
|
8
|
+
class LicenseUnknownComment < Cop
|
9
|
+
include CaskHelp
|
10
|
+
|
11
|
+
COMMENT_TEXT = '# TODO: change license and remove this comment; ' \
|
12
|
+
"':unknown' is a machine-generated placeholder"
|
13
|
+
MISSING_MSG = "Missing required comment: `#{COMMENT_TEXT}'"
|
14
|
+
INLINE_MSG = "Comment belongs on the same line as `license :unknown'"
|
15
|
+
|
16
|
+
def on_cask(cask_block)
|
17
|
+
license_stanza = cask_block.stanzas.find(&:license?)
|
18
|
+
return unless license_stanza && license_unknown?(license_stanza)
|
19
|
+
add_offenses(license_stanza)
|
20
|
+
end
|
21
|
+
|
22
|
+
def autocorrect(stanza)
|
23
|
+
lambda do |corrector|
|
24
|
+
comment = license_unknown_comment
|
25
|
+
remove_comment(corrector, comment) if comment
|
26
|
+
add_comment(corrector, stanza)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :cask_block
|
33
|
+
|
34
|
+
def license_unknown?(stanza)
|
35
|
+
stanza.source.include?(':unknown')
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_offenses(stanza)
|
39
|
+
comment = license_unknown_comment
|
40
|
+
add_missing_offense(stanza) unless comment
|
41
|
+
add_not_inline_offense(stanza, comment) if comment &&
|
42
|
+
!on_same_line?(stanza, comment)
|
43
|
+
end
|
44
|
+
|
45
|
+
def license_unknown_comment
|
46
|
+
processed_source.comments.find { |c| c.text == COMMENT_TEXT }
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_missing_offense(stanza)
|
50
|
+
add_offense(stanza, stanza.source_range, MISSING_MSG)
|
51
|
+
end
|
52
|
+
|
53
|
+
def add_not_inline_offense(stanza, comment)
|
54
|
+
add_offense(stanza, comment.loc.expression, INLINE_MSG)
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_same_line?(stanza, comment)
|
58
|
+
stanza.source_range.line == comment.loc.line
|
59
|
+
end
|
60
|
+
|
61
|
+
def remove_comment(corrector, comment)
|
62
|
+
line = comment.loc.line
|
63
|
+
length = processed_source[line - 1].length
|
64
|
+
range = source_range(processed_source.buffer, line, 0, length + 1)
|
65
|
+
corrector.remove(range)
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_comment(corrector, stanza)
|
69
|
+
corrector.insert_after(stanza.source_range, " #{COMMENT_TEXT}")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -40,11 +40,11 @@ module RuboCop
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def offending_stanzas
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
stanza_pairs = toplevel_stanzas.zip(sorted_toplevel_stanzas)
|
44
|
+
stanza_pairs.each_with_object([]) do |stanza_pair, offending_stanzas|
|
45
|
+
stanza, sorted_stanza = *stanza_pair
|
46
|
+
offending_stanzas << stanza unless stanza == sorted_stanza
|
46
47
|
end
|
47
|
-
offending
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
describe RuboCop::Cop::Cask::LicenseUnknownComment do
|
2
|
+
include CopSharedExamples
|
3
|
+
|
4
|
+
subject(:cop) { described_class.new }
|
5
|
+
let(:license_unknown_comment) { described_class.const_get(:COMMENT_TEXT) }
|
6
|
+
|
7
|
+
context 'when cask has no license stanza' do
|
8
|
+
let(:source) { "cask 'foo' do; end" }
|
9
|
+
|
10
|
+
include_examples 'does not report any offenses'
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when license is not :unknown' do
|
14
|
+
let(:source) do
|
15
|
+
<<-CASK.undent
|
16
|
+
cask 'foo' do
|
17
|
+
license :mit
|
18
|
+
end
|
19
|
+
CASK
|
20
|
+
end
|
21
|
+
|
22
|
+
include_examples 'does not report any offenses'
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when license is :unknown' do
|
26
|
+
let(:correct_source) do
|
27
|
+
<<-CASK.undent
|
28
|
+
cask 'foo' do
|
29
|
+
license :unknown #{license_unknown_comment}
|
30
|
+
end
|
31
|
+
CASK
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with required comment on same line' do
|
35
|
+
let(:source) { correct_source }
|
36
|
+
|
37
|
+
include_examples 'does not report any offenses'
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with required comment on preceding line' do
|
41
|
+
let(:source) do
|
42
|
+
<<-CASK.undent
|
43
|
+
cask 'foo' do
|
44
|
+
#{license_unknown_comment}
|
45
|
+
license :unknown
|
46
|
+
end
|
47
|
+
CASK
|
48
|
+
end
|
49
|
+
let(:expected_offenses) do
|
50
|
+
[{
|
51
|
+
message: "Comment belongs on the same line as `license :unknown'",
|
52
|
+
severity: :convention,
|
53
|
+
line: 2,
|
54
|
+
column: 2,
|
55
|
+
source: "#{license_unknown_comment}"
|
56
|
+
}]
|
57
|
+
end
|
58
|
+
|
59
|
+
include_examples 'reports offenses'
|
60
|
+
|
61
|
+
include_examples 'autocorrects source'
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with required comment missing' do
|
65
|
+
let(:source) do
|
66
|
+
<<-CASK.undent
|
67
|
+
cask 'foo' do
|
68
|
+
license :unknown
|
69
|
+
end
|
70
|
+
CASK
|
71
|
+
end
|
72
|
+
let(:expected_offenses) do
|
73
|
+
[{
|
74
|
+
message: "Missing required comment: `#{license_unknown_comment}'",
|
75
|
+
severity: :convention,
|
76
|
+
line: 2,
|
77
|
+
column: 2,
|
78
|
+
source: 'license :unknown'
|
79
|
+
}]
|
80
|
+
end
|
81
|
+
|
82
|
+
include_examples 'reports offenses'
|
83
|
+
|
84
|
+
include_examples 'autocorrects source'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -16,15 +16,13 @@ describe RuboCop::Cop::Cask::NoDslVersion do
|
|
16
16
|
let(:source) { "cask :v1 => 'foo' do; end" }
|
17
17
|
let(:correct_source) { "cask 'foo' do; end" }
|
18
18
|
let(:expected_offenses) do
|
19
|
-
[
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
}
|
27
|
-
]
|
19
|
+
[{
|
20
|
+
message: "Use `cask 'foo'` instead of `cask :v1 => 'foo'`",
|
21
|
+
severity: :convention,
|
22
|
+
line: 1,
|
23
|
+
column: 0,
|
24
|
+
source: "cask :v1 => 'foo'"
|
25
|
+
}]
|
28
26
|
end
|
29
27
|
|
30
28
|
include_examples 'reports offenses'
|
@@ -36,15 +34,13 @@ describe RuboCop::Cop::Cask::NoDslVersion do
|
|
36
34
|
let(:source) { "cask :v1test => 'foo' do; end" }
|
37
35
|
let(:correct_source) { "test_cask 'foo' do; end" }
|
38
36
|
let(:expected_offenses) do
|
39
|
-
[
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
}
|
47
|
-
]
|
37
|
+
[{
|
38
|
+
message: "Use `test_cask 'foo'` instead of `cask :v1test => 'foo'`",
|
39
|
+
severity: :convention,
|
40
|
+
line: 1,
|
41
|
+
column: 0,
|
42
|
+
source: "cask :v1test => 'foo'"
|
43
|
+
}]
|
48
44
|
end
|
49
45
|
|
50
46
|
include_examples 'reports offenses'
|
@@ -64,16 +60,14 @@ describe RuboCop::Cop::Cask::NoDslVersion do
|
|
64
60
|
let(:source) { "test_cask :v1 => 'foo' do; end" }
|
65
61
|
let(:correct_source) { "test_cask 'foo' do; end" }
|
66
62
|
let(:expected_offenses) do
|
67
|
-
[
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
}
|
76
|
-
]
|
63
|
+
[{
|
64
|
+
message: "Use `test_cask 'foo'` instead of "\
|
65
|
+
"`test_cask :v1 => 'foo'`",
|
66
|
+
severity: :convention,
|
67
|
+
line: 1,
|
68
|
+
column: 0,
|
69
|
+
source: "test_cask :v1 => 'foo'"
|
70
|
+
}]
|
77
71
|
end
|
78
72
|
|
79
73
|
include_examples 'reports offenses'
|
@@ -41,15 +41,13 @@ describe RuboCop::Cop::Cask::StanzaGrouping do
|
|
41
41
|
CASK
|
42
42
|
end
|
43
43
|
let(:expected_offenses) do
|
44
|
-
[
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
}
|
52
|
-
]
|
44
|
+
[{
|
45
|
+
message: extra_line_msg,
|
46
|
+
severity: :convention,
|
47
|
+
line: 3,
|
48
|
+
column: 0,
|
49
|
+
source: "\n"
|
50
|
+
}]
|
53
51
|
end
|
54
52
|
|
55
53
|
include_examples 'reports offenses'
|
@@ -95,36 +93,31 @@ describe RuboCop::Cop::Cask::StanzaGrouping do
|
|
95
93
|
CASK
|
96
94
|
end
|
97
95
|
let(:expected_offenses) do
|
98
|
-
[
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
line: 12,
|
124
|
-
column: 0,
|
125
|
-
source: " uninstall :quit => 'com.example.foo',"
|
126
|
-
}
|
127
|
-
]
|
96
|
+
[{
|
97
|
+
message: missing_line_msg,
|
98
|
+
severity: :convention,
|
99
|
+
line: 4,
|
100
|
+
column: 0,
|
101
|
+
source: " url 'https://foo.example.com/foo.zip'"
|
102
|
+
}, {
|
103
|
+
message: extra_line_msg,
|
104
|
+
severity: :convention,
|
105
|
+
line: 5,
|
106
|
+
column: 0,
|
107
|
+
source: "\n"
|
108
|
+
}, {
|
109
|
+
message: extra_line_msg,
|
110
|
+
severity: :convention,
|
111
|
+
line: 7,
|
112
|
+
column: 0,
|
113
|
+
source: "\n"
|
114
|
+
}, {
|
115
|
+
message: missing_line_msg,
|
116
|
+
severity: :convention,
|
117
|
+
line: 12,
|
118
|
+
column: 0,
|
119
|
+
source: " uninstall :quit => 'com.example.foo',"
|
120
|
+
}]
|
128
121
|
end
|
129
122
|
|
130
123
|
include_examples 'reports offenses'
|
@@ -34,22 +34,19 @@ describe RuboCop::Cop::Cask::StanzaOrder do
|
|
34
34
|
CASK
|
35
35
|
end
|
36
36
|
let(:expected_offenses) do
|
37
|
-
[
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
source: 'version :latest'
|
51
|
-
}
|
52
|
-
]
|
37
|
+
[{
|
38
|
+
message: '`sha256` stanza out of order',
|
39
|
+
severity: :convention,
|
40
|
+
line: 2,
|
41
|
+
column: 2,
|
42
|
+
source: 'sha256 :no_check'
|
43
|
+
}, {
|
44
|
+
message: '`version` stanza out of order',
|
45
|
+
severity: :convention,
|
46
|
+
line: 3,
|
47
|
+
column: 2,
|
48
|
+
source: 'version :latest'
|
49
|
+
}]
|
53
50
|
end
|
54
51
|
|
55
52
|
include_examples 'reports offenses'
|
@@ -83,37 +80,32 @@ describe RuboCop::Cop::Cask::StanzaOrder do
|
|
83
80
|
CASK
|
84
81
|
end
|
85
82
|
let(:expected_offenses) do
|
86
|
-
[
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
column: 2,
|
99
|
-
source: "uninstall :quit => 'com.example.foo',\n" \
|
83
|
+
[{
|
84
|
+
message: '`url` stanza out of order',
|
85
|
+
severity: :convention,
|
86
|
+
line: 2,
|
87
|
+
column: 2,
|
88
|
+
source: "url 'https://foo.example.com/foo.zip'"
|
89
|
+
}, {
|
90
|
+
message: '`uninstall` stanza out of order',
|
91
|
+
severity: :convention,
|
92
|
+
line: 3,
|
93
|
+
column: 2,
|
94
|
+
source: "uninstall :quit => 'com.example.foo',\n" \
|
100
95
|
" :kext => 'com.example.foo.kext'"
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
source: 'sha256 :no_check'
|
115
|
-
}
|
116
|
-
]
|
96
|
+
}, {
|
97
|
+
message: '`version` stanza out of order',
|
98
|
+
severity: :convention,
|
99
|
+
line: 5,
|
100
|
+
column: 2,
|
101
|
+
source: 'version :latest'
|
102
|
+
}, {
|
103
|
+
message: '`sha256` stanza out of order',
|
104
|
+
severity: :convention,
|
105
|
+
line: 7,
|
106
|
+
column: 2,
|
107
|
+
source: 'sha256 :no_check'
|
108
|
+
}]
|
117
109
|
end
|
118
110
|
|
119
111
|
include_examples 'reports offenses'
|
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.
|
4
|
+
version: 0.3.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: 2016-01-
|
11
|
+
date: 2016-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -47,11 +47,13 @@ files:
|
|
47
47
|
- lib/rubocop/cask/extend/string.rb
|
48
48
|
- lib/rubocop/cask/inject.rb
|
49
49
|
- lib/rubocop/cask/version.rb
|
50
|
+
- lib/rubocop/cop/cask/license_unknown_comment.rb
|
50
51
|
- lib/rubocop/cop/cask/mixin/cask_help.rb
|
51
52
|
- lib/rubocop/cop/cask/no_dsl_version.rb
|
52
53
|
- lib/rubocop/cop/cask/stanza_grouping.rb
|
53
54
|
- lib/rubocop/cop/cask/stanza_order.rb
|
54
55
|
- spec/project_spec.rb
|
56
|
+
- spec/rubocop/cop/cask/license_unknown_comment_spec.rb
|
55
57
|
- spec/rubocop/cop/cask/no_dsl_version_spec.rb
|
56
58
|
- spec/rubocop/cop/cask/stanza_grouping_spec.rb
|
57
59
|
- spec/rubocop/cop/cask/stanza_order_spec.rb
|
@@ -83,6 +85,7 @@ specification_version: 4
|
|
83
85
|
summary: Code style checking for Homebrew-Cask files
|
84
86
|
test_files:
|
85
87
|
- spec/project_spec.rb
|
88
|
+
- spec/rubocop/cop/cask/license_unknown_comment_spec.rb
|
86
89
|
- spec/rubocop/cop/cask/no_dsl_version_spec.rb
|
87
90
|
- spec/rubocop/cop/cask/stanza_grouping_spec.rb
|
88
91
|
- spec/rubocop/cop/cask/stanza_order_spec.rb
|