rubyforge 0.0.0 → 1.0.4

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 CHANGED
@@ -1,441 +1,234 @@
1
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
2
+
3
+ $VERBOSE = true
4
+
5
+ $:.unshift(File::join(File::dirname(File::dirname(__FILE__)), "lib"))
6
+
7
+ require 'getoptlong'
8
+ require 'rubyforge'
9
+
10
+ PROGRAM = File::basename $0
11
+
12
+ USAGE = <<-EOL
13
+ SYNOPSIS
14
+
15
+ #{ PROGRAM } [options]* mode [mode_args]*
16
+
17
+ DESCRIPTION
18
+
19
+ simplistic script which automates a limited set of rubyforge operations
20
+
21
+ MODES
22
+
23
+ setup()
24
+ initializes your .rubyforge directory. you need to run this first before
25
+ doing anything else.
26
+
27
+ example :
28
+ #{ PROGRAM } setup
29
+
30
+ config([project])
31
+ Helps you populate your auto-config.yml file by scraping rubyforge and
32
+ getting your groups, projects, and releases.
33
+
34
+ example :
35
+ #{ PROGRAM } config
36
+ #{ PROGRAM } config myproject
37
+
38
+ names()
39
+ Prints out the names of your configured groups and projects.
40
+
41
+ example :
42
+ #{ PROGRAM } names
43
+
44
+ login()
45
+ sends username and password from config.yml (or --username/--password
46
+ options) and stores login cookie in cookie.dat. this is required for
47
+ subsquent operations work.
48
+
49
+ example :
50
+ #{ PROGRAM } login
51
+ #{ PROGRAM } login --username zaphod --password 42
52
+
53
+ create_package(group_id, package_name)
54
+ creates the named package under the specified group.
55
+
56
+ example :
57
+ #{ PROGRAM } create_package 1024 traits
58
+ #{ PROGRAM } login && #{ PROGRAM } create_package codeforpeople.com traits
59
+
60
+ add_release(group_id, package_id, release_name, userfile)
61
+ release a file as release_name under the specified group_id and
62
+ package_id.
63
+
64
+ example :
65
+ #{ PROGRAM } add_release codeforpeople.com traits 0.8.0 traits-0.8.0.gem
66
+ #{ PROGRAM } add_release codeforpeople.com traits 0.8.0 traits-0.8.0.tgz
67
+ #{ PROGRAM } add_release 1024 1242 0.8.0 traits-0.8.0.gem
68
+ #{ PROGRAM } login && #{ PROGRAM } add_release 1024 1242 0.8.0 traits-0.8.0.gem
69
+
70
+ add_file(group_id, package_id, release_id, userfile)
71
+ add a file to an existing release under the specified group_id,
72
+ package_id, and release_id
73
+
74
+ example :
75
+ #{ PROGRAM } add_file codeforpeople.com traits 0.8.0 traits-0.8.0.gem
76
+ #{ PROGRAM } add_file codeforpeople.com traits 0.8.0 traits-0.8.0.tgz
77
+ #{ PROGRAM } add_file 1024 1242 0.8.0 traits-0.8.0.gem
78
+
79
+ delete_package(group_id, package_name)
80
+ deletes a package and all its files.
81
+
82
+ example :
83
+ #{ PROGRAM } delete_package codeforpeople.com traits
84
+ #{ PROGRAM } delete_package 1024 traits
85
+
86
+ NOTES
87
+
88
+ - In order to use group_id, package_id, or release_id by name,
89
+ rather than number, you must edit the rubyforge[group_ids] and
90
+ rubyforge[package_ids] translation tables in your config.yml. See
91
+ the config command for more information and help.
92
+
93
+ - don\'t forget to login! logging in will store a cookie in your
94
+ .rubyforge directory which expires after a time. always run the login
95
+ command before any operation that requires authentication, such as
96
+ uploading a package.
97
+
98
+ TODO
99
+
100
+ - add error checking. this requires screen scraping to see of an operation
101
+ succeeded since 200 is returned from rubyforge even for failed operations
102
+ and only the html text reveals the status.
103
+
104
+ OPTIONS
105
+
106
+ global :
107
+ --help , -h
108
+ this message
109
+ --config , -c
110
+ specify a config file (default #{ RubyForge::CONFIG_F })
111
+ --username , -u
112
+ specify username, taken from config otherwise
113
+ --password , -p
114
+ specify password, taken from config otherwise
115
+ --cookie_jar , -C
116
+ specify cookie storage file (default #{ RubyForge::COOKIE_F })
117
+
118
+ add_release :
119
+ --is_private , -P
120
+ if true, release is not public
121
+ --release_date , -r
122
+ specify time of release (default 'now')
123
+ --type_id , -t
124
+ specify filetype code (default determined by ext)
125
+ --processor_id , -o
126
+ specify processor (default 'Any')
127
+ --release_notes , -n
128
+ specify release notes as string or file
129
+ --release_changes , -a
130
+ specify release changes as string or file
131
+ --preformatted , -f
132
+ specify whether release_notes/changes are preformatted
133
+
134
+ EOL
135
+
136
+ mode = ARGV.shift
137
+
138
+ opts = GetoptLong::new(
139
+ [ "--help" , "-h" , GetoptLong::NO_ARGUMENT ],
140
+ [ "--force" , "-F" , GetoptLong::NO_ARGUMENT ],
141
+ [ "--username" , "-u" , GetoptLong::REQUIRED_ARGUMENT ],
142
+ [ "--password" , "-p" , GetoptLong::REQUIRED_ARGUMENT ],
143
+ [ "--cookie_jar" , "-C" , GetoptLong::REQUIRED_ARGUMENT ],
144
+ [ "--is_private" , "-P" , GetoptLong::REQUIRED_ARGUMENT ],
145
+ [ "--release_date" , "-r" , GetoptLong::REQUIRED_ARGUMENT ],
146
+ [ "--type_id" , "-t" , GetoptLong::REQUIRED_ARGUMENT ],
147
+ [ "--processor_id" , "-o" , GetoptLong::REQUIRED_ARGUMENT ],
148
+ [ "--release_notes" , "-n" , GetoptLong::REQUIRED_ARGUMENT ],
149
+ [ "--release_changes" , "-a" , GetoptLong::REQUIRED_ARGUMENT ],
150
+ [ "--preformatted" , "-f" , GetoptLong::NO_ARGUMENT ]
151
+ ).enum_for.inject({}) { |h, (k, v)| h.update k.delete('-') => v }
152
+
153
+ rubyforge = RubyForge.new
154
+ rubyforge.configure opts
155
+
156
+ mode = "help" if opts["help"]
157
+
158
+ case mode
159
+ when %r/help/
160
+ USAGE.display
161
+ when %r/setup/
162
+ rubyforge.setup
163
+ when %r/config/
164
+ project = ARGV.shift
165
+ if project then
166
+ rubyforge.scrape_project(project)
167
+ else
168
+ rubyforge.scrape_config
413
169
  end
170
+ when %r/names/
171
+ rf = rubyforge.autoconfig
172
+ puts "groups : #{rf["group_ids"].keys.sort.join(", ")}"
173
+ puts "packages: #{rf["package_ids"].keys.sort.join(", ")}"
174
+ when %r/login/
175
+ rubyforge.login
176
+ when %r/logout/
177
+ rubyforge.logout
178
+ when %r/create_package/
179
+ page, msg = "/frs/admin/index.php", "post_content"
180
+
181
+ group_id, package_name = ARGV
182
+
183
+ abort "no <group_id>" unless group_id
184
+ abort "no <package_name>" unless package_name
185
+
186
+ group_id = Integer(group_id) rescue group_id
187
+
188
+ rubyforge.login
189
+
190
+ rubyforge.create_package group_id, package_name
191
+ when %r/delete_package/
192
+ group_id, package_id = ARGV
193
+
194
+ abort "no <group_id>" unless group_id
195
+ abort "no <package_id>" unless package_id
196
+
197
+ group_id = Integer(group_id) rescue group_id
198
+ package_id = Integer(package_id) rescue package_id
199
+
200
+ rubyforge.login
201
+
202
+ rubyforge.delete_package group_id, package_id
203
+ when %r/add_release/
204
+ group_id, package_id, release_name, userfile = ARGV
205
+
206
+ abort "no <group_id>" unless group_id
207
+ abort "no <package_id>" unless package_id
208
+ abort "no <release_name>" unless release_name
209
+ abort "no <userfile>" unless userfile
210
+
211
+ group_id = Integer(group_id) rescue group_id
212
+ package_id = Integer(package_id) rescue package_id
213
+
214
+ rubyforge.login
215
+
216
+ rubyforge.add_release group_id, package_id, release_name, userfile
217
+ when %r/add_file/
218
+ group_id, package_id, release_id, userfile = ARGV
219
+
220
+ abort "no <group_id>" unless group_id
221
+ abort "no <package_id>" unless package_id
222
+ abort "no <release_id>" unless release_id
223
+ abort "no <userfile>" unless userfile
224
+
225
+ group_id = Integer(group_id) rescue group_id
226
+ package_id = Integer(package_id) rescue package_id
227
+ release_id = Integer(release_id) rescue release_id
228
+
229
+ rubyforge.login
414
230
 
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
- }
231
+ rubyforge.add_file group_id, package_id, release_id, userfile
232
+ else
233
+ abort USAGE
234
+ end