rubocop-yast 0.0.4 → 0.0.5
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/Gemfile +1 -0
- data/README.md +122 -0
- data/Rakefile +24 -0
- data/lib/rubocop/cop/yast/builtins.rb +39 -30
- data/lib/rubocop/cop/yast/ops.rb +3 -157
- data/lib/rubocop/yast/builtins/builtin.rb +38 -0
- data/lib/rubocop/yast/builtins/getenv.rb +19 -0
- data/lib/rubocop/yast/builtins/time.rb +16 -0
- data/lib/rubocop/yast/builtins/y2log.rb +138 -0
- data/lib/rubocop/yast/node_helpers.rb +22 -0
- data/lib/rubocop/yast/reformatter.rb +43 -0
- data/lib/rubocop/yast/track_variable_scope.rb +184 -0
- data/lib/rubocop/yast/variable_scope.rb +2 -0
- data/lib/rubocop/yast/version.rb +1 -1
- data/rubocop-yast.gemspec +1 -0
- data/spec/builtins_spec.md +614 -0
- data/spec/builtins_spec.rb +543 -41
- data/spec/ops_spec.rb +12 -7
- data/spec/rspec_code.rb +47 -0
- data/spec/rspec_renderer.rb +206 -0
- data/spec/spec_helper.rb +21 -13
- metadata +29 -2
data/spec/ops_spec.rb
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
def config(safe_mode: true)
|
6
|
-
conf = { "Yast/Ops" => { "SafeMode" => safe_mode } }
|
7
|
-
RuboCop::Config.new(conf)
|
8
|
-
end
|
9
|
-
|
10
5
|
describe RuboCop::Cop::Yast::Ops do
|
11
6
|
context("In safe mode") do
|
12
|
-
|
7
|
+
let(:config) do
|
8
|
+
conf = { "Yast/Ops" => { "SafeMode" => true } }
|
9
|
+
RuboCop::Config.new(conf)
|
10
|
+
end
|
11
|
+
|
12
|
+
subject(:cop) { described_class.new(config) }
|
13
13
|
|
14
14
|
it "finds trivial Ops.add call" do
|
15
15
|
inspect_source(cop, ["Ops.add(2, 4)"])
|
@@ -99,7 +99,12 @@ describe RuboCop::Cop::Yast::Ops do
|
|
99
99
|
end
|
100
100
|
|
101
101
|
context("In unsafe mode") do
|
102
|
-
|
102
|
+
let(:config) do
|
103
|
+
conf = { "Yast/Ops" => { "SafeMode" => false } }
|
104
|
+
RuboCop::Config.new(conf)
|
105
|
+
end
|
106
|
+
|
107
|
+
subject(:cop) { described_class.new(config) }
|
103
108
|
|
104
109
|
it "finds unsafe Ops.add calls" do
|
105
110
|
inspect_source(cop, ["if true\nOps.add(foo, 4)\nend"])
|
data/spec/rspec_code.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
|
2
|
+
# this module provides code block generators for RSpecRenderer
|
3
|
+
module RspecCode
|
4
|
+
# rubocop:disable Metrics/MethodLength
|
5
|
+
def generate_translation_code
|
6
|
+
[
|
7
|
+
"original_code = code_cleanup(<<-EOT)",
|
8
|
+
Code.indent(@original_code),
|
9
|
+
"EOT",
|
10
|
+
"",
|
11
|
+
"translated_code = code_cleanup(<<-EOT)",
|
12
|
+
Code.indent(@translated_code),
|
13
|
+
"EOT",
|
14
|
+
"",
|
15
|
+
"cop = RuboCop::Cop::Yast::Builtins.new",
|
16
|
+
"expect(autocorrect_source(cop, original_code)).to eq(translated_code)"
|
17
|
+
].join("\n")
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate_offense_code
|
21
|
+
[
|
22
|
+
"code = code_cleanup(<<-EOT)",
|
23
|
+
Code.indent(@offense),
|
24
|
+
"EOT",
|
25
|
+
"",
|
26
|
+
"cop = RuboCop::Cop::Yast::Builtins.new",
|
27
|
+
"inspect_source(cop, [code])",
|
28
|
+
"",
|
29
|
+
"expect(cop.offenses.size).to eq(1)",
|
30
|
+
"expect(cop.messages.first).to match(/Builtin call `.*` is obsolete/)"
|
31
|
+
].join("\n")
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate_accepted_code
|
35
|
+
[
|
36
|
+
"code = code_cleanup(<<-EOT)",
|
37
|
+
Code.indent(@accepted_code),
|
38
|
+
"EOT",
|
39
|
+
"",
|
40
|
+
"cop = RuboCop::Cop::Yast::Builtins.new",
|
41
|
+
"inspect_source(cop, [code])",
|
42
|
+
"",
|
43
|
+
"expect(cop.offenses).to be_empty"
|
44
|
+
].join("\n")
|
45
|
+
end
|
46
|
+
# rubocop:enable Metrics/MethodLength
|
47
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require "redcarpet"
|
2
|
+
|
3
|
+
require_relative "rspec_code"
|
4
|
+
|
5
|
+
# Utility functions for manipulating code.
|
6
|
+
module Code
|
7
|
+
INDENT_STEP = 2
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def join(lines)
|
11
|
+
lines.map { |l| "#{l}\n" }.join("")
|
12
|
+
end
|
13
|
+
|
14
|
+
def indent(s)
|
15
|
+
s.gsub(/^(?=.)/, " " * INDENT_STEP)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Represents RSpec's "it" block.
|
21
|
+
class It
|
22
|
+
def initialize(attrs)
|
23
|
+
@description = attrs[:description]
|
24
|
+
@code = attrs[:code]
|
25
|
+
@skip = attrs[:skip]
|
26
|
+
end
|
27
|
+
|
28
|
+
def render
|
29
|
+
[
|
30
|
+
"#{@skip ? "xit" : "it"} #{@description.inspect} do",
|
31
|
+
Code.indent(@code),
|
32
|
+
"end"
|
33
|
+
].join("\n")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Represents RSpec's "describe" block.
|
38
|
+
class Describe
|
39
|
+
attr_reader :blocks
|
40
|
+
|
41
|
+
def initialize(attrs)
|
42
|
+
@description = attrs[:description]
|
43
|
+
@blocks = attrs[:blocks]
|
44
|
+
end
|
45
|
+
|
46
|
+
def render
|
47
|
+
parts = []
|
48
|
+
parts << "describe #{@description.inspect} do"
|
49
|
+
parts << Code.indent(@blocks.map(&:render).join("\n\n")) if !blocks.empty?
|
50
|
+
parts << "end"
|
51
|
+
parts.join("\n")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Renders a Markdown file to an RSpec test script
|
56
|
+
class RSpecRenderer < Redcarpet::Render::Base
|
57
|
+
include RspecCode
|
58
|
+
|
59
|
+
IGNORED_HEADERS = [
|
60
|
+
"Table Of Contents",
|
61
|
+
"Description"
|
62
|
+
]
|
63
|
+
|
64
|
+
def initialize
|
65
|
+
super
|
66
|
+
|
67
|
+
@next_block_type = :unknown
|
68
|
+
@describe = Describe.new(description: "RuboCop-Yast", blocks: [])
|
69
|
+
end
|
70
|
+
|
71
|
+
# preprocess the MarkDown input - remove comments
|
72
|
+
def preprocess(fulldoc)
|
73
|
+
# use multiline regexp pattern
|
74
|
+
fulldoc.gsub(/<!--.*-->/m, "")
|
75
|
+
end
|
76
|
+
|
77
|
+
def header(text, header_level)
|
78
|
+
return nil if header_level == 1 || IGNORED_HEADERS.include?(text)
|
79
|
+
|
80
|
+
if header_level > describes_depth + 1
|
81
|
+
raise "Missing higher level header: #{text}"
|
82
|
+
end
|
83
|
+
|
84
|
+
describe_at_level(header_level - 1).blocks << Describe.new(
|
85
|
+
description: text + ":",
|
86
|
+
blocks: []
|
87
|
+
)
|
88
|
+
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def paragraph(text)
|
93
|
+
if text =~ /^\*\*(.*)\*\*$/
|
94
|
+
@next_block_type = Regexp.last_match[1].downcase.to_sym
|
95
|
+
else
|
96
|
+
first_sentence = text.split(/\.(\s+|$)/).first
|
97
|
+
@description = first_sentence.sub(/^RuboCop-Yast /, "").sub(/\n/, " ")
|
98
|
+
end
|
99
|
+
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
|
103
|
+
# rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity:
|
104
|
+
def block_code(code, _language)
|
105
|
+
escaped_code = escape(code[0..-2])
|
106
|
+
|
107
|
+
case @next_block_type
|
108
|
+
when :original
|
109
|
+
@original_code = escaped_code
|
110
|
+
when :translated
|
111
|
+
@translated_code = escaped_code
|
112
|
+
when :unchanged
|
113
|
+
@original_code = @translated_code = escaped_code
|
114
|
+
when :offense
|
115
|
+
@offense = escaped_code
|
116
|
+
when :accepted
|
117
|
+
@accepted_code = escaped_code
|
118
|
+
else
|
119
|
+
raise "Invalid next code block type: #{@next_block_type}.\n#{code}"
|
120
|
+
end
|
121
|
+
|
122
|
+
@next_block_type = :unknown
|
123
|
+
|
124
|
+
add_translation_block if @original_code && @translated_code
|
125
|
+
add_offense_block if @offense
|
126
|
+
add_accepted_block if @accepted_code
|
127
|
+
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity:
|
131
|
+
|
132
|
+
# escape ruby interpolation
|
133
|
+
def escape(code)
|
134
|
+
code.gsub("\#{", "\\\#{")
|
135
|
+
end
|
136
|
+
|
137
|
+
def doc_header
|
138
|
+
Code.join([
|
139
|
+
"# Automatically generated -- DO NOT EDIT!",
|
140
|
+
"",
|
141
|
+
"require \"spec_helper\"",
|
142
|
+
""
|
143
|
+
])
|
144
|
+
end
|
145
|
+
|
146
|
+
def doc_footer
|
147
|
+
"#{@describe.render}\n"
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
def describes_depth
|
153
|
+
describe = @describe
|
154
|
+
depth = 1
|
155
|
+
while describe.blocks.last.is_a?(Describe)
|
156
|
+
describe = describe.blocks.last
|
157
|
+
depth += 1
|
158
|
+
end
|
159
|
+
depth
|
160
|
+
end
|
161
|
+
|
162
|
+
def current_describe
|
163
|
+
describe = @describe
|
164
|
+
describe = describe.blocks.last while describe.blocks.last.is_a?(Describe)
|
165
|
+
describe
|
166
|
+
end
|
167
|
+
|
168
|
+
def describe_at_level(level)
|
169
|
+
describe = @describe
|
170
|
+
2.upto(level) do
|
171
|
+
describe = describe.blocks.last
|
172
|
+
end
|
173
|
+
describe
|
174
|
+
end
|
175
|
+
|
176
|
+
def add_translation_block
|
177
|
+
current_describe.blocks << It.new(
|
178
|
+
description: @description,
|
179
|
+
code: generate_translation_code,
|
180
|
+
skip: @description =~ /XFAIL/
|
181
|
+
)
|
182
|
+
|
183
|
+
@original_code = nil
|
184
|
+
@translated_code = nil
|
185
|
+
end
|
186
|
+
|
187
|
+
def add_offense_block
|
188
|
+
current_describe.blocks << It.new(
|
189
|
+
description: @description,
|
190
|
+
code: generate_offense_code,
|
191
|
+
skip: @description =~ /XFAIL/
|
192
|
+
)
|
193
|
+
|
194
|
+
@offense = nil
|
195
|
+
end
|
196
|
+
|
197
|
+
def add_accepted_block
|
198
|
+
current_describe.blocks << It.new(
|
199
|
+
description: @description,
|
200
|
+
code: generate_accepted_code,
|
201
|
+
skip: @description =~ /XFAIL/
|
202
|
+
)
|
203
|
+
|
204
|
+
@accepted_code = nil
|
205
|
+
end
|
206
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
require "simplecov"
|
3
|
+
require "simplecov"
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
# use coveralls for on-line code coverage reporting at Travis CI
|
6
|
+
if ENV["TRAVIS"]
|
7
|
+
require "coveralls"
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
10
|
+
SimpleCov::Formatter::HTMLFormatter,
|
11
|
+
Coveralls::SimpleCov::Formatter
|
12
|
+
]
|
13
|
+
end
|
15
14
|
|
16
|
-
|
15
|
+
SimpleCov.minimum_coverage 95
|
17
16
|
|
18
|
-
|
17
|
+
SimpleCov.start do
|
18
|
+
# don't check code coverage in these subdirectories
|
19
|
+
add_filter "/vendor/"
|
20
|
+
add_filter "/spec/"
|
19
21
|
end
|
20
22
|
|
21
23
|
# allow only the new "expect" RSpec syntax
|
@@ -29,11 +31,17 @@ RSpec.configure do |config|
|
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
#
|
34
|
+
# reuse the Rubocop helper, provides some nice methods used in tests
|
33
35
|
require File.join(
|
34
36
|
Gem::Specification.find_by_name("rubocop").gem_dir, "spec", "spec_helper.rb"
|
35
37
|
)
|
36
38
|
|
37
39
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
38
40
|
|
41
|
+
def code_cleanup(s)
|
42
|
+
s.split("\n").reject { |l| l =~ /^\s*$/ }.first =~ /^(\s*)/
|
43
|
+
return s.dup if Regexp.last_match.nil?
|
44
|
+
s.gsub(Regexp.new("^#{Regexp.last_match[1]}"), "")[0..-2]
|
45
|
+
end
|
46
|
+
|
39
47
|
require "rubocop-yast"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-yast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ladislav Slezák
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: redcarpet
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,13 +99,23 @@ files:
|
|
85
99
|
- lib/rubocop-yast.rb
|
86
100
|
- lib/rubocop/cop/yast/builtins.rb
|
87
101
|
- lib/rubocop/cop/yast/ops.rb
|
102
|
+
- lib/rubocop/yast/builtins/builtin.rb
|
103
|
+
- lib/rubocop/yast/builtins/getenv.rb
|
104
|
+
- lib/rubocop/yast/builtins/time.rb
|
105
|
+
- lib/rubocop/yast/builtins/y2log.rb
|
88
106
|
- lib/rubocop/yast/config.rb
|
89
107
|
- lib/rubocop/yast/niceness.rb
|
108
|
+
- lib/rubocop/yast/node_helpers.rb
|
109
|
+
- lib/rubocop/yast/reformatter.rb
|
110
|
+
- lib/rubocop/yast/track_variable_scope.rb
|
90
111
|
- lib/rubocop/yast/variable_scope.rb
|
91
112
|
- lib/rubocop/yast/version.rb
|
92
113
|
- rubocop-yast.gemspec
|
114
|
+
- spec/builtins_spec.md
|
93
115
|
- spec/builtins_spec.rb
|
94
116
|
- spec/ops_spec.rb
|
117
|
+
- spec/rspec_code.rb
|
118
|
+
- spec/rspec_renderer.rb
|
95
119
|
- spec/spec_helper.rb
|
96
120
|
homepage: http://github.com/yast/rubocop-yast
|
97
121
|
licenses:
|
@@ -118,6 +142,9 @@ signing_key:
|
|
118
142
|
specification_version: 4
|
119
143
|
summary: Specific YaST Rubocop checks
|
120
144
|
test_files:
|
145
|
+
- spec/builtins_spec.md
|
121
146
|
- spec/builtins_spec.rb
|
122
147
|
- spec/ops_spec.rb
|
148
|
+
- spec/rspec_code.rb
|
149
|
+
- spec/rspec_renderer.rb
|
123
150
|
- spec/spec_helper.rb
|