atoulme-Saikuro 1.1.2 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.rdoc +10 -22
  2. data/bin/saikuro +2 -1
  3. data/lib/saikuro.rb +113 -130
  4. metadata +8 -9
  5. data/lib/saikuro/usage.rb +0 -39
@@ -1,29 +1,15 @@
1
- Version 1.1.2
2
-
3
- Saikuro:
1
+ =Saikuro
4
2
  Saikuro is a Ruby cyclomatic complexity analyzer. When given Ruby
5
3
  source code Saikuro will generate a report listing the cyclomatic
6
4
  complexity of each method found. In addition, Saikuro counts the
7
5
  number of lines per method and can generate a listing of the number of
8
6
  tokens on each line of code.
9
7
 
10
- License:
11
- Saikuro uses the BSD license.
12
-
13
- Installation:
14
- Option 1: Using setup.rb
15
- * login as root
16
- * run "ruby setup.rb all"
17
-
18
- Option 2: The manual way
19
- Saikuro is a single Ruby file that is executable. You can run it where
20
- you unpacked it or you can move it your preferred location such as
21
- "/usr/local/bin" or "~/bin".
8
+ ==License:
9
+ Saikuro uses the BSD license. See attached LICENSE file.
22
10
 
23
- Note:
24
- Ruby 1.8.5 has a bug in ri_options that will prevent Saikuro from
25
- running. If you are using 1.8.5 please apply this patch :
26
- http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/lib/rdoc/ri/ri_options.rb.diff?r1=1.2.2.13;r2=1.2.2.14
11
+ ==Installation:
12
+ Install atoulme-Saikuro using gem install and have at it.
27
13
 
28
14
 
29
15
  =Usage:
@@ -31,7 +17,7 @@ http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/lib/rdoc/ri/ri_options.rb.diff?
31
17
  Running "saikuro -h" will output a usage statement describing all
32
18
  the various arguments you can pass to it.
33
19
 
34
- "saikuro -c -p tests/samples.rb"
20
+ saikuro -c -p tests/samples.rb
35
21
 
36
22
  The above command is a simple example that generates a cyclomatic
37
23
  complexity report on the samples.rb file, using the default filter,
@@ -40,7 +26,7 @@ directory.
40
26
 
41
27
 
42
28
  A more detailed example is
43
- "saikuro -c -t -i tests -y 0 -w 11 -e 16 -o out/"
29
+ saikuro -c -t -i tests -y 0 -w 11 -e 16 -o out/
44
30
 
45
31
  This will analyze all Ruby files found in the "tests/" directory.
46
32
  Saikuro will generate a token count report and a cyclomatic complexity
@@ -108,7 +94,7 @@ currently do not contribute to a method's complexity, although
108
94
  McCabe's paper listed above suggests doing so.
109
95
 
110
96
 
111
- #Example for "and" operator handling:
97
+ #Example for "and" operator handling:
112
98
 
113
99
  # Starting values for case 1 and 2
114
100
  x = false
@@ -145,6 +131,8 @@ please report them.
145
131
  =Contact:
146
132
  Saikuro is written by
147
133
  Zev Blut (zb at ubit dot com)
134
+ Morton Jonuschat
135
+ Antoine Toulme (antoine at lunar-ocean.com)
148
136
 
149
137
  =Acknowledgments:
150
138
  Thanks to Elbert Corpuz for writing the CSS for the HTML output!
@@ -90,5 +90,6 @@
90
90
 
91
91
  require 'saikuro'
92
92
 
93
- SaikuroCMDLineRunner.new.run
93
+ saikuro = SaikuroCMDLineRunner.new(ARGV)
94
+ saikuro.run!
94
95
 
@@ -1,55 +1,8 @@
1
- # $Id$
2
- # == Usage
3
- #
4
- # saikuro [ -h ] [-o output_directory] [-f type] [ -c, -t ]
5
- # [ -y, -w, -e, -k, -s, -d - number ] ( -p file | -i directory )
6
- #
7
- # == Help
8
- #
9
- # -o, --output_directory (directory) : A directory to ouput the results in.
10
- # The current directory is used if this option is not passed.
11
- #
12
- # -h, --help : This help message.
13
- #
14
- # -f, --formater (html | text) : The format to output the results in.
15
- # The default is html
16
- #
17
- # -c, --cyclo : Compute the cyclomatic complexity of the input.
18
- #
19
- # -t, --token : Count the number of tokens per line of the input.
20
- #
21
- # -y, --filter_cyclo (number) : Filter the output to only include methods
22
- # whose cyclomatic complexity are greater than the passed number.
23
- #
24
- # -w, --warn_cyclo (number) : Highlight with a warning methods whose
25
- # cyclomatic complexity are greather than or equal to the passed number.
26
- #
27
- #
28
- # -e, --error_cyclo (number) : Highligh with an error methods whose
29
- # cyclomatic complexity are greather than or equal to the passed number.
30
- #
31
- #
32
- # -k, --filter_token (number) : Filter the output to only include lines
33
- # whose token count are greater than the passed number.
34
- #
35
- #
36
- # -s, --warn_token (number) : Highlight with a warning lines whose
37
- # token count are greater than or equal to the passed number.
38
- #
39
- #
40
- # -d, --error_token (number) : Highlight with an error lines whose
41
- # token count are greater than or equal to the passed number.
42
- #
43
- #
44
- # -p, --parse_file (file) : A file to use as input.
45
- #
46
- # -i, --input_directory (directory) : All ruby files found recursively
47
- # inside the directory are passed as input.
48
-
49
-
50
1
  # Saikruo uses the BSD license.
51
2
  #
52
3
  # Copyright (c) 2005, Ubiquitous Business Technology (http://ubit.com)
4
+ # Copyright (c) 2010, Morton Jonuschat (http://www.github.com/yabawock)
5
+ # Copyright (c) 2010, Antoine Toulme (http://www.lunar-ocean.com)
53
6
  # All rights reserved.
54
7
  #
55
8
  # Redistribution and use in source and binary forms, with or without
@@ -85,6 +38,8 @@
85
38
  #
86
39
  # == Author
87
40
  # Zev Blut (zb@ubit.com)
41
+ # Morton Jonuschat
42
+ # Antoine Toulme (antoine@lunar-ocean.com)
88
43
 
89
44
  require 'irb/ruby-lex'
90
45
  require 'yaml'
@@ -419,8 +374,8 @@ class ParseState
419
374
  def end_debug
420
375
  STDOUT.puts "got an end: #{@name} in #{self.class.name}" if $VERBOSE
421
376
  if @parent.nil?
422
- STDOUT.puts "DEBUG: Line #{@lexer.line_no}"
423
- STDOUT.puts "DEBUG: #{@name}; #{self.class}"
377
+ STDOUT.puts "DEBUG: Line #{@lexer.line_no}" if $VERBOSE
378
+ STDOUT.puts "DEBUG: #{@name}; #{self.class}" if $VERBOSE
424
379
  # to_yaml can cause an infinite loop?
425
380
  #STDOUT.puts "TOP: #{@@top_state.to_yaml}"
426
381
  #STDOUT.puts "TOP: #{@@top_state.inspect}"
@@ -1098,17 +1053,10 @@ end
1098
1053
 
1099
1054
  class SaikuroCMDLineRunner
1100
1055
  require 'stringio'
1101
- require 'getoptlong'
1056
+ require 'optparse'
1102
1057
  require 'fileutils'
1103
1058
  require 'find'
1104
1059
 
1105
- def initialize
1106
- # modification to RDoc.usage that allows main_program_file to be set
1107
- # for RDoc.usage
1108
- require 'saikuro/usage'
1109
- RDoc::main_program_file = __FILE__
1110
- end
1111
-
1112
1060
  include ResultIndexGenerator
1113
1061
 
1114
1062
  def get_ruby_files(path)
@@ -1122,91 +1070,126 @@ class SaikuroCMDLineRunner
1122
1070
  end
1123
1071
  files
1124
1072
  end
1073
+
1074
+ def parse(args)
1075
+ # Set up reasonable defaults for options.
1076
+ options = {}
1077
+ options[:files] = Array.new
1078
+ options[:output_dir] = './'
1079
+ options[:formater] = 'html'
1080
+ options[:state_filter] = Filter.new(5)
1081
+ options[:token_filter] = Filter.new(10, 25, 50)
1082
+ options[:comp_state] = false
1083
+ options[:comp_token] = false
1084
+
1085
+ # Parse the command-line arguments.
1086
+ @opts = OptionParser.new do |opts|
1087
+ opts.banner = 'Usage: saikuro [ -h ] [-o output_directory] [-f type] [ -c, -t ] [ -y, -w, -e, -k, -s, -d - number ] ( -p file | -i directory )'
1088
+
1089
+ opts.separator ''
1090
+ opts.separator 'Specific options:'
1091
+
1092
+ opts.on('-v', '--verbose', 'Verbose output.') do
1093
+ options[:verbose] = true
1094
+ $VERBOSE = true
1095
+ end
1125
1096
 
1126
- def run
1127
- files = Array.new
1128
- output_dir = "./"
1129
- formater = "html"
1130
- state_filter = Filter.new(5)
1131
- token_filter = Filter.new(10, 25, 50)
1132
- comp_state = comp_token = false
1133
- begin
1134
- opt = GetoptLong.new(
1135
- ["-o","--output_directory", GetoptLong::REQUIRED_ARGUMENT],
1136
- ["-h","--help", GetoptLong::NO_ARGUMENT],
1137
- ["-f","--formater", GetoptLong::REQUIRED_ARGUMENT],
1138
- ["-c","--cyclo", GetoptLong::NO_ARGUMENT],
1139
- ["-t","--token", GetoptLong::NO_ARGUMENT],
1140
- ["-y","--filter_cyclo", GetoptLong::REQUIRED_ARGUMENT],
1141
- ["-k","--filter_token", GetoptLong::REQUIRED_ARGUMENT],
1142
- ["-w","--warn_cyclo", GetoptLong::REQUIRED_ARGUMENT],
1143
- ["-s","--warn_token", GetoptLong::REQUIRED_ARGUMENT],
1144
- ["-e","--error_cyclo", GetoptLong::REQUIRED_ARGUMENT],
1145
- ["-d","--error_token", GetoptLong::REQUIRED_ARGUMENT],
1146
- ["-p","--parse_file", GetoptLong::REQUIRED_ARGUMENT],
1147
- ["-i","--input_directory", GetoptLong::REQUIRED_ARGUMENT],
1148
- ["-v","--verbose", GetoptLong::NO_ARGUMENT]
1149
- )
1150
-
1151
- opt.each do |arg,val|
1152
- case arg
1153
- when "-o"
1154
- output_dir = val
1155
- when "-h"
1156
- RDoc.usage('help')
1157
- when "-f"
1158
- formater = val
1159
- when "-c"
1160
- comp_state = true
1161
- when "-t"
1162
- comp_token = true
1163
- when "-k"
1164
- token_filter.limit = val.to_i
1165
- when "-s"
1166
- token_filter.warn = val.to_i
1167
- when "-d"
1168
- token_filter.error = val.to_i
1169
- when "-y"
1170
- state_filter.limit = val.to_i
1171
- when "-w"
1172
- state_filter.warn = val.to_i
1173
- when "-e"
1174
- state_filter.error = val.to_i
1175
- when "-p"
1176
- files<< val
1177
- when "-i"
1178
- files.concat(get_ruby_files(val))
1179
- when "-v"
1180
- STDOUT.puts "Verbose mode on"
1181
- $VERBOSE = true
1182
- end
1097
+ opts.on('-o', '--output_directory DIRECTORY', 'A directory to ouput the results in. The current directory is used if this option is not passed.') do |output_dir|
1098
+ options[:output_dir] = output_dir
1099
+ end
1183
1100
 
1101
+ opts.on('-f', '--formater (html | text)', 'The format to output the results in. The default is html') do |formater|
1102
+ options[:formater] = formater
1103
+ end
1104
+
1105
+ opts.on('-c', '--cyclo', 'Compute the cyclomatic complexity of the input.') do
1106
+ options[:comp_state] = true
1107
+ end
1108
+
1109
+ opts.on('-t', '--token', 'Count the number of tokens per line of the input.') do
1110
+ options[:comp_token] = true
1111
+ end
1112
+
1113
+ opts.on('-y', '--filter_cyclo NUMBER', 'Filter the output to only include methods whose cyclomatic complexity are greater than the passed number.') do |number|
1114
+ options[:state_filter].limit = number.to_i
1115
+ end
1116
+
1117
+ opts.on('-w', '--warn_cyclo NUMBER', 'Highlight with a warning methods whose cyclomatic complexity are greather than or equal to the passed number.') do |number|
1118
+ options[:state_filter].warn = number.to_i
1119
+ end
1120
+
1121
+ opts.on('-e', '--error_cyclo NUMBER', 'Highlight with a error methods whose cyclomatic complexity are greather than or equal to the passed number.') do |number|
1122
+ options[:state_filter].error = number.to_i
1123
+ end
1124
+
1125
+ opts.on('-k', '--filter_token NUMBER', 'Filter the output to only include lines whose token count are greater than the passed number.') do |number|
1126
+ options[:token_filter].limit = number.to_i
1127
+ end
1128
+
1129
+ opts.on('-s', '--warn_token NUMBER', 'Highlight with a warning lines whose token count are greather than or equal to the passed number.') do |number|
1130
+ options[:token_filter].warn = number.to_i
1131
+ end
1132
+
1133
+ opts.on('-d', '--error_token NUMBER', 'Highlight with a error lines whose token count are greather than or equal to the passed number.') do |number|
1134
+ options[:token_filter].error = number.to_i
1135
+ end
1136
+
1137
+ opts.on('-p', '--parse_file FILE', 'A file to use as input.') do |file|
1138
+ options[:files] << file
1139
+ end
1140
+
1141
+ opts.on('-i', '--input_directory DIRECTORY', 'All ruby files found recursively inside the directory are passed as input.') do |directory|
1142
+ options[:files].concat(get_ruby_files(directory))
1143
+ end
1144
+
1145
+ opts.separator ''
1146
+
1147
+ # No argument, shows at tail. This will print an options summary.
1148
+ # Try it and see!
1149
+ opts.on_tail('-h', '--help', 'Show this message') do
1150
+ puts opts
1151
+ exit
1184
1152
  end
1185
- RDoc.usage if !comp_state && !comp_token
1186
- rescue => err
1187
- RDoc.usage
1188
1153
  end
1189
1154
 
1190
- if formater =~ /html/i
1191
- state_formater = StateHTMLComplexityFormater.new(STDOUT,state_filter)
1192
- token_count_formater = HTMLTokenCounterFormater.new(STDOUT,token_filter)
1155
+ @opts.parse! args
1156
+ options
1157
+ end
1158
+
1159
+ def initialize(args="-h")
1160
+ @options = parse(args)
1161
+ show_help_message("No input files specified") if @options[:files].empty?
1162
+ show_help_message('Please choose token or cyclo mode') if !@options[:comp_state] && !@options[:comp_token]
1163
+ end
1164
+
1165
+ def run!
1166
+ if @options[:formater] =~ /html/i
1167
+ state_formater = StateHTMLComplexityFormater.new(STDOUT,@options[:state_filter])
1168
+ token_count_formater = HTMLTokenCounterFormater.new(STDOUT,@options[:token_filter])
1193
1169
  else
1194
- state_formater = ParseStateFormater.new(STDOUT,state_filter)
1195
- token_count_formater = TokenCounterFormater.new(STDOUT,token_filter)
1170
+ state_formater = ParseStateFormater.new(STDOUT,@options[:state_filter])
1171
+ token_count_formater = TokenCounterFormater.new(STDOUT,@options[:token_filter])
1196
1172
  end
1197
1173
 
1198
- state_formater = nil if !comp_state
1199
- token_count_formater = nil if !comp_token
1174
+ state_formater = nil if !@options[:comp_state]
1175
+ token_count_formater = nil if !@options[:comp_token]
1200
1176
 
1201
- idx_states, idx_tokens = Saikuro.analyze(files,
1177
+ idx_states, idx_tokens = Saikuro.analyze(@options[:files],
1202
1178
  state_formater,
1203
1179
  token_count_formater,
1204
- output_dir)
1180
+ @options[:output_dir])
1205
1181
 
1206
- write_cyclo_index(idx_states, output_dir)
1207
- write_token_index(idx_tokens, output_dir)
1182
+ write_cyclo_index(idx_states, @options[:output_dir])
1183
+ write_token_index(idx_tokens, @options[:output_dir])
1208
1184
  end
1209
1185
 
1186
+ private
1187
+
1188
+ def show_help_message(msg)
1189
+ puts "Error starting script: #{msg}\n\n"
1190
+ puts @opts.help
1191
+ exit
1192
+ end
1210
1193
  end
1211
1194
 
1212
1195
  #
metadata CHANGED
@@ -1,26 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atoulme-Saikuro
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 29
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 1
9
8
  - 2
10
- version: 1.1.2
9
+ - 1
10
+ version: 1.2.1
11
11
  platform: ruby
12
12
  authors:
13
- - Zev Blut, Antoine Toulme
13
+ - Zev Blut, Morton Jonuschat, Antoine Toulme
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-23 00:00:00 -07:00
18
+ date: 2010-07-24 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
22
22
  description:
23
- email: zb@ubit.com
23
+ email: antoine@lunar-ocean.com
24
24
  executables:
25
25
  - saikuro
26
26
  extensions: []
@@ -29,13 +29,12 @@ extra_rdoc_files:
29
29
  - README.rdoc
30
30
  files:
31
31
  - bin/saikuro
32
- - lib/saikuro/usage.rb
33
32
  - lib/saikuro.rb
34
33
  - tests/large_example.rb
35
34
  - tests/samples.rb
36
35
  - README.rdoc
37
36
  has_rdoc: true
38
- homepage: http://saikuro.rubyforge.org/
37
+ homepage: http://www.github.com/atoulme/Saikuro
39
38
  licenses: []
40
39
 
41
40
  post_install_message:
@@ -63,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
62
  version: "0"
64
63
  requirements: []
65
64
 
66
- rubyforge_project: saikuro
65
+ rubyforge_project:
67
66
  rubygems_version: 1.3.7
68
67
  signing_key:
69
68
  specification_version: 3
@@ -1,39 +0,0 @@
1
- # This is a patch to RDoc so that when saikuro is installed as a
2
- # RubyGem usage will read the proper file.
3
-
4
- require 'rdoc/usage'
5
-
6
- module RDoc
7
-
8
- def RDoc.main_program_file=(file)
9
- @@main_program_file = file
10
- end
11
-
12
- # Display usage
13
- def RDoc.usage_no_exit(*args)
14
- @@main_program_file ||= caller[-1].sub(/:\d+$/, '')
15
- comment = File.open(@@main_program_file) do |file|
16
- find_comment(file)
17
- end
18
-
19
- comment = comment.gsub(/^\s*#/, '')
20
-
21
- markup = SM::SimpleMarkup.new
22
- flow_convertor = SM::ToFlow.new
23
-
24
- flow = markup.convert(comment, flow_convertor)
25
-
26
- format = "plain"
27
-
28
- unless args.empty?
29
- flow = extract_sections(flow, args)
30
- end
31
-
32
- options = RI::Options.instance
33
- if args = ENV["RI"]
34
- options.parse(args.split)
35
- end
36
- formatter = options.formatter.new(options, "")
37
- formatter.display_flow(flow)
38
- end
39
- end