rubyforge 0.0.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 +441 -0
- metadata +39 -0
data/bin/rubyforge
ADDED
@@ -0,0 +1,441 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
$VERBOSE = nil
|
3
|
+
#
|
4
|
+
# load gems/libs
|
5
|
+
#
|
6
|
+
%w( getoptlong enumerator http-access2 yaml fileutils ).each do |l|
|
7
|
+
begin require "rubygems"; require_gem l; rescue LoadError; require l end
|
8
|
+
end
|
9
|
+
#
|
10
|
+
# defaults
|
11
|
+
#
|
12
|
+
PROGRAM = File::basename $0
|
13
|
+
HOME = ENV["HOME"] || ENV["HOMEPATH"] || File::expand_path("~")
|
14
|
+
RUBYFORGE_D = File::join HOME, ".rubyforge"
|
15
|
+
CONFIG_F = File::join RUBYFORGE_D, "config.yml"
|
16
|
+
COOKIE_F = File::join RUBYFORGE_D, "cookie.dat"
|
17
|
+
#
|
18
|
+
# usage
|
19
|
+
#
|
20
|
+
USAGE = <<-txt
|
21
|
+
SYNOPSIS
|
22
|
+
|
23
|
+
#{ PROGRAM } [options]* mode [mode_args]*
|
24
|
+
|
25
|
+
DESCRIPTION
|
26
|
+
|
27
|
+
simplistic script which automates a limited set of rubyforge operations
|
28
|
+
|
29
|
+
MODES
|
30
|
+
|
31
|
+
setup()
|
32
|
+
initializes your #{ RUBYFORGE_D } directory. you need to run this first
|
33
|
+
before doing anything else.
|
34
|
+
|
35
|
+
example :
|
36
|
+
#{ PROGRAM } setup
|
37
|
+
|
38
|
+
login()
|
39
|
+
sends username and password from #{ CONFIG_F } (or --username/--password
|
40
|
+
options) and stores login cookie in #{ COOKIE_F }. this is required for
|
41
|
+
subsquent operations work.
|
42
|
+
|
43
|
+
example :
|
44
|
+
#{ PROGRAM } login
|
45
|
+
#{ PROGRAM } login --username zaphod --password 42
|
46
|
+
|
47
|
+
create_package(group_id, package_name)
|
48
|
+
creates the named package under the specified group.
|
49
|
+
|
50
|
+
example :
|
51
|
+
#{ PROGRAM } create_package codeforpeople.com traits
|
52
|
+
#{ PROGRAM } create_package 1024 traits
|
53
|
+
|
54
|
+
notes :
|
55
|
+
in order to use group_ids by name, rather than number, you must edit the
|
56
|
+
rubyforge[group_ids] translation table in your #{ CONFIG_F }.
|
57
|
+
|
58
|
+
add_release(group_id, package_id, release_name, userfile)
|
59
|
+
release a file as release_name under the specified group_id and
|
60
|
+
package_id.
|
61
|
+
|
62
|
+
example :
|
63
|
+
#{ PROGRAM } add_package codeforpeople.com traits 0.8.0 traits-0.8.0.gem
|
64
|
+
#{ PROGRAM } add_package codeforpeople.com traits 0.8.0 traits-0.8.0.tgz
|
65
|
+
#{ PROGRAM } add_package 1024 1242 0.8.0 traits-0.8.0.gem
|
66
|
+
|
67
|
+
notes :
|
68
|
+
in order to use group_ids and package_ids by name, rather than number,
|
69
|
+
you must edit the rubyforge[group_ids] and rubyforge[package_ids]
|
70
|
+
translation tables in your #{ CONFIG_F }.
|
71
|
+
|
72
|
+
delete_package(group_id, package_name)
|
73
|
+
deletes a package and all it's files.
|
74
|
+
|
75
|
+
example :
|
76
|
+
#{ PROGRAM } delete_package codeforpeople.com traits
|
77
|
+
#{ PROGRAM } delete_package 1024 traits
|
78
|
+
|
79
|
+
OPTIONS
|
80
|
+
|
81
|
+
global :
|
82
|
+
--help , -h
|
83
|
+
this message
|
84
|
+
--config , -c
|
85
|
+
specify a config file (default #{ CONFIG_F })
|
86
|
+
--username , -u
|
87
|
+
specify username, taken from config otherwise
|
88
|
+
--password , -p
|
89
|
+
specify password, taken from config otherwise
|
90
|
+
--cookie_jar , -C
|
91
|
+
specify cookie storage file (default #{ COOKIE_F })
|
92
|
+
|
93
|
+
add_release :
|
94
|
+
--is_private , -P
|
95
|
+
if true, release is not public
|
96
|
+
--release_date , -r
|
97
|
+
specify time of release (default 'now')
|
98
|
+
--type_id , -t
|
99
|
+
specify filetype code (default determined by ext)
|
100
|
+
--processor_id , -o
|
101
|
+
specify processor (default 'Any')
|
102
|
+
--release_notes , -n
|
103
|
+
specify release notes as string or file
|
104
|
+
--release_changes , -a
|
105
|
+
specify release changes as string or file
|
106
|
+
--preformatted , -f
|
107
|
+
specify whether release_notes/changes are preformatted
|
108
|
+
|
109
|
+
txt
|
110
|
+
USAGE.gsub! %r|^#{ USAGE[%r/^\s*/] }|, ''
|
111
|
+
#
|
112
|
+
# config
|
113
|
+
#
|
114
|
+
CONFIG = <<-yml
|
115
|
+
#
|
116
|
+
# base rubyforge uri - store in #{ CONFIG_F }
|
117
|
+
#
|
118
|
+
uri : http://rubyforge.org
|
119
|
+
#
|
120
|
+
# this must be your username
|
121
|
+
#
|
122
|
+
username : username
|
123
|
+
#
|
124
|
+
# this must be your password
|
125
|
+
#
|
126
|
+
password : password
|
127
|
+
#
|
128
|
+
# defaults for some values
|
129
|
+
#
|
130
|
+
defaults :
|
131
|
+
cookie_jar : #{ COOKIE_F }
|
132
|
+
is_private : false
|
133
|
+
#
|
134
|
+
# server side rubyforge configuration
|
135
|
+
#
|
136
|
+
rubyforge :
|
137
|
+
#
|
138
|
+
# map your package names to their rubyforge ids
|
139
|
+
#
|
140
|
+
package_ids :
|
141
|
+
traits : 1241
|
142
|
+
#
|
143
|
+
# map your group names to their rubyforge ids
|
144
|
+
#
|
145
|
+
group_ids :
|
146
|
+
codeforpeople.com : 1024
|
147
|
+
#
|
148
|
+
# mapping file exts to rubyforge ids
|
149
|
+
#
|
150
|
+
type_ids :
|
151
|
+
.deb : 1000
|
152
|
+
.rpm : 2000
|
153
|
+
.zip : 3000
|
154
|
+
.bz2 : 3100
|
155
|
+
.gz : 3110
|
156
|
+
.src.zip : 5000
|
157
|
+
.src.bz2 : 5010
|
158
|
+
.src.gz : 5020
|
159
|
+
.src.rpm : 5100
|
160
|
+
.src : 5900
|
161
|
+
.jpg : 8000
|
162
|
+
.txt : 8100
|
163
|
+
.text : 8100
|
164
|
+
.htm : 8200
|
165
|
+
.html : 8200
|
166
|
+
.pdf : 8300
|
167
|
+
.oth : 9999
|
168
|
+
.ebuild : 1300
|
169
|
+
.exe : 1100
|
170
|
+
.dmg : 1200
|
171
|
+
.tar.gz : 5000
|
172
|
+
.tgz : 5000
|
173
|
+
.gem : 1400
|
174
|
+
.pgp : 8150
|
175
|
+
.sig : 8150
|
176
|
+
#
|
177
|
+
# map processor names to rubyforge ids
|
178
|
+
#
|
179
|
+
processor_ids :
|
180
|
+
i386 : 1000
|
181
|
+
IA64 : 6000
|
182
|
+
Alpha : 7000
|
183
|
+
Any : 8000
|
184
|
+
PPC : 2000
|
185
|
+
MIPS : 3000
|
186
|
+
Sparc : 4000
|
187
|
+
UltraSparc : 5000
|
188
|
+
Other : 9999
|
189
|
+
yml
|
190
|
+
CONFIG.gsub! %r|^#{ CONFIG[%r/^\s*/] }|, ''
|
191
|
+
#
|
192
|
+
# load mode, global opts, and config
|
193
|
+
#
|
194
|
+
mode = ARGV.shift
|
195
|
+
|
196
|
+
opts = GetoptLong::new(
|
197
|
+
[ "--help" , "-h" , GetoptLong::REQUIRED_ARGUMENT ] ,
|
198
|
+
[ "--config" , "-c" , GetoptLong::REQUIRED_ARGUMENT ] ,
|
199
|
+
[ "--username" , "-u" , GetoptLong::REQUIRED_ARGUMENT ] ,
|
200
|
+
[ "--password" , "-p" , GetoptLong::REQUIRED_ARGUMENT ] ,
|
201
|
+
[ "--cookie_jar" , "-C" , GetoptLong::REQUIRED_ARGUMENT ] ,
|
202
|
+
|
203
|
+
[ "--is_private", "-P", GetoptLong::REQUIRED_ARGUMENT ],
|
204
|
+
|
205
|
+
[ "--release_date" , "-r" , GetoptLong::REQUIRED_ARGUMENT ] ,
|
206
|
+
[ "--type_id" , "-t" , GetoptLong::REQUIRED_ARGUMENT ] ,
|
207
|
+
[ "--processor_id" , "-o" , GetoptLong::REQUIRED_ARGUMENT ] ,
|
208
|
+
[ "--release_notes" , "-n" , GetoptLong::REQUIRED_ARGUMENT ] ,
|
209
|
+
[ "--release_changes" , "-a" , GetoptLong::REQUIRED_ARGUMENT ] ,
|
210
|
+
[ "--preformatted" , "-f" , GetoptLong::NO_ARGUMENT ]
|
211
|
+
).enum_for.inject({}){|h,kv| h.update kv.first.delete('-') => kv.last}
|
212
|
+
|
213
|
+
config = opts["config"] || CONFIG_F
|
214
|
+
config = test(?e, config) ? IO::read(config) : CONFIG
|
215
|
+
config = YAML::load config
|
216
|
+
|
217
|
+
username = opts["username"] || config["username"]
|
218
|
+
password = opts["password"] || config["password"]
|
219
|
+
cookie_jar = opts["cookie_jar"] || config["defaults"]["cookie_jar"]
|
220
|
+
|
221
|
+
abort "no <username>" unless username
|
222
|
+
abort "no <password>" unless password
|
223
|
+
abort "no <cookie_jar>" unless cookie_jar
|
224
|
+
|
225
|
+
mode = "help" if opts["help"]
|
226
|
+
#
|
227
|
+
# run based on mode
|
228
|
+
#
|
229
|
+
msg, page, form, extheader = nil, nil, nil, {}
|
230
|
+
|
231
|
+
case mode
|
232
|
+
#
|
233
|
+
# help mode
|
234
|
+
#
|
235
|
+
when %r/help/
|
236
|
+
USAGE.display
|
237
|
+
exit
|
238
|
+
#
|
239
|
+
# setup mode
|
240
|
+
#
|
241
|
+
when %r/setup/
|
242
|
+
FileUtils::mkdir_p RUBYFORGE_D
|
243
|
+
test ?e, CONFIG_F and FileUtils::mv CONFIG_F, "#{ CONFIG_F }.bak"
|
244
|
+
open(CONFIG_F,"w"){|f| f.write CONFIG}
|
245
|
+
FileUtils::touch COOKIE_F
|
246
|
+
edit = (ENV["EDITOR"] || ENV["EDIT"] || "gvim") + " #{ CONFIG_F }"
|
247
|
+
system edit or puts "edit #{ CONFIG_F }"
|
248
|
+
exit
|
249
|
+
#
|
250
|
+
# login mode
|
251
|
+
#
|
252
|
+
when %r/login/
|
253
|
+
page, msg = "/account/login.php", "post_content"
|
254
|
+
|
255
|
+
form = {
|
256
|
+
"return_to" => "",
|
257
|
+
"form_loginname" => username,
|
258
|
+
"form_pw" => password,
|
259
|
+
"login" => "Login"
|
260
|
+
}
|
261
|
+
#
|
262
|
+
# create_package mode
|
263
|
+
#
|
264
|
+
when %r/create_package/
|
265
|
+
page, msg = "/frs/admin/index.php", "post_content"
|
266
|
+
|
267
|
+
group_id, package_name = ARGV
|
268
|
+
|
269
|
+
abort "no <group_id>" unless group_id
|
270
|
+
abort "no <package_name>" unless package_name
|
271
|
+
|
272
|
+
unless group_id.to_s =~ %r/^\d+$/
|
273
|
+
key = group_id.to_s
|
274
|
+
group_id = config["rubyforge"]["group_ids"][key]
|
275
|
+
abort "no <group_id> configured for <#{ key }>" unless group_id
|
276
|
+
end
|
277
|
+
|
278
|
+
is_private = opts["is_private"] || config["defaults"]["is_private"]
|
279
|
+
is_public = is_private ? 0 : 1
|
280
|
+
|
281
|
+
form = {
|
282
|
+
"func" => "add_package",
|
283
|
+
"group_id" => group_id,
|
284
|
+
"package_name" => package_name,
|
285
|
+
"is_public" => is_public,
|
286
|
+
"submit" => "Create This Package",
|
287
|
+
}
|
288
|
+
#
|
289
|
+
# delete_package mode
|
290
|
+
#
|
291
|
+
when %r/delete_package/
|
292
|
+
page, msg = "/frs/admin/index.php", "post_content"
|
293
|
+
|
294
|
+
group_id, package_id = ARGV
|
295
|
+
|
296
|
+
abort "no <group_id>" unless group_id
|
297
|
+
abort "no <package_id>" unless package_id
|
298
|
+
|
299
|
+
unless group_id.to_s =~ %r/^\d+$/
|
300
|
+
key = group_id.to_s
|
301
|
+
group_id = config["rubyforge"]["group_ids"][key]
|
302
|
+
abort "no <group_id> configured for <#{ key }>" unless group_id
|
303
|
+
end
|
304
|
+
|
305
|
+
unless package_id.to_s =~ %r/^\d+$/
|
306
|
+
key = package_id.to_s
|
307
|
+
package_id = config["rubyforge"]["package_ids"][key]
|
308
|
+
abort "no <package_id> configured for <#{ key }>" unless package_id
|
309
|
+
end
|
310
|
+
|
311
|
+
form = {
|
312
|
+
"func" => "delete_package",
|
313
|
+
"group_id" => group_id,
|
314
|
+
"package_id" => package_id,
|
315
|
+
"sure" => "1",
|
316
|
+
"really_sure" => "1",
|
317
|
+
"submit" => "Delete",
|
318
|
+
}
|
319
|
+
#
|
320
|
+
# add_release mode
|
321
|
+
#
|
322
|
+
when %r/add_release/
|
323
|
+
page, msg = "/frs/admin/qrs.php", "post_content"
|
324
|
+
|
325
|
+
group_id, package_id, release_name, userfile = ARGV
|
326
|
+
|
327
|
+
abort "no <group_id>" unless group_id
|
328
|
+
abort "no <package_id>" unless package_id
|
329
|
+
abort "no <release_name>" unless release_name
|
330
|
+
abort "no <userfile>" unless userfile
|
331
|
+
|
332
|
+
unless group_id.to_s =~ %r/^\d+$/
|
333
|
+
key = group_id.to_s
|
334
|
+
group_id = config["rubyforge"]["group_ids"][key]
|
335
|
+
abort "no <group_id> configured for <#{ key }>" unless group_id
|
336
|
+
end
|
337
|
+
|
338
|
+
unless package_id.to_s =~ %r/^\d+$/
|
339
|
+
key = package_id.to_s
|
340
|
+
package_id = config["rubyforge"]["package_ids"][key]
|
341
|
+
abort "no <package_id> configured for <#{ key }>" unless package_id
|
342
|
+
end
|
343
|
+
|
344
|
+
userfile = open userfile
|
345
|
+
|
346
|
+
release_date = opts["release_date"]
|
347
|
+
type_id = opts["type_id"]
|
348
|
+
processor_id = opts["processor_id"]
|
349
|
+
release_notes = opts["release_notes"]
|
350
|
+
release_changes = opts["release_changes"]
|
351
|
+
preformatted = opts["preformatted"]
|
352
|
+
|
353
|
+
release_date ||= Time::now.strftime("%Y-%m-%d %H:%M")
|
354
|
+
|
355
|
+
type_id ||= userfile.path[%r|\.[^\./]+$|]
|
356
|
+
unless type_id.to_s =~ %r/^\d+$/
|
357
|
+
key = type_id.to_s
|
358
|
+
type_id = config["rubyforge"]["type_ids"][key]
|
359
|
+
abort "no <type_id> configured for <#{ key }>" unless type_id
|
360
|
+
end
|
361
|
+
|
362
|
+
processor_id ||= "Any"
|
363
|
+
unless processor_id.to_s =~ %r/^\d+$/
|
364
|
+
key = processor_id.to_s
|
365
|
+
processor_id = config["rubyforge"]["processor_ids"][key]
|
366
|
+
abort "no <processor_id> configured for <#{ key }>" unless processor_id
|
367
|
+
end
|
368
|
+
|
369
|
+
release_notes = IO::read(release_notes) if release_notes and test(?e, release_notes)
|
370
|
+
|
371
|
+
release_changes = IO::read(release_changes) if release_changes and test(?e, release_changes)
|
372
|
+
|
373
|
+
preformatted = preformatted ? 1 : 0
|
374
|
+
|
375
|
+
form = {
|
376
|
+
"group_id" => group_id,
|
377
|
+
"package_id" => package_id,
|
378
|
+
"release_name" => release_name,
|
379
|
+
"release_date" => release_date,
|
380
|
+
"type_id" => type_id,
|
381
|
+
"processor_id" => processor_id,
|
382
|
+
"release_notes" => release_notes,
|
383
|
+
"release_changes" => release_changes,
|
384
|
+
"preformatted" => preformatted,
|
385
|
+
"userfile" => userfile,
|
386
|
+
"submit" => "Release File"
|
387
|
+
}
|
388
|
+
|
389
|
+
boundary = Array::new(8){ "%2.2d" % rand(42) }.join('__')
|
390
|
+
extheader['content-type'] = "multipart/form-data; boundary=___#{ boundary }___"
|
391
|
+
#
|
392
|
+
# bad mode
|
393
|
+
#
|
394
|
+
else
|
395
|
+
abort USAGE
|
396
|
+
end
|
397
|
+
#
|
398
|
+
# commit http transaction
|
399
|
+
#
|
400
|
+
if [msg, page, form].all?
|
401
|
+
client = HTTPAccess2::Client::new ENV["HTTP_PROXY"]
|
402
|
+
client.debug_dev = STDERR if ENV["RUBYFORGE_DEBUG"] || ENV["DEBUG"]
|
403
|
+
client.set_cookie_store cookie_jar
|
404
|
+
#
|
405
|
+
# hack to fix http-access2 redirect bug/feature
|
406
|
+
#
|
407
|
+
client.redirect_uri_callback = lambda do |res|
|
408
|
+
page = res.header['location'].first
|
409
|
+
page =~ %r/http/ ? page : "#{ config['uri'] }/#{ page }"
|
410
|
+
end
|
411
|
+
response = client.send "#{ msg }", "#{ config['uri'] }/#{ page }", form, extheader
|
412
|
+
client.save_cookie_store
|
413
|
+
end
|
414
|
+
|
415
|
+
exit 0
|
416
|
+
#
|
417
|
+
# hack to fix http-access2 cookie selection bug
|
418
|
+
#
|
419
|
+
BEGIN {
|
420
|
+
begin
|
421
|
+
require "rubygems"
|
422
|
+
require_gem "http-access2"
|
423
|
+
rescue LoadError
|
424
|
+
require "http-access2"
|
425
|
+
end
|
426
|
+
module WebAgent::CookieUtils
|
427
|
+
def domain_match(host, domain)
|
428
|
+
case domain
|
429
|
+
when /\d+\.\d+\.\d+\.\d+/
|
430
|
+
return (host == domain)
|
431
|
+
when '.'
|
432
|
+
return true
|
433
|
+
when /^\./
|
434
|
+
#return tail_match?(domain, host)
|
435
|
+
return tail_match?(host, domain)
|
436
|
+
else
|
437
|
+
return (host == domain)
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
}
|
metadata
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: rubyforge
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.0
|
7
|
+
date: 2005-11-06 00:00:00.000000 -07:00
|
8
|
+
summary: rubyforge
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: ara.t.howard@noaa.gov
|
12
|
+
homepage: http://codeforpeople.com/lib/ruby/rubyforge/
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: rubyforge
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
signing_key:
|
28
|
+
cert_chain:
|
29
|
+
authors:
|
30
|
+
- Ara T. Howard
|
31
|
+
files:
|
32
|
+
- bin/rubyforge
|
33
|
+
test_files: []
|
34
|
+
rdoc_options: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
executables: []
|
37
|
+
extensions: []
|
38
|
+
requirements: []
|
39
|
+
dependencies: []
|