indirect-metric_fu 0.8.1 → 0.8.2
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/lib/metric_fu/base.rb +53 -0
- data/lib/metric_fu/churn.rb +73 -113
- data/lib/metric_fu/flay_reporter.rb +17 -0
- data/lib/metric_fu/flog_reporter/base.rb +5 -14
- data/lib/metric_fu/flog_reporter/generator.rb +29 -61
- data/lib/metric_fu/flog_reporter/operator.rb +1 -1
- data/lib/metric_fu/flog_reporter/page.rb +11 -14
- data/lib/metric_fu/flog_reporter/scanned_method.rb +2 -2
- data/lib/metric_fu/md5_tracker.rb +5 -5
- data/lib/metric_fu.rb +1 -12
- data/lib/tasks/churn.rake +1 -1
- data/lib/tasks/coverage.rake +7 -5
- data/lib/tasks/flay.rake +9 -0
- data/lib/tasks/flog.rake +10 -10
- data/lib/tasks/metric_fu.rake +15 -11
- data/lib/tasks/saikuro.rake +5 -5
- data/lib/tasks/stats.rake +2 -2
- data/lib/templates/churn.css +38 -0
- data/lib/templates/churn.html.erb +19 -0
- data/lib/templates/flay.css +38 -0
- data/lib/templates/flay.html.erb +23 -0
- data/lib/templates/flog.css +39 -0
- data/lib/templates/flog.html.erb +26 -0
- data/lib/templates/flog_page.html.erb +13 -0
- data/spec/base_spec.rb +35 -0
- data/spec/churn_spec.rb +81 -34
- data/spec/flay_reporter_spec.rb +12 -0
- data/spec/flog_reporter/base_spec.rb +7 -7
- data/spec/md5_tracker_spec.rb +7 -7
- data/spec/spec_helper.rb +7 -0
- metadata +24 -3
- data/lib/metric_fu/flay.rb +0 -40
@@ -0,0 +1,53 @@
|
|
1
|
+
module MetricFu
|
2
|
+
|
3
|
+
TEMPLATE_DIR = File.join(File.dirname(__FILE__), '..', 'templates')
|
4
|
+
BASE_DIRECTORY = ENV['CC_BUILD_ARTIFACTS'] || 'tmp/metric_fu'
|
5
|
+
RAILS = File.exist?("config/environment.rb")
|
6
|
+
|
7
|
+
if RAILS
|
8
|
+
CODE_DIRS = ['app', 'lib']
|
9
|
+
else
|
10
|
+
CODE_DIRS = ['lib']
|
11
|
+
end
|
12
|
+
|
13
|
+
module Base
|
14
|
+
class Generator
|
15
|
+
|
16
|
+
def initialize(base_dir, options={})
|
17
|
+
@base_dir = base_dir
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.generate_report(base_dir, options={})
|
21
|
+
self.new(base_dir, options).generate_report
|
22
|
+
end
|
23
|
+
|
24
|
+
def save_html(content, file='index')
|
25
|
+
open("#{@base_dir}/#{file}.html", "w") do |f|
|
26
|
+
f.puts content
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def generate_report
|
31
|
+
save_html(generate_html)
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate_html
|
35
|
+
analyze
|
36
|
+
html = ERB.new(File.read(template_file)).result(binding)
|
37
|
+
end
|
38
|
+
|
39
|
+
def template_file
|
40
|
+
File.join(MetricFu::TEMPLATE_DIR, "#{template_name}.html.erb")
|
41
|
+
end
|
42
|
+
|
43
|
+
def link_to_filename(name, line = nil)
|
44
|
+
filename = File.expand_path(name)
|
45
|
+
if PLATFORM['darwin']
|
46
|
+
%{<a href="txmt://open/?url=file://#{filename}&line=#{line}">#{name}</a>}
|
47
|
+
else
|
48
|
+
%{<a href="file://#{filename}">#{name}</a>}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/metric_fu/churn.rb
CHANGED
@@ -1,127 +1,87 @@
|
|
1
1
|
module MetricFu
|
2
|
-
class Churn
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
class Churn < Base::Generator
|
3
|
+
|
4
|
+
def initialize(base_dir, options={})
|
5
|
+
@base_dir = base_dir
|
6
|
+
if File.exist?(".git")
|
7
|
+
@source_control = Git.new(options[:start_date])
|
8
|
+
elsif File.exist?(".svn")
|
9
|
+
@source_control = Svn.new(options[:start_date])
|
10
|
+
else
|
11
|
+
raise "Churning requires a subversion or git repo"
|
12
|
+
end
|
13
|
+
|
14
|
+
@minimum_churn_count = options[:minimum_churn_count] || 5
|
15
|
+
end
|
16
|
+
|
17
|
+
def analyze
|
18
|
+
@changes = parse_log_for_changes.reject! {|file, change_count| change_count < @minimum_churn_count}
|
19
|
+
end
|
20
|
+
|
21
|
+
# should be dynamically read from the class
|
22
|
+
def template_name
|
23
|
+
'churn'
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def parse_log_for_changes
|
29
|
+
changes = {}
|
30
|
+
|
31
|
+
logs = @source_control.get_logs
|
32
|
+
logs.each do |line|
|
33
|
+
changes[line] ? changes[line] += 1 : changes[line] = 1
|
10
34
|
end
|
11
|
-
|
35
|
+
changes
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
class SourceControl
|
40
|
+
def initialize(start_date=nil)
|
41
|
+
@start_date = start_date
|
42
|
+
end
|
43
|
+
|
12
44
|
private
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
45
|
+
def require_rails_env
|
46
|
+
# not sure if the following works because active_support might only be in vendor/rails
|
47
|
+
# require 'activesupport'
|
48
|
+
require RAILS_ROOT + '/config/environment'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Git < SourceControl
|
53
|
+
def get_logs
|
54
|
+
`git log #{date_range} --name-only --pretty=format:`.split(/\n/).reject{|line| line == ""}
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def date_range
|
59
|
+
if @start_date
|
60
|
+
require_rails_env
|
61
|
+
"--after=#{@start_date.call.strftime('%Y-%m-%d')}"
|
20
62
|
end
|
21
|
-
|
22
|
-
changes
|
23
63
|
end
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
class Svn < SourceControl
|
68
|
+
def get_logs
|
69
|
+
`svn log #{date_range} --verbose`.split(/\n/).map { |line| clean_up_svn_line(line) }.compact
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def date_range
|
74
|
+
if @start_date
|
75
|
+
require_rails_env
|
76
|
+
"--revision {#{@start_date.call.strftime('%Y-%m-%d')}}:{#{Time.now.strftime('%Y-%m-%d')}}"
|
30
77
|
end
|
31
78
|
end
|
32
|
-
|
79
|
+
|
33
80
|
def clean_up_svn_line(line)
|
34
81
|
m = line.match(/\W*[A,M]\W+(\/.*)\b/)
|
35
82
|
m ? m[1] : nil
|
36
83
|
end
|
37
|
-
|
38
|
-
def churn_options(options)
|
39
|
-
if File.exist?(".git")
|
40
|
-
scm = :git
|
41
|
-
elsif File.exist?(".svn")
|
42
|
-
scm = :svn
|
43
|
-
end
|
44
|
-
raise "Churning requires a subversion or git repo" unless scm
|
45
|
-
|
46
|
-
if options[:start_date]
|
47
|
-
require 'activesupport'
|
48
|
-
if scm == :git
|
49
|
-
date_range = "--after=#{options[:start_date].call.strftime('%Y-%m-%d')}"
|
50
|
-
else
|
51
|
-
date_range = "--revision {#{options[:start_date].call.strftime('%Y-%m-%d')}}:{#{Time.now.strftime('%Y-%m-%d')}}"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
minimum_churn_count = options[:minimum_churn_count] ? options[:minimum_churn_count] : 5
|
56
|
-
return date_range, minimum_churn_count, scm
|
57
|
-
end
|
58
|
-
|
59
|
-
def write_churn_file(changes, output_dir)
|
60
|
-
FileUtils.mkdir_p(output_dir, :verbose => false) unless File.directory?(output_dir)
|
61
|
-
File.open("#{output_dir}/index.html", "w+") do |file|
|
62
|
-
file << CHURN_FILE_BEGINING
|
63
|
-
changes.to_a.sort {|x,y| y[1] <=> x[1]}.each do |change|
|
64
|
-
file << "<tr><td>#{change[0]}</td><td class='warning'>#{change[1]}</td></tr>\n"
|
65
|
-
end
|
66
|
-
file << CHURN_FILE_END
|
67
|
-
end
|
68
|
-
end
|
69
84
|
end
|
70
|
-
|
71
|
-
CHURN_FILE_BEGINING = <<-EOS
|
72
|
-
<html><head><title>Source Control Churn Results</title></head>
|
73
|
-
<style>
|
74
|
-
body {
|
75
|
-
margin: 20px;
|
76
|
-
padding: 0;
|
77
|
-
font-size: 12px;
|
78
|
-
font-family: bitstream vera sans, verdana, arial, sans serif;
|
79
|
-
background-color: #efefef;
|
80
|
-
}
|
81
|
-
|
82
|
-
table {
|
83
|
-
border-collapse: collapse;
|
84
|
-
/*border-spacing: 0;*/
|
85
|
-
border: 1px solid #666;
|
86
|
-
background-color: #fff;
|
87
|
-
margin-bottom: 20px;
|
88
|
-
}
|
89
|
-
|
90
|
-
table, th, th+th, td, td+td {
|
91
|
-
border: 1px solid #ccc;
|
92
|
-
}
|
93
|
-
|
94
|
-
table th {
|
95
|
-
font-size: 12px;
|
96
|
-
color: #fc0;
|
97
|
-
padding: 4px 0;
|
98
|
-
background-color: #336;
|
99
|
-
}
|
100
|
-
|
101
|
-
th, td {
|
102
|
-
padding: 4px 10px;
|
103
|
-
}
|
104
|
-
|
105
|
-
td {
|
106
|
-
font-size: 13px;
|
107
|
-
}
|
108
|
-
|
109
|
-
.warning {
|
110
|
-
background-color: yellow;
|
111
|
-
}
|
112
|
-
</style>
|
113
|
-
|
114
|
-
<body>
|
115
|
-
<h1>Source Control Churn Results</h1>
|
116
|
-
<table width="100%" border="1">
|
117
|
-
<tr><th>File Path</th><th>Times Changed</th></tr>
|
118
|
-
EOS
|
119
|
-
|
120
|
-
CHURN_FILE_END = <<-EOS
|
121
|
-
</table>
|
122
|
-
</body>
|
123
|
-
</html>
|
124
|
-
EOS
|
125
|
-
|
85
|
+
|
126
86
|
end
|
127
87
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module MetricFu
|
4
|
+
class FlayReporter < Base::Generator
|
5
|
+
|
6
|
+
def analyze
|
7
|
+
files_to_flay = MetricFu::CODE_DIRS.map{|dir| Dir[File.join(dir, "**/*.rb")] }
|
8
|
+
output = `flay #{files_to_flay.join(" ")}`
|
9
|
+
@matches = output.chomp.split("\n\n").map{|m| m.split("\n ") }
|
10
|
+
end
|
11
|
+
|
12
|
+
def template_name
|
13
|
+
'flay'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module MetricFu::FlogReporter
|
2
|
-
|
2
|
+
|
3
3
|
SCORE_FORMAT = "%0.2f"
|
4
|
-
|
4
|
+
|
5
5
|
class InvalidFlog < RuntimeError
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
class Base
|
9
9
|
MODULE_NAME = "([A-Za-z]+)+"
|
10
10
|
METHOD_NAME = "#([a-z0-9]+_?)+\\??\\!?"
|
@@ -12,7 +12,7 @@ module MetricFu::FlogReporter
|
|
12
12
|
|
13
13
|
METHOD_NAME_RE = Regexp.new("#{MODULE_NAME}#{METHOD_NAME}")
|
14
14
|
SCORE_RE = Regexp.new(SCORE)
|
15
|
-
|
15
|
+
|
16
16
|
METHOD_LINE_RE = Regexp.new("#{MODULE_NAME}#{METHOD_NAME}:\\s\\(#{SCORE}\\)")
|
17
17
|
OPERATOR_LINE_RE = Regexp.new("\\s+(#{SCORE}):\\s(.*)$")
|
18
18
|
|
@@ -22,15 +22,6 @@ module MetricFu::FlogReporter
|
|
22
22
|
return second_value
|
23
23
|
end
|
24
24
|
|
25
|
-
def load_css(css_file = nil)
|
26
|
-
filepath = css_file || File.join(File.dirname(__FILE__), 'flog_reporter.css')
|
27
|
-
css = ""
|
28
|
-
file = File.open(filepath, "r")
|
29
|
-
file.each_line { |line| css << line }
|
30
|
-
file.close
|
31
|
-
css
|
32
|
-
end
|
33
|
-
|
34
25
|
def parse(text)
|
35
26
|
score = text[/\w+ = (\d+\.\d+)/, 1]
|
36
27
|
return nil unless score
|
@@ -50,7 +41,7 @@ module MetricFu::FlogReporter
|
|
50
41
|
page.scanned_methods.last.operators << Operator.new(score, operator)
|
51
42
|
end
|
52
43
|
end
|
53
|
-
|
44
|
+
|
54
45
|
page
|
55
46
|
end
|
56
47
|
end
|
@@ -1,71 +1,39 @@
|
|
1
1
|
module MetricFu::FlogReporter
|
2
|
-
class Generator
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
begin
|
13
|
-
page = Base.parse(content)
|
14
|
-
rescue InvalidFlog
|
15
|
-
puts "Invalid flog for #{filename}"
|
16
|
-
next
|
17
|
-
end
|
2
|
+
class Generator < MetricFu::Base::Generator
|
3
|
+
def generate_report
|
4
|
+
flog_hashes = []
|
5
|
+
Dir.glob("#{@base_dir}/**/*.txt").each do |filename|
|
6
|
+
begin
|
7
|
+
page = Base.parse(open(filename, "r") { |f| f.read })
|
8
|
+
rescue InvalidFlog
|
9
|
+
puts "Invalid flog for #{filename}"
|
10
|
+
next
|
11
|
+
end
|
18
12
|
|
19
|
-
|
13
|
+
next unless page
|
20
14
|
|
21
|
-
|
22
|
-
|
23
|
-
:page => page,
|
24
|
-
:path => filename.sub('.txt', '.html').sub("#{base_dir}/", "")
|
25
|
-
}
|
26
|
-
else
|
27
|
-
flog_hashes << generate_page(filename, page, base_dir)
|
28
|
-
end
|
15
|
+
unless MetricFu::MD5Tracker.file_already_counted?(filename)
|
16
|
+
generate_page(filename, page)
|
29
17
|
end
|
30
|
-
|
31
|
-
generate_index(flog_hashes, base_dir)
|
32
|
-
end
|
33
|
-
|
34
|
-
def generate_page(filename, page, base_dir)
|
35
|
-
html_file = File.new(filename.gsub(/\.txt/, '.html'), "w")
|
36
|
-
html_file.puts page.to_html
|
37
|
-
html_file.close
|
38
|
-
return { :path => html_file.path.sub("#{base_dir}/", ''),
|
18
|
+
flog_hashes << { :path => File.basename(filename, ".txt") + '.html',
|
39
19
|
:page => page }
|
40
20
|
end
|
41
21
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
<td class='score'>#{sprintf(SCORE_FORMAT, flog_hash[:page].average_score)}</td>
|
58
|
-
<td class='score'>#{sprintf(SCORE_FORMAT, flog_hash[:page].highest_score)}</td>
|
59
|
-
</tr>
|
60
|
-
EOF
|
61
|
-
count += 1
|
62
|
-
end
|
63
|
-
html << "</table>\n"
|
64
|
-
html << "</body></html>\n"
|
65
|
-
index = File.new("#{base_dir}/index.html", "w")
|
66
|
-
index.puts html
|
67
|
-
index.close
|
68
|
-
end
|
22
|
+
generate_index(flog_hashes)
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_page(filename, page)
|
26
|
+
save_html(page.to_html, File.basename(filename, ".txt"))
|
27
|
+
end
|
28
|
+
|
29
|
+
# should be dynamically read from the class
|
30
|
+
def template_name
|
31
|
+
'flog'
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate_index(flog_hashes)
|
35
|
+
html = ERB.new(File.read(template_file)).result(binding)
|
36
|
+
save_html(html)
|
69
37
|
end
|
70
38
|
end
|
71
39
|
end
|
@@ -1,24 +1,16 @@
|
|
1
1
|
module MetricFu::FlogReporter
|
2
|
-
class Page
|
2
|
+
class Page < MetricFu::Base::Generator
|
3
3
|
attr_accessor :score, :scanned_methods
|
4
|
-
|
4
|
+
|
5
5
|
def initialize(score, scanned_methods = [])
|
6
6
|
@score = score.to_f
|
7
7
|
@scanned_methods = scanned_methods
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def to_html
|
11
|
-
|
12
|
-
output << Base.load_css
|
13
|
-
output << "</style></head><body>"
|
14
|
-
output << "Score: #{score}\n"
|
15
|
-
scanned_methods.each do |sm|
|
16
|
-
output << sm.to_html
|
17
|
-
end
|
18
|
-
output << "</body></html>"
|
19
|
-
output
|
11
|
+
ERB.new(File.read(template_file)).result(binding)
|
20
12
|
end
|
21
|
-
|
13
|
+
|
22
14
|
def average_score
|
23
15
|
sum = 0
|
24
16
|
scanned_methods.each do |m|
|
@@ -26,11 +18,16 @@ module MetricFu::FlogReporter
|
|
26
18
|
end
|
27
19
|
sum / scanned_methods.length
|
28
20
|
end
|
29
|
-
|
21
|
+
|
30
22
|
def highest_score
|
31
23
|
scanned_methods.inject(0) do |highest, m|
|
32
24
|
m.score > highest ? m.score : highest
|
33
25
|
end
|
34
26
|
end
|
27
|
+
|
28
|
+
# should be dynamically read from the class
|
29
|
+
def template_name
|
30
|
+
'flog_page'
|
31
|
+
end
|
35
32
|
end
|
36
33
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module MetricFu::FlogReporter
|
2
2
|
class ScannedMethod
|
3
3
|
attr_accessor :name, :score, :operators
|
4
|
-
|
4
|
+
|
5
5
|
def initialize(name, score, operators = [])
|
6
6
|
@name = name
|
7
7
|
@score = score.to_f
|
8
8
|
@operators = operators
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def to_html
|
12
12
|
output = "<p><strong>#{name} (#{score})</strong></p>\n"
|
13
13
|
output << "<table>\n"
|
@@ -9,11 +9,11 @@ module MetricFu
|
|
9
9
|
class << self
|
10
10
|
def md5_dir(path_to_file, base_dir)
|
11
11
|
File.join(base_dir,
|
12
|
-
path_to_file.split('/')[0..-2].join('/'))
|
12
|
+
path_to_file.split('/')[0..-2].join('/'))
|
13
13
|
end
|
14
14
|
|
15
15
|
def md5_file(path_to_file, base_dir)
|
16
|
-
File.join(md5_dir(path_to_file, base_dir),
|
16
|
+
File.join(md5_dir(path_to_file, base_dir),
|
17
17
|
path_to_file.split('/').last.sub(/\.[a-z]+/, '.md5'))
|
18
18
|
end
|
19
19
|
|
@@ -25,7 +25,7 @@ module MetricFu
|
|
25
25
|
f.close
|
26
26
|
md5
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def file_changed?(path_to_file, base_dir)
|
30
30
|
orig_md5_file = md5_file(path_to_file, base_dir)
|
31
31
|
return !!track(path_to_file, base_dir) unless File.exist?(orig_md5_file)
|
@@ -35,7 +35,7 @@ module MetricFu
|
|
35
35
|
file.each_line { |line| current_md5 << line }
|
36
36
|
file.close
|
37
37
|
current_md5.chomp!
|
38
|
-
|
38
|
+
|
39
39
|
new_md5 = Digest::MD5.hexdigest(File.read(path_to_file))
|
40
40
|
new_md5.chomp!
|
41
41
|
|
@@ -43,7 +43,7 @@ module MetricFu
|
|
43
43
|
|
44
44
|
return new_md5 != current_md5
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def file_already_counted?(path_to_file)
|
48
48
|
return @@unchanged_md5s.include?(path_to_file)
|
49
49
|
end
|
data/lib/metric_fu.rb
CHANGED
@@ -1,14 +1,3 @@
|
|
1
|
-
|
2
|
-
TEMPLATE_DIR = File.join(File.dirname(__FILE__), "templates")
|
3
|
-
BASE_DIRECTORY = ENV['CC_BUILD_ARTIFACTS'] || 'tmp/metric_fu'
|
4
|
-
RAILS = File.exist?("config/environment.rb")
|
5
|
-
|
6
|
-
if RAILS
|
7
|
-
CODE_DIRS = ['app', 'lib']
|
8
|
-
else
|
9
|
-
CODE_DIRS = ['lib']
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
1
|
+
require File.join(File.dirname(__FILE__), 'metric_fu', 'base') #require first because of dependecies
|
13
2
|
require File.join(File.dirname(__FILE__), 'tasks', 'metric_fu')
|
14
3
|
Dir[File.join(File.dirname(__FILE__), 'metric_fu/*.rb')].each{|l| require l }
|
data/lib/tasks/churn.rake
CHANGED
data/lib/tasks/coverage.rake
CHANGED
@@ -13,10 +13,11 @@ begin
|
|
13
13
|
|
14
14
|
namespace :coverage do
|
15
15
|
rcov_output = COVERAGE_DIR
|
16
|
-
|
16
|
+
|
17
17
|
desc "Delete aggregate coverage data."
|
18
18
|
task(:clean) { rm_f("rcov_tmp", :verbose => false) }
|
19
|
-
|
19
|
+
|
20
|
+
desc "RCov task to generate report"
|
20
21
|
Spec::Rake::SpecTask.new(:do => :clean) do |t|
|
21
22
|
FileUtils.mkdir_p(MetricFu::BASE_DIRECTORY) unless File.directory?(MetricFu::BASE_DIRECTORY)
|
22
23
|
t.ruby_opts = ['-rtest/unit']
|
@@ -27,10 +28,10 @@ begin
|
|
27
28
|
t.rcov_dir = COVERAGE_DIR
|
28
29
|
end
|
29
30
|
end
|
30
|
-
|
31
|
-
desc "Generate
|
31
|
+
|
32
|
+
desc "Generate and open coverage report"
|
32
33
|
task :coverage => ['coverage:do'] do
|
33
|
-
system("open #{
|
34
|
+
system("open #{COVERAGE_DIR}/index.html") if PLATFORM['darwin']
|
34
35
|
end
|
35
36
|
end
|
36
37
|
rescue LoadError
|
@@ -38,5 +39,6 @@ rescue LoadError
|
|
38
39
|
puts 'running in jruby - rcov tasks not available'
|
39
40
|
else
|
40
41
|
puts 'sudo gem install rcov # if you want the rcov tasks'
|
42
|
+
|
41
43
|
end
|
42
44
|
end
|
data/lib/tasks/flay.rake
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
FLAY_DIR = File.join(MetricFu::BASE_DIRECTORY, 'flay')
|
2
|
+
|
3
|
+
namespace :metrics do
|
4
|
+
desc "Generate code duplication report with flay"
|
5
|
+
task :flay do
|
6
|
+
MetricFu::FlayReporter.generate_report(FLAY_DIR)
|
7
|
+
system("open #{FLAY_DIR}/index.html") if PLATFORM['darwin']
|
8
|
+
end
|
9
|
+
end
|
data/lib/tasks/flog.rake
CHANGED
@@ -10,40 +10,40 @@ begin
|
|
10
10
|
end
|
11
11
|
|
12
12
|
namespace :metrics do
|
13
|
-
|
13
|
+
|
14
14
|
task :flog => ['flog:all'] do
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
namespace :flog do
|
18
18
|
desc "Delete aggregate flog data."
|
19
19
|
task(:clean) { rm_rf(FLOG_DIR, :verbose => false) }
|
20
|
-
|
20
|
+
|
21
21
|
desc "Flog code in app/models"
|
22
22
|
task :models do
|
23
23
|
flog "models", "app/models"
|
24
24
|
end
|
25
25
|
|
26
|
-
desc "Flog code in app/controllers"
|
26
|
+
desc "Flog code in app/controllers"
|
27
27
|
task :controllers do
|
28
28
|
flog "controllers", "app/controllers"
|
29
29
|
end
|
30
30
|
|
31
|
-
desc "Flog code in app/helpers"
|
31
|
+
desc "Flog code in app/helpers"
|
32
32
|
task :helpers do
|
33
33
|
flog "helpers", "app/helpers"
|
34
34
|
end
|
35
35
|
|
36
|
-
desc "Flog code in lib"
|
36
|
+
desc "Flog code in lib"
|
37
37
|
task :lib do
|
38
38
|
flog "lib", "lib"
|
39
|
-
end
|
39
|
+
end
|
40
40
|
|
41
41
|
desc "Generate a flog report from specified directories"
|
42
42
|
task :custom do
|
43
43
|
MetricFu::CODE_DIRS.each { |directory| flog(directory, directory) }
|
44
44
|
MetricFu::FlogReporter::Generator.generate_report(FLOG_DIR)
|
45
|
-
end
|
46
|
-
|
45
|
+
end
|
46
|
+
|
47
47
|
desc "Generate and open flog report"
|
48
48
|
if MetricFu::RAILS
|
49
49
|
task :all => [:models, :controllers, :helpers, :lib] do
|
@@ -56,7 +56,7 @@ begin
|
|
56
56
|
system("open #{FLOG_DIR}/index.html") if PLATFORM['darwin']
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
end
|
61
61
|
|
62
62
|
end
|