hitimes 1.3.0-x64-mingw32
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.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +57 -0
- data/HISTORY.md +124 -0
- data/LICENSE +16 -0
- data/Manifest.txt +44 -0
- data/README.md +200 -0
- data/Rakefile +28 -0
- data/examples/benchmarks.rb +113 -0
- data/examples/stats.rb +31 -0
- data/ext/hitimes/c/extconf.rb +24 -0
- data/ext/hitimes/c/hitimes.c +37 -0
- data/ext/hitimes/c/hitimes_instant_clock_gettime.c +28 -0
- data/ext/hitimes/c/hitimes_instant_osx.c +45 -0
- data/ext/hitimes/c/hitimes_instant_windows.c +27 -0
- data/ext/hitimes/c/hitimes_interval.c +370 -0
- data/ext/hitimes/c/hitimes_interval.h +73 -0
- data/ext/hitimes/c/hitimes_stats.c +269 -0
- data/ext/hitimes/c/hitimes_stats.h +30 -0
- data/ext/hitimes/java/src/hitimes/Hitimes.java +66 -0
- data/ext/hitimes/java/src/hitimes/HitimesInterval.java +176 -0
- data/ext/hitimes/java/src/hitimes/HitimesService.java +16 -0
- data/ext/hitimes/java/src/hitimes/HitimesStats.java +112 -0
- data/lib/hitimes.rb +66 -0
- data/lib/hitimes/2.0/hitimes.so +0 -0
- data/lib/hitimes/2.1/hitimes.so +0 -0
- data/lib/hitimes/2.2/hitimes.so +0 -0
- data/lib/hitimes/2.3/hitimes.so +0 -0
- data/lib/hitimes/2.4/hitimes.so +0 -0
- data/lib/hitimes/2.5/hitimes.so +0 -0
- data/lib/hitimes/metric.rb +118 -0
- data/lib/hitimes/mutexed_stats.rb +32 -0
- data/lib/hitimes/paths.rb +53 -0
- data/lib/hitimes/stats.rb +58 -0
- data/lib/hitimes/timed_metric.rb +176 -0
- data/lib/hitimes/timed_value_metric.rb +233 -0
- data/lib/hitimes/value_metric.rb +71 -0
- data/lib/hitimes/version.rb +8 -0
- data/spec/hitimes_spec.rb +24 -0
- data/spec/interval_spec.rb +136 -0
- data/spec/metric_spec.rb +28 -0
- data/spec/mutex_stats_spec.rb +36 -0
- data/spec/paths_spec.rb +11 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/stats_spec.rb +98 -0
- data/spec/timed_metric_spec.rb +155 -0
- data/spec/timed_value_metric_spec.rb +171 -0
- data/spec/value_metric_spec.rb +108 -0
- data/spec/version_spec.rb +7 -0
- data/tasks/default.rake +242 -0
- data/tasks/extension.rake +38 -0
- data/tasks/this.rb +208 -0
- metadata +216 -0
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hitimes::TimedValueMetric do
|
4
|
+
before( :each ) do
|
5
|
+
@tm = Hitimes::TimedValueMetric.new( 'test-timed-value-metric' )
|
6
|
+
end
|
7
|
+
|
8
|
+
it "knows if it is running or not" do
|
9
|
+
@tm.running?.must_equal false
|
10
|
+
@tm.start
|
11
|
+
@tm.running?.must_equal true
|
12
|
+
@tm.stop( 1 )
|
13
|
+
@tm.running?.must_equal false
|
14
|
+
end
|
15
|
+
|
16
|
+
it "#split returns the last duration and the timer is still running" do
|
17
|
+
@tm.start
|
18
|
+
d = @tm.split( 1 )
|
19
|
+
@tm.running?.must_equal true
|
20
|
+
d.must_be :>, 0
|
21
|
+
@tm.value_stats.count.must_equal 1
|
22
|
+
@tm.timed_stats.count.must_equal 1
|
23
|
+
@tm.duration.must_equal d
|
24
|
+
end
|
25
|
+
|
26
|
+
it "#stop returns false if called more than once in a row" do
|
27
|
+
@tm.start
|
28
|
+
@tm.stop( 1 ).must_be :>, 0
|
29
|
+
@tm.stop( 1 ).must_equal false
|
30
|
+
end
|
31
|
+
|
32
|
+
it "does not count a currently running interval as an interval in calculations" do
|
33
|
+
@tm.start
|
34
|
+
@tm.value_stats.count.must_equal 0
|
35
|
+
@tm.timed_stats.count.must_equal 0
|
36
|
+
@tm.split( 1 )
|
37
|
+
@tm.value_stats.count.must_equal 1
|
38
|
+
@tm.timed_stats.count.must_equal 1
|
39
|
+
end
|
40
|
+
|
41
|
+
it "#split called on a stopped timer does nothing" do
|
42
|
+
@tm.start
|
43
|
+
@tm.stop( 1 )
|
44
|
+
@tm.split( 1 ).must_equal false
|
45
|
+
end
|
46
|
+
|
47
|
+
it "calculates the mean of the durations" do
|
48
|
+
3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop(x) }
|
49
|
+
@tm.timed_stats.mean.must_be_close_to(0.05, 0.01)
|
50
|
+
@tm.value_stats.mean.must_equal 1.00
|
51
|
+
end
|
52
|
+
|
53
|
+
it "calculates the rate of the counts " do
|
54
|
+
5.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
55
|
+
@tm.rate.must_be_close_to(40.0, 1.0)
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
it "calculates the stddev of the durations" do
|
60
|
+
3.times { |x| @tm.start ; sleep(0.05 * x) ; @tm.stop(x) }
|
61
|
+
@tm.timed_stats.stddev.must_be_close_to(0.05, 0.001)
|
62
|
+
@tm.value_stats.stddev.must_equal 1.0
|
63
|
+
end
|
64
|
+
|
65
|
+
it "returns 0.0 for stddev if there is no data" do
|
66
|
+
@tm.timed_stats.stddev.must_equal 0.0
|
67
|
+
@tm.value_stats.stddev.must_equal 0.0
|
68
|
+
end
|
69
|
+
|
70
|
+
it "keeps track of the min value" do
|
71
|
+
3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
72
|
+
@tm.timed_stats.min.must_be_close_to( 0.05, 0.003 )
|
73
|
+
@tm.value_stats.min.must_equal 0
|
74
|
+
end
|
75
|
+
|
76
|
+
it "keeps track of the max value" do
|
77
|
+
3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
78
|
+
@tm.timed_stats.max.must_be_close_to( 0.05, 0.003 )
|
79
|
+
@tm.value_stats.max.must_equal 2
|
80
|
+
end
|
81
|
+
|
82
|
+
it "keeps track of the sum value" do
|
83
|
+
3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
84
|
+
@tm.timed_stats.sum.must_be_close_to( 0.15, 0.01 )
|
85
|
+
@tm.value_stats.sum.must_equal 3
|
86
|
+
end
|
87
|
+
|
88
|
+
it "keeps track of the sum of squares value" do
|
89
|
+
3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
90
|
+
@tm.timed_stats.sumsq.must_be_close_to(0.0075, 0.0005)
|
91
|
+
@tm.value_stats.sumsq.must_equal 5
|
92
|
+
end
|
93
|
+
|
94
|
+
it "keeps track of the minimum start time of all the intervals" do
|
95
|
+
f1 = Time.now.gmtime.to_f * 1000000
|
96
|
+
5.times { @tm.start ; sleep 0.05 ; @tm.stop( 1 ) }
|
97
|
+
f2 = Time.now.gmtime.to_f * 1000000
|
98
|
+
@tm.sampling_start_time.must_be :>=, f1
|
99
|
+
@tm.sampling_start_time.must_be :<, f2
|
100
|
+
# distance from now to start time should be greater than the distance from
|
101
|
+
# the start to the min start_time
|
102
|
+
(f2 - @tm.sampling_start_time).must_be :>, ( @tm.sampling_start_time - f1 )
|
103
|
+
end
|
104
|
+
|
105
|
+
it "keeps track of the last stop time of all the intervals" do
|
106
|
+
f1 = Time.now.gmtime.to_f * 1_000_000
|
107
|
+
5.times { @tm.start ; sleep 0.05 ; @tm.stop( 1 ) }
|
108
|
+
sleep 0.05
|
109
|
+
f2 = Time.now.gmtime.to_f * 1_000_000
|
110
|
+
@tm.sampling_stop_time.must_be :>, f1
|
111
|
+
@tm.sampling_stop_time.must_be :<=, f2
|
112
|
+
# distance from now to max stop time time should be less than the distance
|
113
|
+
# from the start to the max stop time
|
114
|
+
(f2 - @tm.sampling_stop_time).must_be :<, ( @tm.sampling_stop_time - f1 )
|
115
|
+
end
|
116
|
+
|
117
|
+
it "can create an already running timer" do
|
118
|
+
t = Hitimes::TimedValueMetric.now( 'already-running' )
|
119
|
+
t.running?.must_equal true
|
120
|
+
end
|
121
|
+
|
122
|
+
it "can measure a block of code from an instance" do
|
123
|
+
t = Hitimes::TimedValueMetric.new( 'measure a block' )
|
124
|
+
3.times { t.measure( 1 ) { sleep 0.05 } }
|
125
|
+
t.duration.must_be_close_to(0.15, 0.004)
|
126
|
+
t.timed_stats.count.must_equal 3
|
127
|
+
t.value_stats.count.must_equal 3
|
128
|
+
end
|
129
|
+
|
130
|
+
it "returns the value of the block when measuring" do
|
131
|
+
t = Hitimes::TimedValueMetric.new( 'measure a block' )
|
132
|
+
x = t.measure( 42 ) { sleep 0.05; 42 }
|
133
|
+
t.duration.must_be_close_to(0.05, 0.002)
|
134
|
+
x.must_equal 42
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#to_hash" do
|
138
|
+
|
139
|
+
it "has name value" do
|
140
|
+
h = @tm.to_hash
|
141
|
+
h['name'].must_equal "test-timed-value-metric"
|
142
|
+
end
|
143
|
+
|
144
|
+
it "has an empty has for additional_data" do
|
145
|
+
h = @tm.to_hash
|
146
|
+
h['additional_data'].must_equal Hash.new
|
147
|
+
h['additional_data'].size.must_equal 0
|
148
|
+
end
|
149
|
+
|
150
|
+
it "has a rate" do
|
151
|
+
5.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
152
|
+
h = @tm.to_hash
|
153
|
+
h['rate'].must_be_close_to(40.0, 1.0)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "has a unit_count" do
|
157
|
+
5.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
158
|
+
h = @tm.to_hash
|
159
|
+
h['unit_count'].must_equal 10
|
160
|
+
end
|
161
|
+
|
162
|
+
fields = %w[ name additional_data sampling_start_time sampling_stop_time value_stats timed_stats rate unit_count ]
|
163
|
+
fields.each do |f|
|
164
|
+
it "has a value for #{f}" do
|
165
|
+
3.times { |x| @tm.measure(x) { sleep 0.001 } }
|
166
|
+
h = @tm.to_hash
|
167
|
+
h[f].wont_be_nil
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hitimes::ValueMetric do
|
4
|
+
before( :each ) do
|
5
|
+
@metric = Hitimes::ValueMetric.new( "testing" )
|
6
|
+
10.times { |x| @metric.measure( x ) }
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'has a name' do
|
10
|
+
@metric.name.must_equal "testing"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "has associated data from initialization" do
|
14
|
+
m = Hitimes::ValueMetric.new( "more-data", 'foo' => 'bar', 'this' => 'that' )
|
15
|
+
m.additional_data['foo'].must_equal 'bar'
|
16
|
+
m.additional_data['this'].must_equal 'that'
|
17
|
+
|
18
|
+
m = Hitimes::ValueMetric.new( "more-data", { 'foo' => 'bar', 'this' => 'that' } )
|
19
|
+
m.additional_data['foo'].must_equal 'bar'
|
20
|
+
m.additional_data['this'].must_equal 'that'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "calculates the mean of the measurements" do
|
24
|
+
@metric.mean.must_equal 4.5
|
25
|
+
end
|
26
|
+
|
27
|
+
it "calculates the stddev of the measurements" do
|
28
|
+
@metric.stddev.must_be :>, 0.0
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns 0.0 for stddev if there is no data" do
|
32
|
+
m = Hitimes::ValueMetric.new('0-data')
|
33
|
+
m.stddev.must_equal 0.0
|
34
|
+
end
|
35
|
+
|
36
|
+
it "keeps track of the sum of data" do
|
37
|
+
@metric.sum.must_equal 45.0
|
38
|
+
end
|
39
|
+
|
40
|
+
it "keeps track of the sum of squars of data" do
|
41
|
+
@metric.sumsq.must_equal 285.0
|
42
|
+
end
|
43
|
+
|
44
|
+
it "retuns 0.0 for mean if there is no data" do
|
45
|
+
Hitimes::ValueMetric.new('0-data').mean.must_equal 0.0
|
46
|
+
end
|
47
|
+
|
48
|
+
it "keeps track of the min value" do
|
49
|
+
@metric.min.must_equal 0
|
50
|
+
end
|
51
|
+
|
52
|
+
it "keeps track of the max value" do
|
53
|
+
@metric.max.must_equal 9
|
54
|
+
end
|
55
|
+
|
56
|
+
it "keeps track of the first start time of all the measurements" do
|
57
|
+
m = Hitimes::ValueMetric.new( "first-start-time" )
|
58
|
+
f1 = Time.now.gmtime.to_f * 1_000_000
|
59
|
+
10.times{ |x| m.measure( x ); sleep 0.1 }
|
60
|
+
f2 = Time.now.gmtime.to_f * 1_000_000
|
61
|
+
m.sampling_start_time.must_be :>=, f1
|
62
|
+
m.sampling_start_time.must_be :<, f2
|
63
|
+
# distance from now to start time should be greater than the distance from
|
64
|
+
# the start to the min start_time
|
65
|
+
(f2 - m.sampling_start_time).must_be :>, ( m.sampling_start_time - f1 )
|
66
|
+
end
|
67
|
+
|
68
|
+
it "keeps track of the last stop time of all the intervals" do
|
69
|
+
m = Hitimes::ValueMetric.new( "last-stop-time" )
|
70
|
+
f1 = Time.now.gmtime.to_f * 1_000_000
|
71
|
+
10.times {|x| m.measure( x ); sleep 0.1 }
|
72
|
+
f2 = Time.now.gmtime.to_f * 1_000_000
|
73
|
+
m.sampling_stop_time.must_be :>, f1
|
74
|
+
m.sampling_stop_time.must_be :<=, f2
|
75
|
+
# distance from now to max stop time time should be less than the distance
|
76
|
+
# from the start to the max stop time
|
77
|
+
(f2 - m.sampling_stop_time).must_be :<, ( m.sampling_stop_time - f1 )
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#to_hash" do
|
81
|
+
|
82
|
+
it "has name value" do
|
83
|
+
h = @metric.to_hash
|
84
|
+
h['name'].must_equal "testing"
|
85
|
+
end
|
86
|
+
|
87
|
+
it "has an empty has for additional_data" do
|
88
|
+
h = @metric.to_hash
|
89
|
+
h['additional_data'].must_equal Hash.new
|
90
|
+
h['additional_data'].size.must_equal 0
|
91
|
+
end
|
92
|
+
|
93
|
+
it "has the right sum" do
|
94
|
+
h = @metric.to_hash
|
95
|
+
h['sum'].must_equal 45
|
96
|
+
end
|
97
|
+
|
98
|
+
fields = ::Hitimes::Stats::STATS.dup + %w[ name additional_data sampling_start_time sampling_stop_time ]
|
99
|
+
fields = fields - [ 'rate' ]
|
100
|
+
fields.each do |f|
|
101
|
+
it "has a value for #{f}" do
|
102
|
+
h = @metric.to_hash
|
103
|
+
h[f].wont_be_nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
data/tasks/default.rake
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
# vim: syntax=ruby
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'digest'
|
4
|
+
#------------------------------------------------------------------------------
|
5
|
+
# If you want to Develop on this project just run 'rake develop' and you'll
|
6
|
+
# have all you need to get going. If you want to use bundler for development,
|
7
|
+
# then run 'rake develop:using_bundler'
|
8
|
+
#------------------------------------------------------------------------------
|
9
|
+
namespace :develop do
|
10
|
+
|
11
|
+
# Install all the development and runtime dependencies of this gem using the
|
12
|
+
# gemspec.
|
13
|
+
task :default => 'Gemfile' do
|
14
|
+
require 'rubygems/dependency_installer'
|
15
|
+
installer = ::Gem::DependencyInstaller.new
|
16
|
+
puts "Installing bundler..."
|
17
|
+
installer.install 'bundler'
|
18
|
+
sh 'bundle install'
|
19
|
+
puts "\n\nNow run 'rake test'"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Create a Gemfile that just references the gemspec
|
23
|
+
file 'Gemfile' => :gemspec do
|
24
|
+
File.open( "Gemfile", "w+" ) do |f|
|
25
|
+
f.puts "# DO NOT EDIT - This file is automatically generated"
|
26
|
+
f.puts "# Make changes to Manifest.txt and/or Rakefile and regenerate"
|
27
|
+
f.puts 'source "https://rubygems.org"'
|
28
|
+
f.puts 'gemspec'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
desc "Bootstrap development"
|
33
|
+
task :develop => "develop:default"
|
34
|
+
|
35
|
+
#------------------------------------------------------------------------------
|
36
|
+
# Minitest - standard TestTask
|
37
|
+
#------------------------------------------------------------------------------
|
38
|
+
begin
|
39
|
+
require 'rake/testtask'
|
40
|
+
Rake::TestTask.new( :test ) do |t|
|
41
|
+
t.ruby_opts = %w[ -w ]
|
42
|
+
t.libs = %w[ lib spec test ]
|
43
|
+
t.pattern = "{test,spec}/**/{test_*,*_spec}.rb"
|
44
|
+
end
|
45
|
+
|
46
|
+
task :test_requirements
|
47
|
+
task :test => :test_requirements
|
48
|
+
task :default => :test
|
49
|
+
rescue LoadError
|
50
|
+
This.task_warning( 'test' )
|
51
|
+
end
|
52
|
+
|
53
|
+
#------------------------------------------------------------------------------
|
54
|
+
# RDoc - standard rdoc rake task, although we must make sure to use a more
|
55
|
+
# recent version of rdoc since it is the one that has 'tomdoc' markup
|
56
|
+
#------------------------------------------------------------------------------
|
57
|
+
begin
|
58
|
+
gem 'rdoc' # otherwise we get the wrong task from stdlib
|
59
|
+
require 'rdoc/task'
|
60
|
+
RDoc::Task.new do |t|
|
61
|
+
t.markup = 'tomdoc'
|
62
|
+
t.rdoc_dir = 'doc'
|
63
|
+
t.main = 'README.md'
|
64
|
+
t.title = "#{This.name} #{This.version}"
|
65
|
+
t.rdoc_files.include( FileList['*.{rdoc,md,txt}'], FileList['ext/**/*.c'],
|
66
|
+
FileList['lib/**/*.rb'] )
|
67
|
+
end
|
68
|
+
rescue StandardError, LoadError
|
69
|
+
This.task_warning( 'rdoc' )
|
70
|
+
end
|
71
|
+
|
72
|
+
#------------------------------------------------------------------------------
|
73
|
+
# Coverage - optional code coverage, rcov for 1.8 and simplecov for 1.9, so
|
74
|
+
# for the moment only rcov is listed.
|
75
|
+
#------------------------------------------------------------------------------
|
76
|
+
begin
|
77
|
+
require 'simplecov'
|
78
|
+
desc 'Run tests with code coverage'
|
79
|
+
task :coverage do
|
80
|
+
ENV['COVERAGE'] = 'true'
|
81
|
+
Rake::Task[:test].execute
|
82
|
+
end
|
83
|
+
CLOBBER << 'coverage' if File.directory?( 'coverage' )
|
84
|
+
rescue LoadError
|
85
|
+
This.task_warning( 'simplecov' )
|
86
|
+
end
|
87
|
+
|
88
|
+
#------------------------------------------------------------------------------
|
89
|
+
# Manifest - We want an explicit list of thos files that are to be packaged in
|
90
|
+
# the gem. Most of this is from Hoe.
|
91
|
+
#------------------------------------------------------------------------------
|
92
|
+
namespace 'manifest' do
|
93
|
+
desc "Check the manifest"
|
94
|
+
task :check => :clean do
|
95
|
+
files = FileList["**/*", ".*"].exclude( This.exclude_from_manifest ).to_a.sort
|
96
|
+
files = files.select{ |f| File.file?( f ) }
|
97
|
+
|
98
|
+
tmp = "Manifest.tmp"
|
99
|
+
File.open( tmp, 'w' ) do |f|
|
100
|
+
f.puts files.join("\n")
|
101
|
+
end
|
102
|
+
|
103
|
+
begin
|
104
|
+
sh "diff -du Manifest.txt #{tmp}"
|
105
|
+
ensure
|
106
|
+
rm tmp
|
107
|
+
end
|
108
|
+
puts "Manifest looks good"
|
109
|
+
end
|
110
|
+
|
111
|
+
desc "Generate the manifest"
|
112
|
+
task :generate => :clean do
|
113
|
+
files = %x[ git ls-files ].split("\n").sort
|
114
|
+
files.reject! { |f| f =~ This.exclude_from_manifest }
|
115
|
+
File.open( "Manifest.txt", "w" ) do |f|
|
116
|
+
f.puts files.join("\n")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
#------------------------------------------------------------------------------
|
122
|
+
# Fixme - look for fixmes and report them
|
123
|
+
#------------------------------------------------------------------------------
|
124
|
+
namespace :fixme do
|
125
|
+
task :default => 'manifest:check' do
|
126
|
+
This.manifest.each do |file|
|
127
|
+
next if file == __FILE__
|
128
|
+
next unless file =~ %r/(txt|rb|md|rdoc|css|html|xml|css)\Z/
|
129
|
+
puts "FIXME: Rename #{file}" if file =~ /fixme/i
|
130
|
+
IO.readlines( file ).each_with_index do |line, idx|
|
131
|
+
prefix = "FIXME: #{file}:#{idx+1}".ljust(42)
|
132
|
+
puts "#{prefix} => #{line.strip}" if line =~ /fixme/i
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def fixme_project_root
|
138
|
+
This.project_path( '../fixme' )
|
139
|
+
end
|
140
|
+
|
141
|
+
def fixme_project_path( subtree )
|
142
|
+
fixme_project_root.join( subtree )
|
143
|
+
end
|
144
|
+
|
145
|
+
def local_fixme_files
|
146
|
+
This.manifest.select { |p| p =~ %r|^tasks/| }
|
147
|
+
end
|
148
|
+
|
149
|
+
def outdated_fixme_files
|
150
|
+
local_fixme_files.select do |local|
|
151
|
+
upstream = fixme_project_path( local )
|
152
|
+
upstream.exist? &&
|
153
|
+
( Digest::SHA256.file( local ) != Digest::SHA256.file( upstream ) )
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def fixme_up_to_date?
|
158
|
+
outdated_fixme_files.empty?
|
159
|
+
end
|
160
|
+
|
161
|
+
desc "See if the fixme tools are outdated"
|
162
|
+
task :outdated => :release_check do
|
163
|
+
if fixme_up_to_date? then
|
164
|
+
puts "Fixme files are up to date."
|
165
|
+
else
|
166
|
+
outdated_fixme_files.each do |f|
|
167
|
+
puts "#{f} is outdated"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
desc "Update outdated fixme files"
|
173
|
+
task :update => :release_check do
|
174
|
+
if fixme_up_to_date? then
|
175
|
+
puts "Fixme files are already up to date."
|
176
|
+
else
|
177
|
+
puts "Updating fixme files:"
|
178
|
+
outdated_fixme_files.each do |local|
|
179
|
+
upstream = fixme_project_path( local )
|
180
|
+
puts " * #{local}"
|
181
|
+
FileUtils.cp( upstream, local )
|
182
|
+
end
|
183
|
+
puts "Use your git commands as appropriate."
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
desc "Look for fixmes and report them"
|
188
|
+
task :fixme => "fixme:default"
|
189
|
+
|
190
|
+
#------------------------------------------------------------------------------
|
191
|
+
# Gem Specification
|
192
|
+
#------------------------------------------------------------------------------
|
193
|
+
# Really this is only here to support those who use bundler
|
194
|
+
desc "Build the #{This.name}.gemspec file"
|
195
|
+
task :gemspec do
|
196
|
+
File.open( This.gemspec_file, "wb+" ) do |f|
|
197
|
+
f.puts "# DO NOT EDIT - This file is automatically generated"
|
198
|
+
f.puts "# Make changes to Manifest.txt and/or Rakefile and regenerate"
|
199
|
+
f.write This.platform_gemspec.to_ruby
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
# .rbc files from ruby 2.0
|
204
|
+
CLOBBER << FileList["**/*.rbc"]
|
205
|
+
|
206
|
+
# The standard gem packaging task, everyone has it.
|
207
|
+
require 'rubygems/package_task'
|
208
|
+
::Gem::PackageTask.new( This.platform_gemspec ) do
|
209
|
+
# nothing
|
210
|
+
end
|
211
|
+
|
212
|
+
#------------------------------------------------------------------------------
|
213
|
+
# Release - the steps we go through to do a final release, this is pulled from
|
214
|
+
# a compbination of mojombo's rakegem, hoe and hoe-git
|
215
|
+
#
|
216
|
+
# 1) make sure we are on the master branch
|
217
|
+
# 2) make sure there are no uncommitted items
|
218
|
+
# 3) check the manifest and make sure all looks good
|
219
|
+
# 4) build the gem
|
220
|
+
# 5) do an empty commit to have the commit message of the version
|
221
|
+
# 6) tag that commit as the version
|
222
|
+
# 7) push master
|
223
|
+
# 8) push the tag
|
224
|
+
# 7) pus the gem
|
225
|
+
#------------------------------------------------------------------------------
|
226
|
+
task :release_check do
|
227
|
+
unless `git branch` =~ /^\* master$/
|
228
|
+
abort "You must be on the master branch to release!"
|
229
|
+
end
|
230
|
+
unless `git status` =~ /^nothing to commit/m
|
231
|
+
abort "Nope, sorry, you have unfinished business"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
desc "Create tag v#{This.version}, build and push #{This.platform_gemspec.full_name} to rubygems.org"
|
236
|
+
task :release => [ :release_check, 'manifest:check', :gem ] do
|
237
|
+
sh "git commit --allow-empty -a -m 'Release #{This.version}'"
|
238
|
+
sh "git tag -a -m 'v#{This.version}' v#{This.version}"
|
239
|
+
sh "git push origin master"
|
240
|
+
sh "git push origin v#{This.version}"
|
241
|
+
sh "gem push pkg/#{This.platform_gemspec.full_name}.gem"
|
242
|
+
end
|