rubyforge 0.1.1 → 0.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.
- data/bin/rubyforge +219 -476
- data/lib/http-access2.rb +1 -1
- data/lib/rubyforge.rb +337 -0
- data/test/test_rubyforge.rb +229 -0
- metadata +28 -26
- data/README +0 -125
- data/gemspec.rb +0 -23
- data/install.rb +0 -174
- data/rubyforge-0.1.1.gem +0 -0
data/lib/http-access2.rb
CHANGED
@@ -24,7 +24,7 @@ require 'http-access2/cookie'
|
|
24
24
|
module HTTPAccess2
|
25
25
|
VERSION = '2.0.6'
|
26
26
|
RUBY_VERSION_STRING = "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
27
|
-
s = %w$Id: http-access2.rb
|
27
|
+
s = %w$Id: http-access2.rb,v 1.1.1.1 2006/09/13 04:28:30 zenspider Exp $
|
28
28
|
RCS_FILE, RCS_REVISION = s[1][/.*(?=,v$)/], s[2]
|
29
29
|
|
30
30
|
SSLEnabled = begin
|
data/lib/rubyforge.rb
ADDED
@@ -0,0 +1,337 @@
|
|
1
|
+
#! /usr/bin/env ruby -w
|
2
|
+
|
3
|
+
require 'enumerator'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'http-access2'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
$TESTING = false unless defined? $TESTING
|
9
|
+
|
10
|
+
# HACK to fix http-access2 cookie selection bug
|
11
|
+
module WebAgent::CookieUtils
|
12
|
+
alias :old_domain_match :domain_match
|
13
|
+
def domain_match(host, domain)
|
14
|
+
case domain
|
15
|
+
when /\d+\.\d+\.\d+\.\d+/
|
16
|
+
return (host == domain)
|
17
|
+
when '.'
|
18
|
+
return true
|
19
|
+
when /^\./
|
20
|
+
#return tail_match?(domain, host)
|
21
|
+
return tail_match?(host, domain)
|
22
|
+
else
|
23
|
+
return (host == domain)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class RubyForge
|
29
|
+
VERSION = "0.2.0"
|
30
|
+
HOME = ENV["HOME"] || ENV["HOMEPATH"] || File::expand_path("~")
|
31
|
+
RUBYFORGE_D = File::join HOME, ".rubyforge"
|
32
|
+
CONFIG_F = File::join RUBYFORGE_D, "config.yml"
|
33
|
+
COOKIE_F = File::join RUBYFORGE_D, "cookie.dat"
|
34
|
+
|
35
|
+
# We must use __FILE__ instead of DATA because this is now a library
|
36
|
+
# and DATA is relative to $0, not __FILE__.
|
37
|
+
CONFIG = File.read(__FILE__).split(/__END__/).last.gsub(/#\{(.*)\}/) { eval $1 }
|
38
|
+
|
39
|
+
attr_reader :config
|
40
|
+
attr_reader :client if $TESTING
|
41
|
+
|
42
|
+
def initialize(config=CONFIG_F, opts={})
|
43
|
+
@config = test(?e, config) ? IO::read(config) : CONFIG
|
44
|
+
@config = YAML.load(@config).merge(opts)
|
45
|
+
|
46
|
+
raise "no <username>" unless @config["username"]
|
47
|
+
raise "no <password>" unless @config["password"]
|
48
|
+
raise "no <cookie_jar>" unless @config["cookie_jar"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def setup
|
52
|
+
FileUtils::mkdir_p RUBYFORGE_D unless test ?d, RUBYFORGE_D
|
53
|
+
test ?e, CONFIG_F and FileUtils::mv CONFIG_F, "#{ CONFIG_F }.bak"
|
54
|
+
open(CONFIG_F, "w") { |f| f.write CONFIG }
|
55
|
+
FileUtils::touch COOKIE_F
|
56
|
+
edit = (ENV["EDITOR"] || ENV["EDIT"] || "vi") + " #{ CONFIG_F }"
|
57
|
+
system edit or puts "edit #{ CONFIG_F }"
|
58
|
+
end
|
59
|
+
|
60
|
+
def login
|
61
|
+
page = "/account/login.php"
|
62
|
+
|
63
|
+
username = @config["username"]
|
64
|
+
password = @config["password"]
|
65
|
+
|
66
|
+
form = {
|
67
|
+
"return_to" => "",
|
68
|
+
"form_loginname" => username,
|
69
|
+
"form_pw" => password,
|
70
|
+
"login" => "Login"
|
71
|
+
}
|
72
|
+
|
73
|
+
run page, form
|
74
|
+
end
|
75
|
+
|
76
|
+
def scrape_config(username)
|
77
|
+
require 'open-uri'
|
78
|
+
|
79
|
+
data = {
|
80
|
+
"group_ids" => {},
|
81
|
+
"package_ids" => {},
|
82
|
+
"release_ids" => Hash.new { |h,k| h[k] = {} },
|
83
|
+
}
|
84
|
+
|
85
|
+
html = URI.parse("http://rubyforge.org/users/#{username}/index.html").read
|
86
|
+
html.scan(%r%/projects/([^/]+)/%).flatten.each do |project|
|
87
|
+
next if project == "support"
|
88
|
+
html = URI.parse("http://rubyforge.org/projects/#{project}/index.html").read
|
89
|
+
|
90
|
+
group_id = html[/(frs|tracker)\/\?group_id=\d+/][/\d+/].to_i
|
91
|
+
data["group_ids"][project] = group_id
|
92
|
+
|
93
|
+
html = URI.parse("http://rubyforge.org/frs/?group_id=#{group_id}").read
|
94
|
+
|
95
|
+
package = nil
|
96
|
+
html.scan(/<h3>\w+|release_id=\d+">[^>]+|filemodule_id=\d+/).each do |s|
|
97
|
+
case s
|
98
|
+
when /<h3>(\w+)/ then
|
99
|
+
package = $1
|
100
|
+
when /release_id=(\d+)">([^<]+)/ then
|
101
|
+
data["release_ids"][package][$2] = $1.to_i
|
102
|
+
when /filemodule_id=(\d+)/ then
|
103
|
+
data["package_ids"][package] = $1.to_i
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
data
|
108
|
+
end
|
109
|
+
|
110
|
+
def create_package(group_id, package_name)
|
111
|
+
page = "/frs/admin/index.php"
|
112
|
+
|
113
|
+
group_id = lookup "group", group_id
|
114
|
+
is_private = @config["is_private"]
|
115
|
+
is_public = is_private ? 0 : 1
|
116
|
+
|
117
|
+
form = {
|
118
|
+
"func" => "add_package",
|
119
|
+
"group_id" => group_id,
|
120
|
+
"package_name" => package_name,
|
121
|
+
"is_public" => is_public,
|
122
|
+
"submit" => "Create This Package",
|
123
|
+
}
|
124
|
+
|
125
|
+
run page, form
|
126
|
+
end
|
127
|
+
|
128
|
+
def delete_package(group_id, package_id)
|
129
|
+
page = "/frs/admin/index.php"
|
130
|
+
|
131
|
+
group_id = lookup "group", group_id
|
132
|
+
package_id = lookup "package", package_id
|
133
|
+
|
134
|
+
form = {
|
135
|
+
"func" => "delete_package",
|
136
|
+
"group_id" => group_id,
|
137
|
+
"package_id" => package_id,
|
138
|
+
"sure" => "1",
|
139
|
+
"really_sure" => "1",
|
140
|
+
"submit" => "Delete",
|
141
|
+
}
|
142
|
+
|
143
|
+
run page, form
|
144
|
+
end
|
145
|
+
|
146
|
+
def add_release(group_id, package_id, release_name, userfile)
|
147
|
+
# TODO: *userfiles
|
148
|
+
page = "/frs/admin/qrs.php"
|
149
|
+
|
150
|
+
group_id = lookup "group", group_id
|
151
|
+
package_id = lookup "package", package_id
|
152
|
+
userfile = open userfile
|
153
|
+
release_date = @config["release_date"]
|
154
|
+
type_id = @config["type_id"]
|
155
|
+
processor_id = @config["processor_id"]
|
156
|
+
release_notes = @config["release_notes"]
|
157
|
+
release_changes = @config["release_changes"]
|
158
|
+
preformatted = @config["preformatted"]
|
159
|
+
|
160
|
+
release_date ||= Time::now.strftime("%Y-%m-%d %H:%M")
|
161
|
+
|
162
|
+
type_id ||= userfile.path[%r|\.[^\./]+$|]
|
163
|
+
type_id = lookup "type", type_id
|
164
|
+
|
165
|
+
processor_id ||= "Any"
|
166
|
+
processor_id = lookup "processor", processor_id
|
167
|
+
|
168
|
+
release_notes = IO::read(release_notes) if release_notes and test(?e, release_notes)
|
169
|
+
|
170
|
+
release_changes = IO::read(release_changes) if release_changes and test(?e, release_changes)
|
171
|
+
|
172
|
+
preformatted = preformatted ? 1 : 0
|
173
|
+
|
174
|
+
form = {
|
175
|
+
"group_id" => group_id,
|
176
|
+
"package_id" => package_id,
|
177
|
+
"release_name" => release_name,
|
178
|
+
"release_date" => release_date,
|
179
|
+
"type_id" => type_id,
|
180
|
+
"processor_id" => processor_id,
|
181
|
+
"release_notes" => release_notes,
|
182
|
+
"release_changes" => release_changes,
|
183
|
+
"preformatted" => preformatted,
|
184
|
+
"userfile" => userfile,
|
185
|
+
"submit" => "Release File"
|
186
|
+
}
|
187
|
+
|
188
|
+
boundary = Array::new(8){ "%2.2d" % rand(42) }.join('__')
|
189
|
+
boundary = "multipart/form-data; boundary=___#{ boundary }___"
|
190
|
+
|
191
|
+
run page, form, 'content-type' => boundary
|
192
|
+
end
|
193
|
+
|
194
|
+
def add_file(group_name, package_name, release_name, userfile)
|
195
|
+
page = '/frs/admin/editrelease.php'
|
196
|
+
type_id = @config["type_id"]
|
197
|
+
group_id = lookup "group", group_name
|
198
|
+
package_id = lookup "package", package_name
|
199
|
+
release_id = (Integer === release_name) ? release_name : lookup("release", package_name)[release_name]
|
200
|
+
processor_id = @config["processor_id"]
|
201
|
+
|
202
|
+
page = "/frs/admin/editrelease.php?group_id=#{group_id}&release_id=#{release_id}&package_id=#{package_id}"
|
203
|
+
|
204
|
+
userfile = open userfile
|
205
|
+
|
206
|
+
type_id ||= userfile.path[%r|\.[^\./]+$|]
|
207
|
+
type_id = lookup "type", type_id
|
208
|
+
|
209
|
+
processor_id ||= "Any"
|
210
|
+
processor_id = lookup "processor", processor_id
|
211
|
+
|
212
|
+
form = {
|
213
|
+
"step2" => 1,
|
214
|
+
"type_id" => type_id,
|
215
|
+
"processor_id" => processor_id,
|
216
|
+
"userfile" => userfile,
|
217
|
+
"submit" => "Add This File"
|
218
|
+
}
|
219
|
+
|
220
|
+
boundary = Array::new(8){ "%2.2d" % rand(42) }.join('__')
|
221
|
+
boundary = "multipart/form-data; boundary=___#{ boundary }___"
|
222
|
+
|
223
|
+
run page, form, 'content-type' => boundary
|
224
|
+
end
|
225
|
+
|
226
|
+
def run(page, form, extheader={})
|
227
|
+
client = HTTPAccess2::Client::new ENV["HTTP_PROXY"]
|
228
|
+
client.debug_dev = STDERR if ENV["RUBYFORGE_DEBUG"] || ENV["DEBUG"]
|
229
|
+
client.set_cookie_store @config["cookie_jar"]
|
230
|
+
|
231
|
+
# HACK to fix http-access2 redirect bug/feature
|
232
|
+
client.redirect_uri_callback = lambda do |res|
|
233
|
+
page = res.header['location'].first
|
234
|
+
page =~ %r/http/ ? page : "#{ @config['uri'] }/#{ page }"
|
235
|
+
end
|
236
|
+
|
237
|
+
response = client.post_content "#{ File.join(@config['uri'], page) }", form, extheader
|
238
|
+
|
239
|
+
@client = client if $TESTING
|
240
|
+
|
241
|
+
client.save_cookie_store
|
242
|
+
|
243
|
+
return response
|
244
|
+
end
|
245
|
+
|
246
|
+
def lookup(type, val)
|
247
|
+
unless Fixnum === val then
|
248
|
+
key = val.to_s
|
249
|
+
val = @config["rubyforge"]["#{type}_ids"][key]
|
250
|
+
raise "no <#{type}_id> configured for <#{ key }>" unless val
|
251
|
+
end
|
252
|
+
val
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
__END__
|
257
|
+
#
|
258
|
+
# base rubyforge uri - store in #{ CONFIG_F }
|
259
|
+
#
|
260
|
+
uri : http://rubyforge.org
|
261
|
+
#
|
262
|
+
# this must be your username
|
263
|
+
#
|
264
|
+
username : username
|
265
|
+
#
|
266
|
+
# this must be your password
|
267
|
+
#
|
268
|
+
password : password
|
269
|
+
#
|
270
|
+
# defaults for some values
|
271
|
+
#
|
272
|
+
cookie_jar : #{ COOKIE_F }
|
273
|
+
is_private : false
|
274
|
+
#
|
275
|
+
# server side rubyforge configuration
|
276
|
+
#
|
277
|
+
rubyforge :
|
278
|
+
#
|
279
|
+
# map your group names to their rubyforge ids
|
280
|
+
#
|
281
|
+
group_ids :
|
282
|
+
codeforpeople.com : 1024
|
283
|
+
#
|
284
|
+
# map your package names to their rubyforge ids
|
285
|
+
#
|
286
|
+
package_ids :
|
287
|
+
traits : 1241
|
288
|
+
#
|
289
|
+
# map your package names to their rubyforge ids
|
290
|
+
#
|
291
|
+
release_ids :
|
292
|
+
traits :
|
293
|
+
1.2.3 : 666
|
294
|
+
#
|
295
|
+
# mapping file exts to rubyforge ids
|
296
|
+
#
|
297
|
+
type_ids :
|
298
|
+
.deb : 1000
|
299
|
+
.rpm : 2000
|
300
|
+
.zip : 3000
|
301
|
+
.bz2 : 3100
|
302
|
+
.gz : 3110
|
303
|
+
.src.zip : 5000
|
304
|
+
.src.bz2 : 5010
|
305
|
+
.src.tar.bz2 : 5010
|
306
|
+
.src.gz : 5020
|
307
|
+
.src.tar.gz : 5020
|
308
|
+
.src.rpm : 5100
|
309
|
+
.src : 5900
|
310
|
+
.jpg : 8000
|
311
|
+
.txt : 8100
|
312
|
+
.text : 8100
|
313
|
+
.htm : 8200
|
314
|
+
.html : 8200
|
315
|
+
.pdf : 8300
|
316
|
+
.oth : 9999
|
317
|
+
.ebuild : 1300
|
318
|
+
.exe : 1100
|
319
|
+
.dmg : 1200
|
320
|
+
.tar.gz : 5000
|
321
|
+
.tgz : 5000
|
322
|
+
.gem : 1400
|
323
|
+
.pgp : 8150
|
324
|
+
.sig : 8150
|
325
|
+
#
|
326
|
+
# map processor names to rubyforge ids
|
327
|
+
#
|
328
|
+
processor_ids :
|
329
|
+
i386 : 1000
|
330
|
+
IA64 : 6000
|
331
|
+
Alpha : 7000
|
332
|
+
Any : 8000
|
333
|
+
PPC : 2000
|
334
|
+
MIPS : 3000
|
335
|
+
Sparc : 4000
|
336
|
+
UltraSparc : 5000
|
337
|
+
Other : 9999
|
@@ -0,0 +1,229 @@
|
|
1
|
+
require 'test/unit' unless defined? $ZENTEST and $ZENTEST
|
2
|
+
|
3
|
+
$TESTING = true
|
4
|
+
require 'rubyforge'
|
5
|
+
|
6
|
+
class FakeRubyForge < RubyForge
|
7
|
+
attr_accessor :page, :form, :extheader
|
8
|
+
def run(page, form, extheader={})
|
9
|
+
@page, @form, @extheader = page, form, extheader
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class HTTPAccess2::Client
|
14
|
+
attr_accessor :url, :form, :headers
|
15
|
+
alias :old_post_content :post_content
|
16
|
+
def post_content(url, form, headers)
|
17
|
+
@url, @form, @headers = url, form, headers
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class TestRubyForge < Test::Unit::TestCase
|
22
|
+
|
23
|
+
def setup
|
24
|
+
srand(0)
|
25
|
+
util_new FakeRubyForge
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_initialize_bad
|
29
|
+
assert_raise RuntimeError do
|
30
|
+
RubyForge.new(RubyForge::CONFIG_F, "username" => nil)
|
31
|
+
end
|
32
|
+
assert_raise RuntimeError do
|
33
|
+
RubyForge.new(RubyForge::CONFIG_F, "password" => nil)
|
34
|
+
end
|
35
|
+
assert_raise RuntimeError do
|
36
|
+
RubyForge.new(RubyForge::CONFIG_F, "cookie_jar" => nil)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_setup
|
41
|
+
# TODO raise NotImplementedError, 'Need to write test_setup'
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_login
|
45
|
+
u, p = 'fooby', 's3kr3t'
|
46
|
+
@rubyforge.config['username'] = u
|
47
|
+
@rubyforge.config['password'] = p
|
48
|
+
@rubyforge.login
|
49
|
+
|
50
|
+
util_run('/account/login.php',
|
51
|
+
'form_pw' => p,
|
52
|
+
'form_loginname' => u,
|
53
|
+
'return_to' => '',
|
54
|
+
'login' => 'Login')
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_create_package
|
58
|
+
@rubyforge.create_package(42, 'woot_pkg')
|
59
|
+
|
60
|
+
util_run('/frs/admin/index.php',
|
61
|
+
"submit" => "Create This Package",
|
62
|
+
"group_id" => 42,
|
63
|
+
"is_public" => 1,
|
64
|
+
"package_name" => "woot_pkg",
|
65
|
+
"func" => "add_package")
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_delete_package
|
69
|
+
@rubyforge.delete_package(42, 666)
|
70
|
+
util_delete_package
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_delete_package_package_name
|
74
|
+
@rubyforge.config["rubyforge"]["package_ids"]["woot_pkg"] = 666
|
75
|
+
@rubyforge.delete_package(42, "woot_pkg")
|
76
|
+
util_delete_package
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_delete_package_undefined_package_name
|
80
|
+
assert_raise RuntimeError do
|
81
|
+
@rubyforge.delete_package(42, "blah")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_delete_package_group_name
|
86
|
+
@rubyforge.config["rubyforge"]["group_ids"]["seattlerb"] = 42
|
87
|
+
@rubyforge.delete_package("seattlerb", 666)
|
88
|
+
util_delete_package
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_delete_package_undefined_group_name
|
92
|
+
assert_raise RuntimeError do
|
93
|
+
@rubyforge.delete_package("blah", 666)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_add_file
|
98
|
+
@rubyforge.config["rubyforge"]["group_ids"]["seattlerb"] = 666
|
99
|
+
@rubyforge.config["rubyforge"]["package_ids"]["ringy_dingy"] = 42
|
100
|
+
@rubyforge.config["rubyforge"]["release_ids"]["ringy_dingy"] ||= {}
|
101
|
+
@rubyforge.config["rubyforge"]["release_ids"]["ringy_dingy"]["1.2.3"] = 43
|
102
|
+
|
103
|
+
@rubyforge.add_file('seattlerb', 'ringy_dingy', '1.2.3', __FILE__)
|
104
|
+
|
105
|
+
util_run('/frs/admin/editrelease.php?group_id=666&release_id=43&package_id=42',
|
106
|
+
{ "step2" => 1,
|
107
|
+
"type_id" => 9999,
|
108
|
+
"processor_id" => 8000,
|
109
|
+
"submit" => "Add This File"},
|
110
|
+
{"content-type"=> "multipart/form-data; boundary=___00__03__03__39__09__19__21__36___"})
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_add_release
|
114
|
+
@rubyforge.add_release(42, 666, '1.2.3', __FILE__)
|
115
|
+
util_add_release
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_add_release_package_name
|
119
|
+
@rubyforge.config["rubyforge"]["package_ids"]["woot_pkg"] = 666
|
120
|
+
@rubyforge.add_release(42, "woot_pkg", '1.2.3', __FILE__)
|
121
|
+
util_add_release
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_add_release_undefined_package_name
|
125
|
+
assert_raise RuntimeError do
|
126
|
+
@rubyforge.add_release(42, "blah", '1.2.3', __FILE__)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_add_release_group_name
|
131
|
+
@rubyforge.config["rubyforge"]["group_ids"]["seattlerb"] = 42
|
132
|
+
@rubyforge.add_release("seattlerb", 666, '1.2.3', __FILE__)
|
133
|
+
util_add_release
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_add_release_undefined_group_name
|
137
|
+
assert_raise RuntimeError do
|
138
|
+
@rubyforge.add_release("blah", 666, '1.2.3', __FILE__)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_lookup_id
|
143
|
+
assert_equal 43, @rubyforge.lookup("package", 43)
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_lookup_string_number
|
147
|
+
assert_raise RuntimeError do
|
148
|
+
@rubyforge.lookup("package", "43")
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_lookup_name
|
153
|
+
@rubyforge.config["rubyforge"]["package_ids"]["ringy_dingy"] = 42
|
154
|
+
assert_equal 42, @rubyforge.lookup("package", "ringy_dingy")
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_lookup_undefined
|
158
|
+
assert_raise RuntimeError do
|
159
|
+
@rubyforge.lookup("package", "blah")
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_run
|
164
|
+
util_new RubyForge
|
165
|
+
@rubyforge.add_release(42, 666, '1.2.3', __FILE__)
|
166
|
+
|
167
|
+
extheader = {"content-type"=> "multipart/form-data; boundary=___00__03__03__39__09__19__21__36___"}
|
168
|
+
|
169
|
+
form = {
|
170
|
+
"processor_id" => 8000,
|
171
|
+
"submit" => "Release File",
|
172
|
+
"preformatted" => 0,
|
173
|
+
"release_changes" => nil,
|
174
|
+
"type_id" => 9999,
|
175
|
+
"group_id" => 42,
|
176
|
+
"release_name" => "1.2.3",
|
177
|
+
"release_notes" => nil,
|
178
|
+
"package_id" => 666,
|
179
|
+
"release_date" => "today"
|
180
|
+
}
|
181
|
+
|
182
|
+
client = @rubyforge.client
|
183
|
+
assert client.form.delete("userfile")
|
184
|
+
|
185
|
+
assert_equal 'http://rubyforge.org/frs/admin/qrs.php', client.url
|
186
|
+
assert_equal form, client.form
|
187
|
+
assert_equal extheader, client.headers
|
188
|
+
end
|
189
|
+
|
190
|
+
def util_new(klass)
|
191
|
+
@rubyforge = klass.new
|
192
|
+
@rubyforge.config["release_date"] = "today"
|
193
|
+
@rubyforge.config["rubyforge"]["type_ids"][".rb"] = 9999
|
194
|
+
end
|
195
|
+
|
196
|
+
def util_run(page, form={}, extheader={})
|
197
|
+
form_result = @rubyforge.form
|
198
|
+
assert form_result.delete("userfile") unless extheader.empty?
|
199
|
+
|
200
|
+
assert_equal page, @rubyforge.page
|
201
|
+
assert_equal form, form_result
|
202
|
+
assert_equal extheader, @rubyforge.extheader
|
203
|
+
end
|
204
|
+
|
205
|
+
def util_add_release
|
206
|
+
util_run('/frs/admin/qrs.php',
|
207
|
+
{"processor_id" => 8000,
|
208
|
+
"submit" => "Release File",
|
209
|
+
"preformatted" => 0,
|
210
|
+
"release_changes" => nil,
|
211
|
+
"type_id" => 9999,
|
212
|
+
"group_id" => 42,
|
213
|
+
"release_name" => "1.2.3",
|
214
|
+
"release_notes" => nil,
|
215
|
+
"package_id" => 666,
|
216
|
+
"release_date" => "today"},
|
217
|
+
{"content-type"=> "multipart/form-data; boundary=___00__03__03__39__09__19__21__36___"})
|
218
|
+
end
|
219
|
+
|
220
|
+
def util_delete_package
|
221
|
+
util_run('/frs/admin/index.php',
|
222
|
+
"submit" => "Delete",
|
223
|
+
"really_sure" => "1",
|
224
|
+
"group_id" => 42,
|
225
|
+
"func" => "delete_package",
|
226
|
+
"package_id" => 666,
|
227
|
+
"sure" => "1")
|
228
|
+
end
|
229
|
+
end
|