flog 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,65 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minitest/spec'
3
- require 'ostruct'
4
-
5
- # must_be
6
- # must_be_close_to
7
- # must_be_empty
8
- # must_be_instance_of
9
- # must_be_kind_of
10
- # must_be_nil
11
- # must_be_same_as
12
- # must_be_within_delta
13
- # must_be_within_epsilon
14
- # must_equal
15
- # must_include
16
- # must_match
17
- # must_raise
18
- # must_respond_to
19
- # must_send
20
- # must_throw
21
-
22
- class MiniTest::Spec
23
- def self.currently(name, &block)
24
- it("*** CURRENTLY *** #{name}", &block)
25
- end
26
- end
27
-
28
- class Object # HACK - mocha blows
29
- def ignore(*args)
30
- self
31
- end
32
-
33
- # alias :returns :ignore
34
- alias :expects :ignore
35
- alias :with :ignore
36
- # alias :never :ignore
37
- # alias :raises :ignore
38
- # alias :times :ignore
39
-
40
- alias :stubs :ignore
41
-
42
- def stub(name, methods = {})
43
- o = OpenStruct.new
44
- methods.each do |k,v|
45
- o.send "#{k}=", v
46
- end
47
-
48
- o.puts = nil # HACK
49
- o
50
- end
51
- end
52
-
53
- class Proc # HACK - worthless
54
- def wont_raise_error *args
55
- call
56
- end
57
- end
58
-
59
- def fixture_files(paths)
60
- paths.collect do |path|
61
- File.expand_path(File.dirname(__FILE__) + '/../spec_fixtures/' + path)
62
- end
63
- end
64
-
65
- $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
data/unpack.rb DELETED
@@ -1,22 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
-
3
- code = '../code'
4
-
5
- pattern = ARGV.empty? ? nil : Regexp.union(*ARGV)
6
-
7
- Dir.mkdir code unless File.directory? code
8
-
9
- Dir.chdir code do
10
- Dir["../gems/*.gem"].each do |gem|
11
- project = File.basename gem
12
- next unless project =~ pattern if pattern
13
- dir = project.sub(/\.gem$/, '')
14
- warn dir
15
- unless File.directory? dir then
16
- Dir.mkdir dir
17
- Dir.chdir dir do
18
- system "(tar -Oxf ../#{gem} data.tar.gz | tar zxf -) 2> /dev/null"
19
- end
20
- end
21
- end
22
- end
@@ -1,245 +0,0 @@
1
- #!/usr/bin/env ruby -ws
2
-
3
- # Update the flog scores for a specific set of gems.
4
-
5
- $: << 'lib' << '../../ParseTree/dev/lib'
6
- $:.unshift File.expand_path("~/Work/svn/rubygems/lib")
7
-
8
- require 'yaml'
9
- require 'flog'
10
- require 'gem_updater'
11
-
12
- $u ||= false
13
- $f ||= false
14
-
15
- $score_file = '../dev/scores.yml'
16
- $misc_error = {:total => -1, :average => -1, :methods => {}}
17
- $syntax_error = {:total => -2, :average => -2, :methods => {}}
18
- $no_gem = {:total => -4, :average => -4, :methods => {}}
19
-
20
- max = (ARGV.shift || 10).to_i
21
-
22
- scores = YAML.load(File.read($score_file)) rescue {}
23
-
24
- ##
25
- # Save the scores in $score_file.
26
- #--
27
- # Creates a new file, then renames to overwrite the old one.
28
- # Wouldn't it be better to copy the old one, then create a new
29
- # one so you can do a diff?
30
- #++
31
-
32
- def save_scores scores
33
- File.open("#{$score_file}.new", 'w') do |f|
34
- warn "*** saving scores"
35
- YAML.dump scores, f
36
- end
37
- File.rename "#{$score_file}.new", $score_file
38
- end
39
-
40
- GemUpdater::stupid_gems.each do|p|
41
- scores[p] = $no_gem.dup
42
- end
43
-
44
- GemUpdater::initialize_dir
45
-
46
- if $u then
47
- GemUpdater.update_gem_tarballs
48
- exit 1
49
- end
50
-
51
- my_projects = Regexp.union("InlineFortran", "ParseTree", "RubyInline",
52
- "RubyToC", "ZenHacks", "ZenTest", "bfts",
53
- "box_layout", "flog", "heckle", "hoe",
54
- "image_science", "miniunit", "png", "ruby2ruby",
55
- "rubyforge", "vlad", "zentest")
56
-
57
- $owners = {}
58
-
59
- GemUpdater.get_latest_gems.each do |spec|
60
- name = spec.name
61
- owner = spec.authors.compact
62
- owner = Array(spec.email) if owner.empty?
63
- owner.map! { |o| o.sub(/\s*[^ \w@.].*$/, '') }
64
- owner = ["NOT Ryan Davis"] if owner.include? "Ryan Davis" and name !~ my_projects
65
-
66
- # because we screwed these up back before hoe
67
- owner << "Eric Hodel" if name =~ /bfts|RubyToC|ParseTree|heckle/
68
-
69
- $owners["#{spec.full_name}.tgz"] = owner.uniq || 'omg I have no idea'
70
- end
71
-
72
- def score_for dir
73
- files = `find #{dir} -name \\*.rb | grep -v gen.*templ`.split(/\n/)
74
-
75
- flogger = Flog.new
76
- flogger.flog_files files
77
- methods = flogger.totals.reject { |k,v| k =~ /\#none$/ }
78
- {
79
- :total => flogger.total,
80
- :size => methods.size,
81
- :average => flogger.average,
82
- :stddev => flogger.stddev,
83
- :methods => methods
84
- }
85
- rescue SyntaxError => e
86
- warn e.inspect + " at " + e.backtrace.first(5).join(', ') if $v
87
- $syntax_error.dup
88
- rescue => e
89
- warn e.inspect + " at " + e.backtrace.first(5).join(', ') if $v
90
- $misc_error.dup
91
- end
92
-
93
- # extract all the gems and process the data for them.
94
- begin
95
- dirty = false
96
- Dir.chdir "../gems" do
97
- Dir["*.tgz"].each_with_index do |gem, i|
98
- project = File.basename gem
99
- next if scores.has_key? project unless $f and scores[project][:total] < 0
100
- dirty = true
101
- begin
102
- warn gem
103
- dir = gem.sub(/\.tgz$/, '')
104
-
105
- system "tar -zmxf #{gem} 2> /dev/null"
106
-
107
- Dir.chdir dir do
108
- system "chmod -R a+r ."
109
- scores[project] = score_for(File.directory?('lib') ? 'lib' : '.')
110
- end
111
- ensure
112
- system "rm -rf #{dir}"
113
- end
114
- end
115
- end
116
- ensure
117
- save_scores scores if dirty
118
- end
119
-
120
- scores.reject! { |k,v| v[:total].nil? or v[:methods].empty? }
121
-
122
- class Hash
123
- def sorted_methods
124
- self[:methods].sort_by { |k,v| -v }
125
- end
126
- end
127
-
128
- class Array
129
- def sum
130
- sum = 0
131
- self.each { |i| sum += i }
132
- sum
133
- end
134
-
135
- def average
136
- return self.sum / self.length.to_f
137
- end
138
-
139
- def sample_variance
140
- avg = self.average
141
- sum = 0
142
- self.each { |i| sum += (i - avg) ** 2 }
143
- return (1 / self.length.to_f * sum)
144
- end
145
-
146
- def stddev
147
- return Math.sqrt(self.sample_variance)
148
- end
149
- end
150
-
151
- def title heading
152
- puts
153
- puts "#{heading}:"
154
- puts
155
- yield if block_given?
156
- end
157
-
158
- def report title, data
159
- max = data.map { |d| d.first.size }.max
160
-
161
- title "Top #{data.size} #{title}" if title
162
- data.each_with_index do |(n, c, a, s), i|
163
- puts "%4d: %-#{max}s: %4d methods, %8.2f +/- %8.2f flog" % [i + 1, n, c, a, s]
164
- end
165
- end
166
-
167
- project_numbers = scores.map { |k,v| [k, v[:methods].map {|_,n| n}.flatten] }
168
- project_stats = project_numbers.map { |k,v| [k, v.size, v.average, v.stddev] }
169
-
170
- title "Statistics" do
171
- flog_numbers = scores.map { |k,v| v[:total] }
172
- all_scores = scores.map { |k,v| v[:methods].values }.flatten
173
- method_counts = scores.map { |k,v| v[:size] }
174
-
175
- puts "total # gems : %8d" % scores.size
176
- puts "total # methods : %8d" % all_scores.size
177
- puts "avg methods / gem : %8.2f +/- %8.2f" % [method_counts.average, method_counts.stddev]
178
- puts "avg flog / project: %8.2f +/- %8.2f" % [flog_numbers.average, flog_numbers.stddev]
179
- puts "avg flog / method : %8.2f +/- %8.2f" % [all_scores.average, all_scores.stddev]
180
- end
181
-
182
- def report_worst section, data
183
- title section do
184
- max_size = data.map { |k| k.first.size }.max
185
- data.each_with_index do |(k,v), i|
186
- puts "%3d: %9.2f: %-#{max_size}s %s" % [i + 1, *yield(k, v)]
187
- end
188
- end
189
- end
190
-
191
- worst = scores.sort_by { |k,v| -v[:total] }.first(max)
192
- report_worst "Worst Projects EVAR", worst do |project, score|
193
- owner = $owners[project].join(', ') rescue nil
194
- raise "#{project} seems not to have an owner" if owner.nil?
195
- [score[:total], project, owner]
196
- end
197
-
198
- worst = {}
199
- scores.each do |long_name, spec|
200
- name = long_name.sub(/-(\d+\.)*\d+\.gem$/, '')
201
- spec[:methods].each do |method_name, score|
202
- worst[[name, method_name]] = score
203
- end
204
- end
205
-
206
- worst = worst.sort_by { |_,v| -v }.first(max)
207
-
208
- max_size = worst.map { |(name, meth), score| name.size }.max
209
- title "Worth Methods EVAR"
210
- worst.each_with_index do |((name, meth), score), i|
211
- puts "%3d: %9.2f: %-#{max_size}s %s" % [i + 1, score, name, meth]
212
- end
213
-
214
- report "Methods per Gem", project_stats.sort_by { |n, c, a, sd| -c }.first(max)
215
- report "Avg Flog / Method", project_stats.sort_by { |n, c, a, sd| -a }.first(max)
216
-
217
- $score_per_owner = Hash.new(0.0)
218
- $projects_per_owner = Hash.new { |h,k| h[k] = {} }
219
- $owners.each do |project, owners|
220
- next unless scores.has_key? project # bad project
221
- owners.each do |owner|
222
- score = scores[project][:total] || 1000000
223
- $projects_per_owner[owner][project] = score
224
- $score_per_owner[owner] += score
225
- end
226
- end
227
-
228
- def report_bad_people section
229
- title section
230
- bad_people = yield
231
- max_size = bad_people.map { |a| a.first.size }.max
232
- fmt = "%4d: %#{max_size}s: %2d projects %8.1f tot %8.1f avg"
233
- bad_people.each_with_index do |(name, projects), i|
234
- avg = projects.values.average
235
- puts fmt % [i + 1, name, projects.size, $score_per_owner[name], avg]
236
- end
237
- end
238
-
239
- report_bad_people "Top Flog Scores per Developer" do
240
- $projects_per_owner.sort_by { |k,v| -$score_per_owner[k] }.first(max)
241
- end
242
-
243
- report_bad_people "Most Prolific Developers" do |k,v|
244
- $projects_per_owner.sort_by { |k,v| [-v.size, -$score_per_owner[k]] }.first(max)
245
- end