saikuro 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/saikuro +0 -2
- data/lib/saikuro.rb +13 -268
- data/lib/saikuro/base_formater.rb +33 -0
- data/lib/saikuro/cli.rb +1 -5
- data/lib/saikuro/html_style_sheet.rb +85 -0
- data/lib/saikuro/html_token_counter_formater.rb +48 -0
- data/lib/saikuro/parse_state_formater.rb +30 -0
- data/lib/saikuro/result_index_generator.rb +69 -68
- data/lib/saikuro/state_html_complexity_formater.rb +41 -0
- data/lib/saikuro/token_counter_formater.rb +37 -0
- data/lib/saikuro/version.rb +1 -1
- data/saikuro.gemspec +1 -1
- metadata +9 -3
data/bin/saikuro
CHANGED
data/lib/saikuro.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require "saikuro/version"
|
2
2
|
|
3
|
+
require "saikuro/html_style_sheet"
|
4
|
+
|
3
5
|
require "saikuro/result_index_generator"
|
6
|
+
|
7
|
+
require "saikuro/base_formater"
|
8
|
+
require "saikuro/token_counter_formater"
|
9
|
+
require "saikuro/parse_state_formater"
|
10
|
+
require "saikuro/html_token_counter_formater"
|
11
|
+
require "saikuro/state_html_complexity_formater"
|
12
|
+
|
4
13
|
require "saikuro/cli"
|
5
14
|
|
6
15
|
require 'irb/ruby-lex'
|
@@ -23,9 +32,9 @@ def get_ruby_files(path)
|
|
23
32
|
files = Array.new
|
24
33
|
Find.find(path) do |f|
|
25
34
|
if !FileTest.directory?(f)
|
26
|
-
if f =~ /rb$/
|
27
|
-
|
28
|
-
end
|
35
|
+
if f =~ /rb$/
|
36
|
+
files<< f
|
37
|
+
end
|
29
38
|
end
|
30
39
|
end
|
31
40
|
files
|
@@ -190,7 +199,7 @@ class ParseState
|
|
190
199
|
end
|
191
200
|
@last_token_line_and_char<< [@lexer.line_no.to_i, @lexer.char_no.to_i, tok]
|
192
201
|
if $VERBOSE
|
193
|
-
|
202
|
+
puts "DEBUG: #{@lexer.line_no} #{tok.class}:#{tok.name if tok.respond_to?(:name)}"
|
194
203
|
end
|
195
204
|
@@token_counter.count_token(@lexer.line_no, tok) if count_tokens?
|
196
205
|
parse_token(tok)
|
@@ -603,270 +612,6 @@ class Filter
|
|
603
612
|
|
604
613
|
end
|
605
614
|
|
606
|
-
|
607
|
-
class BaseFormater
|
608
|
-
attr_accessor :warnings, :errors, :current
|
609
|
-
|
610
|
-
def initialize(out, filter = nil)
|
611
|
-
@out = out
|
612
|
-
@filter = filter
|
613
|
-
reset_data
|
614
|
-
end
|
615
|
-
|
616
|
-
def warn_error?(num, marker)
|
617
|
-
klass = ""
|
618
|
-
|
619
|
-
if @filter.error?(num)
|
620
|
-
klass = ' class="error"'
|
621
|
-
@errors<< [@current, marker, num]
|
622
|
-
elsif @filter.warn?(num)
|
623
|
-
klass = ' class="warning"'
|
624
|
-
@warnings<< [@current, marker, num]
|
625
|
-
end
|
626
|
-
|
627
|
-
klass
|
628
|
-
end
|
629
|
-
|
630
|
-
def reset_data
|
631
|
-
@warnings = Array.new
|
632
|
-
@errors = Array.new
|
633
|
-
@current = ""
|
634
|
-
end
|
635
|
-
|
636
|
-
end
|
637
|
-
|
638
|
-
class TokenCounterFormater < BaseFormater
|
639
|
-
|
640
|
-
def start(new_out=nil)
|
641
|
-
reset_data
|
642
|
-
@out = new_out if new_out
|
643
|
-
@out.puts "Token Count"
|
644
|
-
end
|
645
|
-
|
646
|
-
def start_count(number_of_files)
|
647
|
-
@out.puts "Counting tokens for #{number_of_files} files."
|
648
|
-
end
|
649
|
-
|
650
|
-
def start_file(file_name)
|
651
|
-
@current = file_name
|
652
|
-
@out.puts "File:#{file_name}"
|
653
|
-
end
|
654
|
-
|
655
|
-
def line_token_count(line_number,number_of_tokens)
|
656
|
-
return if @filter.ignore?(number_of_tokens)
|
657
|
-
warn_error?(number_of_tokens, line_number)
|
658
|
-
@out.puts "Line:#{line_number} ; Tokens : #{number_of_tokens}"
|
659
|
-
end
|
660
|
-
|
661
|
-
def end_file
|
662
|
-
@out.puts ""
|
663
|
-
end
|
664
|
-
|
665
|
-
def end_count
|
666
|
-
end
|
667
|
-
|
668
|
-
def end
|
669
|
-
end
|
670
|
-
|
671
|
-
end
|
672
|
-
|
673
|
-
module HTMLStyleSheet
|
674
|
-
def HTMLStyleSheet.style_sheet
|
675
|
-
out = StringIO.new
|
676
|
-
|
677
|
-
out.puts "<style>"
|
678
|
-
out.puts 'body {'
|
679
|
-
out.puts ' margin: 20px;'
|
680
|
-
out.puts ' padding: 0;'
|
681
|
-
out.puts ' font-size: 12px;'
|
682
|
-
out.puts ' font-family: bitstream vera sans, verdana, arial, sans serif;'
|
683
|
-
out.puts ' background-color: #efefef;'
|
684
|
-
out.puts '}'
|
685
|
-
out.puts ''
|
686
|
-
out.puts 'table { '
|
687
|
-
out.puts ' border-collapse: collapse;'
|
688
|
-
out.puts ' /*border-spacing: 0;*/'
|
689
|
-
out.puts ' border: 1px solid #666;'
|
690
|
-
out.puts ' background-color: #fff;'
|
691
|
-
out.puts ' margin-bottom: 20px;'
|
692
|
-
out.puts '}'
|
693
|
-
out.puts ''
|
694
|
-
out.puts 'table, th, th+th, td, td+td {'
|
695
|
-
out.puts ' border: 1px solid #ccc;'
|
696
|
-
out.puts '}'
|
697
|
-
out.puts ''
|
698
|
-
out.puts 'table th {'
|
699
|
-
out.puts ' font-size: 12px;'
|
700
|
-
out.puts ' color: #fc0;'
|
701
|
-
out.puts ' padding: 4px 0;'
|
702
|
-
out.puts ' background-color: #336;'
|
703
|
-
out.puts '}'
|
704
|
-
out.puts ''
|
705
|
-
out.puts 'th, td {'
|
706
|
-
out.puts ' padding: 4px 10px;'
|
707
|
-
out.puts '}'
|
708
|
-
out.puts ''
|
709
|
-
out.puts 'td { '
|
710
|
-
out.puts ' font-size: 13px;'
|
711
|
-
out.puts '}'
|
712
|
-
out.puts ''
|
713
|
-
out.puts '.class_name {'
|
714
|
-
out.puts ' font-size: 17px;'
|
715
|
-
out.puts ' margin: 20px 0 0;'
|
716
|
-
out.puts '}'
|
717
|
-
out.puts ''
|
718
|
-
out.puts '.class_complexity {'
|
719
|
-
out.puts 'margin: 0 auto;'
|
720
|
-
out.puts '}'
|
721
|
-
out.puts ''
|
722
|
-
out.puts '.class_complexity>.class_complexity {'
|
723
|
-
out.puts ' margin: 0;'
|
724
|
-
out.puts '}'
|
725
|
-
out.puts ''
|
726
|
-
out.puts '.class_total_complexity, .class_total_lines, .start_token_count, .file_count {'
|
727
|
-
out.puts ' font-size: 13px;'
|
728
|
-
out.puts ' font-weight: bold;'
|
729
|
-
out.puts '}'
|
730
|
-
out.puts ''
|
731
|
-
out.puts '.class_total_complexity, .class_total_lines {'
|
732
|
-
out.puts ' color: #c00;'
|
733
|
-
out.puts '}'
|
734
|
-
out.puts ''
|
735
|
-
out.puts '.start_token_count, .file_count {'
|
736
|
-
out.puts ' color: #333;'
|
737
|
-
out.puts '}'
|
738
|
-
out.puts ''
|
739
|
-
out.puts '.warning {'
|
740
|
-
out.puts ' background-color: yellow;'
|
741
|
-
out.puts '}'
|
742
|
-
out.puts ''
|
743
|
-
out.puts '.error {'
|
744
|
-
out.puts ' background-color: #f00;'
|
745
|
-
out.puts '}'
|
746
|
-
out.puts "</style>"
|
747
|
-
|
748
|
-
out.string
|
749
|
-
end
|
750
|
-
|
751
|
-
def style_sheet
|
752
|
-
HTMLStyleSheet.style_sheet
|
753
|
-
end
|
754
|
-
end
|
755
|
-
|
756
|
-
|
757
|
-
class HTMLTokenCounterFormater < TokenCounterFormater
|
758
|
-
include HTMLStyleSheet
|
759
|
-
|
760
|
-
def start(new_out=nil)
|
761
|
-
reset_data
|
762
|
-
@out = new_out if new_out
|
763
|
-
@out.puts "<html>"
|
764
|
-
@out.puts style_sheet
|
765
|
-
@out.puts "<body>"
|
766
|
-
end
|
767
|
-
|
768
|
-
def start_count(number_of_files)
|
769
|
-
@out.puts "<div class=\"start_token_count\">"
|
770
|
-
@out.puts "Number of files: #{number_of_files}"
|
771
|
-
@out.puts "</div>"
|
772
|
-
end
|
773
|
-
|
774
|
-
def start_file(file_name)
|
775
|
-
@current = file_name
|
776
|
-
@out.puts "<div class=\"file_count\">"
|
777
|
-
@out.puts "<p class=\"file_name\">"
|
778
|
-
@out.puts "File: #{file_name}"
|
779
|
-
@out.puts "</p>"
|
780
|
-
@out.puts "<table width=\"100%\" border=\"1\">"
|
781
|
-
@out.puts "<tr><th>Line</th><th>Tokens</th></tr>"
|
782
|
-
end
|
783
|
-
|
784
|
-
def line_token_count(line_number,number_of_tokens)
|
785
|
-
return if @filter.ignore?(number_of_tokens)
|
786
|
-
klass = warn_error?(number_of_tokens, line_number)
|
787
|
-
@out.puts "<tr><td>#{line_number}</td><td#{klass}>#{number_of_tokens}</td></tr>"
|
788
|
-
end
|
789
|
-
|
790
|
-
def end_file
|
791
|
-
@out.puts "</table>"
|
792
|
-
end
|
793
|
-
|
794
|
-
def end_count
|
795
|
-
end
|
796
|
-
|
797
|
-
def end
|
798
|
-
@out.puts "</body>"
|
799
|
-
@out.puts "</html>"
|
800
|
-
end
|
801
|
-
end
|
802
|
-
|
803
|
-
class ParseStateFormater < BaseFormater
|
804
|
-
|
805
|
-
def start(new_out=nil)
|
806
|
-
reset_data
|
807
|
-
@out = new_out if new_out
|
808
|
-
end
|
809
|
-
|
810
|
-
def end
|
811
|
-
end
|
812
|
-
|
813
|
-
def start_class_compute_state(type_name,name,complexity,lines)
|
814
|
-
@current = name
|
815
|
-
@out.puts "-- START #{name} --"
|
816
|
-
@out.puts "Type:#{type_name} Name:#{name} Complexity:#{complexity} Lines:#{lines}"
|
817
|
-
end
|
818
|
-
|
819
|
-
def end_class_compute_state(name)
|
820
|
-
@out.puts "-- END #{name} --"
|
821
|
-
end
|
822
|
-
|
823
|
-
def def_compute_state(name,complexity,lines)
|
824
|
-
return if @filter.ignore?(complexity)
|
825
|
-
warn_error?(complexity, name)
|
826
|
-
@out.puts "Type:Def Name:#{name} Complexity:#{complexity} Lines:#{lines}"
|
827
|
-
end
|
828
|
-
|
829
|
-
end
|
830
|
-
|
831
|
-
class StateHTMLComplexityFormater < ParseStateFormater
|
832
|
-
include HTMLStyleSheet
|
833
|
-
|
834
|
-
def start(new_out=nil)
|
835
|
-
reset_data
|
836
|
-
@out = new_out if new_out
|
837
|
-
@out.puts "<html><head><title>Cyclometric Complexity</title></head>"
|
838
|
-
@out.puts style_sheet
|
839
|
-
@out.puts "<body>"
|
840
|
-
end
|
841
|
-
|
842
|
-
def end
|
843
|
-
@out.puts "</body>"
|
844
|
-
@out.puts "</html>"
|
845
|
-
end
|
846
|
-
|
847
|
-
def start_class_compute_state(type_name,name,complexity,lines)
|
848
|
-
@current = name
|
849
|
-
@out.puts "<div class=\"class_complexity\">"
|
850
|
-
@out.puts "<h2 class=\"class_name\">#{type_name} : #{name}</h2>"
|
851
|
-
@out.puts "<div class=\"class_total_complexity\">Total Complexity: #{complexity}</div>"
|
852
|
-
@out.puts "<div class=\"class_total_lines\">Total Lines: #{lines}</div>"
|
853
|
-
@out.puts "<table width=\"100%\" border=\"1\">"
|
854
|
-
@out.puts "<tr><th>Method</th><th>Complexity</th><th># Lines</th></tr>"
|
855
|
-
end
|
856
|
-
|
857
|
-
def end_class_compute_state(name)
|
858
|
-
@out.puts "</table>"
|
859
|
-
@out.puts "</div>"
|
860
|
-
end
|
861
|
-
|
862
|
-
def def_compute_state(name, complexity, lines)
|
863
|
-
return if @filter.ignore?(complexity)
|
864
|
-
klass = warn_error?(complexity, name)
|
865
|
-
@out.puts "<tr><td>#{name}</td><td#{klass}>#{complexity}</td><td>#{lines}</td></tr>"
|
866
|
-
end
|
867
|
-
|
868
|
-
end
|
869
|
-
|
870
615
|
module Saikuro
|
871
616
|
def Saikuro.analyze(files, state_formater, token_count_formater, output_dir)
|
872
617
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Saikuro
|
2
|
+
class BaseFormater
|
3
|
+
attr_accessor :warnings, :errors, :current
|
4
|
+
|
5
|
+
def initialize(out, filter = nil)
|
6
|
+
@out = out
|
7
|
+
@filter = filter
|
8
|
+
reset_data
|
9
|
+
end
|
10
|
+
|
11
|
+
def warn_error?(num, marker)
|
12
|
+
klass = ""
|
13
|
+
|
14
|
+
if @filter.error?(num)
|
15
|
+
klass = ' class="error"'
|
16
|
+
@errors<< [@current, marker, num]
|
17
|
+
elsif @filter.warn?(num)
|
18
|
+
klass = ' class="warning"'
|
19
|
+
@warnings<< [@current, marker, num]
|
20
|
+
end
|
21
|
+
|
22
|
+
klass
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset_data
|
26
|
+
@warnings = Array.new
|
27
|
+
@errors = Array.new
|
28
|
+
@current = ""
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
data/lib/saikuro/cli.rb
CHANGED
@@ -9,7 +9,6 @@ module Saikuro
|
|
9
9
|
|
10
10
|
include ResultIndexGenerator
|
11
11
|
|
12
|
-
|
13
12
|
def run
|
14
13
|
|
15
14
|
files = Array.new
|
@@ -86,10 +85,7 @@ module Saikuro
|
|
86
85
|
state_formater = nil if !comp_state
|
87
86
|
token_count_formater = nil if !comp_token
|
88
87
|
|
89
|
-
idx_states, idx_tokens = Saikuro.analyze(files,
|
90
|
-
state_formater,
|
91
|
-
token_count_formater,
|
92
|
-
output_dir)
|
88
|
+
idx_states, idx_tokens = Saikuro.analyze(files, state_formater, token_count_formater, output_dir)
|
93
89
|
|
94
90
|
write_cyclo_index(idx_states, output_dir)
|
95
91
|
write_token_index(idx_tokens, output_dir)
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Saikuro
|
2
|
+
module HTMLStyleSheet
|
3
|
+
def HTMLStyleSheet.style_sheet
|
4
|
+
out = StringIO.new
|
5
|
+
|
6
|
+
out.puts "<style>"
|
7
|
+
out.puts 'body {'
|
8
|
+
out.puts ' margin: 20px;'
|
9
|
+
out.puts ' padding: 0;'
|
10
|
+
out.puts ' font-size: 12px;'
|
11
|
+
out.puts ' font-family: bitstream vera sans, verdana, arial, sans serif;'
|
12
|
+
out.puts ' background-color: #efefef;'
|
13
|
+
out.puts '}'
|
14
|
+
out.puts ''
|
15
|
+
out.puts 'table { '
|
16
|
+
out.puts ' border-collapse: collapse;'
|
17
|
+
out.puts ' /*border-spacing: 0;*/'
|
18
|
+
out.puts ' border: 1px solid #666;'
|
19
|
+
out.puts ' background-color: #fff;'
|
20
|
+
out.puts ' margin-bottom: 20px;'
|
21
|
+
out.puts '}'
|
22
|
+
out.puts ''
|
23
|
+
out.puts 'table, th, th+th, td, td+td {'
|
24
|
+
out.puts ' border: 1px solid #ccc;'
|
25
|
+
out.puts '}'
|
26
|
+
out.puts ''
|
27
|
+
out.puts 'table th {'
|
28
|
+
out.puts ' font-size: 12px;'
|
29
|
+
out.puts ' color: #fc0;'
|
30
|
+
out.puts ' padding: 4px 0;'
|
31
|
+
out.puts ' background-color: #336;'
|
32
|
+
out.puts '}'
|
33
|
+
out.puts ''
|
34
|
+
out.puts 'th, td {'
|
35
|
+
out.puts ' padding: 4px 10px;'
|
36
|
+
out.puts '}'
|
37
|
+
out.puts ''
|
38
|
+
out.puts 'td { '
|
39
|
+
out.puts ' font-size: 13px;'
|
40
|
+
out.puts '}'
|
41
|
+
out.puts ''
|
42
|
+
out.puts '.class_name {'
|
43
|
+
out.puts ' font-size: 17px;'
|
44
|
+
out.puts ' margin: 20px 0 0;'
|
45
|
+
out.puts '}'
|
46
|
+
out.puts ''
|
47
|
+
out.puts '.class_complexity {'
|
48
|
+
out.puts 'margin: 0 auto;'
|
49
|
+
out.puts '}'
|
50
|
+
out.puts ''
|
51
|
+
out.puts '.class_complexity>.class_complexity {'
|
52
|
+
out.puts ' margin: 0;'
|
53
|
+
out.puts '}'
|
54
|
+
out.puts ''
|
55
|
+
out.puts '.class_total_complexity, .class_total_lines, .start_token_count, .file_count {'
|
56
|
+
out.puts ' font-size: 13px;'
|
57
|
+
out.puts ' font-weight: bold;'
|
58
|
+
out.puts '}'
|
59
|
+
out.puts ''
|
60
|
+
out.puts '.class_total_complexity, .class_total_lines {'
|
61
|
+
out.puts ' color: #c00;'
|
62
|
+
out.puts '}'
|
63
|
+
out.puts ''
|
64
|
+
out.puts '.start_token_count, .file_count {'
|
65
|
+
out.puts ' color: #333;'
|
66
|
+
out.puts '}'
|
67
|
+
out.puts ''
|
68
|
+
out.puts '.warning {'
|
69
|
+
out.puts ' background-color: yellow;'
|
70
|
+
out.puts '}'
|
71
|
+
out.puts ''
|
72
|
+
out.puts '.error {'
|
73
|
+
out.puts ' background-color: #f00;'
|
74
|
+
out.puts '}'
|
75
|
+
out.puts "</style>"
|
76
|
+
|
77
|
+
out.string
|
78
|
+
end
|
79
|
+
|
80
|
+
def style_sheet
|
81
|
+
HTMLStyleSheet.style_sheet
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Saikuro
|
2
|
+
class HTMLTokenCounterFormater < TokenCounterFormater
|
3
|
+
include HTMLStyleSheet
|
4
|
+
|
5
|
+
def start(new_out=nil)
|
6
|
+
reset_data
|
7
|
+
@out = new_out if new_out
|
8
|
+
@out.puts "<html>"
|
9
|
+
@out.puts style_sheet
|
10
|
+
@out.puts "<body>"
|
11
|
+
end
|
12
|
+
|
13
|
+
def start_count(number_of_files)
|
14
|
+
@out.puts "<div class=\"start_token_count\">"
|
15
|
+
@out.puts "Number of files: #{number_of_files}"
|
16
|
+
@out.puts "</div>"
|
17
|
+
end
|
18
|
+
|
19
|
+
def start_file(file_name)
|
20
|
+
@current = file_name
|
21
|
+
@out.puts "<div class=\"file_count\">"
|
22
|
+
@out.puts "<p class=\"file_name\">"
|
23
|
+
@out.puts "File: #{file_name}"
|
24
|
+
@out.puts "</p>"
|
25
|
+
@out.puts "<table width=\"100%\" border=\"1\">"
|
26
|
+
@out.puts "<tr><th>Line</th><th>Tokens</th></tr>"
|
27
|
+
end
|
28
|
+
|
29
|
+
def line_token_count(line_number,number_of_tokens)
|
30
|
+
return if @filter.ignore?(number_of_tokens)
|
31
|
+
klass = warn_error?(number_of_tokens, line_number)
|
32
|
+
@out.puts "<tr><td>#{line_number}</td><td#{klass}>#{number_of_tokens}</td></tr>"
|
33
|
+
end
|
34
|
+
|
35
|
+
def end_file
|
36
|
+
@out.puts "</table>"
|
37
|
+
end
|
38
|
+
|
39
|
+
def end_count
|
40
|
+
end
|
41
|
+
|
42
|
+
def end
|
43
|
+
@out.puts "</body>"
|
44
|
+
@out.puts "</html>"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Saikuro
|
2
|
+
class ParseStateFormater < BaseFormater
|
3
|
+
|
4
|
+
def start(new_out=nil)
|
5
|
+
reset_data
|
6
|
+
@out = new_out if new_out
|
7
|
+
end
|
8
|
+
|
9
|
+
def end
|
10
|
+
end
|
11
|
+
|
12
|
+
def start_class_compute_state(type_name,name,complexity,lines)
|
13
|
+
@current = name
|
14
|
+
@out.puts "-- START #{name} --"
|
15
|
+
@out.puts "Type:#{type_name} Name:#{name} Complexity:#{complexity} Lines:#{lines}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def end_class_compute_state(name)
|
19
|
+
@out.puts "-- END #{name} --"
|
20
|
+
end
|
21
|
+
|
22
|
+
def def_compute_state(name,complexity,lines)
|
23
|
+
return if @filter.ignore?(complexity)
|
24
|
+
warn_error?(complexity, name)
|
25
|
+
@out.puts "Type:Def Name:#{name} Complexity:#{complexity} Lines:#{lines}"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -1,88 +1,89 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Saikuro
|
2
|
+
module ResultIndexGenerator
|
3
|
+
def summarize_errors_and_warnings(enw, header)
|
4
|
+
return "" if enw.empty?
|
5
|
+
f = StringIO.new
|
6
|
+
erval = Hash.new { |h,k| h[k] = Array.new }
|
7
|
+
wval = Hash.new { |h,k| h[k] = Array.new }
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
enw.each do |fname, warnings, errors|
|
10
|
+
errors.each do |c,m,v|
|
11
|
+
erval[v] << [fname, c, m]
|
12
|
+
end
|
13
|
+
warnings.each do |c,m,v|
|
14
|
+
wval[v] << [fname, c, m]
|
15
|
+
end
|
11
16
|
end
|
12
|
-
warnings.each do |c,m,v|
|
13
|
-
wval[v] << [fname, c, m]
|
14
|
-
end
|
15
|
-
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
f.puts "<h2 class=\"class_name\">Errors and Warnings</h2>"
|
19
|
+
f.puts "<table width=\"100%\" border=\"1\">"
|
20
|
+
f.puts header
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
f.puts print_summary_table_rows(erval, "error")
|
23
|
+
f.puts print_summary_table_rows(wval, "warning")
|
24
|
+
f.puts "</table>"
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
f.string
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
def print_summary_table_rows(ewvals, klass_type)
|
30
|
+
f = StringIO.new
|
31
|
+
ewvals.sort { |a,b| b <=> a}.each do |v, vals|
|
32
|
+
vals.sort.each do |fname, c, m|
|
33
|
+
f.puts "<tr><td><a href=\"./#{fname}\">#{c}</a></td><td>#{m}</td>"
|
34
|
+
f.puts "<td class=\"#{klass_type}\">#{v}</td></tr>"
|
35
|
+
end
|
34
36
|
end
|
37
|
+
f.string
|
35
38
|
end
|
36
|
-
f.string
|
37
|
-
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
40
|
+
def list_analyzed_files(files)
|
41
|
+
f = StringIO.new
|
42
|
+
f.puts "<h2 class=\"class_name\">Analyzed Files</h2>"
|
43
|
+
f.puts "<ul>"
|
44
|
+
files.each do |fname, warnings, errors|
|
45
|
+
readname = fname.split("_")[0...-1].join("_")
|
46
|
+
f.puts "<li>"
|
47
|
+
f.puts "<p class=\"file_name\"><a href=\"./#{fname}\">#{readname}</a>"
|
48
|
+
f.puts "</li>"
|
49
|
+
end
|
50
|
+
f.puts "</ul>"
|
51
|
+
f.string
|
48
52
|
end
|
49
|
-
f.puts "</ul>"
|
50
|
-
f.string
|
51
|
-
end
|
52
53
|
|
53
|
-
|
54
|
-
|
54
|
+
def write_index(files, filename, title, header)
|
55
|
+
return if files.empty?
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
File.open(filename,"w") do |f|
|
58
|
+
f.puts "<html><head><title>#{title}</title></head>"
|
59
|
+
f.puts "#{HTMLStyleSheet.style_sheet}\n<body>"
|
60
|
+
f.puts "<h1>#{title}</h1>"
|
60
61
|
|
61
|
-
|
62
|
+
enw = files.find_all { |fn,w,e| (!w.empty? || !e.empty?) }
|
62
63
|
|
63
|
-
|
64
|
+
f.puts summarize_errors_and_warnings(enw, header)
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
66
|
+
f.puts "<hr/>"
|
67
|
+
f.puts list_analyzed_files(files)
|
68
|
+
f.puts "</body></html>"
|
69
|
+
end
|
68
70
|
end
|
69
|
-
end
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
72
|
+
def write_cyclo_index(files, output_dir)
|
73
|
+
header = "<tr><th>Class</th><th>Method</th><th>Complexity</th></tr>"
|
74
|
+
write_index(files,
|
75
|
+
"#{output_dir}/index_cyclo.html",
|
76
|
+
"Index for cyclomatic complexity",
|
77
|
+
header)
|
78
|
+
end
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
80
|
+
def write_token_index(files, output_dir)
|
81
|
+
header = "<tr><th>File</th><th>Line #</th><th>Tokens</th></tr>"
|
82
|
+
write_index(files,
|
83
|
+
"#{output_dir}/index_token.html",
|
84
|
+
"Index for tokens per line",
|
85
|
+
header)
|
86
|
+
end
|
86
87
|
|
88
|
+
end
|
87
89
|
end
|
88
|
-
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Saikuro
|
2
|
+
class StateHTMLComplexityFormater < ParseStateFormater
|
3
|
+
include HTMLStyleSheet
|
4
|
+
|
5
|
+
def start(new_out=nil)
|
6
|
+
reset_data
|
7
|
+
@out = new_out if new_out
|
8
|
+
@out.puts "<html><head><title>Cyclometric Complexity</title></head>"
|
9
|
+
@out.puts style_sheet
|
10
|
+
@out.puts "<body>"
|
11
|
+
end
|
12
|
+
|
13
|
+
def end
|
14
|
+
@out.puts "</body>"
|
15
|
+
@out.puts "</html>"
|
16
|
+
end
|
17
|
+
|
18
|
+
def start_class_compute_state(type_name,name,complexity,lines)
|
19
|
+
@current = name
|
20
|
+
@out.puts "<div class=\"class_complexity\">"
|
21
|
+
@out.puts "<h2 class=\"class_name\">#{type_name} : #{name}</h2>"
|
22
|
+
@out.puts "<div class=\"class_total_complexity\">Total Complexity: #{complexity}</div>"
|
23
|
+
@out.puts "<div class=\"class_total_lines\">Total Lines: #{lines}</div>"
|
24
|
+
@out.puts "<table width=\"100%\" border=\"1\">"
|
25
|
+
@out.puts "<tr><th>Method</th><th>Complexity</th><th># Lines</th></tr>"
|
26
|
+
end
|
27
|
+
|
28
|
+
def end_class_compute_state(name)
|
29
|
+
@out.puts "</table>"
|
30
|
+
@out.puts "</div>"
|
31
|
+
end
|
32
|
+
|
33
|
+
def def_compute_state(name, complexity, lines)
|
34
|
+
return if @filter.ignore?(complexity)
|
35
|
+
klass = warn_error?(complexity, name)
|
36
|
+
@out.puts "<tr><td>#{name}</td><td#{klass}>#{complexity}</td><td>#{lines}</td></tr>"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Saikuro
|
2
|
+
class TokenCounterFormater < BaseFormater
|
3
|
+
|
4
|
+
def start(new_out=nil)
|
5
|
+
reset_data
|
6
|
+
@out = new_out if new_out
|
7
|
+
@out.puts "Token Count"
|
8
|
+
end
|
9
|
+
|
10
|
+
def start_count(number_of_files)
|
11
|
+
@out.puts "Counting tokens for #{number_of_files} files."
|
12
|
+
end
|
13
|
+
|
14
|
+
def start_file(file_name)
|
15
|
+
@current = file_name
|
16
|
+
@out.puts "File:#{file_name}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def line_token_count(line_number,number_of_tokens)
|
20
|
+
return if @filter.ignore?(number_of_tokens)
|
21
|
+
warn_error?(number_of_tokens, line_number)
|
22
|
+
@out.puts "Line:#{line_number} ; Tokens : #{number_of_tokens}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def end_file
|
26
|
+
@out.puts ""
|
27
|
+
end
|
28
|
+
|
29
|
+
def end_count
|
30
|
+
end
|
31
|
+
|
32
|
+
def end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
data/lib/saikuro/version.rb
CHANGED
data/saikuro.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = ["zb@ubit.com", "romanvbabenko@gmail.com"]
|
10
10
|
s.homepage = ""
|
11
11
|
s.summary = %q{Saikuro is a Ruby cyclomatic complexity analyzer}
|
12
|
-
s.description
|
12
|
+
s.description = %q{When given Ruby source code Saikuro will generate a report listing the cyclomatic complexity of each method found. In addition, Saikuro counts the number of lines per method and can generate a listing of the number of tokens on each line of code.}
|
13
13
|
|
14
14
|
s.rubyforge_project = "saikuro"
|
15
15
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saikuro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 1.2.
|
9
|
+
- 1
|
10
|
+
version: 1.2.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Zev Blut
|
@@ -37,8 +37,14 @@ files:
|
|
37
37
|
- examples/large_example.rb
|
38
38
|
- examples/samples.rb
|
39
39
|
- lib/saikuro.rb
|
40
|
+
- lib/saikuro/base_formater.rb
|
40
41
|
- lib/saikuro/cli.rb
|
42
|
+
- lib/saikuro/html_style_sheet.rb
|
43
|
+
- lib/saikuro/html_token_counter_formater.rb
|
44
|
+
- lib/saikuro/parse_state_formater.rb
|
41
45
|
- lib/saikuro/result_index_generator.rb
|
46
|
+
- lib/saikuro/state_html_complexity_formater.rb
|
47
|
+
- lib/saikuro/token_counter_formater.rb
|
42
48
|
- lib/saikuro/version.rb
|
43
49
|
- saikuro.gemspec
|
44
50
|
homepage: ""
|