banalize 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +25 -0
- data/bin/banalize +6 -2
- data/lib/banalize/parser.rb +33 -9
- data/lib/banalize/parser/numbered.rb +92 -7
- data/lib/banalize/parser/pod_comments.rb +49 -0
- data/lib/banalize/policy.rb +12 -10
- data/lib/banalize/registry.rb +15 -17
- data/lib/banalize/runner.rb +4 -1
- data/lib/commands/describe.rb +13 -6
- data/lib/policies/comment_coverage.rb +24 -0
- data/lib/policies/trailing_spaces.rb +1 -1
- data/version.txt +1 -1
- 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: 87630dc6d2b7488f3fb027555a11fa8a55e51e69
|
4
|
+
data.tar.gz: 7125e23ea24ff1e1d76755431cc89e20a639c1b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e3f424b7c271325b8824af7be082dcadc94960045389d0d668277afd5e9d36ed61e41a6a1ff2780d234755dd55918c7d2463b3a184a2a953dca208df56db20c
|
7
|
+
data.tar.gz: e6c02e8669009ae01a06b6e6b42622909227ae576496c5e2826189ea70802dbe12d852bf39292bdead538c9de93ca661458c1b514e9e8acc74ff6d3399b2a604
|
data/History.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
## v.0.0.2
|
3
|
+
|
4
|
+
* Wed Mar 27 2013 -- Dmytro Kovalov
|
5
|
+
Multiple changes:
|
6
|
+
- Allow search policies by regexp from CLI
|
7
|
+
- search method changes in Policy
|
8
|
+
- add search by Regexp
|
9
|
+
- YARD formatting
|
10
|
+
- Changes to describe command
|
11
|
+
- Better screen output with color support
|
12
|
+
- Drop policy name argument from desc command, use global policies search
|
13
|
+
- Fix NaN - divizion by 0n comment coverage
|
14
|
+
- Use of active = false
|
15
|
+
By using false on active default allow disabling policies.
|
16
|
+
- Policy to check percetantage coverage of the comments over code
|
17
|
+
- POD comments module
|
18
|
+
POD comments included into standard parser as module. It recognizes comments in POD here-doc style and moves them from code part to comments.
|
19
|
+
- For Numbered class:
|
20
|
+
- method slice
|
21
|
+
- method sort
|
22
|
+
- Move @lines parsing to Parser class
|
23
|
+
- Add GLI_DEBUG for exit_now!
|
24
|
+
- Documnetation for Numbered class
|
25
|
+
- Fix no method error when $styles section for policy don't exist
|
data/bin/banalize
CHANGED
@@ -20,7 +20,7 @@ EOF
|
|
20
20
|
|
21
21
|
flag [:group, :g], :desc => 'Use only policies included in specified group'
|
22
22
|
flag [:severity, :s], :desc => 'Use only policies of specified severity and above'
|
23
|
-
flag [:policy, :p], :desc => '
|
23
|
+
flag [:policy, :p], :desc => 'Select policies by name (single) or regexp, include in slashes: /indent/'
|
24
24
|
flag [:style, :S], :desc => 'Use custom style file instead of default one.',
|
25
25
|
:default_value => Banalize::USER[:styles]
|
26
26
|
|
@@ -52,6 +52,8 @@ pre do |global,command,options,args|
|
|
52
52
|
search.merge!({ :severity => global[:severity].to_i }) if global[:severity]
|
53
53
|
end
|
54
54
|
|
55
|
+
|
56
|
+
search = Regexp.new(search[1..-2]) if search =~ /^\/.*\/$/
|
55
57
|
$search = search
|
56
58
|
$policies = Banalize::Policy.search search
|
57
59
|
|
@@ -112,7 +114,9 @@ post do |global,command,options,args|
|
|
112
114
|
end
|
113
115
|
|
114
116
|
on_error do |exception|
|
115
|
-
|
117
|
+
unless ENV['GLI_DEBUG'] == 'true'
|
118
|
+
exit_now! exception.message unless exception.is_a? GLI::BadCommandLine
|
119
|
+
end
|
116
120
|
true
|
117
121
|
end
|
118
122
|
|
data/lib/banalize/parser.rb
CHANGED
@@ -1,28 +1,52 @@
|
|
1
1
|
module Banalize
|
2
|
+
|
3
|
+
require_relative 'parser/pod_comments'
|
2
4
|
|
5
|
+
# Instance attributes
|
6
|
+
# -----------
|
7
|
+
# Class sets following attribute accessor methods:
|
8
|
+
#
|
9
|
+
# - {#lines}
|
10
|
+
# - {#path}
|
11
|
+
# - {#shebang}
|
12
|
+
# - {#comments}
|
13
|
+
# - {#code}
|
14
|
+
|
3
15
|
class Parser
|
4
|
-
|
16
|
+
|
17
|
+
include Banalize::Parser::PodStyleComments
|
18
|
+
|
5
19
|
def initialize path
|
6
|
-
@
|
20
|
+
@lines = IO.read(path).force_encoding("utf-8").split($/)
|
21
|
+
@shebang = Numbered.new
|
7
22
|
@comments = Numbered.new
|
8
|
-
@code
|
23
|
+
@code = Numbered.new
|
9
24
|
|
10
|
-
@shebang.add lines.shift if lines.first =~ /^#!/
|
25
|
+
@shebang.add @lines.shift if @lines.first =~ /^#!/
|
11
26
|
|
12
|
-
lines.each_index do |idx|
|
27
|
+
@lines.each_index do |idx|
|
13
28
|
|
14
|
-
next if lines[idx] =~ /^\s*$/
|
29
|
+
next if @lines[idx] =~ /^\s*$/
|
15
30
|
|
16
31
|
lineno = idx + 1 + (@shebang ? 1 : 0) # Compensate for base-0 and shebang line
|
17
32
|
|
18
|
-
if lines[idx] =~ /^\s*\#/
|
19
|
-
@comments.add lines[idx], lineno
|
33
|
+
if @lines[idx] =~ /^\s*\#/
|
34
|
+
@comments.add @lines[idx], lineno
|
20
35
|
else
|
21
|
-
@code.add lines[idx], lineno
|
36
|
+
@code.add @lines[idx], lineno
|
22
37
|
end
|
23
38
|
end
|
39
|
+
pod_comments
|
40
|
+
|
24
41
|
end
|
25
42
|
|
43
|
+
# Lines of the tested bash file, split by \n's
|
44
|
+
attr_accessor :lines
|
45
|
+
|
46
|
+
# UNIX path to the tested file
|
47
|
+
attr_accessor :path
|
48
|
+
|
49
|
+
|
26
50
|
##
|
27
51
|
# Shebang contains first line of the script if it's in `#!`
|
28
52
|
# format. Otherwise it is nil.
|
@@ -4,8 +4,23 @@ module Banalize
|
|
4
4
|
# Class numbered implements simple model of numbered lines data
|
5
5
|
# structure. It's Mash (think Hash).
|
6
6
|
#
|
7
|
-
# Each pair is line_number => row. Line numbers are *not*
|
8
|
-
# necessarily sequential.
|
7
|
+
# Each pair is { line_number => row }. Line numbers are *not*
|
8
|
+
# necessarily sequential, i.e. line numbers in {Numbered} instance
|
9
|
+
# corresponds to those of actuall analyzed script.
|
10
|
+
#
|
11
|
+
# Base of numbers is 1. Examples:
|
12
|
+
#
|
13
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ruby
|
14
|
+
# p @shebang # { 1 => "#!/bin/bash" }
|
15
|
+
#
|
16
|
+
# p @code
|
17
|
+
# # {
|
18
|
+
# # 2 => 'set -e',
|
19
|
+
# # 3 => 'set -u'
|
20
|
+
# # }
|
21
|
+
#
|
22
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
23
|
+
#
|
9
24
|
class Numbered < ::Mash
|
10
25
|
|
11
26
|
def initialize *p
|
@@ -48,6 +63,8 @@ module Banalize
|
|
48
63
|
)
|
49
64
|
end
|
50
65
|
end
|
66
|
+
|
67
|
+
alias :numbers :lines
|
51
68
|
|
52
69
|
##
|
53
70
|
# Search attribute always contains last result of search (grep)
|
@@ -67,7 +84,38 @@ module Banalize
|
|
67
84
|
end
|
68
85
|
|
69
86
|
alias :inspect :to_s
|
70
|
-
|
87
|
+
|
88
|
+
|
89
|
+
##
|
90
|
+
# Return all lines with numbers between from and to
|
91
|
+
#
|
92
|
+
# @param [Finxum] from Starting line
|
93
|
+
# @param [Finxum] to Ending line
|
94
|
+
#
|
95
|
+
# @return [Numbered] Instance of Numbered with all lines beween
|
96
|
+
# specified numbers. Numbers can be not sequntial.
|
97
|
+
#
|
98
|
+
def slice from, to
|
99
|
+
from, to = from.to_i, to.to_i
|
100
|
+
ret = self.class.new self.select { |k,v| k.to_i.between?(from,to) }
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Sort by the order of lines numbers
|
105
|
+
#
|
106
|
+
# @return [Array] Sorted array of 2-elements arrays:
|
107
|
+
#
|
108
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ruby
|
109
|
+
# >> a.comments.sort { |a,b| a.first.to_i <=> b.first.to_i }
|
110
|
+
# => [["2", " Use perldoc functions to see documentation for this file."],
|
111
|
+
# ["4", ":<<\"=cut\
|
112
|
+
# ...
|
113
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
114
|
+
#
|
115
|
+
def sort
|
116
|
+
self.sort { |a,b| a.first.to_i <=> b.first.to_i }
|
117
|
+
end
|
118
|
+
|
71
119
|
##
|
72
120
|
# Grep lines of the Numbered object (i.e. values of the hash) and
|
73
121
|
# return all lines together with numbers that match
|
@@ -89,13 +137,50 @@ module Banalize
|
|
89
137
|
# *Attention*: since {Numbered} is a hash, adding line with the
|
90
138
|
# number that already exists will overwrite existing one.
|
91
139
|
#
|
140
|
+
# @param [String,Numbered] line Line or Numbered object to add
|
141
|
+
#
|
142
|
+
# @param [Finxum] number Line number in the analized script. If
|
143
|
+
# First param is {Numbered} instance, then this argument is
|
144
|
+
# not used.
|
145
|
+
#
|
92
146
|
# ## Example
|
93
147
|
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
148
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ruby
|
149
|
+
# @shebang.add lines.shift if lines.first =~ /^#!/
|
150
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
151
|
+
#
|
97
152
|
def add line, number=0
|
98
|
-
|
153
|
+
case line
|
154
|
+
when String
|
155
|
+
self[number.to_i] = line.chomp
|
156
|
+
when Numbered
|
157
|
+
self.merge! line
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
# Delete numbered line by its number
|
163
|
+
#
|
164
|
+
# Delete line from {Numbered} and return it as
|
165
|
+
# single element {Numbered} object with line number.
|
166
|
+
#
|
167
|
+
# @param [Fixnum,Array[Fixnum],Numbered] lines Lines to delete from Numbered instance.
|
168
|
+
#
|
169
|
+
# @return [Hash] Deleted lines as instance of {Numbered}
|
170
|
+
#
|
171
|
+
def delete lines
|
172
|
+
ret = self.class.new
|
173
|
+
|
174
|
+
case lines
|
175
|
+
when Fixnum
|
176
|
+
ret.add super(lines), lines
|
177
|
+
when Array
|
178
|
+
lines.each { |line| ret.add super(line), line }
|
179
|
+
when Numbered
|
180
|
+
ret.add self.delete lines.keys
|
181
|
+
end
|
182
|
+
|
183
|
+
ret
|
99
184
|
end
|
100
185
|
|
101
186
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Banalize
|
2
|
+
class Parser
|
3
|
+
|
4
|
+
##
|
5
|
+
# Munin project uses documentation in the style of Perl's
|
6
|
+
# POD. These comments are not detected by standard Bash
|
7
|
+
# parser. This mixin takes POD style comments from {#code} and put
|
8
|
+
# them in {#comments}
|
9
|
+
#
|
10
|
+
# POD style comments are in the form:
|
11
|
+
#
|
12
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~bash
|
13
|
+
# :<<"=cut"
|
14
|
+
#
|
15
|
+
# =head1 NAME
|
16
|
+
# ....
|
17
|
+
# ...
|
18
|
+
#
|
19
|
+
# =cut
|
20
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
21
|
+
module PodStyleComments
|
22
|
+
|
23
|
+
##
|
24
|
+
# Parse bash here-doc comments in the POD style and move them to
|
25
|
+
# {#comments}
|
26
|
+
#
|
27
|
+
#
|
28
|
+
def pod_comments
|
29
|
+
start = code.grep(/^:<<"?=cut"?\s*$/)
|
30
|
+
cut = code.grep(/^=cut\s*$/)
|
31
|
+
|
32
|
+
raise "Started not the same number of POD blocks as ended: #{start.size} vs #{cut.size}" if
|
33
|
+
start.size != cut.size
|
34
|
+
|
35
|
+
start.each do |start_pod|
|
36
|
+
|
37
|
+
start_pod = start_pod.first.to_i
|
38
|
+
cut_pod = cut.shift.first.to_i
|
39
|
+
|
40
|
+
raise "Starting line of POD comment after ending line: #{start_pod} > #{cut_pod}" if
|
41
|
+
start_pod > cut_pod
|
42
|
+
|
43
|
+
comments.add code.delete(code.slice(start_pod,cut_pod))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end # PodStyleComments
|
48
|
+
end # Parser
|
49
|
+
end # Banalize
|
data/lib/banalize/policy.rb
CHANGED
@@ -26,19 +26,18 @@ module Banalize
|
|
26
26
|
|
27
27
|
# Find policy or list of policies by search criteria.
|
28
28
|
#
|
29
|
-
#
|
30
|
-
# :policy and/or :severity keys or nil.
|
29
|
+
# Can perform policy search by:
|
31
30
|
#
|
32
|
-
# -
|
31
|
+
# - policy name (Symbol, String or Regegp)
|
32
|
+
# - or Hash with :policy and/or :severity keys or nil.
|
33
|
+
# - `nil` - no filtering. Simply list of all policies returned.
|
34
|
+
# - `:severity` searched for policies with severity value same as
|
35
|
+
# search or higher.
|
36
|
+
# - `:style` - can be Symbol or Array of symbols. If it's :core
|
37
|
+
# or includes :core, all policies returned.
|
33
38
|
#
|
34
|
-
# - `:severity` searched for policies with severity value same as
|
35
|
-
# search or higher.
|
36
39
|
#
|
37
|
-
#
|
38
|
-
# or includes :core, all policies returned.
|
39
|
-
#
|
40
|
-
#
|
41
|
-
# @param [String, Symbol, Hash] search Name of a policy to check
|
40
|
+
# @param [String, Symbol, Hash, Regexp, nil] search Name of a policy to check
|
42
41
|
# against or hash having :severity and/or :policy keys.
|
43
42
|
#
|
44
43
|
# @return [Hash]
|
@@ -52,6 +51,9 @@ module Banalize
|
|
52
51
|
when Symbol, String
|
53
52
|
[Files.policies.find { |x| x[:policy] == search.to_sym }]
|
54
53
|
|
54
|
+
when Regexp
|
55
|
+
Files.policies.find_all { |x| x[:policy] =~ search }
|
56
|
+
|
55
57
|
when Hash
|
56
58
|
res = Files.policies
|
57
59
|
#
|
data/lib/banalize/registry.rb
CHANGED
@@ -9,11 +9,8 @@ module Banalize
|
|
9
9
|
#
|
10
10
|
# Instance attributes
|
11
11
|
# -----------
|
12
|
-
# Class sets following attribute accessor methods:
|
13
|
-
#
|
14
|
-
# - {#lines}
|
15
|
-
# - {#path}
|
16
12
|
# - {#errors}
|
13
|
+
# - {#default}
|
17
14
|
#
|
18
15
|
# Other attributes are inherited from parent Parser class.
|
19
16
|
#
|
@@ -71,7 +68,7 @@ module Banalize
|
|
71
68
|
c = Object.const_set klass, Class.new(self , &block)
|
72
69
|
|
73
70
|
c.synopsis myname
|
74
|
-
c.default({})
|
71
|
+
c.default({}) # make sure defaults are initialized
|
75
72
|
c.severity Policy::DEFAULT[:severity] unless c.severity # Set default severity if it's not defined in block
|
76
73
|
|
77
74
|
# Override these with Styles file
|
@@ -94,22 +91,28 @@ module Banalize
|
|
94
91
|
##
|
95
92
|
# Creates new instance of policy check.
|
96
93
|
#
|
97
|
-
# @param [String]
|
94
|
+
# @param [String] bash UNIX PATH to Bash script
|
98
95
|
#
|
99
|
-
def initialize
|
100
|
-
raise RuntimeError, "File does not exist: #{
|
101
|
-
|
102
|
-
@path =
|
96
|
+
def initialize bash
|
97
|
+
raise RuntimeError, "File does not exist: #{bash}" unless File.exists? bash
|
98
|
+
|
99
|
+
@path = bash
|
103
100
|
@errors = Errors.new self
|
104
101
|
|
105
102
|
# Make class level default variable accessible as instance level
|
106
103
|
# variable and accessor
|
107
104
|
|
108
|
-
@
|
105
|
+
super @path
|
106
|
+
@default = self.class.default.merge( $styles[self.class.config[:policy]] || {} )
|
109
107
|
|
110
|
-
super path
|
111
108
|
end
|
112
109
|
|
110
|
+
##
|
111
|
+
# Instance level accessor for the defaults
|
112
|
+
#
|
113
|
+
# Instance defaults hold same data as in class level default
|
114
|
+
# method. Instance level data are merged on initializing with
|
115
|
+
# personal styles data.
|
113
116
|
attr_accessor :default
|
114
117
|
|
115
118
|
# Instance of Errors class to hold all error messages from tests
|
@@ -121,11 +124,6 @@ module Banalize
|
|
121
124
|
raise ArgumentError, "You must override #run method in class ''#{self.class.policy_name}'"
|
122
125
|
end
|
123
126
|
|
124
|
-
# Lines of the tested bash file, split by \n's
|
125
|
-
attr_accessor :lines
|
126
|
-
|
127
|
-
# UNIX path to the tested file
|
128
|
-
attr_accessor :path
|
129
127
|
|
130
128
|
##
|
131
129
|
# Name of this policy.
|
data/lib/banalize/runner.rb
CHANGED
@@ -70,7 +70,10 @@ module Banalize
|
|
70
70
|
#
|
71
71
|
def ruby
|
72
72
|
object = policy[:klass].constantize.new(bash)
|
73
|
-
|
73
|
+
|
74
|
+
# Policy executed by default unless it explicitly deactivated
|
75
|
+
res = object.default[:active] == false ? true : object.run
|
76
|
+
|
74
77
|
@result = {
|
75
78
|
:status => res ? true : false,
|
76
79
|
:messages => Errors.to_s(object.errors.messages)
|
data/lib/commands/describe.rb
CHANGED
@@ -5,14 +5,21 @@ command [:describe,:desc] do |c|
|
|
5
5
|
|
6
6
|
c.desc 'Print help for the specified policy'
|
7
7
|
c.command [:policy, :pol, :p] do |p|
|
8
|
-
|
9
|
-
|
8
|
+
|
9
|
+
def yellow
|
10
|
+
printf "%s\n", ('~' * 80).color(:yellow)
|
11
|
+
end
|
10
12
|
|
11
13
|
p.action do |global_options, options, args|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
$policies.each do |pol|
|
15
|
+
|
16
|
+
yellow
|
17
|
+
printf "%s : %s\n", pol[:policy].to_s.color(:bold), pol[:synopsis].color(:green)
|
18
|
+
yellow
|
19
|
+
|
20
|
+
puts pol[:description]
|
21
|
+
puts
|
22
|
+
end
|
16
23
|
end
|
17
24
|
|
18
25
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
banalizer File.basename(__FILE__, '.rb').to_sym do
|
2
|
+
|
3
|
+
synopsis 'Script file should be commented. Check percentage of code vs commetns'
|
4
|
+
severity :brutal
|
5
|
+
style :cosmetic
|
6
|
+
|
7
|
+
# What the minumum percentage of comments, by number of lines should
|
8
|
+
# be in your code
|
9
|
+
default percent: 30
|
10
|
+
|
11
|
+
def run
|
12
|
+
|
13
|
+
if code.size == 0
|
14
|
+
errors.add "Code size is 0"
|
15
|
+
|
16
|
+
else
|
17
|
+
pct = ((comments.size.to_f / code.size) * 100).to_i
|
18
|
+
errors.add "Code commented on #{pct}%" if pct < default[:percent]
|
19
|
+
end
|
20
|
+
|
21
|
+
errors.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: banalize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmytro Kovalov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-03-
|
11
|
+
date: 2013-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -76,12 +76,14 @@ extra_rdoc_files: []
|
|
76
76
|
files:
|
77
77
|
- bin/banalize
|
78
78
|
- version.txt
|
79
|
+
- History.md
|
79
80
|
- PARSER.md
|
80
81
|
- README.md
|
81
82
|
- ./lib/banalize/errors.rb
|
82
83
|
- ./lib/banalize/exception.rb
|
83
84
|
- ./lib/banalize/files.rb
|
84
85
|
- ./lib/banalize/parser/numbered.rb
|
86
|
+
- ./lib/banalize/parser/pod_comments.rb
|
85
87
|
- ./lib/banalize/parser.rb
|
86
88
|
- ./lib/banalize/policy/severity.rb
|
87
89
|
- ./lib/banalize/policy.rb
|
@@ -94,6 +96,7 @@ files:
|
|
94
96
|
- ./lib/commands/list.rb
|
95
97
|
- ./lib/core_extensions/string.rb
|
96
98
|
- ./lib/helpers/beautify.rb
|
99
|
+
- ./lib/policies/comment_coverage.rb
|
97
100
|
- ./lib/policies/consistent_indents.rb
|
98
101
|
- ./lib/policies/define_path.rb
|
99
102
|
- ./lib/policies/exit_on_error.rb
|