banalize 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8a4e26483ea5692063efa9d08adb90fcbc552243
4
- data.tar.gz: 1225cf15d13b89501f0d6bf2cdff359f2927bcf6
3
+ metadata.gz: 87630dc6d2b7488f3fb027555a11fa8a55e51e69
4
+ data.tar.gz: 7125e23ea24ff1e1d76755431cc89e20a639c1b8
5
5
  SHA512:
6
- metadata.gz: 0ac7bff7e15664f2beb9aa862c539451f8dab4531346abfca0d1f4fff5f13c7769666440c24e50c792f10aedaeb7bedf7d8b1c41d92cb53a917c812a65abef95
7
- data.tar.gz: 940407208055587056763facf1b72c5720a5933f35cc01284e0d54e6d84bf54259b279ae2fea15202ee44e8c9a3bc5c3f7c0947bb697a8288cbb68f62fc7b146
6
+ metadata.gz: 8e3f424b7c271325b8824af7be082dcadc94960045389d0d668277afd5e9d36ed61e41a6a1ff2780d234755dd55918c7d2463b3a184a2a953dca208df56db20c
7
+ data.tar.gz: e6c02e8669009ae01a06b6e6b42622909227ae576496c5e2826189ea70802dbe12d852bf39292bdead538c9de93ca661458c1b514e9e8acc74ff6d3399b2a604
@@ -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
@@ -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 => 'Apply single policy only (by name)'
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
- exit_now! exception.message unless exception.is_a? GLI::BadCommandLine
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
 
@@ -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
- @shebang = Numbered.new
20
+ @lines = IO.read(path).force_encoding("utf-8").split($/)
21
+ @shebang = Numbered.new
7
22
  @comments = Numbered.new
8
- @code = Numbered.new
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
- # @shebang.add lines.shift if lines.first =~ /^#!/
96
- # ```
148
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ruby
149
+ # @shebang.add lines.shift if lines.first =~ /^#!/
150
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
151
+ #
97
152
  def add line, number=0
98
- self[number] = line.chomp
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
@@ -26,19 +26,18 @@ module Banalize
26
26
 
27
27
  # Find policy or list of policies by search criteria.
28
28
  #
29
- # Search can be policy name (Symbol or String), Hash with
30
- # :policy and/or :severity keys or nil.
29
+ # Can perform policy search by:
31
30
  #
32
- # - `nil` - no filtering. Simply list of all policies returned.
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
- # - `:style` - can be Symbol or Array of symbols. If it's :core
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
  #
@@ -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] path UNIX PATH to Bash script
94
+ # @param [String] bash UNIX PATH to Bash script
98
95
  #
99
- def initialize path
100
- raise RuntimeError, "File does not exist: #{path}" unless File.exists? path
101
- @lines = IO.read(path).force_encoding("utf-8").split($/)
102
- @path = 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
- @default = self.class.default.merge($styles[self.class.config[:policy]] || {})
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.
@@ -70,7 +70,10 @@ module Banalize
70
70
  #
71
71
  def ruby
72
72
  object = policy[:klass].constantize.new(bash)
73
- res = object.run
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)
@@ -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
- p.desc 'Policy name'
9
- p.arg_name 'policy_name'
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
- raise "Need a policy name to see description" if args.empty?
13
- p = args.first.to_sym
14
- print "\n#{p}: #{Banalize::Policy.synopsis(p)}\n\n"
15
- print Banalize::Policy.description(p) + "\n\n"
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
@@ -1,7 +1,7 @@
1
1
  banalizer File.basename(__FILE__, '.rb').to_sym do
2
2
 
3
3
  synopsis 'Code lines should not have spaces or tabs at the end'
4
- severity :harsh
4
+ severity :brutal
5
5
  style :cosmetic
6
6
 
7
7
  def run
@@ -1 +1 @@
1
- 0.0.1
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.1
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-26 00:00:00.000000000 Z
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