starling 0.9.3 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +49 -0
- data/{License.txt → LICENSE} +1 -1
- data/README.rdoc +106 -0
- data/Rakefile +22 -4
- data/bin/starling +3 -1
- data/bin/starling_top +57 -0
- data/etc/sample-config.yml +9 -0
- data/etc/starling.redhat +63 -0
- data/etc/starling.ubuntu +71 -0
- data/lib/starling.rb +4 -4
- data/lib/starling/handler.rb +97 -56
- data/lib/starling/persistent_queue.rb +21 -26
- data/lib/starling/queue_collection.rb +6 -5
- data/lib/starling/server.rb +47 -137
- data/lib/starling/{runner.rb → server_runner.rb} +63 -24
- data/spec/starling_server_spec.rb +205 -0
- metadata +66 -42
- data/History.txt +0 -3
- data/Manifest.txt +0 -29
- data/README.txt +0 -42
- data/config/hoe.rb +0 -71
- data/config/requirements.rb +0 -15
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/script/txt2html +0 -74
- data/setup.rb +0 -1585
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/website.rake +0 -17
- data/test/test_helper.rb +0 -2
- data/test/test_persistent_queue.rb +0 -17
- data/test/test_starling.rb +0 -111
- data/website/index.html +0 -0
- data/website/index.txt +0 -66
- data/website/javascripts/rounded_corners_lite.inc.js +0 -285
- data/website/stylesheets/screen.css +0 -138
- data/website/template.rhtml +0 -48
@@ -0,0 +1,205 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'memcache'
|
6
|
+
require 'digest/md5'
|
7
|
+
|
8
|
+
require 'starling/server'
|
9
|
+
|
10
|
+
class StarlingServer::PersistentQueue
|
11
|
+
remove_const :SOFT_LOG_MAX_SIZE
|
12
|
+
SOFT_LOG_MAX_SIZE = 16 * 1024 # 16 KB
|
13
|
+
end
|
14
|
+
|
15
|
+
def safely_fork(&block)
|
16
|
+
# anti-race juice:
|
17
|
+
blocking = true
|
18
|
+
Signal.trap("USR1") { blocking = false }
|
19
|
+
|
20
|
+
pid = Process.fork(&block)
|
21
|
+
|
22
|
+
while blocking
|
23
|
+
sleep 0.1
|
24
|
+
end
|
25
|
+
|
26
|
+
pid
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "StarlingServer" do
|
30
|
+
before do
|
31
|
+
@tmp_path = File.join(File.dirname(__FILE__), "tmp")
|
32
|
+
|
33
|
+
begin
|
34
|
+
Dir::mkdir(@tmp_path)
|
35
|
+
rescue Errno::EEXIST
|
36
|
+
end
|
37
|
+
|
38
|
+
@server_pid = safely_fork do
|
39
|
+
server = StarlingServer::Base.new(:host => '127.0.0.1',
|
40
|
+
:port => 22133,
|
41
|
+
:path => @tmp_path,
|
42
|
+
:logger => Logger.new(STDERR),
|
43
|
+
:log_level => Logger::FATAL)
|
44
|
+
Signal.trap("INT") {
|
45
|
+
server.stop
|
46
|
+
exit
|
47
|
+
}
|
48
|
+
|
49
|
+
Process.kill("USR1", Process.ppid)
|
50
|
+
server.run
|
51
|
+
end
|
52
|
+
|
53
|
+
@client = MemCache.new('127.0.0.1:22133')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should test if temp_path exists and is writeable" do
|
57
|
+
File.exist?(@tmp_path).should be_true
|
58
|
+
File.directory?(@tmp_path).should be_true
|
59
|
+
File.writable?(@tmp_path).should be_true
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should set and get" do
|
63
|
+
v = rand((2**32)-1)
|
64
|
+
@client.get('test_set_and_get_one_entry').should be_nil
|
65
|
+
@client.set('test_set_and_get_one_entry', v)
|
66
|
+
@client.get('test_set_and_get_one_entry').should eql(v)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should expire entries" do
|
70
|
+
v = rand((2**32)-1)
|
71
|
+
@client.get('test_set_with_expiry').should be_nil
|
72
|
+
now = Time.now.to_i
|
73
|
+
@client.set('test_set_with_expiry', v + 2, now)
|
74
|
+
@client.set('test_set_with_expiry', v)
|
75
|
+
sleep(1.0)
|
76
|
+
@client.get('test_set_with_expiry').should eql(v)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should have age stat" do
|
80
|
+
now = Time.now.to_i
|
81
|
+
@client.set('test_age', 'nibbler')
|
82
|
+
sleep(1.0)
|
83
|
+
@client.get('test_age').should eql('nibbler')
|
84
|
+
|
85
|
+
stats = @client.stats['127.0.0.1:22133']
|
86
|
+
stats.has_key?('queue_test_age_age').should be_true
|
87
|
+
(stats['queue_test_age_age'] >= 1000).should be_true
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should rotate log" do
|
91
|
+
log_rotation_path = File.join(@tmp_path, 'test_log_rotation')
|
92
|
+
|
93
|
+
Dir.glob("#{log_rotation_path}*").each do |file|
|
94
|
+
File.unlink(file) rescue nil
|
95
|
+
end
|
96
|
+
@client.get('test_log_rotation').should be_nil
|
97
|
+
|
98
|
+
v = 'x' * 8192
|
99
|
+
|
100
|
+
@client.set('test_log_rotation', v)
|
101
|
+
File.size(log_rotation_path).should eql(8207)
|
102
|
+
@client.get('test_log_rotation')
|
103
|
+
|
104
|
+
@client.get('test_log_rotation').should be_nil
|
105
|
+
|
106
|
+
@client.set('test_log_rotation', v)
|
107
|
+
@client.get('test_log_rotation').should eql(v)
|
108
|
+
|
109
|
+
File.size(log_rotation_path).should eql(1)
|
110
|
+
# rotated log should be erased after a successful roll.
|
111
|
+
Dir.glob("#{log_rotation_path}*").size.should eql(1)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should output statistics per server" do
|
115
|
+
stats = @client.stats
|
116
|
+
assert_kind_of Hash, stats
|
117
|
+
assert stats.has_key?('127.0.0.1:22133')
|
118
|
+
|
119
|
+
server_stats = stats['127.0.0.1:22133']
|
120
|
+
|
121
|
+
basic_stats = %w( bytes pid time limit_maxbytes cmd_get version
|
122
|
+
bytes_written cmd_set get_misses total_connections
|
123
|
+
curr_connections curr_items uptime get_hits total_items
|
124
|
+
rusage_system rusage_user bytes_read )
|
125
|
+
|
126
|
+
basic_stats.each do |stat|
|
127
|
+
server_stats.has_key?(stat).should be_true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should return valid response with unkown command" do
|
132
|
+
response = @client.add('blah', 1)
|
133
|
+
response.should eql("CLIENT_ERROR bad command line format\r\n")
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should disconnect and reconnect again" do
|
137
|
+
v = rand(2**32-1)
|
138
|
+
@client.set('test_that_disconnecting_and_reconnecting_works', v)
|
139
|
+
@client.reset
|
140
|
+
@client.get('test_that_disconnecting_and_reconnecting_works').should eql(v)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should use epoll on linux" do
|
144
|
+
# this may take a few seconds.
|
145
|
+
# the point is to make sure that we're using epoll on Linux, so we can
|
146
|
+
# handle more than 1024 connections.
|
147
|
+
|
148
|
+
unless IO::popen("uname").read.chomp == "Linux"
|
149
|
+
pending "skipping epoll test: not on Linux"
|
150
|
+
end
|
151
|
+
|
152
|
+
fd_limit = IO::popen("bash -c 'ulimit -n'").read.chomp.to_i
|
153
|
+
unless fd_limit > 1024
|
154
|
+
pending "skipping epoll test: 'ulimit -n' = #{fd_limit}, need > 1024"
|
155
|
+
end
|
156
|
+
|
157
|
+
v = rand(2**32 - 1)
|
158
|
+
@client.set('test_epoll', v)
|
159
|
+
|
160
|
+
# we can't open 1024 connections to memcache from within this process,
|
161
|
+
# because we will hit ruby's 1024 fd limit ourselves!
|
162
|
+
pid1 = safely_fork do
|
163
|
+
unused_sockets = []
|
164
|
+
600.times do
|
165
|
+
unused_sockets << TCPSocket.new("127.0.0.1", 22133)
|
166
|
+
end
|
167
|
+
Process.kill("USR1", Process.ppid)
|
168
|
+
sleep 90
|
169
|
+
end
|
170
|
+
pid2 = safely_fork do
|
171
|
+
unused_sockets = []
|
172
|
+
600.times do
|
173
|
+
unused_sockets << TCPSocket.new("127.0.0.1", 22133)
|
174
|
+
end
|
175
|
+
Process.kill("USR1", Process.ppid)
|
176
|
+
sleep 90
|
177
|
+
end
|
178
|
+
|
179
|
+
begin
|
180
|
+
client = MemCache.new('127.0.0.1:22133')
|
181
|
+
client.get('test_epoll').should eql(v)
|
182
|
+
ensure
|
183
|
+
Process.kill("TERM", pid1)
|
184
|
+
Process.kill("TERM", pid2)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should raise error if queue collection is an invalid path" do
|
189
|
+
invalid_path = nil
|
190
|
+
while invalid_path.nil? || File.exist?(invalid_path)
|
191
|
+
invalid_path = File.join('/', Digest::MD5.hexdigest(rand(2**32-1).to_s)[0,8])
|
192
|
+
end
|
193
|
+
|
194
|
+
lambda {
|
195
|
+
StarlingServer::QueueCollection.new(invalid_path)
|
196
|
+
}.should raise_error(StarlingServer::InaccessibleQueuePath)
|
197
|
+
end
|
198
|
+
|
199
|
+
after do
|
200
|
+
Process.kill("INT", @server_pid)
|
201
|
+
Process.wait(@server_pid)
|
202
|
+
@client.reset
|
203
|
+
FileUtils.rm(Dir.glob(File.join(@tmp_path, '*')))
|
204
|
+
end
|
205
|
+
end
|
metadata
CHANGED
@@ -1,66 +1,92 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: starling
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
5
|
-
platform:
|
4
|
+
version: 0.9.8
|
5
|
+
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blaine Cook
|
8
|
+
- Chris Wanstrath
|
9
|
+
- Britt Selvitelle
|
10
|
+
- Glenn Rempe
|
11
|
+
- Abdul-Rahman Advany
|
8
12
|
autorequire:
|
9
13
|
bindir: bin
|
10
14
|
cert_chain: []
|
11
15
|
|
12
|
-
date: 2008-
|
16
|
+
date: 2008-08-26 00:00:00 -07:00
|
13
17
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
18
|
+
dependencies:
|
19
|
+
- !ruby/object:Gem::Dependency
|
20
|
+
name: memcache-client
|
21
|
+
type: :runtime
|
22
|
+
version_requirement:
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: "0"
|
28
|
+
version:
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: SyslogLogger
|
31
|
+
type: :runtime
|
32
|
+
version_requirement:
|
33
|
+
version_requirements: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: "0"
|
38
|
+
version:
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: eventmachine
|
41
|
+
type: :runtime
|
42
|
+
version_requirement:
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.12.0
|
48
|
+
version:
|
16
49
|
description: Starling is a lightweight, transactional, distributed queue server
|
17
|
-
email:
|
50
|
+
email:
|
51
|
+
- blaine@twitter.com
|
52
|
+
- chris@ozmm.org
|
53
|
+
- abdulrahman@advany.com
|
18
54
|
executables:
|
19
55
|
- starling
|
56
|
+
- starling_top
|
20
57
|
extensions: []
|
21
58
|
|
22
59
|
extra_rdoc_files:
|
23
|
-
-
|
24
|
-
-
|
25
|
-
-
|
26
|
-
- README.txt
|
27
|
-
- website/index.txt
|
60
|
+
- README.rdoc
|
61
|
+
- CHANGELOG
|
62
|
+
- LICENSE
|
28
63
|
files:
|
29
|
-
-
|
30
|
-
-
|
31
|
-
-
|
32
|
-
- README.txt
|
64
|
+
- README.rdoc
|
65
|
+
- LICENSE
|
66
|
+
- CHANGELOG
|
33
67
|
- Rakefile
|
34
|
-
- bin/starling
|
35
|
-
- config/hoe.rb
|
36
|
-
- config/requirements.rb
|
37
|
-
- lib/starling.rb
|
38
68
|
- lib/starling/handler.rb
|
39
69
|
- lib/starling/persistent_queue.rb
|
40
70
|
- lib/starling/queue_collection.rb
|
41
|
-
- lib/starling/
|
71
|
+
- lib/starling/server_runner.rb
|
42
72
|
- lib/starling/server.rb
|
43
|
-
-
|
44
|
-
-
|
45
|
-
-
|
46
|
-
-
|
47
|
-
- tasks/deployment.rake
|
48
|
-
- tasks/environment.rake
|
49
|
-
- tasks/website.rake
|
50
|
-
- test/test_helper.rb
|
51
|
-
- test/test_persistent_queue.rb
|
52
|
-
- test/test_starling.rb
|
53
|
-
- website/index.html
|
54
|
-
- website/index.txt
|
55
|
-
- website/javascripts/rounded_corners_lite.inc.js
|
56
|
-
- website/stylesheets/screen.css
|
57
|
-
- website/template.rhtml
|
73
|
+
- lib/starling.rb
|
74
|
+
- etc/starling.redhat
|
75
|
+
- etc/starling.ubuntu
|
76
|
+
- etc/sample-config.yml
|
58
77
|
has_rdoc: true
|
59
|
-
homepage: http://starling
|
78
|
+
homepage: http://github.com/starling/starling/
|
60
79
|
post_install_message:
|
61
80
|
rdoc_options:
|
81
|
+
- --quiet
|
82
|
+
- --title
|
83
|
+
- starling documentation
|
84
|
+
- --opname
|
85
|
+
- index.html
|
86
|
+
- --line-numbers
|
62
87
|
- --main
|
63
|
-
- README.
|
88
|
+
- README.rdoc
|
89
|
+
- --inline-source
|
64
90
|
require_paths:
|
65
91
|
- lib
|
66
92
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -77,12 +103,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
103
|
version:
|
78
104
|
requirements: []
|
79
105
|
|
80
|
-
rubyforge_project:
|
81
|
-
rubygems_version:
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 1.2.0
|
82
108
|
signing_key:
|
83
109
|
specification_version: 2
|
84
110
|
summary: Starling is a lightweight, transactional, distributed queue server
|
85
111
|
test_files:
|
86
|
-
-
|
87
|
-
- test/test_persistent_queue.rb
|
88
|
-
- test/test_starling.rb
|
112
|
+
- spec/starling_server_spec.rb
|
data/History.txt
DELETED
data/Manifest.txt
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
History.txt
|
2
|
-
License.txt
|
3
|
-
Manifest.txt
|
4
|
-
README.txt
|
5
|
-
Rakefile
|
6
|
-
bin/starling
|
7
|
-
config/hoe.rb
|
8
|
-
config/requirements.rb
|
9
|
-
lib/starling.rb
|
10
|
-
lib/starling/handler.rb
|
11
|
-
lib/starling/persistent_queue.rb
|
12
|
-
lib/starling/queue_collection.rb
|
13
|
-
lib/starling/runner.rb
|
14
|
-
lib/starling/server.rb
|
15
|
-
script/destroy
|
16
|
-
script/generate
|
17
|
-
script/txt2html
|
18
|
-
setup.rb
|
19
|
-
tasks/deployment.rake
|
20
|
-
tasks/environment.rake
|
21
|
-
tasks/website.rake
|
22
|
-
test/test_helper.rb
|
23
|
-
test/test_persistent_queue.rb
|
24
|
-
test/test_starling.rb
|
25
|
-
website/index.html
|
26
|
-
website/index.txt
|
27
|
-
website/javascripts/rounded_corners_lite.inc.js
|
28
|
-
website/stylesheets/screen.css
|
29
|
-
website/template.rhtml
|
data/README.txt
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
= Name
|
2
|
-
|
3
|
-
Starling - a light weight server for reliable distributed message passing.
|
4
|
-
|
5
|
-
= Synopsis
|
6
|
-
|
7
|
-
# Start the Starling server as a daemonized process:
|
8
|
-
starling -h 192.168.1.1 -d
|
9
|
-
|
10
|
-
# Put messages onto a queue:
|
11
|
-
require 'memcache'
|
12
|
-
starling = MemCache.new('192.168.1.1:22122')
|
13
|
-
starling.set('my_queue', 12345)
|
14
|
-
|
15
|
-
# Get messages from the queue:
|
16
|
-
require 'memcache'
|
17
|
-
starling = MemCache.new('192.168.1.1:22122')
|
18
|
-
loop { puts starling.get('my_queue') }
|
19
|
-
|
20
|
-
# See the Starling documentation for more information.
|
21
|
-
|
22
|
-
= Description
|
23
|
-
|
24
|
-
Starling is a powerful but simple messaging server that enables reliable
|
25
|
-
distributed queuing with an absolutely minimal overhead. It speaks the
|
26
|
-
MemCache protocol for maximum cross-platform compatibility. Any language
|
27
|
-
that speaks MemCache can take advantage of Starling's queue facilities.
|
28
|
-
|
29
|
-
= Known Issues
|
30
|
-
|
31
|
-
* Starling is "slow" as far as messaging systems are concerned. In practice,
|
32
|
-
it's fast enough. If you'd like to help make it faster please do. Starting
|
33
|
-
points would be to use an event-driven interface, and get rid of threading.
|
34
|
-
|
35
|
-
= Authors
|
36
|
-
|
37
|
-
Blaine Cook <romeda@gmail.com>
|
38
|
-
|
39
|
-
= Copyright
|
40
|
-
|
41
|
-
Starling - a light-weight server for reliable distributed message passing.
|
42
|
-
Copyright 2007 Blaine Cook <blaine@twitter.com>, Twitter Inc.
|
data/config/hoe.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'starling/server'
|
2
|
-
|
3
|
-
AUTHOR = 'Blaine Cook' # can also be an array of Authors
|
4
|
-
EMAIL = "blaine@twitter.com"
|
5
|
-
DESCRIPTION = "Starling is a lightweight, transactional, distributed queue server"
|
6
|
-
GEM_NAME = 'starling' # what ppl will type to install your gem
|
7
|
-
RUBYFORGE_PROJECT = 'starling' # The unix name for your project
|
8
|
-
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
9
|
-
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
10
|
-
|
11
|
-
@config_file = "~/.rubyforge/user-config.yml"
|
12
|
-
@config = nil
|
13
|
-
RUBYFORGE_USERNAME = "unknown"
|
14
|
-
def rubyforge_username
|
15
|
-
unless @config
|
16
|
-
begin
|
17
|
-
@config = YAML.load(File.read(File.expand_path(@config_file)))
|
18
|
-
rescue
|
19
|
-
puts <<-EOS
|
20
|
-
ERROR: No rubyforge config file found: #{@config_file}
|
21
|
-
Run 'rubyforge setup' to prepare your env for access to Rubyforge
|
22
|
-
- See http://newgem.rubyforge.org/rubyforge.html for more details
|
23
|
-
EOS
|
24
|
-
exit
|
25
|
-
end
|
26
|
-
end
|
27
|
-
RUBYFORGE_USERNAME.replace @config["username"]
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
|
-
REV = nil
|
32
|
-
# UNCOMMENT IF REQUIRED:
|
33
|
-
# REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
|
34
|
-
VERS = StarlingServer::VERSION + (REV ? ".#{REV}" : "")
|
35
|
-
RDOC_OPTS = ['--quiet', '--title', 'starling documentation',
|
36
|
-
"--opname", "index.html",
|
37
|
-
"--line-numbers",
|
38
|
-
"--main", "README",
|
39
|
-
"--inline-source"]
|
40
|
-
|
41
|
-
class Hoe
|
42
|
-
def extra_deps
|
43
|
-
@extra_deps.reject! { |x| Array(x).first == 'hoe' }
|
44
|
-
@extra_deps
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# Generate all the Rake tasks
|
49
|
-
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
50
|
-
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
51
|
-
p.author = AUTHOR
|
52
|
-
p.description = DESCRIPTION
|
53
|
-
p.email = EMAIL
|
54
|
-
p.summary = DESCRIPTION
|
55
|
-
p.url = HOMEPATH
|
56
|
-
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
57
|
-
p.test_globs = ["test/**/test_*.rb"]
|
58
|
-
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
59
|
-
|
60
|
-
# == Optional
|
61
|
-
p.changes = p.paragraphs_of("History.txt", 0..1).join("\\n\\n")
|
62
|
-
#p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
63
|
-
|
64
|
-
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
|
69
|
-
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
70
|
-
hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
71
|
-
hoe.rsync_args = '-av --delete --ignore-errors'
|