kjess 1.1.0 → 1.2.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.
- checksums.yaml +15 -0
- data/{HISTORY.rdoc → HISTORY.md} +9 -3
- data/Manifest.txt +5 -2
- data/{README.rdoc → README.md} +9 -9
- data/Rakefile +5 -334
- data/lib/kjess.rb +1 -1
- data/lib/kjess/client.rb +4 -4
- data/lib/kjess/connection.rb +38 -7
- data/lib/kjess/error.rb +5 -2
- data/lib/kjess/response/error.rb +1 -1
- data/lib/kjess/response/stats.rb +1 -1
- data/lib/kjess/socket.rb +19 -10
- data/spec/client_spec.rb +3 -3
- data/spec/connection_spec.rb +15 -0
- data/tasks/default.rake +271 -0
- data/tasks/this.rb +209 -0
- metadata +17 -24
data/lib/kjess.rb
CHANGED
data/lib/kjess/client.rb
CHANGED
@@ -65,7 +65,7 @@ module KJess
|
|
65
65
|
v = KJess::Request::Version.new
|
66
66
|
r = send_recv( v )
|
67
67
|
return r.version if Response::Version === r
|
68
|
-
raise KJess::
|
68
|
+
raise KJess::ProtocolError, "Unexpected Response from VERSION command"
|
69
69
|
end
|
70
70
|
|
71
71
|
# Public: Add an item to the given queue
|
@@ -98,7 +98,7 @@ module KJess
|
|
98
98
|
g = KJess::Request::Get.new( opts )
|
99
99
|
|
100
100
|
if opts[:wait_for]
|
101
|
-
wait_for_in_seconds = opts[:wait_for] / 1000
|
101
|
+
wait_for_in_seconds = Float(opts[:wait_for]) / 1000.0
|
102
102
|
else
|
103
103
|
wait_for_in_seconds = 0.1
|
104
104
|
end
|
@@ -236,7 +236,7 @@ module KJess
|
|
236
236
|
# Returns a String.
|
237
237
|
def status( update_to = nil )
|
238
238
|
resp = send_recv( KJess::Request::Status.new( :update_to => update_to ) )
|
239
|
-
raise KJess::
|
239
|
+
raise KJess::ProtocolError, "Status command is not supported" if KJess::Response::ClientError === resp
|
240
240
|
return resp.message
|
241
241
|
end
|
242
242
|
|
@@ -256,7 +256,7 @@ module KJess
|
|
256
256
|
# Returns a Hash
|
257
257
|
def stats!
|
258
258
|
stats = send_recv( KJess::Request::Stats.new )
|
259
|
-
raise KJess::
|
259
|
+
raise KJess::ProtocolError, "Problem receiving stats: #{stats.inspect}" unless KJess::Response::Stats === stats
|
260
260
|
|
261
261
|
h = stats.data
|
262
262
|
dump_stats = send_recv( KJess::Request::DumpStats.new )
|
data/lib/kjess/connection.rb
CHANGED
@@ -7,16 +7,39 @@ require 'kjess/socket'
|
|
7
7
|
module KJess
|
8
8
|
# Connection
|
9
9
|
class Connection
|
10
|
-
class Error < KJess::
|
10
|
+
class Error < KJess::NetworkError; end
|
11
|
+
|
12
|
+
# Public: Set a socket factory
|
13
|
+
#
|
14
|
+
# factory - an object that responds to #call(options) where options is
|
15
|
+
# a Hash.
|
16
|
+
#
|
17
|
+
# returns nothing
|
18
|
+
def self.socket_factory=(factory)
|
19
|
+
@socket_factory = factory
|
20
|
+
end
|
21
|
+
|
22
|
+
# Public: Return the socket factory
|
23
|
+
#
|
24
|
+
def self.socket_factory
|
25
|
+
@socket_factory ||= nil
|
26
|
+
@socket_factory.respond_to?(:call) ? @socket_factory : default_socket_factory
|
27
|
+
end
|
28
|
+
|
29
|
+
# Internal: Returns the default socket factory
|
30
|
+
#
|
31
|
+
def self.default_socket_factory
|
32
|
+
lambda { |options| KJess::Socket.connect(options) }
|
33
|
+
end
|
11
34
|
|
12
35
|
# Public: The hostname/ip address to connect to.
|
13
36
|
def host
|
14
|
-
|
37
|
+
@options[:host]
|
15
38
|
end
|
16
39
|
|
17
40
|
# Public: The port number to connect to. Default 22133
|
18
41
|
def port
|
19
|
-
|
42
|
+
@options[:port]
|
20
43
|
end
|
21
44
|
|
22
45
|
# Public: The timeout for connecting in seconds. Defaults to 2
|
@@ -95,10 +118,12 @@ module KJess
|
|
95
118
|
def socket
|
96
119
|
close if @pid && @pid != Process.pid
|
97
120
|
return @socket if @socket and not @socket.closed?
|
98
|
-
@socket =
|
121
|
+
@socket = self.class.socket_factory.call(@options)
|
99
122
|
@pid = Process.pid
|
100
123
|
@read_buffer = ''
|
101
124
|
return @socket
|
125
|
+
rescue => e
|
126
|
+
raise Error, "Could not connect to #{host}:#{port}: #{e.class}: #{e.message}", e.backtrace
|
102
127
|
end
|
103
128
|
|
104
129
|
# Internal: close the socket if it is not already closed
|
@@ -127,9 +152,12 @@ module KJess
|
|
127
152
|
def write( msg )
|
128
153
|
$stderr.puts "--> #{msg}" if $DEBUG
|
129
154
|
socket.write( msg )
|
130
|
-
rescue KJess::
|
155
|
+
rescue KJess::NetworkError
|
131
156
|
close
|
132
157
|
raise
|
158
|
+
rescue => e
|
159
|
+
close
|
160
|
+
raise Error, "Could not write to #{host}:#{port}: #{e.class}: #{e.message}", e.backtrace
|
133
161
|
end
|
134
162
|
|
135
163
|
# Internal: read a single line from the socket
|
@@ -148,7 +176,7 @@ module KJess
|
|
148
176
|
break unless line.strip.length == 0
|
149
177
|
end
|
150
178
|
return line
|
151
|
-
rescue KJess::
|
179
|
+
rescue KJess::NetworkError
|
152
180
|
close
|
153
181
|
raise
|
154
182
|
rescue EOFError
|
@@ -173,9 +201,12 @@ module KJess
|
|
173
201
|
|
174
202
|
$stderr.puts "<-- #{result}" if $DEBUG
|
175
203
|
return result
|
176
|
-
rescue KJess::
|
204
|
+
rescue KJess::NetworkError
|
177
205
|
close
|
178
206
|
raise
|
207
|
+
rescue => e
|
208
|
+
close
|
209
|
+
raise Error, "Could not read from #{host}:#{port}: #{e.class}: #{e.message}", e.backtrace
|
179
210
|
end
|
180
211
|
end
|
181
212
|
end
|
data/lib/kjess/error.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
module KJess
|
2
2
|
class Error < ::StandardError; end
|
3
|
-
class
|
4
|
-
|
3
|
+
class NetworkError < Error; end
|
4
|
+
|
5
|
+
class ProtocolError < Error; end
|
6
|
+
class ClientError < ProtocolError; end
|
7
|
+
class ServerError < ProtocolError; end
|
5
8
|
end
|
data/lib/kjess/response/error.rb
CHANGED
data/lib/kjess/response/stats.rb
CHANGED
data/lib/kjess/socket.rb
CHANGED
@@ -3,7 +3,7 @@ require 'socket'
|
|
3
3
|
module KJess
|
4
4
|
# Socket: A specialized socket that has been configure
|
5
5
|
class Socket
|
6
|
-
class Error < KJess::
|
6
|
+
class Error < KJess::NetworkError; end
|
7
7
|
class Timeout < Error; end
|
8
8
|
|
9
9
|
# Internal:
|
@@ -21,7 +21,7 @@ module KJess
|
|
21
21
|
# Internal:
|
22
22
|
# The host this socket is connected to
|
23
23
|
attr_reader :host
|
24
|
-
|
24
|
+
|
25
25
|
# Internal:
|
26
26
|
# The port this socket is connected to
|
27
27
|
attr_reader :port
|
@@ -98,7 +98,7 @@ module KJess
|
|
98
98
|
end
|
99
99
|
|
100
100
|
# Internal: Low level socket allocation and option configuration
|
101
|
-
#
|
101
|
+
#
|
102
102
|
# Using the options from the initializer, a new ::Socket is created that
|
103
103
|
# is:
|
104
104
|
#
|
@@ -167,12 +167,12 @@ module KJess
|
|
167
167
|
conn_error = lambda { raise errors.first }
|
168
168
|
sock = nil
|
169
169
|
|
170
|
-
addrs.find( conn_error ) do |addr|
|
170
|
+
addrs.find( conn_error ) do |addr|
|
171
171
|
sock = connect_or_error( addr, deadline, errors )
|
172
172
|
end
|
173
173
|
return sock
|
174
174
|
end
|
175
|
-
|
175
|
+
|
176
176
|
# Internal: Connect to the destination or raise an error.
|
177
177
|
#
|
178
178
|
# Connect to the address or capture the error of the connection
|
@@ -208,7 +208,7 @@ module KJess
|
|
208
208
|
sock.connect_nonblock( sockaddr )
|
209
209
|
return sock
|
210
210
|
rescue Errno::EINPROGRESS
|
211
|
-
if
|
211
|
+
if !wait_writable(timeout, sock)
|
212
212
|
raise Timeout, "Could not connect to #{host}:#{port} within #{timeout} seconds"
|
213
213
|
end
|
214
214
|
return connect_nonblock_finalize( sock, sockaddr )
|
@@ -218,12 +218,13 @@ module KJess
|
|
218
218
|
|
219
219
|
|
220
220
|
# Internal: Make sure that a non-blocking connect has truely connected.
|
221
|
-
#
|
221
|
+
#
|
222
222
|
# Ensure that the given socket is actually connected to the given adddress.
|
223
223
|
#
|
224
224
|
# Returning the socket if it is and raising an Error if it isn't.
|
225
225
|
def connect_nonblock_finalize( sock, sockaddr )
|
226
226
|
sock.connect_nonblock( sockaddr )
|
227
|
+
return sock
|
227
228
|
rescue Errno::EISCONN
|
228
229
|
return sock
|
229
230
|
rescue => ex
|
@@ -260,7 +261,7 @@ module KJess
|
|
260
261
|
def readpartial(maxlen, outbuf = nil)
|
261
262
|
return socket.read_nonblock(maxlen, outbuf)
|
262
263
|
rescue Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNRESET
|
263
|
-
if
|
264
|
+
if wait_readable(read_timeout)
|
264
265
|
retry
|
265
266
|
else
|
266
267
|
raise Timeout, "Could not read from #{host}:#{port} in #{read_timeout} seconds"
|
@@ -276,16 +277,24 @@ module KJess
|
|
276
277
|
#
|
277
278
|
# returns nothing
|
278
279
|
def write( buf )
|
279
|
-
until buf.length == 0
|
280
|
+
until buf.nil? or (buf.length == 0) do
|
280
281
|
written = socket.write_nonblock(buf)
|
281
282
|
buf = buf[written, buf.length]
|
282
283
|
end
|
283
284
|
rescue Errno::EWOULDBLOCK, Errno::EINTR, Errno::EAGAIN, Errno::ECONNRESET
|
284
|
-
if
|
285
|
+
if wait_writable(write_timeout)
|
285
286
|
retry
|
286
287
|
else
|
287
288
|
raise Timeout, "Could not write to #{host}:#{port} in #{write_timeout} seconds"
|
288
289
|
end
|
289
290
|
end
|
291
|
+
|
292
|
+
def wait_writable(timeout = nil, socket = @socket)
|
293
|
+
IO.select(nil, [socket], nil, timeout || write_timeout)
|
294
|
+
end
|
295
|
+
|
296
|
+
def wait_readable(timeout = nil, socket = @socket)
|
297
|
+
IO.select([socket], nil, nil, timeout || read_timeout)
|
298
|
+
end
|
290
299
|
end
|
291
300
|
end
|
data/spec/client_spec.rb
CHANGED
@@ -128,7 +128,7 @@ describe KJess::Client do
|
|
128
128
|
@client.set( "get_q", "get item 1" )
|
129
129
|
@client.set( "get_q", "get item 2" )
|
130
130
|
@client.reserve( "get_q" )
|
131
|
-
lambda { @client.get( "get_q" ) }.must_raise KJess::
|
131
|
+
lambda { @client.get( "get_q" ) }.must_raise KJess::ClientError
|
132
132
|
end
|
133
133
|
|
134
134
|
end
|
@@ -292,14 +292,14 @@ describe KJess::Client do
|
|
292
292
|
describe "connecting to a server on a port that isn't listening" do
|
293
293
|
it "throws an exception" do
|
294
294
|
c = KJess::Connection.new '127.0.0.1', 65521
|
295
|
-
lambda { c.socket }.must_raise KJess::
|
295
|
+
lambda { c.socket }.must_raise KJess::Connection::Error
|
296
296
|
end
|
297
297
|
end
|
298
298
|
|
299
299
|
describe "connecting to a server that isn't responding" do
|
300
300
|
it "throws an exception" do
|
301
301
|
c = KJess::Connection.new '127.1.1.1', 65521, :timeout => 0.5
|
302
|
-
lambda { c.socket }.must_raise KJess::
|
302
|
+
lambda { c.socket }.must_raise KJess::Connection::Error
|
303
303
|
end
|
304
304
|
end
|
305
305
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe KJess::Connection do
|
4
|
+
|
5
|
+
it "Returns a callable for the factory" do
|
6
|
+
KJess::Connection.socket_factory.respond_to?(:call).must_equal true
|
7
|
+
end
|
8
|
+
|
9
|
+
it "Default Factory returns a KJess::Socket" do
|
10
|
+
factory = KJess::Connection.socket_factory
|
11
|
+
s = factory.call( :port => KJess::Spec.memcache_port, :host => 'localhost' )
|
12
|
+
s.instance_of?(KJess::Socket).must_equal true
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/tasks/default.rake
ADDED
@@ -0,0 +1,271 @@
|
|
1
|
+
# vim: syntax=ruby
|
2
|
+
require 'rake/clean'
|
3
|
+
#------------------------------------------------------------------------------
|
4
|
+
# If you want to Develop on this project just run 'rake develop' and you'll
|
5
|
+
# have all you need to get going. If you want to use bundler for development,
|
6
|
+
# then run 'rake develop:using_bundler'
|
7
|
+
#------------------------------------------------------------------------------
|
8
|
+
namespace :develop do
|
9
|
+
|
10
|
+
# Install all the development and runtime dependencies of this gem using the
|
11
|
+
# gemspec.
|
12
|
+
task :default do
|
13
|
+
require 'rubygems/dependency_installer'
|
14
|
+
installer = Gem::DependencyInstaller.new
|
15
|
+
|
16
|
+
This.set_coverage_gem
|
17
|
+
|
18
|
+
puts "Installing gem depedencies needed for development"
|
19
|
+
This.platform_gemspec.dependencies.each do |dep|
|
20
|
+
if dep.matching_specs.empty? then
|
21
|
+
puts "Installing : #{dep}"
|
22
|
+
installer.install dep
|
23
|
+
else
|
24
|
+
puts "Skipping : #{dep} -> already installed #{dep.matching_specs.first.full_name}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
puts "\n\nNow run 'rake test'"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Create a Gemfile that just references the gemspec
|
31
|
+
file 'Gemfile' => :gemspec do
|
32
|
+
File.open( "Gemfile", "w+" ) do |f|
|
33
|
+
f.puts 'source :rubygems'
|
34
|
+
f.puts 'gemspec'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Create a bundler Gemfile"
|
39
|
+
task :using_bundler => 'Gemfile' do
|
40
|
+
puts "Now you can 'bundle'"
|
41
|
+
end
|
42
|
+
|
43
|
+
# Gemfiles are build artifacts
|
44
|
+
CLOBBER << FileList['Gemfile*']
|
45
|
+
end
|
46
|
+
desc "Boostrap development"
|
47
|
+
task :develop => "develop:default"
|
48
|
+
|
49
|
+
#------------------------------------------------------------------------------
|
50
|
+
# Minitest - standard TestTask
|
51
|
+
#------------------------------------------------------------------------------
|
52
|
+
begin
|
53
|
+
require 'rake/testtask'
|
54
|
+
Rake::TestTask.new( :test ) do |t|
|
55
|
+
t.ruby_opts = %w[ -w -rubygems ]
|
56
|
+
t.libs = %w[ lib spec ]
|
57
|
+
t.pattern = "spec/**/*_spec.rb"
|
58
|
+
end
|
59
|
+
|
60
|
+
task :test_requirements
|
61
|
+
task :test => :test_requirements
|
62
|
+
task :default => :test
|
63
|
+
rescue LoadError
|
64
|
+
This.task_warning( 'test' )
|
65
|
+
end
|
66
|
+
|
67
|
+
#------------------------------------------------------------------------------
|
68
|
+
# RDoc - standard rdoc rake task, although we must make sure to use a more
|
69
|
+
# recent version of rdoc since it is the one that has 'tomdoc' markup
|
70
|
+
#------------------------------------------------------------------------------
|
71
|
+
begin
|
72
|
+
gem 'rdoc' # otherwise we get the wrong task from stdlib
|
73
|
+
require 'rdoc/task'
|
74
|
+
RDoc::Task.new do |t|
|
75
|
+
t.markup = 'tomdoc'
|
76
|
+
t.rdoc_dir = 'doc'
|
77
|
+
t.main = 'README.md'
|
78
|
+
t.title = "#{This.name} #{This.version}"
|
79
|
+
t.rdoc_files.include( FileList['*.{rdoc,md,txt}'], FileList['ext/**/*.c'],
|
80
|
+
FileList['lib/**/*.rb'] )
|
81
|
+
end
|
82
|
+
rescue StandardError, LoadError
|
83
|
+
This.task_warning( 'rdoc' )
|
84
|
+
end
|
85
|
+
|
86
|
+
#------------------------------------------------------------------------------
|
87
|
+
# Coverage - optional code coverage, rcov for 1.8 and simplecov for 1.9, so
|
88
|
+
# for the moment only rcov is listed.
|
89
|
+
#------------------------------------------------------------------------------
|
90
|
+
if RUBY_VERSION < "1.9.0"
|
91
|
+
begin
|
92
|
+
require 'rcov/rcovtask'
|
93
|
+
Rcov::RcovTask.new( 'coverage' ) do |t|
|
94
|
+
t.libs << 'spec'
|
95
|
+
t.pattern = 'spec/**/*_spec.rb'
|
96
|
+
t.verbose = true
|
97
|
+
t.rcov_opts << "-x ^/" # remove all the global files
|
98
|
+
t.rcov_opts << "--sort coverage" # so we see the worst files at the top
|
99
|
+
end
|
100
|
+
rescue LoadError
|
101
|
+
This.task_warning( 'rcov' )
|
102
|
+
end
|
103
|
+
else
|
104
|
+
begin
|
105
|
+
require 'simplecov'
|
106
|
+
desc 'Run tests with code coverage'
|
107
|
+
task :coverage do
|
108
|
+
ENV['COVERAGE'] = 'true'
|
109
|
+
Rake::Task[:test].execute
|
110
|
+
end
|
111
|
+
CLOBBER << FileList["coverage"]
|
112
|
+
rescue LoadError
|
113
|
+
This.task_warning( 'simplecov' )
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
#------------------------------------------------------------------------------
|
118
|
+
# Manifest - We want an explicit list of thos files that are to be packaged in
|
119
|
+
# the gem. Most of this is from Hoe.
|
120
|
+
#------------------------------------------------------------------------------
|
121
|
+
namespace 'manifest' do
|
122
|
+
desc "Check the manifest"
|
123
|
+
task :check => :clean do
|
124
|
+
files = FileList["**/*", ".*"].exclude( This.exclude_from_manifest ).to_a.sort
|
125
|
+
files = files.select{ |f| File.file?( f ) }
|
126
|
+
|
127
|
+
tmp = "Manifest.tmp"
|
128
|
+
File.open( tmp, 'w' ) do |f|
|
129
|
+
f.puts files.join("\n")
|
130
|
+
end
|
131
|
+
|
132
|
+
begin
|
133
|
+
sh "diff -du Manifest.txt #{tmp}"
|
134
|
+
ensure
|
135
|
+
rm tmp
|
136
|
+
end
|
137
|
+
puts "Manifest looks good"
|
138
|
+
end
|
139
|
+
|
140
|
+
desc "Generate the manifest"
|
141
|
+
task :generate => :clean do
|
142
|
+
files = %x[ git ls-files ].split("\n").sort
|
143
|
+
files.reject! { |f| f =~ This.exclude_from_manifest }
|
144
|
+
File.open( "Manifest.txt", "w" ) do |f|
|
145
|
+
f.puts files.join("\n")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
#------------------------------------------------------------------------------
|
151
|
+
# Fixme - look for fixmes and report them
|
152
|
+
#------------------------------------------------------------------------------
|
153
|
+
namespace :fixme do
|
154
|
+
task :default => 'manifest:check' do
|
155
|
+
This.manifest.each do |file|
|
156
|
+
next if file == __FILE__
|
157
|
+
next unless file =~ %r/(txt|rb|md|rdoc|css|html|xml|css)\Z/
|
158
|
+
puts "FIXME: Rename #{file}" if file =~ /fixme/i
|
159
|
+
IO.readlines( file ).each_with_index do |line, idx|
|
160
|
+
prefix = "FIXME: #{file}:#{idx+1}".ljust(42)
|
161
|
+
puts "#{prefix} => #{line.strip}" if line =~ /fixme/i
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def fixme_project_root
|
167
|
+
This.project_path( '../fixme' )
|
168
|
+
end
|
169
|
+
|
170
|
+
def fixme_project_path( subtree )
|
171
|
+
fixme_project_root.join( subtree )
|
172
|
+
end
|
173
|
+
|
174
|
+
def local_fixme_files
|
175
|
+
This.manifest.select { |p| p =~ %r|^tasks/| }
|
176
|
+
end
|
177
|
+
|
178
|
+
def outdated_fixme_files
|
179
|
+
local_fixme_files.reject do |local|
|
180
|
+
upstream = fixme_project_path( local )
|
181
|
+
Digest::SHA256.file( local ) == Digest::SHA256.file( upstream )
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def fixme_up_to_date?
|
186
|
+
outdated_fixme_files.empty?
|
187
|
+
end
|
188
|
+
|
189
|
+
desc "See if the fixme tools are outdated"
|
190
|
+
task :outdated => :release_check do
|
191
|
+
if fixme_up_to_date? then
|
192
|
+
puts "Fixme files are up to date."
|
193
|
+
else
|
194
|
+
outdated_fixme_files.each do |f|
|
195
|
+
puts "#{f} is outdated"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
desc "Update outdated fixme files"
|
201
|
+
task :update => :release_check do
|
202
|
+
if fixme_up_to_date? then
|
203
|
+
puts "Fixme files are already up to date."
|
204
|
+
else
|
205
|
+
puts "Updating fixme files:"
|
206
|
+
outdated_fixme_files.each do |local|
|
207
|
+
upstream = fixme_project_path( local )
|
208
|
+
puts " * #{local}"
|
209
|
+
FileUtils.cp( upstream, local )
|
210
|
+
end
|
211
|
+
puts "Use your git commands as appropriate."
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
desc "Look for fixmes and report them"
|
216
|
+
task :fixme => "fixme:default"
|
217
|
+
|
218
|
+
#------------------------------------------------------------------------------
|
219
|
+
# Gem Specification
|
220
|
+
#------------------------------------------------------------------------------
|
221
|
+
# Really this is only here to support those who use bundler
|
222
|
+
desc "Build the #{This.name}.gemspec file"
|
223
|
+
task :gemspec do
|
224
|
+
File.open( This.gemspec_file, "wb+" ) do |f|
|
225
|
+
f.write This.platform_gemspec.to_ruby
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# the gemspec is also a dev artifact and should not be kept around.
|
230
|
+
CLOBBER << This.gemspec_file.to_s
|
231
|
+
|
232
|
+
# .rbc files from ruby 2.0
|
233
|
+
CLOBBER << FileList["**/*.rbc"]
|
234
|
+
|
235
|
+
# The standard gem packaging task, everyone has it.
|
236
|
+
require 'rubygems/package_task'
|
237
|
+
Gem::PackageTask.new( This.platform_gemspec ) do
|
238
|
+
# nothing
|
239
|
+
end
|
240
|
+
|
241
|
+
#------------------------------------------------------------------------------
|
242
|
+
# Release - the steps we go through to do a final release, this is pulled from
|
243
|
+
# a compbination of mojombo's rakegem, hoe and hoe-git
|
244
|
+
#
|
245
|
+
# 1) make sure we are on the master branch
|
246
|
+
# 2) make sure there are no uncommitted items
|
247
|
+
# 3) check the manifest and make sure all looks good
|
248
|
+
# 4) build the gem
|
249
|
+
# 5) do an empty commit to have the commit message of the version
|
250
|
+
# 6) tag that commit as the version
|
251
|
+
# 7) push master
|
252
|
+
# 8) push the tag
|
253
|
+
# 7) pus the gem
|
254
|
+
#------------------------------------------------------------------------------
|
255
|
+
task :release_check do
|
256
|
+
unless `git branch` =~ /^\* master$/
|
257
|
+
abort "You must be on the master branch to release!"
|
258
|
+
end
|
259
|
+
unless `git status` =~ /^nothing to commit/m
|
260
|
+
abort "Nope, sorry, you have unfinished business"
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
desc "Create tag v#{This.version}, build and push #{This.platform_gemspec.full_name} to rubygems.org"
|
265
|
+
task :release => [ :release_check, 'manifest:check', :gem ] do
|
266
|
+
sh "git commit --allow-empty -a -m 'Release #{This.version}'"
|
267
|
+
sh "git tag -a -m 'v#{This.version}' v#{This.version}"
|
268
|
+
sh "git push origin master"
|
269
|
+
sh "git push origin v#{This.version}"
|
270
|
+
sh "gem push pkg/#{This.platform_gemspec.full_name}.gem"
|
271
|
+
end
|