continuous4r 0.0.2 → 0.0.3
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.
- data/History.txt +10 -3
- data/Manifest.txt +4 -0
- data/lib/changelog_builder.rb +10 -4
- data/lib/continuous4r.rb +165 -127
- data/lib/dcov_builder.rb +22 -1
- data/lib/flay_builder.rb +53 -7
- data/lib/flog_builder.rb +24 -0
- data/lib/rcov_builder.rb +33 -11
- data/lib/reek_builder.rb +50 -6
- data/lib/saikuro_builder.rb +28 -0
- data/lib/site/body-continuous4r-reports.rhtml +57 -1
- data/lib/site/body-dependencies.rhtml +16 -7
- data/lib/site/body-flay.rhtml +1 -1
- data/lib/site/build.xml.erb +48 -0
- data/lib/site/charts/AC_RunActiveContent.js +292 -0
- data/lib/site/charts/charts.swf +0 -0
- data/lib/site/charts/charts_library/pono.swf +0 -0
- data/lib/site/flog.html.erb +8 -4
- data/lib/site/flog_page.html.erb +20 -1
- data/lib/site/header.rhtml +1 -13
- data/lib/site/menu-continuous4r-reports.rhtml +6 -1
- data/lib/site/menu-task.rhtml +6 -1
- data/lib/tests_builder.rb +10 -0
- data/lib/utils.rb +69 -1
- data/lib/zen_test_formatter.rb +1 -1
- data/lib/zentest_builder.rb +10 -0
- data/website/index.txt +37 -28
- metadata +6 -2
data/History.txt
CHANGED
@@ -1,4 +1,11 @@
|
|
1
|
-
== 0.0.
|
1
|
+
== 0.0.3 2009-03-02
|
2
2
|
|
3
|
-
*
|
4
|
-
|
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
|
data/lib/changelog_builder.rb
CHANGED
@@ -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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
puts "
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
#
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
puts "
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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")
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
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
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
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
|