flog 2.2.0 → 2.3.0

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