rscm 0.2.1.1404 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|