rscm 0.2.1.1404 → 0.3.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/README +34 -23
- data/Rakefile +24 -29
- data/bin/touch.exe +0 -0
- data/lib/rscm.rb +6 -3
- data/lib/rscm/annotations.rb +26 -7
- data/lib/rscm/{abstract_scm.rb → base.rb} +109 -71
- data/lib/rscm/better.rb +16 -0
- data/lib/rscm/logging.rb +11 -5
- data/lib/rscm/path_converter.rb +9 -16
- data/lib/rscm/revision.rb +201 -0
- data/lib/rscm/revision_file.rb +71 -0
- data/lib/rscm/scm/clearcase.rb +7 -7
- data/lib/rscm/scm/cvs.rb +69 -70
- data/lib/rscm/scm/cvs_log_parser.rb +29 -29
- data/lib/rscm/scm/darcs.rb +82 -34
- data/lib/rscm/scm/darcs_log_parser.rb +65 -0
- data/lib/rscm/scm/monotone.rb +249 -77
- data/lib/rscm/scm/monotone_log_parser.rb +57 -43
- data/lib/rscm/scm/mooky.rb +3 -3
- data/lib/rscm/scm/perforce.rb +196 -134
- data/lib/rscm/scm/star_team.rb +10 -10
- data/lib/rscm/scm/subversion.rb +106 -77
- data/lib/rscm/scm/subversion_log_parser.rb +76 -47
- data/lib/rscm/time_ext.rb +2 -116
- data/test/rscm/annotations_test.rb +15 -2
- data/test/rscm/{abstract_scm_test.rb → base_test.rb} +3 -3
- data/test/rscm/difftool_test.rb +9 -3
- data/test/rscm/generic_scm_tests.rb +195 -124
- data/test/rscm/revision_fixture.rb +20 -0
- data/test/rscm/revision_test.rb +129 -0
- data/test/rscm/{changesets.yaml → revisions.yaml} +10 -10
- data/test/rscm/scm/clearcase.log +608 -0
- data/test/rscm/scm/clearcase_test.rb +39 -0
- data/test/rscm/scm/cvs_log_parser_test.rb +73 -73
- data/test/rscm/scm/cvs_test.rb +1 -1
- data/test/rscm/scm/darcs_log_parser_test.rb +171 -0
- data/test/rscm/scm/monotone_log_parser_test.rb +49 -31
- data/test/rscm/scm/monotone_test.rb +3 -2
- data/test/rscm/scm/p4client_test.rb +33 -0
- data/test/rscm/scm/perforce_test.rb +25 -3
- data/test/rscm/scm/star_team.rb +9 -9
- data/test/rscm/scm/subversion_log_parser_test.rb +107 -47
- metadata +17 -13
- data/lib/multipart.rb +0 -95
- data/lib/rscm/RSS.txt +0 -41
- data/lib/rscm/changes.rb +0 -268
- data/lib/rscm/example.yaml +0 -21
- data/lib/rubyforge_file_publisher.rb +0 -176
- data/test/rscm/changes_fixture.rb +0 -20
- data/test/rscm/changes_test.rb +0 -129
data/lib/multipart.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
require 'net/http'
|
3
|
-
require 'cgi'
|
4
|
-
|
5
|
-
# Adds multipart support to Net::HTTP
|
6
|
-
# based on Code from Patrick May
|
7
|
-
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/113774
|
8
|
-
module Net
|
9
|
-
class Param
|
10
|
-
def initialize(k, v)
|
11
|
-
@k = k
|
12
|
-
@v = v
|
13
|
-
end
|
14
|
-
|
15
|
-
def to_multipart
|
16
|
-
"Content-Disposition: form-data; name=\"#{CGI::escape(@k)}\"\r\n\r\n#{@v}\r\n"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class FileParam
|
21
|
-
def initialize(k, file, mime_type)
|
22
|
-
@k = k
|
23
|
-
@file = file
|
24
|
-
@mime_type = mime_type
|
25
|
-
end
|
26
|
-
|
27
|
-
def to_multipart
|
28
|
-
content = File.open(@file).read
|
29
|
-
"Content-Disposition: form-data; name=\"#{CGI::escape(@k)}\"; filename=\"#{File.basename(@file)}\"\r\n" +
|
30
|
-
"Content-Type: #{@mime_type}\r\n\r\n" + content + "\r\n"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class HTTP
|
35
|
-
|
36
|
-
def post_multipart(path, params, header={}, dest=nil, boundary="----------ThIs_Is_tHe_bouNdaRY_$") # :yield: self
|
37
|
-
body = params.collect { |p|
|
38
|
-
"--" + boundary + "\r\n" + p.to_multipart
|
39
|
-
}.join("") + "--" + boundary + "--" + "\r\n"
|
40
|
-
|
41
|
-
header["Content-Type"] = "multipart/form-data; boundary=" + boundary
|
42
|
-
header["Content-Length"] = "#{body.length}"
|
43
|
-
|
44
|
-
post(path, body, header, dest)
|
45
|
-
end
|
46
|
-
|
47
|
-
alias :old_post :post
|
48
|
-
def post(path, data, initheader = nil, dest = nil)
|
49
|
-
puts "----POST----"
|
50
|
-
puts path
|
51
|
-
puts "------------"
|
52
|
-
if(initheader)
|
53
|
-
initheader.each {|k,v|
|
54
|
-
puts "#{k}: #{v}"
|
55
|
-
}
|
56
|
-
end
|
57
|
-
puts
|
58
|
-
puts data
|
59
|
-
|
60
|
-
response, data = old_post(path, data, initheader, dest)
|
61
|
-
|
62
|
-
puts "----POST RESP----"
|
63
|
-
puts response.class.name
|
64
|
-
puts "------------"
|
65
|
-
response.each {|k,v|
|
66
|
-
puts "#{k}: #{v}"
|
67
|
-
}
|
68
|
-
|
69
|
-
return response, data
|
70
|
-
end
|
71
|
-
|
72
|
-
alias :old_get :get
|
73
|
-
def get(path, initheader = nil, dest = nil)
|
74
|
-
puts "----GET-----"
|
75
|
-
puts path
|
76
|
-
puts "------------"
|
77
|
-
if(initheader)
|
78
|
-
initheader.each {|k,v|
|
79
|
-
puts "#{k}: #{v}"
|
80
|
-
}
|
81
|
-
end
|
82
|
-
|
83
|
-
response, data = old_get(path, initheader, dest)
|
84
|
-
|
85
|
-
puts "----GET RESP----"
|
86
|
-
puts response.class.name
|
87
|
-
puts "------------"
|
88
|
-
response.each {|k,v|
|
89
|
-
puts "#{k}: #{v}"
|
90
|
-
}
|
91
|
-
|
92
|
-
return response, data
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
data/lib/rscm/RSS.txt
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
Sketch of RSS layout for DC and RSCM
|
2
|
-
|
3
|
-
rss
|
4
|
-
channel
|
5
|
-
title:
|
6
|
-
link:
|
7
|
-
description:
|
8
|
-
item
|
9
|
-
pubDate:
|
10
|
-
title:
|
11
|
-
link:
|
12
|
-
description
|
13
|
-
xxx:
|
14
|
-
|
15
|
-
rss
|
16
|
-
channel
|
17
|
-
title: PicoContainer Builds
|
18
|
-
link: http://builds.codehaus.org/build/damagecontrol/project/picocontainer
|
19
|
-
description: DamageControl build of PicoContainer
|
20
|
-
item (one per build)
|
21
|
-
pubDate: <dc_creation_time>
|
22
|
-
title: PicoContainer Build FAILED
|
23
|
-
link: http://builds.codehaus.org/build/damagecontrol/project/picocontainer/build/<dc_creation_time>
|
24
|
-
description
|
25
|
-
"Blurb about why it failed (tail from logs)"
|
26
|
-
"who broke it (from changesets)"
|
27
|
-
"Changesets"
|
28
|
-
|
29
|
-
rss
|
30
|
-
channel
|
31
|
-
title: PicoContainer CVS
|
32
|
-
link: http://cvs.picocontainer.org/
|
33
|
-
description: Changesets for PicoContainer (viewcvs/fisheye etc)
|
34
|
-
item (one per changeset)
|
35
|
-
pubDate: <changeset_time>
|
36
|
-
title: changeset commit message (trunkated - w/o links)
|
37
|
-
link: Link to changeset page (if supported - fisheye etc). otherwise to root of scm_web
|
38
|
-
description
|
39
|
-
"changeset message with tracker URLs (newline-escaped)"
|
40
|
-
"|revision|path (with links)|"
|
41
|
-
|
data/lib/rscm/changes.rb
DELETED
@@ -1,268 +0,0 @@
|
|
1
|
-
require 'xmlrpc/utils'
|
2
|
-
require 'rscm/time_ext'
|
3
|
-
|
4
|
-
module RSCM
|
5
|
-
|
6
|
-
# A collection of ChangeSet.
|
7
|
-
class ChangeSets
|
8
|
-
include Enumerable
|
9
|
-
include XMLRPC::Marshallable
|
10
|
-
|
11
|
-
attr_reader :changesets
|
12
|
-
|
13
|
-
def initialize(changesets=[])
|
14
|
-
@changesets = changesets
|
15
|
-
end
|
16
|
-
|
17
|
-
# Accepts a visitor that will receive callbacks while
|
18
|
-
# iterating over this instance's internal structure.
|
19
|
-
# The visitor should respond to the following methods:
|
20
|
-
#
|
21
|
-
# * visit_changesets(changesets)
|
22
|
-
# * visit_changeset(changeset)
|
23
|
-
# * visit_change(change)
|
24
|
-
#
|
25
|
-
def accept(visitor)
|
26
|
-
visitor.visit_changesets(self)
|
27
|
-
self.each{|changeset| changeset.accept(visitor)}
|
28
|
-
end
|
29
|
-
|
30
|
-
def [](change)
|
31
|
-
@changesets[change]
|
32
|
-
end
|
33
|
-
|
34
|
-
def each(&block)
|
35
|
-
@changesets.each(&block)
|
36
|
-
end
|
37
|
-
|
38
|
-
def reverse
|
39
|
-
ChangeSets.new(@changesets.dup.reverse)
|
40
|
-
end
|
41
|
-
|
42
|
-
def length
|
43
|
-
@changesets.length
|
44
|
-
end
|
45
|
-
|
46
|
-
def ==(other)
|
47
|
-
return false if !other.is_a?(self.class)
|
48
|
-
@changesets == other.changesets
|
49
|
-
end
|
50
|
-
|
51
|
-
def empty?
|
52
|
-
@changesets.empty?
|
53
|
-
end
|
54
|
-
|
55
|
-
# The set of developers that contributed to all of the contained ChangeSet s.
|
56
|
-
def developers
|
57
|
-
result = []
|
58
|
-
each do |changeset|
|
59
|
-
result << changeset.developer unless result.index(changeset.developer)
|
60
|
-
end
|
61
|
-
result
|
62
|
-
end
|
63
|
-
|
64
|
-
# The latest ChangeSet (with the latest time)
|
65
|
-
# or nil if there are none.
|
66
|
-
def latest
|
67
|
-
result = nil
|
68
|
-
each do |changeset|
|
69
|
-
result = changeset if result.nil? || result.time < changeset.time
|
70
|
-
end
|
71
|
-
result
|
72
|
-
end
|
73
|
-
|
74
|
-
# Adds a Change or a ChangeSet.
|
75
|
-
# If the argument is a Change and no corresponding ChangeSet exists,
|
76
|
-
# a new ChangeSet is created, added, and the Change is added to that ChangeSet -
|
77
|
-
# and then finally the newly created ChangeSet is returned.
|
78
|
-
# Otherwise nil is returned.
|
79
|
-
def add(change_or_changeset)
|
80
|
-
if(change_or_changeset.is_a?(ChangeSet))
|
81
|
-
@changesets << change_or_changeset
|
82
|
-
return change_or_changeset
|
83
|
-
else
|
84
|
-
changeset = @changesets.find { |a_changeset| a_changeset.can_contain?(change_or_changeset) }
|
85
|
-
if(changeset.nil?)
|
86
|
-
changeset = ChangeSet.new
|
87
|
-
@changesets << changeset
|
88
|
-
changeset << change_or_changeset
|
89
|
-
return changeset
|
90
|
-
end
|
91
|
-
changeset << change_or_changeset
|
92
|
-
return nil
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def push(*change_or_changesets)
|
97
|
-
change_or_changesets.each { |change_or_changeset| self << (change_or_changeset) }
|
98
|
-
self
|
99
|
-
end
|
100
|
-
|
101
|
-
# The most recent time of all the ChangeSet s.
|
102
|
-
def time
|
103
|
-
time = nil
|
104
|
-
changesets.each do |changeset|
|
105
|
-
time = changeset.time if @time.nil? || @time < changeset.time
|
106
|
-
end
|
107
|
-
time
|
108
|
-
end
|
109
|
-
|
110
|
-
# Sorts the changesets according to time
|
111
|
-
def sort!
|
112
|
-
@changesets.sort!
|
113
|
-
self
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
# Represents a collection of Change that were committed at the same time.
|
119
|
-
# Non-transactional SCMs (such as CVS and StarTeam) emulate ChangeSet
|
120
|
-
# by grouping Change s that were committed by the same developer, with the
|
121
|
-
# same commit message, and within a "reasonably" small timespan.
|
122
|
-
class ChangeSet
|
123
|
-
include Enumerable
|
124
|
-
include XMLRPC::Marshallable
|
125
|
-
|
126
|
-
attr_reader :changes
|
127
|
-
attr_accessor :revision
|
128
|
-
attr_accessor :developer
|
129
|
-
attr_accessor :message
|
130
|
-
attr_accessor :time
|
131
|
-
|
132
|
-
def initialize(changes=[])
|
133
|
-
@changes = changes
|
134
|
-
end
|
135
|
-
|
136
|
-
def accept(visitor)
|
137
|
-
visitor.visit_changeset(self)
|
138
|
-
@changes.each{|change| change.accept(visitor)}
|
139
|
-
end
|
140
|
-
|
141
|
-
def << (change)
|
142
|
-
@changes << change
|
143
|
-
self.time = change.time if self.time.nil? || self.time < change.time unless change.time.nil?
|
144
|
-
self.developer = change.developer if change.developer
|
145
|
-
self.message = change.message if change.message
|
146
|
-
end
|
147
|
-
|
148
|
-
def [] (change)
|
149
|
-
@changes[change]
|
150
|
-
end
|
151
|
-
|
152
|
-
def each(&block)
|
153
|
-
@changes.each(&block)
|
154
|
-
end
|
155
|
-
|
156
|
-
def length
|
157
|
-
@changes.length
|
158
|
-
end
|
159
|
-
|
160
|
-
def time=(t)
|
161
|
-
raise "time must be a Time object - it was a #{t.class.name} with the string value #{t}" unless t.is_a?(Time)
|
162
|
-
raise "can't set time to an inferiour value than the previous value" if @time && (t < @time)
|
163
|
-
@time = t
|
164
|
-
end
|
165
|
-
|
166
|
-
def ==(other)
|
167
|
-
return false if !other.is_a?(self.class)
|
168
|
-
@changes == other.changes
|
169
|
-
end
|
170
|
-
|
171
|
-
def <=>(other)
|
172
|
-
@time <=> other.time
|
173
|
-
end
|
174
|
-
|
175
|
-
# Whether this instance can contain a Change. Used
|
176
|
-
# by non-transactional SCMs.
|
177
|
-
def can_contain?(change)
|
178
|
-
self.developer == change.developer &&
|
179
|
-
self.message == change.message &&
|
180
|
-
(self.time - change.time).abs < 60
|
181
|
-
end
|
182
|
-
|
183
|
-
# String representation that can be used for debugging.
|
184
|
-
def to_s
|
185
|
-
result = "#{revision} | #{developer} | #{time} | #{message}\n"
|
186
|
-
self.each do |change|
|
187
|
-
result << " " << change.to_s << "\n"
|
188
|
-
end
|
189
|
-
result
|
190
|
-
end
|
191
|
-
|
192
|
-
# Returns the identifier of the changeset. This is the revision
|
193
|
-
# (if defined) or an UTC time if revision is undefined.
|
194
|
-
def identifier
|
195
|
-
@revision || @time
|
196
|
-
end
|
197
|
-
|
198
|
-
end
|
199
|
-
|
200
|
-
# Represents a change to an individual file.
|
201
|
-
class Change
|
202
|
-
include XMLRPC::Marshallable
|
203
|
-
|
204
|
-
MODIFIED = "MODIFIED"
|
205
|
-
DELETED = "DELETED"
|
206
|
-
ADDED = "ADDED"
|
207
|
-
MOVED = "MOVED"
|
208
|
-
|
209
|
-
attr_accessor :status
|
210
|
-
attr_accessor :path
|
211
|
-
attr_accessor :previous_revision
|
212
|
-
attr_accessor :revision
|
213
|
-
|
214
|
-
# TODO: Remove redundant attributes that are in ChangeSet
|
215
|
-
attr_accessor :developer
|
216
|
-
attr_accessor :message
|
217
|
-
# This is a UTC ruby time
|
218
|
-
attr_accessor :time
|
219
|
-
|
220
|
-
def initialize(path=nil, status=nil, developer=nil, message=nil, revision=nil, time=nil)
|
221
|
-
@path, @developer, @message, @revision, @time, @status = path, developer, message, revision, time, status
|
222
|
-
end
|
223
|
-
|
224
|
-
def accept(visitor)
|
225
|
-
visitor.visit_change(self)
|
226
|
-
end
|
227
|
-
|
228
|
-
def to_s
|
229
|
-
"#{path} | #{revision}"
|
230
|
-
end
|
231
|
-
|
232
|
-
def developer=(developer)
|
233
|
-
raise "can't be null" if developer.nil?
|
234
|
-
@developer = developer
|
235
|
-
end
|
236
|
-
|
237
|
-
def message=(message)
|
238
|
-
raise "can't be null" if message.nil?
|
239
|
-
@message = message
|
240
|
-
end
|
241
|
-
|
242
|
-
def path=(path)
|
243
|
-
raise "can't be null" if path.nil?
|
244
|
-
@path = path
|
245
|
-
end
|
246
|
-
|
247
|
-
def revision=(revision)
|
248
|
-
raise "can't be null" if revision.nil?
|
249
|
-
@revision = revision
|
250
|
-
end
|
251
|
-
|
252
|
-
def time=(time)
|
253
|
-
raise "time must be a Time object" unless time.is_a?(Time)
|
254
|
-
@time = time
|
255
|
-
end
|
256
|
-
|
257
|
-
def ==(other)
|
258
|
-
return false if !other.is_a?(self.class)
|
259
|
-
self.path == other.path &&
|
260
|
-
self.developer == other.developer &&
|
261
|
-
self.message == other.message &&
|
262
|
-
self.revision == other.revision &&
|
263
|
-
self.time == other.time
|
264
|
-
end
|
265
|
-
|
266
|
-
end
|
267
|
-
|
268
|
-
end
|
data/lib/rscm/example.yaml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
--- !ruby/object:RSCM::RssService
|
2
|
-
rss_file: target/ngst.xml
|
3
|
-
title: NGST Changesets
|
4
|
-
url: http://damagecontrol.codehaus.org/
|
5
|
-
description: StarTeam changes for NGST
|
6
|
-
checkout_dir: target/ngst
|
7
|
-
interval: 10
|
8
|
-
port: 9090
|
9
|
-
scm: !ruby/object:RSCM::StarTeam
|
10
|
-
st_user_name: jimmitchell
|
11
|
-
st_password: gandalf1
|
12
|
-
st_server_name: "192.168.254.21"
|
13
|
-
st_server_port: 49201
|
14
|
-
st_project_name: "NGST Application"
|
15
|
-
st_view_name: "NGST Application"
|
16
|
-
st_folder_name: "java"
|
17
|
-
scm_web: !ruby/object:RSCM::SCMWeb::ViewCVS
|
18
|
-
view_cvs_url: http://cvs.damagecontrol.codehaus.org/
|
19
|
-
tracker: !ruby/object:RSCM::Tracker::JIRA
|
20
|
-
jira_project_id: NGST
|
21
|
-
jira_url: http://jira.ctcdcx.local:8080/
|
@@ -1,176 +0,0 @@
|
|
1
|
-
# Copyright 2005 by Aslak Hellesoy (aslak.hellesoy@gmail.com)
|
2
|
-
# All rights reserved.
|
3
|
-
#
|
4
|
-
# Permission is granted for use, copying, modification, distribution,
|
5
|
-
# and distribution of modified versions of this work as long as the
|
6
|
-
# above copyright notice is included.
|
7
|
-
|
8
|
-
require 'lib/multipart'
|
9
|
-
|
10
|
-
module Rake
|
11
|
-
|
12
|
-
# This publisher allows scripted submission of RubyForge's release files form.
|
13
|
-
class RubyForgeFilePublisher
|
14
|
-
# extension => [mime_type, rubyforge_bin_type_id, rubyforge_src_type_id]
|
15
|
-
FILE_TYPES = Hash.new(["application/octet-stream", 9999, 5900]) # default to "other", "other source"
|
16
|
-
FILE_TYPES.merge!(
|
17
|
-
".deb" => ["application/octet-stream", 1000],
|
18
|
-
|
19
|
-
# all of these can be source or binary
|
20
|
-
".rpm" => ["application/octet-stream", 2000, 5100],
|
21
|
-
".zip" => ["application/octet-stream", 3000, 5000],
|
22
|
-
".bz2" => ["application/octet-stream", 3100, 5010],
|
23
|
-
".gz" => ["application/octet-stream", 3110, 5020],
|
24
|
-
".jpg" => ["application/octet-stream", 8000],
|
25
|
-
".jpeg" => ["application/octet-stream", 8000],
|
26
|
-
".txt" => ["text/plain", 8100],
|
27
|
-
".html" => ["text/html", 8200],
|
28
|
-
".pdf" => ["application/octet-stream", 8300],
|
29
|
-
".ebuild" => ["application/octet-stream", 1300],
|
30
|
-
".exe" => ["application/octet-stream", 1100],
|
31
|
-
".dmg" => ["application/octet-stream", 1200],
|
32
|
-
".gem" => ["application/octet-stream", 1400],
|
33
|
-
".sig" => ["application/octet-stream", 8150]
|
34
|
-
)
|
35
|
-
|
36
|
-
# Returns an array of 2 elements where 1st is mime-type and 2nd is rubyforge-type
|
37
|
-
def types(filename, source)
|
38
|
-
extension = nil
|
39
|
-
if(filename =~ /.*(\.[a-zA-Z]*)/)
|
40
|
-
extension = $1
|
41
|
-
end
|
42
|
-
|
43
|
-
types = FILE_TYPES[extension]
|
44
|
-
if(types.length == 3 && source)
|
45
|
-
[types[0], types[2]]
|
46
|
-
else
|
47
|
-
types
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# processor_id
|
52
|
-
I386 = 1000
|
53
|
-
IA64 = 6000
|
54
|
-
ALPHA = 7000
|
55
|
-
ANY = 8000
|
56
|
-
PPC = 2000
|
57
|
-
MIPS = 3000
|
58
|
-
SPARC = 4000
|
59
|
-
ULTRA_SPARC = 5000
|
60
|
-
OTHER_PLATFORM = 9999
|
61
|
-
|
62
|
-
# Create a publisher for a RubyForge project with id +group_id+.
|
63
|
-
# The RubyForge +user+'s password must be specified in the environment
|
64
|
-
# variable RUBYFORGE_PASSWORD.
|
65
|
-
#
|
66
|
-
# This publisher will upload/release a +file+ for a RubyForge project
|
67
|
-
# with id +group_id+, under the release package +package_id+ and
|
68
|
-
# name the release +release_name+.
|
69
|
-
#
|
70
|
-
# The package_id can be found by viewing the source of the HTML page
|
71
|
-
# http://rubyforge.org/frs/admin/qrs.php?package=&group_id=YOUR_GROUP_ID
|
72
|
-
# Look for a select tag named package_id and see what the alternatives are.
|
73
|
-
#
|
74
|
-
# The optional argument +source+ can be set to true if the file
|
75
|
-
# pointed to by +filename+ is a source file of some sort. This is
|
76
|
-
# to make sure RubyForge lists the file as the appropriate type.
|
77
|
-
# (This task will figure out the correct mime-type and rubyforge type
|
78
|
-
# based on the file's extension and the source parameter).
|
79
|
-
#
|
80
|
-
# If called with a block, the file will be uploaded at the end of the
|
81
|
-
# construction of this object. Otherwise, the +upload+ method will
|
82
|
-
# have to be called explicitly.
|
83
|
-
#
|
84
|
-
# The following attributes (which represent form data) have default
|
85
|
-
# values, but can be set/overridden explicitly:
|
86
|
-
#
|
87
|
-
# * processor_id
|
88
|
-
# * release_date
|
89
|
-
# * release_notes
|
90
|
-
# * change_log
|
91
|
-
#
|
92
|
-
def initialize(group_id, user, file, package_id, release_name, source=false) # :yield: self
|
93
|
-
|
94
|
-
@group_id = group_id
|
95
|
-
@user = user
|
96
|
-
@file = file
|
97
|
-
|
98
|
-
@form_data = {"preformatted" => "1", "submit" => "Release File" }
|
99
|
-
|
100
|
-
self.package_id = package_id
|
101
|
-
self.release_name = release_name
|
102
|
-
|
103
|
-
@types = types(file, source)
|
104
|
-
self.type_id = @types[1]
|
105
|
-
self.processor_id = ANY
|
106
|
-
self.release_date = Time.now.utc
|
107
|
-
self.release_notes = "Uploaded by Rake::RubyforgeFilePublisher"
|
108
|
-
self.release_changes = "This is a change log"
|
109
|
-
|
110
|
-
yield self if block_given?
|
111
|
-
upload if block_given?
|
112
|
-
end
|
113
|
-
|
114
|
-
def package_id=(s)
|
115
|
-
@form_data["package_id"] = s
|
116
|
-
end
|
117
|
-
def package_id
|
118
|
-
@form_data["package_id"]
|
119
|
-
end
|
120
|
-
def release_name=(s)
|
121
|
-
@form_data["release_name"] = s
|
122
|
-
end
|
123
|
-
def type_id=(s)
|
124
|
-
@form_data["type_id"] = s
|
125
|
-
end
|
126
|
-
def processor_id=(s)
|
127
|
-
@form_data["processor_id"] = s
|
128
|
-
end
|
129
|
-
def release_date=(t)
|
130
|
-
@form_data["release_date"] = t.strftime("%Y-%m-%d %H:%M")
|
131
|
-
end
|
132
|
-
def release_notes=(s)
|
133
|
-
@form_data["release_notes"] = s
|
134
|
-
end
|
135
|
-
def release_changes=(s)
|
136
|
-
@form_data["release_changes"] = s
|
137
|
-
end
|
138
|
-
def preformatted=(b)
|
139
|
-
@form_data["preformatted"] = b ? "1" : "0"
|
140
|
-
end
|
141
|
-
|
142
|
-
def upload
|
143
|
-
Net::HTTP.start('rubyforge.org', 80) do |http|
|
144
|
-
|
145
|
-
# log in so we get a cookie. we need it to post the upload form.
|
146
|
-
password = ENV['RUBYFORGE_PASSWORD']
|
147
|
-
raise "The RUBYFORGE_PASSWORD environment variable is not set.\n" +
|
148
|
-
"It can be passed on the Rake command line with RUBYFORGE_PASSWORD=<your password>" if password.nil?
|
149
|
-
|
150
|
-
response, data = http.post("/account/login.php", "form_loginname=#{@user}&form_pw=#{password}&login=Login")
|
151
|
-
cookie = CGI::Cookie.parse(response['set-cookie'])['session_ser'].to_s
|
152
|
-
header = {"Cookie" => cookie, "Host" => "rubyforge.org"}
|
153
|
-
|
154
|
-
response, data = http.get(response['location'], header)
|
155
|
-
|
156
|
-
upload_form = "/frs/admin/qrs.php?package=#{package_id}&group_id=#{@group_id}"
|
157
|
-
response, data = http.get(upload_form, header)
|
158
|
-
|
159
|
-
params = []
|
160
|
-
@form_data.each do |k, v|
|
161
|
-
params << Net::Param.new(k,v)
|
162
|
-
end
|
163
|
-
params << Net::FileParam.new("userfile", @file, @types[0])
|
164
|
-
header["Referer"] = "http://rubyforge.org#{upload_form}"
|
165
|
-
response, data = http.post_multipart(upload_form, params, header)
|
166
|
-
|
167
|
-
File.open("rf.html", "w") { |io|
|
168
|
-
io.write data
|
169
|
-
}
|
170
|
-
# upload_redirect = response['location']
|
171
|
-
# response, data = http.get(upload_redirect, header)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
end
|
176
|
-
end
|