atoulme-Saikuro 1.1.2 → 1.2.1

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.
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