continuous4r 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,4 +1,11 @@
1
- == 0.0.1 2009-02-03
1
+ == 0.0.3 2009-03-02
2
2
 
3
- * 1 major enhancement:
4
- * Initial release
3
+ * Third release
4
+ Major bug fixes on rcov, ZenTest, tests, and changelog builders
5
+ Various bug fixes on gems and tasks management
6
+ Tests made on other projects than mine !!! (Apologies for all errors, everyone)
7
+ Introduction of reporting quality indicators (will be completed for 0.0.4)
8
+ The release of 0.0.4 will be here very shortly, this release is here for build capability
9
+
10
+
11
+ To see this release details, go to http://dubois.vct.free.fr/continuous4r
data/Manifest.txt CHANGED
@@ -9,6 +9,10 @@ lib/git_extractor.rb
9
9
  lib/subversion_extractor.rb
10
10
  lib/tests_formatter.rb
11
11
  lib/zen_test_formatter.rb
12
+ lib/site/charts/charts.swf
13
+ lib/site/build.xml.erb
14
+ lib/site/charts/AC_RunActiveContent.js
15
+ lib/site/charts/charts_library/pono.swf
12
16
  lib/site/body-changelog.rhtml
13
17
  lib/site/body-continuous4r-reports.rhtml
14
18
  lib/site/body-dcov.rhtml
@@ -6,12 +6,18 @@
6
6
  class ChangelogBuilder
7
7
  include Utils
8
8
 
9
+ # Prérequis à la tâche
10
+ def prerequisite_met?
11
+ File.exist?(".svn") or File.exist?(".git")
12
+ end
13
+
14
+ # Dans le cas de l'erreur de prérequis
15
+ def prerequisite_unmet_message
16
+ " Only Subversion and Git are supported. The 'changelog' task will be empty."
17
+ end
18
+
9
19
  # Implementation de la construction de la tache
10
20
  def build(project_name, auto_install, proxy_option)
11
- unless File.exist?(".svn") or File.exist?(".git")
12
- puts " Only Subversion and Git are supported. The 'changelog' task will be empty."
13
- break
14
- end
15
21
  # On verifie l'existence de Subversion
16
22
  scm_name = "svn"
17
23
  if File.exist?(".git")
data/lib/continuous4r.rb CHANGED
@@ -1,127 +1,165 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
- require File.join(File.dirname(__FILE__), 'tasks', 'continuous4r')
4
-
5
- require 'rubygems'
6
- require 'XmlElements'
7
- require 'date'
8
- require 'erb'
9
- require 'stats_formatter.rb'
10
- require 'tests_formatter.rb'
11
- require 'zen_test_formatter.rb'
12
- require 'subversion_extractor.rb'
13
- require 'git_extractor.rb'
14
- require 'utils.rb'
15
-
16
- # ==============================================================================
17
- # Classe modelisant un fichier de description de projet Ruby on Rails
18
- # Author:: Vincent Dubois
19
- # Date : 03 decembre 2007 - version 0.0.1
20
- # 03 fevrier 2009 - version 0.0.2
21
- # ==============================================================================
22
- module Continuous4r
23
- include Utils
24
- VERSION = '0.0.2'
25
-
26
- # Support de CruiseControl.rb
27
- WORK_DIR = "#{ENV['CC_BUILD_ARTIFACTS'].nil? ? "tmp/continuous4r" : "#{ENV['CC_BUILD_ARTIFACTS']}/continuous4r"}"
28
-
29
- TASKS = ['dcov','rcov','rdoc','stats','changelog','flog','xdoclet','flay','reek','roodi','saikuro','tests','zentest']
30
-
31
- # Methode de generation du site au complet
32
- def self.generate_site
33
- tasks = TASKS
34
- project = XmlElements.fromString(File.read("#{RAILS_ROOT}/continuous4r-project.xml"))
35
- generation_date = DateTime.now
36
- auto_install = project['auto-install-tools']
37
- auto_install ||= "false"
38
-
39
- puts "====================================================================="
40
- puts " Continuous Integration for Ruby, starting website generation..."
41
- puts "---------------------------------------------------------------------"
42
- puts " Project name : #{project['name']}"
43
- puts " Project URL : #{project.url.text}"
44
- puts " Generation date : #{generation_date}"
45
- puts "---------------------------------------------------------------------"
46
-
47
- # Récupération des paramètres de proxy s'ils existent
48
- proxy_option = ""
49
- if File.exist?("#{(Config::CONFIG['host_os'] =~ /mswin/ ? ENV['USERPROFILE'] : ENV['HOME'])}/.continuous4r/proxy.yml")
50
- require 'YAML'
51
- proxy_options = YAML.load_file("#{(Config::CONFIG['host_os'] =~ /mswin/ ? ENV['USERPROFILE'] : ENV['HOME'])}/.continuous4r/proxy.yml")
52
- proxy_option = " -p \"http://#{proxy_options['proxy']['login']}:#{proxy_options['proxy']['password']}@#{proxy_options['proxy']['server']}:#{proxy_options['proxy']['port']}\""
53
- end
54
-
55
- # Vérification de présence et de la version de Rubygems
56
- puts " Checking presence and version of RubyGems..."
57
- rubygems_version = Utils.run_command("gem --version")
58
- if rubygems_version.empty?
59
- raise " You don't seem to have RubyGems installed, please go first to http://rubygems.rubyforge.org"
60
- end
61
-
62
- # Verification de la presence d'hpricot
63
- Utils.verify_gem_presence("hpricot", auto_install, proxy_option)
64
-
65
- # Chargement/Vérification des gems nécessaires à l'application
66
- puts " Checking gems for this project, please hold on..."
67
- project.gems.each('gem') do |gem|
68
- puts " Checking for #{gem['name']} gem, version #{gem['version']}..."
69
- gem_version = Utils.run_command("gem list #{gem['name']}")
70
- if gem_version.empty? or gem_version.index("#{gem['version']}").nil?
71
- if project['auto-install-gems'] == "false"
72
- raise " The #{gem['name']} gem with version #{gem['version']} is needed. Please run '#{"sudo " unless Config::CONFIG['host_os'] =~ /mswin/}gem install #{gem['name']} --version #{gem['version']}' to install it.\n BUILD FAILED."
73
- end
74
- gem_installed = Utils.run_command("#{"sudo " unless Config::CONFIG['host_os'] =~ /mswin/}gem install #{gem['name']} --version #{gem['version']}#{proxy_option} 2>&1")
75
- if !gem_installed.index("ERROR").nil?
76
- raise " Unable to install #{gem['name']} gem with version #{gem['version']}.\n BUILD FAILED."
77
- end
78
- end
79
- end
80
-
81
- puts "---------------------------------------------------------------------"
82
- # Création du répertoire de travail
83
- if File.exist?(WORK_DIR)
84
- FileUtils.rm_rf(WORK_DIR)
85
- end
86
- Dir.mkdir WORK_DIR
87
-
88
- # Construction des taches
89
- tasks.each do |task|
90
- self.build_task task, project['name'], auto_install, proxy_option
91
- puts "\n---------------------------------------------------------------------"
92
- end
93
- puts " All tasks done."
94
- puts "\n---------------------------------------------------------------------"
95
- # On copie les feuilles de styles
96
- FileUtils.cp_r("#{File.dirname(__FILE__)}/site/style/", "#{WORK_DIR}/")
97
- # On copie les images
98
- FileUtils.cp_r("#{File.dirname(__FILE__)}/site/images/", "#{WORK_DIR}/")
99
- FileUtils.copy_file("#{File.dirname(__FILE__)}/site/images/continuous4r-logo.png", "#{WORK_DIR}/continuous4r-logo.png")
100
- puts " Building project information page..."
101
- Utils.erb_run "index", false
102
- puts " Building team list page..."
103
- Utils.erb_run "team-list", false
104
- puts " Building project dependencies page..."
105
- Utils.erb_run "dependencies", false
106
- puts " Building source control management page..."
107
- Utils.erb_run "scm-usage", false
108
- puts " Building issue tracking page..."
109
- Utils.erb_run "issue-tracking", false
110
- puts " Building project reports page..."
111
- Utils.erb_run "continuous4r-reports", false
112
- tasks.each do |task|
113
- puts " Building #{task} page..."
114
- Utils.erb_run task, true
115
- end
116
- puts "\n BUILD SUCCESSFUL."
117
- puts "====================================================================="
118
- end
119
-
120
- # Methode qui permet de construire une tache de nom donne
121
- def self.build_task task, project_name, auto_install, proxy_option
122
- require "#{task}_builder.rb"
123
- task_class = Object.const_get("#{task.capitalize}Builder")
124
- task_builder = task_class.new
125
- task_builder.build(project_name, auto_install, proxy_option)
126
- end
127
- end
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+ require File.join(File.dirname(__FILE__), 'tasks', 'continuous4r')
4
+
5
+ require 'rubygems'
6
+ require 'XmlElements'
7
+ require 'date'
8
+ require 'erb'
9
+ require 'stats_formatter.rb'
10
+ require 'tests_formatter.rb'
11
+ require 'zen_test_formatter.rb'
12
+ require 'subversion_extractor.rb'
13
+ require 'git_extractor.rb'
14
+ require 'utils.rb'
15
+
16
+ # ==============================================================================
17
+ # Classe modelisant un fichier de description de projet Ruby on Rails
18
+ # Author:: Vincent Dubois
19
+ # Date : 03 decembre 2007 - version 0.0.1
20
+ # 03 fevrier 2009 - version 0.0.2
21
+ # 25 fevrier 2009 - version 0.0.3
22
+ # ==============================================================================
23
+ module Continuous4r
24
+ include Utils
25
+ VERSION = '0.0.3'
26
+
27
+ # Support de CruiseControl.rb
28
+ WORK_DIR = "#{ENV['CC_BUILD_ARTIFACTS'].nil? ? "tmp/continuous4r" : "#{ENV['CC_BUILD_ARTIFACTS']}/continuous4r"}"
29
+
30
+ TASKS = ['rdoc','dcov','rcov','stats','changelog','flog','xdoclet','flay','reek','roodi','saikuro','tests','zentest']
31
+ #TASKS = ['rdoc', 'dcov', 'rcov', 'stats', 'flog', 'xdoclet', 'flay', 'reek']
32
+ #TASKS = ['zentest']
33
+
34
+ METRICS_HASH = Hash.new
35
+
36
+ # Méthode qui permet de récupérer le nom du build pour la construction du template notamment
37
+ def self.build_name
38
+ @build_name ||= "no build name found"
39
+ end
40
+
41
+ # Methode de generation du site au complet
42
+ def self.generate_site
43
+ @build_name = Utils.build_name
44
+ tasks = TASKS
45
+ project = XmlElements.fromString(File.read("#{RAILS_ROOT}/continuous4r-project.xml"))
46
+ generation_date = DateTime.now
47
+ auto_install = project['auto-install-tools']
48
+ auto_install ||= "false"
49
+
50
+ puts "====================================================================="
51
+ puts " Continuous Integration for Ruby, starting website generation..."
52
+ puts "---------------------------------------------------------------------"
53
+ puts " Project name : #{project['name']}"
54
+ puts " Project URL : #{project.url.text}"
55
+ puts " Generation date : #{generation_date}"
56
+ puts "---------------------------------------------------------------------"
57
+
58
+ # Récupération des paramètres de proxy s'ils existent
59
+ proxy_option = ""
60
+ if File.exist?("#{(Config::CONFIG['host_os'] =~ /mswin/ ? ENV['USERPROFILE'] : ENV['HOME'])}/.continuous4r/proxy.yml")
61
+ require 'YAML'
62
+ proxy_options = YAML.load_file("#{(Config::CONFIG['host_os'] =~ /mswin/ ? ENV['USERPROFILE'] : ENV['HOME'])}/.continuous4r/proxy.yml")
63
+ proxy_option = " -p \"http://#{proxy_options['proxy']['login']}:#{proxy_options['proxy']['password']}@#{proxy_options['proxy']['server']}:#{proxy_options['proxy']['port']}\""
64
+ end
65
+
66
+ # Vérification de présence et de la version de Rubygems
67
+ puts " Checking presence and version of RubyGems..."
68
+ rubygems_version = Utils.run_command("gem --version")
69
+ if rubygems_version.empty?
70
+ raise " You don't seem to have RubyGems installed, please go first to http://rubygems.rubyforge.org"
71
+ end
72
+
73
+ # Verification de la presence d'hpricot
74
+ Utils.verify_gem_presence("hpricot", auto_install, proxy_option)
75
+
76
+ # Chargement/Vérification des gems nécessaires à l'application
77
+ puts " Checking gems for this project, please hold on..."
78
+ begin
79
+ project.gems.each('gem') do |gem|
80
+ puts " Checking for #{gem['name']} gem, version #{gem['version']}..."
81
+ gem_version = Utils.run_command("gem list #{gem['name']}")
82
+ if gem_version.empty? or gem_version.index("#{gem['version']}").nil?
83
+ if project['auto-install-gems'] == "false"
84
+ raise " The #{gem['name']} gem with version #{gem['version']} is needed. Please run '#{"sudo " unless Config::CONFIG['host_os'] =~ /mswin/}gem install #{gem['name']} --version #{gem['version']}' to install it.\n BUILD FAILED."
85
+ end
86
+ gem_installed = Utils.run_command("#{"sudo " unless Config::CONFIG['host_os'] =~ /mswin/}gem install #{gem['name']} --version #{gem['version']}#{proxy_option} 2>&1")
87
+ if !gem_installed.index("ERROR").nil?
88
+ raise " Unable to install #{gem['name']} gem with version #{gem['version']}.\n BUILD FAILED."
89
+ end
90
+ end
91
+ end
92
+ rescue
93
+ puts " No gems declared for this project, continuing..."
94
+ end
95
+
96
+ puts "---------------------------------------------------------------------"
97
+ # Création du répertoire de travail
98
+ if File.exist?(WORK_DIR)
99
+ FileUtils.rm_rf(WORK_DIR)
100
+ end
101
+ FileUtils.mkdir_p WORK_DIR
102
+
103
+ # Construction des taches
104
+ tasks.each do |task|
105
+ self.build_task task, project['name'], auto_install, proxy_option
106
+ puts "\n---------------------------------------------------------------------"
107
+ end
108
+ puts " All tasks done."
109
+ puts "\n---------------------------------------------------------------------"
110
+
111
+ # On copie les feuilles de styles
112
+ FileUtils.cp_r("#{File.dirname(__FILE__)}/site/style/", "#{WORK_DIR}/")
113
+
114
+ # On copie la partie flash
115
+ FileUtils.cp_r("#{File.dirname(__FILE__)}/site/charts/", "#{WORK_DIR}/")
116
+ # Production du fichier XML des indicateurs de qualité
117
+ page_file = File.open("#{Continuous4r::WORK_DIR}/build.xml", "w")
118
+ erb = ERB.new(File.read("#{File.dirname(__FILE__)}/site/build.xml.erb"))
119
+ page_file.write(erb.result)
120
+ page_file.close
121
+
122
+ # On copie les images
123
+ FileUtils.cp_r("#{File.dirname(__FILE__)}/site/images/", "#{WORK_DIR}/")
124
+ FileUtils.copy_file("#{File.dirname(__FILE__)}/site/images/continuous4r-logo.png", "#{WORK_DIR}/continuous4r-logo.png")
125
+ puts " Building project information page..."
126
+ Utils.erb_run "index", false
127
+ puts " Building team list page..."
128
+ Utils.erb_run "team-list", false
129
+ puts " Building project dependencies page..."
130
+ Utils.erb_run "dependencies", false
131
+ puts " Building source control management page..."
132
+ Utils.erb_run "scm-usage", false
133
+ puts " Building issue tracking page..."
134
+ Utils.erb_run "issue-tracking", false
135
+ puts " Building project reports page..."
136
+ Utils.erb_run "continuous4r-reports", false
137
+ tasks.each do |task|
138
+ task_class = Object.const_get("#{task.capitalize}Builder")
139
+ task_builder = task_class.new
140
+ next if task_builder.respond_to?(:prerequisite_met?) and !task_builder.prerequisite_met?
141
+ puts " Building #{task} page..."
142
+ Utils.erb_run task, true
143
+ end
144
+ puts "\n BUILD SUCCESSFUL."
145
+ puts "====================================================================="
146
+ end
147
+
148
+ # Methode qui permet de construire une tache de nom donne
149
+ def self.build_task task, project_name, auto_install, proxy_option
150
+ require "#{task}_builder.rb"
151
+ task_class = Object.const_get("#{task.capitalize}Builder")
152
+ task_builder = task_class.new
153
+ if task_builder.respond_to?(:prerequisite_met?)
154
+ if !task_builder.prerequisite_met?
155
+ puts task_builder.prerequisite_unmet_message
156
+ return
157
+ end
158
+ end
159
+ task_builder.build(project_name, auto_install, proxy_option)
160
+ if task_builder.respond_to?(:quality_percentage)
161
+ METRICS_HASH[task_builder.quality_indicator_name] = task_builder.quality_percentage
162
+ end
163
+ end
164
+
165
+ end
data/lib/dcov_builder.rb CHANGED
@@ -29,6 +29,11 @@ module Dcov
29
29
 
30
30
  def build_stats_body
31
31
  output = ""
32
+ num_classes = File.read("#{Continuous4r::WORK_DIR}/rdoc/rdoc.log").split(/$/).select { |l| l =~ /^Classes:/ }[0].strip.split(/Classes:/)[1].strip.to_f
33
+ num_modules = File.read("#{Continuous4r::WORK_DIR}/rdoc/rdoc.log").split(/$/).select { |l| l =~ /^Modules:/ }[0].strip.split(/Modules:/)[1].strip.to_f
34
+ num_methods = File.read("#{Continuous4r::WORK_DIR}/rdoc/rdoc.log").split(/$/).select { |l| l =~ /^Methods:/ }[0].strip.split(/Methods:/)[1].strip.to_f
35
+ global_coverage = ((class_coverage.to_f * num_classes) + (module_coverage.to_f * num_modules) + (method_coverage.to_f * num_methods)) / (num_classes + num_modules + num_methods)
36
+ output << "<h3 #{Utils.percent_to_css_style(global_coverage.to_i)}>Global coverage percentage : #{global_coverage.to_i}%</h3>\n"
32
37
  output << "<h3>Summary</h3><p>\n"
33
38
  output << "<table class='bodyTable' style='width: 200px;'><tr><th>Type</th><th>Coverage</th></tr>"
34
39
  output << "<tr class='a'><td><b>Class</b></td><td style='text-align: right;'>#{class_coverage}%</td></tr>\n"
@@ -140,5 +145,21 @@ class DcovBuilder
140
145
  raise " Execution of dcov failed.\n BUILD FAILED."
141
146
  end
142
147
  end
148
+
149
+ # Methode qui permet d'extraire le pourcentage de qualité extrait d'un builder
150
+ def quality_percentage
151
+ require 'hpricot'
152
+ doc = Hpricot(File.read("#{Continuous4r::WORK_DIR}/dcov/coverage.html"))
153
+ doc.search('//h3') do |h3|
154
+ if h3.inner_text.match(/^Global coverage percentage/)
155
+ return h3.inner_text.split(/Global coverage percentage : /)[1].split(/%/)[0]
156
+ end
157
+ end
158
+ end
159
+
160
+ # Nom de l'indicateur de qualité
161
+ def quality_indicator_name
162
+ "rdoc coverage"
163
+ end
143
164
  end
144
-
165
+
data/lib/flay_builder.rb CHANGED
@@ -18,21 +18,67 @@ class FlayBuilder
18
18
  files << Dir.glob("lib/**/*.rb")
19
19
  files << Dir.glob("test/**/*.rb")
20
20
  files.flatten!
21
- flay_command = "flay"
21
+ flay_command = "flay -v"
22
22
  files.each do |file|
23
23
  flay_command += " '#{file}'"
24
24
  end
25
25
  flay_result = Utils.run_command(flay_command)
26
- matches = flay_result.chomp.split("\n\n").map{|m| m.split("\n ") }
26
+ matches = flay_result.chomp.split("\n\n")
27
27
  FileUtils.mkdir("#{Continuous4r::WORK_DIR}/flay")
28
28
  flay_file = File.open("#{Continuous4r::WORK_DIR}/flay/index.html","w")
29
- matches.each_with_index do |match, count|
30
- flay_file.write("<tr class='#{count % 2 == 0 ? "a" : "b"}'><td>")
31
- match[1..-1].each do |filename|
32
- flay_file.write("<a href='xdoclet/#{filename.split(":")[0].gsub(/\//,'_')}.html##{filename.split(":")[1]}' target='_blank'>#{filename}</a><br/>")
29
+ class_index = 0
30
+ summary = ""
31
+ duplicate_lines = 0
32
+ matches.each_with_index do |match, index|
33
+ if index % 2 == 0
34
+ flay_file.write("<tr class='#{class_index % 2 == 0 ? "a" : "b"}'>")
35
+ lines = match.split(/$/)
36
+ summary = lines[0]
37
+ flay_file.write("<td>")
38
+ (1..(lines.length - 1)).to_a.each do |line|
39
+ flay_file.write("<a href='xdoclet/#{lines[line].split(":")[1].strip.gsub(/\//,'_')}.html##{lines[line].split(":")[2]}' target='_blank'>#{lines[line].strip}</a><br/>")
40
+ end
41
+ flay_file.write("</td>")
42
+ class_index += 1
43
+ else
44
+ flay_file.write("<td")
45
+ begin
46
+ mass = summary.split(/mass = /)[1].split(/\)/)[0].to_i
47
+ rescue
48
+ mass = summary.split(Regexp.new(" = "))[1].split(/\)/)[0].to_i
49
+ end
50
+ if summary.match(/IDENTICAL/)
51
+ flay_file.write(" style='background-color: orange;' title='Not DRY'")
52
+ elsif mass >= 40
53
+ flay_file.write(" style='background-color: yellow;' title='Not DRY'")
54
+ end
55
+ if summary.match(/IDENTICAL/) or mass >= 40
56
+ arr_match = match.split(/$/)
57
+ arr_match.each do |elem|
58
+ if elem.match(/^A:/) or elem.match(/^ /)
59
+ duplicate_lines += 1
60
+ end
61
+ end
62
+ end
63
+ flay_file.write(">#{summary}<br/><pre>")
64
+ flay_file.write("#{match}</pre></td></tr>")
33
65
  end
34
- flay_file.write("</td><td>#{match.first}</td></tr>")
66
+ require 'hpricot'
67
+ doc = Hpricot(File.read("#{Continuous4r::WORK_DIR}/stats_body.html"))
68
+ tr_arr = doc.search("//tr")
69
+ loc = tr_arr[tr_arr.length-1].search("td")[2].inner_text.strip.to_f
70
+ @dryness = 100.0 - ((duplicate_lines.to_f * 100.0) / loc)
35
71
  end
36
72
  flay_file.close
37
73
  end
74
+
75
+ # Methode qui permet d'extraire le pourcentage de qualité extrait d'un builder
76
+ def quality_percentage
77
+ @dryness
78
+ end
79
+
80
+ # Nom de l'indicateur de qualité
81
+ def quality_indicator_name
82
+ "DRYness"
83
+ end
38
84
  end
data/lib/flog_builder.rb CHANGED
@@ -117,4 +117,28 @@ class FlogBuilder
117
117
  end
118
118
  save_html(ERB.new(File.read(File.join(File.dirname(__FILE__), "site/flog.html.erb"))).result(binding))
119
119
  end
120
+
121
+ # Methode qui permet d'extraire le pourcentage de qualité extrait d'un builder
122
+ def quality_percentage
123
+ require 'hpricot'
124
+ doc = Hpricot(File.read("#{Continuous4r::WORK_DIR}/flog/index.html"))
125
+ doc.search('//h3') do |h3|
126
+ if h3.inner_text.match(/^Project average score/)
127
+ score = h3.inner_text.split(/Project average score : /)[1].to_f
128
+ if score > 100.0
129
+ percent = 0
130
+ elsif score < 11.0
131
+ percent = 100
132
+ else
133
+ percent = ((100.0 - score) * 100.0) / 89.0
134
+ end
135
+ return percent
136
+ end
137
+ end
138
+ end
139
+
140
+ # Nom de l'indicateur de qualité
141
+ def quality_indicator_name
142
+ "code complexity"
143
+ end
120
144
  end
data/lib/rcov_builder.rb CHANGED
@@ -6,18 +6,40 @@
6
6
  class RcovBuilder
7
7
  include Utils
8
8
 
9
+ # Prérequis à la tâche
10
+ def prerequisite_met?
11
+ Dir.glob("test/rcov*.rb").length > 0
12
+ end
13
+
14
+ # Dans le cas de l'erreur de prérequis
15
+ def prerequisite_unmet_message
16
+ " No file matching the [test/rcov*.rb] pattern. Rcov task will be ignored."
17
+ end
18
+
9
19
  # Implementation de la construction de la tache
10
20
  def build(project_name, auto_install, proxy_option)
11
- # On verifie la presence de rcov
12
- Utils.verify_gem_presence("rcov", auto_install, proxy_option)
13
- # On lance la generation
14
- puts " Building rcov code coverage report..."
15
- rcov_pass = Utils.run_command("rcov --rails --exclude rcov,rubyforge,builder,mime-types,xml-simple test/rcov*.rb")
16
- if rcov_pass.index("Finished in").nil?
17
- raise " Execution of rcov failed with command 'rcov --rails --exclude rcov,rubyforge test/rcov*.rb'.\n BUILD FAILED."
18
- end
19
- # On recupere le rapport genere
20
- Dir.mkdir "#{Continuous4r::WORK_DIR}/rcov"
21
- FileUtils.mv("coverage", "#{Continuous4r::WORK_DIR}/rcov/")
21
+ # On verifie la presence de rcov
22
+ Utils.verify_gem_presence("rcov", auto_install, proxy_option)
23
+ # On lance la generation
24
+ puts " Building rcov code coverage report..."
25
+ rcov_pass = Utils.run_command("rcov --rails --exclude rcov,rubyforge,builder,mime-types,xml-simple test/rcov*.rb")
26
+ if rcov_pass.index("Finished in").nil?
27
+ raise " Execution of rcov failed with command 'rcov --rails --exclude rcov,rubyforge,builder,mime-types,xml-simple test/rcov*.rb'.\n BUILD FAILED."
28
+ end
29
+ # On recupere le rapport genere
30
+ Dir.mkdir "#{Continuous4r::WORK_DIR}/rcov"
31
+ FileUtils.mv("coverage", "#{Continuous4r::WORK_DIR}/rcov/")
32
+ end
33
+
34
+ # Methode qui permet d'extraire le pourcentage de qualite extrait d'un builder
35
+ def quality_percentage
36
+ require 'hpricot'
37
+ doc = Hpricot(File.read("#{Continuous4r::WORK_DIR}/rcov/coverage/index.html"))
38
+ (doc/'tt[@class^="coverage_code"]')[0].inner_text.split(/%/)[0]
39
+ end
40
+
41
+ # Nom de l'indicateur de qualite
42
+ def quality_indicator_name
43
+ "tests coverage"
22
44
  end
23
45
  end
data/lib/reek_builder.rb CHANGED
@@ -3,6 +3,23 @@
3
3
  # author: Vincent Dubois
4
4
  # date: 08 fevrier 2009
5
5
  # ==========================================================================
6
+ require 'reek'
7
+ require 'reek/options'
8
+ require 'reek/smells/smells'
9
+
10
+ module Reek
11
+
12
+ SMELLS = {
13
+ :defn => [
14
+ Smells::ControlCouple,
15
+ Smells::UncommunicativeName,
16
+ Smells::LongMethod,
17
+ Smells::UtilityFunction,
18
+ Smells::FeatureEnvy
19
+ ]
20
+ }
21
+ end
22
+
6
23
  class ReekBuilder
7
24
  include Utils
8
25
 
@@ -13,7 +30,9 @@ class ReekBuilder
13
30
  # On lance la generation
14
31
  puts " Building reek report..."
15
32
  files = Array.new
16
- files << Dir.glob("app/**/*.rb")
33
+ files << Dir.glob("app/controllers/*.rb")
34
+ files << Dir.glob("app/helpers/*.rb")
35
+ files << Dir.glob("app/models/*.rb")
17
36
  files << Dir.glob("lib/**/*.rb")
18
37
  files << Dir.glob("test/**/*.rb")
19
38
  files.flatten!
@@ -25,14 +44,39 @@ class ReekBuilder
25
44
  matches = reek_result.chomp.split("\n\n").map{|m| m.split("\n") }
26
45
  FileUtils.mkdir("#{Continuous4r::WORK_DIR}/reek")
27
46
  reek_file = File.open("#{Continuous4r::WORK_DIR}/reek/index.html","w")
28
- matches.each_with_index do |match, count|
29
- reek_file.write("<tr class='#{count % 2 == 0 ? "a" : "b"}'>")
30
- reek_file.write("<td><a href='xdoclet/#{match.first.split("\"")[1].gsub(/\//,'_')}.html' target='_blank'>#{match.first.split("\"")[1]}</a> #{match.first.split("\"")[2]}</td><td>")
47
+ count = 0
48
+ score = 0.0
49
+ matches.each do |match|
50
+ smells = Array.new
31
51
  match[1..-1].each do |filename|
32
- reek_file.write("#{filename}<br/>")
52
+ smells << filename if filename.index("[Duplication]").nil?
53
+ end
54
+ if smells.length > 0
55
+ reek_file.write("<tr class='#{count % 2 == 0 ? "a" : "b"}'>")
56
+ reek_file.write("<td><a href='xdoclet/#{match.first.split("\"")[1].gsub(/\//,'_')}.html' target='_blank'>#{match.first.split("\"")[1]}</a> -- #{smells.length} warning#{"s" if smells.length > 1}</td><td>")
57
+ if smells.length > 10
58
+ score += 1.0
59
+ else
60
+ score += 0.5
61
+ end
62
+ smells.each do |smell|
63
+ reek_file.write("#{smell}<br/>")
64
+ end
65
+ reek_file.write("</td></tr>")
66
+ count += 1
33
67
  end
34
- reek_file.write("</td></tr>")
35
68
  end
36
69
  reek_file.close
70
+ @percent = 100 - ((score * files.length) / 100)
71
+ end
72
+
73
+ # Methode qui permet d'extraire le pourcentage de qualité extrait d'un builder
74
+ def quality_percentage
75
+ @percent
76
+ end
77
+
78
+ # Nom de l'indicateur de qualité
79
+ def quality_indicator_name
80
+ "code smells"
37
81
  end
38
82
  end