cobplexity 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/cobplexity ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'cobplexity/runner'
data/lib/cobplexity.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'cobplexity/paragraph'
2
+ require 'cobplexity/line'
3
+ require 'cobplexity/module'
4
+ require 'cobplexity/analyzer'
@@ -0,0 +1,52 @@
1
+ module Cobplexity
2
+
3
+ class Analyzer
4
+ attr_accessor :files, :threshold, :group
5
+ def initialize
6
+ @files = []
7
+ @threshold = 0
8
+ @group = "APPLICATION"
9
+ @metrics = []
10
+ end
11
+ def analyze
12
+ @files.each do |file|
13
+ Dir.glob file do |filename|
14
+ @filename = filename
15
+ analyze_file
16
+ end
17
+ end
18
+ @metrics
19
+ end
20
+ def analyze_file
21
+ File.open @filename do |file|
22
+ program = Module.new file.readlines.join
23
+ program.paragraphs.each do |paragraph|
24
+ analyze_paragraph paragraph
25
+ end
26
+ end
27
+ end
28
+ def analyze_paragraph paragraph
29
+ metric = Metric.new
30
+ metric.size = paragraph.lines
31
+ metric.color = @threshold == 0 ? paragraph.complexity : @threshold - paragraph.complexity
32
+ metric.categories << @group
33
+ metric.categories << @filename
34
+ metric.categories << paragraph.name
35
+ @metrics << metric
36
+ end
37
+ end
38
+
39
+ class Metric
40
+ attr_accessor :size, :color, :categories
41
+ def initialize
42
+ @categories = []
43
+ end
44
+ def to_s
45
+ categories = @categories.collect do |category|
46
+ category.delete '",'
47
+ end
48
+ "#{@size},#{@color},#{categories.join ','}"
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,44 @@
1
+ module Cobplexity
2
+
3
+ class Line
4
+ def initialize line
5
+ @line = line.strip
6
+ end
7
+ def code?
8
+ !self.blank? && !self.comment? && !self.continuation? && !self.paragraph? && !self.procedure_division?
9
+ end
10
+ def blank?
11
+ self.statement.empty?
12
+ end
13
+ def comment?
14
+ self.control == '*'
15
+ end
16
+ def continuation?
17
+ self.control == '-'
18
+ end
19
+ def branches
20
+ self.statement.split.count do |item|
21
+ ['IF', 'ELSE', 'WHEN', 'WHILE', 'UNTIL'].include? item.upcase
22
+ end
23
+ end
24
+ def paragraph?
25
+ !self.statement.match(/COPY /i) && !self.area_a.strip.empty?
26
+ end
27
+ def paragraph_name
28
+ self.statement.strip.delete '.'
29
+ end
30
+ def area_a
31
+ self.statement[0..3]
32
+ end
33
+ def control
34
+ @line.length > 6 ? @line[6] : ' '
35
+ end
36
+ def statement
37
+ @line.length > 7 ? @line[7..@line.length] : ''
38
+ end
39
+ def procedure_division?
40
+ @line.match /PROCEDURE DIVISION/i
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,40 @@
1
+ module Cobplexity
2
+
3
+ class Module
4
+ attr_reader :code, :lines, :paragraphs
5
+ def initialize code=''
6
+ self.code = code
7
+ end
8
+ def code= code
9
+ @code = code
10
+ analyze_code
11
+ end
12
+ def analyze_code
13
+ reset_data
14
+ @code.lines.each do |line|
15
+ @line = Line.new line
16
+ if @line.procedure_division?
17
+ reset_data
18
+ else
19
+ count_module
20
+ count_paragraph
21
+ end
22
+ end
23
+ end
24
+ def reset_data
25
+ @lines = 0
26
+ @paragraphs = []
27
+ end
28
+ def count_module
29
+ @lines += 1 if @line.code?
30
+ end
31
+ def count_paragraph
32
+ @paragraphs << Paragraph.new(@line.paragraph_name) if @line.paragraph?
33
+ if @line.code? && !@paragraphs.last.nil?
34
+ @paragraphs.last.lines += 1
35
+ @paragraphs.last.complexity += @line.branches
36
+ end
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,13 @@
1
+ module Cobplexity
2
+
3
+ class Paragraph
4
+ attr_reader :name
5
+ attr_accessor :lines, :complexity
6
+ def initialize name
7
+ @name = name
8
+ @lines = 0
9
+ @complexity = 1
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,21 @@
1
+ require 'optparse'
2
+ require 'cobplexity'
3
+
4
+ analyzer = Cobplexity::Analyzer.new
5
+
6
+ OptionParser.new do |opts|
7
+ opts.banner = "Usage: cobplexity [options]"
8
+ opts.on("-g", "--group NAME", String, "Top level categroy for select code, defaults to 'APPLICATION'") do |group|
9
+ analyzer.group = group
10
+ end
11
+ opts.on("-t", "--threshold NUM", String, "Sets the threshold for code complexity. Complexity greater than threshold will be negative. If not specified, complexity is always a positive number") do |threshold|
12
+ analyzer.threshold = threshold.to_i
13
+ end
14
+ opts.on("-f", "--files a,b,c", Array, "Required: List of files to analyze, accepts wildcards") do |files|
15
+ analyzer.files.concat files
16
+ end
17
+ end.parse!
18
+
19
+ analyzer.analyze.each do |metric|
20
+ puts metric.to_s
21
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cobplexity
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Guy Royse
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-01 00:00:00.000000000 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+ description: Generates CSV files that can be consumed by Microsoft Treemapper from
16
+ COBOL source modules
17
+ email:
18
+ - guy@guyroyse.com
19
+ executables:
20
+ - cobplexity
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - lib/cobplexity/runner.rb
25
+ - lib/cobplexity/analyzer.rb
26
+ - lib/cobplexity/line.rb
27
+ - lib/cobplexity/module.rb
28
+ - lib/cobplexity/paragraph.rb
29
+ - lib/cobplexity.rb
30
+ - bin/cobplexity
31
+ has_rdoc: true
32
+ homepage: http://github.com/guyroyse/cobplexity
33
+ licenses:
34
+ - http://creativecommons.org/licenses/by-sa/3.0/
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: 1.3.6
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 1.6.2
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: Generates CSV files of static code analysis for COBOL modules
57
+ test_files: []