xforge 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,5 +1,13 @@
1
1
  = XForge Changelog
2
2
 
3
+ == Version 0.1.5
4
+
5
+ This release of XForge adds functionality to access scm browsers (ViewCvs) and RSCM objects.
6
+
7
+ * Refactored classes into separate files
8
+ * Added Project.scm_web to access a ViewCvs object
9
+ * Added ViewCvs.scms to access an array of RSCM::Cvs
10
+
3
11
  == Version 0.1.4
4
12
 
5
13
  This is the first functional release of XForge, a Ruby library and Rake task to automate release of
data/Rakefile CHANGED
@@ -10,12 +10,13 @@ $:.unshift('lib')
10
10
  require 'xforge'
11
11
  require 'rake/gempackagetask'
12
12
  require 'rake/contrib/rubyforgepublisher'
13
+ require 'rake/contrib/xforge'
13
14
  require 'rake/clean'
14
15
  require 'rake/testtask'
15
16
  require 'rake/rdoctask'
16
17
 
17
18
  PKG_NAME = "xforge"
18
- PKG_VERSION = "0.1.4"
19
+ PKG_VERSION = "0.1.5"
19
20
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
20
21
  PKG_FILES = FileList[
21
22
  '[A-Z]*',
@@ -0,0 +1,24 @@
1
+ module ScmWeb
2
+ class ViewCvs
3
+
4
+ attr_reader :uri, :project
5
+
6
+ def initialize(uri, project)
7
+ @uri, @project = uri, project
8
+ end
9
+
10
+ def scms
11
+ unless(@scms)
12
+ require 'rscm'
13
+ cvs_root = open(uri) { |data| data.read }
14
+
15
+ @scms = []
16
+ scm = RSCM::Cvs.new
17
+ scm.root = ":pserver:anonymous@#{project.host.cvs_host_name}:#{project.host.cvs_path}/#{project.name}"
18
+ scm.mod = project.name
19
+ @scms << scm
20
+ end
21
+ @scms
22
+ end
23
+ end
24
+ end
data/lib/xforge.rb CHANGED
@@ -1,232 +1,8 @@
1
- require 'net/http'
2
- require 'open-uri'
3
- require 'rake/contrib/xforge'
4
-
5
- # XForge provides an object-oriented view of the administrative interface for
6
- # hosting environments similar to SourceForge.net. This includes http://rubyforge.org/,
7
- # http://sourceforge.net/, custom installations of GForge (http://gforge.org/) and other
8
- # clones (provided their URL schemes are the similar).
9
- #
10
- # Currently it only supports uploading of new releases, but later versions may support
11
- # other functions if there is a demand for it. Patches are welcome.
12
- #
13
- # Example usage:
14
- #
15
- # require 'xforge'
16
- #
17
- # rubyforge = XForge::Host.new('rubyforge.org')
18
- # xforge = rubyforge.project('xforge')
19
- # session = xforge.login(my_user, my_password)
20
- # session.release(['pkg/xforge-0.1.gem'], "XForge-0.1")
21
- #
22
- # Also see Rake::XForge::Release.
23
- #
24
- module XForge
25
- # A Host represents a proxy to a server
26
- class Host
27
- attr_reader :name
28
-
29
- # Create a new Host proxy located at +name+.
30
- def initialize(name)
31
- @name = name
32
- end
33
-
34
- # Get access to
35
- def project(name)
36
- Project.new(self, name)
37
- end
38
- end
39
-
40
- # A Project is an interface to a hosted project.
41
- class Project
42
- def initialize(host, name)
43
- @host = host
44
- @name = name
45
- end
46
-
47
- # Logs in and returns a Session
48
- def login(user_name, password)
49
- login_response = Net::HTTP.start(@host.name, 80) do |http|
50
- data = [
51
- "login=1",
52
- "form_loginname=#{user_name}",
53
- "form_pw=#{password}"
54
- ].join("&")
55
- http.post("/account/login.php", data)
56
- end
57
-
58
- cookie = login_response["set-cookie"]
59
- raise "Login failed" unless cookie
60
- Session.new(@host, self, cookie)
61
- end
62
-
63
- # The group_id of this project
64
- def group_id
65
- unless(@group_id)
66
- project_uri = "http://#{@host.name}/projects/#{@name}/"
67
- project_data = open(project_uri) { |data| data.read }
68
- @group_id = project_data[/[?&]group_id=(\d+)/, 1]
69
- raise "Couldn't get group_id" unless @group_id
70
- end
71
- @group_id
72
- end
73
- end
74
-
75
- # A Session object allows authenticated interaction with a Project, such as releasing files.
76
- #
77
- # A Session object can be obtained via Project.login
78
- #
79
- class Session
80
-
81
- BOUNDARY = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
82
-
83
- def initialize(host, project, cookie) # :nodoc:
84
- @host = host
85
- @project = project
86
- @headers = { "Cookie" => cookie }
87
- end
88
-
89
- # The package_id of our project
90
- def package_id
91
- unless(@package_id)
92
- release_uri = "http://#{@host.name}/frs/admin/?group_id=#{@project.group_id}"
93
- release_data = open(release_uri, @headers) { |data| data.read }
94
- @package_id = release_data[/[?&]package_id=(\d+)/, 1]
95
- raise "Couldn't get package_id" unless @package_id
96
- end
97
- @package_id
98
- end
99
-
100
- # Creates a new release containing the files specified by +filenames+ (Array) and named +release_name+.
101
- # Optional parameters are +processor+ (which should be one of the Processor constants), +release_notes+,
102
- # +release_changes+ and +preformatted+ which will appear on the releas page of the associated project.
103
- #
104
- def release(release_name, filenames, release_notes="", release_changes="", preformatted=true, processor=Processor::ANY)
105
- release_date = Time.now.strftime("%Y-%m-%d %H:%M")
106
- release_id = nil
107
-
108
- puts "About to release '#{release_name}'"
109
- puts "Files:"
110
- puts " " + filenames.join("\n ")
111
- puts "\nRelease Notes:\n"
112
- puts release_notes
113
- puts "\nRelease Changes:\n"
114
- puts release_changes
115
- puts "\nRelease Settings:\n"
116
- puts "Preformatted: #{preformatted}"
117
- puts "Processor: #{processor}"
118
- puts "\nStarting release..."
119
-
120
- xfiles = filenames.collect{|filename| XFile.new(filename)}
121
- xfiles.each_with_index do |xfile, i|
122
- first_file = i==0
123
- puts "Releasing #{xfile.basename}..."
124
-
125
- release_response = Net::HTTP.start(@host.name, 80) do |http|
126
- query_hash = if first_file then
127
- {
128
- "group_id" => @project.group_id,
129
- "package_id" => package_id,
130
- "type_id" => xfile.bin_type_id,
131
- "processor_id" => processor,
132
-
133
- "release_name" => release_name,
134
- "release_date" => release_date,
135
- "release_notes" => release_notes,
136
- "release_changes" => release_changes,
137
- "preformatted" => preformatted ? "1" : "0",
138
- "submit" => "1"
139
- }
140
- else
141
- {
142
- "group_id" => @project.group_id,
143
- "package_id" => package_id,
144
- "type_id" => xfile.bin_type_id,
145
- "processor_id" => processor,
146
-
147
- "step2" => "1",
148
- "release_id" => release_id,
149
- "submit" => "Add This File"
150
- }
151
- end
152
-
153
- query = "?" + query_hash.map do |(name, value)|
154
- [name, URI.encode(value.to_s)].join("=")
155
- end.join("&")
156
-
157
- data = [
158
- "--" + BOUNDARY,
159
- "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{xfile.basename}\"",
160
- "Content-Type: application/octet-stream",
161
- "Content-Transfer-Encoding: binary",
162
- "", xfile.data, ""
163
- ].join("\x0D\x0A")
164
-
165
- release_headers = @headers.merge(
166
- "Content-Type" => "multipart/form-data; boundary=#{BOUNDARY}"
167
- )
168
-
169
- target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
170
- http.post(target + query, data, release_headers)
171
- end
172
-
173
- if first_file then
174
- release_id = release_response.body[/release_id=(\d+)/, 1]
175
- raise("Couldn't get release id") unless release_id
176
- end
177
- end
178
- end
179
- end
180
-
181
- # Simple enumeration of processors. Used from Session.release
182
- class Processor
183
- I386 = 1000
184
- IA64 = 6000
185
- ALPHA = 7000
186
- ANY = 8000
187
- PPC = 2000
188
- MIPS = 3000
189
- SPARC = 4000
190
- ULTRA_SPARC = 5000
191
- OTHER_PLATFORM = 9999
192
- end
193
-
194
- class XFile # :nodoc:
195
-
196
- # extension => [mime_type, rubyforge_bin_type_id, rubyforge_src_type_id]
197
- FILE_TYPES = {
198
- ".deb" => ["application/octet-stream", 1000],
199
-
200
- # all of these can be source or binary
201
- ".rpm" => ["application/octet-stream", 2000, 5100],
202
- ".zip" => ["application/octet-stream", 3000, 5000],
203
- ".bz2" => ["application/octet-stream", 3100, 5010],
204
- ".gz" => ["application/octet-stream", 3110, 5020],
205
- ".jpg" => ["application/octet-stream", 8000],
206
- ".jpeg" => ["application/octet-stream", 8000],
207
- ".txt" => ["text/plain", 8100, 8100],
208
- ".html" => ["text/html", 8200, 8200],
209
- ".pdf" => ["application/octet-stream", 8300],
210
- ".ebuild" => ["application/octet-stream", 1300],
211
- ".exe" => ["application/octet-stream", 1100],
212
- ".dmg" => ["application/octet-stream", 1200],
213
- ".gem" => ["application/octet-stream", 1400],
214
- ".sig" => ["application/octet-stream", 8150]
215
- }
216
- FILE_TYPES.default = ["application/octet-stream", 9999, 5900] # default to "other", "other source"
217
-
218
- attr_reader :basename, :ext, :content_type, :bin_type_id, :src_type_id
219
-
220
- def initialize(filename)
221
- @filename = filename
222
- @basename = File.basename(filename)
223
- @ext = File.extname(filename)
224
- @content_type = FILE_TYPES[@ext][0]
225
- @bin_type_id = FILE_TYPES[@ext][1]
226
- end
227
-
228
- def data
229
- File.open(@filename, "rb") { |file| file.read }
230
- end
231
- end
232
- end
1
+ require 'xforge/version_parser'
2
+ require 'xforge/host'
3
+ require 'xforge/rubyforge'
4
+ require 'xforge/sourceforge'
5
+ require 'xforge/project'
6
+ require 'xforge/session'
7
+ require 'xforge/xfile'
8
+ require 'scm_web/view_cvs'
@@ -0,0 +1,16 @@
1
+ module XForge
2
+ # A Host represents a proxy to a server
3
+ class Host
4
+ attr_reader :name
5
+
6
+ # Create a new Host proxy located at +name+.
7
+ def initialize(name)
8
+ @name = name
9
+ end
10
+
11
+ # Get access to
12
+ def project(name)
13
+ Project.new(self, name)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,50 @@
1
+ require 'net/http'
2
+ require 'open-uri'
3
+
4
+ module XForge
5
+
6
+ # A Project is an interface to a hosted project.
7
+ class Project
8
+
9
+ attr_reader :host, :name
10
+
11
+ def initialize(host, name)
12
+ @host = host
13
+ @name = name
14
+ end
15
+
16
+ # Logs in and returns a Session
17
+ def login(user_name, password)
18
+ login_response = Net::HTTP.start(@host.name, 80) do |http|
19
+ data = [
20
+ "login=1",
21
+ "form_loginname=#{user_name}",
22
+ "form_pw=#{password}"
23
+ ].join("&")
24
+ http.post("/account/login.php", data)
25
+ end
26
+
27
+ cookie = login_response["set-cookie"]
28
+ raise "Login failed" unless cookie
29
+ Session.new(@host, self, cookie)
30
+ end
31
+
32
+ # The group_id of this project
33
+ def group_id
34
+ unless(@group_id)
35
+ regexp = /stats\/[?&]group_id=(\d+)/
36
+ project_uri = "http://#{@host.name}/projects/#{@name}/"
37
+ project_data = open(project_uri) { |data| data.read }
38
+ @group_id = project_data[regexp, 1]
39
+ raise "Couldn't get group_id" unless @group_id
40
+ end
41
+ @group_id
42
+ end
43
+
44
+ # The scm browser of this project
45
+ def scm_web
46
+ @scm_web ||= host.scm_web(self)
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,20 @@
1
+ module XForge
2
+ class RubyForge < Host
3
+ def initialize
4
+ super('rubyforge.org')
5
+ end
6
+
7
+ def cvs_path
8
+ "/var/cvs"
9
+ end
10
+
11
+ def cvs_host_name
12
+ name
13
+ end
14
+
15
+ def scm_web(project)
16
+ ::ScmWeb::ViewCvs.new("http://rubyforge.org/cgi-bin/viewcvs.cgi/?cvsroot=#{project.name}", project)
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,124 @@
1
+ require 'net/http'
2
+ require 'open-uri'
3
+
4
+ module XForge
5
+
6
+ # A Session object allows authenticated interaction with a Project, such as releasing files.
7
+ #
8
+ # A Session object can be obtained via Project.login
9
+ #
10
+ class Session
11
+
12
+ # Simple enumeration of processors. Used from Session.release
13
+ class Processor
14
+ I386 = 1000
15
+ IA64 = 6000
16
+ ALPHA = 7000
17
+ ANY = 8000
18
+ PPC = 2000
19
+ MIPS = 3000
20
+ SPARC = 4000
21
+ ULTRA_SPARC = 5000
22
+ OTHER_PLATFORM = 9999
23
+ end
24
+
25
+ BOUNDARY = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
26
+
27
+ def initialize(host, project, cookie) # :nodoc:
28
+ @host = host
29
+ @project = project
30
+ @headers = { "Cookie" => cookie }
31
+ end
32
+
33
+ # The package_id of our project
34
+ def package_id
35
+ unless(@package_id)
36
+ release_uri = "http://#{@host.name}/frs/admin/?group_id=#{@project.group_id}"
37
+ release_data = open(release_uri, @headers) { |data| data.read }
38
+ @package_id = release_data[/[?&]package_id=(\d+)/, 1]
39
+ raise "Couldn't get package_id" unless @package_id
40
+ end
41
+ @package_id
42
+ end
43
+
44
+ # Creates a new release containing the files specified by +filenames+ (Array) and named +release_name+.
45
+ # Optional parameters are +processor+ (which should be one of the Processor constants), +release_notes+,
46
+ # +release_changes+ and +preformatted+ which will appear on the releas page of the associated project.
47
+ #
48
+ def release(release_name, filenames, release_notes="", release_changes="", preformatted=true, processor=Processor::ANY)
49
+ release_date = Time.now.strftime("%Y-%m-%d %H:%M")
50
+ release_id = nil
51
+
52
+ puts "About to release '#{release_name}'"
53
+ puts "Files:"
54
+ puts " " + filenames.join("\n ")
55
+ puts "\nRelease Notes:\n"
56
+ puts release_notes
57
+ puts "\nRelease Changes:\n"
58
+ puts release_changes
59
+ puts "\nRelease Settings:\n"
60
+ puts "Preformatted: #{preformatted}"
61
+ puts "Processor: #{processor}"
62
+ puts "\nStarting release..."
63
+
64
+ xfiles = filenames.collect{|filename| XFile.new(filename)}
65
+ xfiles.each_with_index do |xfile, i|
66
+ first_file = i==0
67
+ puts "Releasing #{xfile.basename}..."
68
+
69
+ release_response = Net::HTTP.start(@host.name, 80) do |http|
70
+ query_hash = if first_file then
71
+ {
72
+ "group_id" => @project.group_id,
73
+ "package_id" => package_id,
74
+ "type_id" => xfile.bin_type_id,
75
+ "processor_id" => processor,
76
+
77
+ "release_name" => release_name,
78
+ "release_date" => release_date,
79
+ "release_notes" => release_notes,
80
+ "release_changes" => release_changes,
81
+ "preformatted" => preformatted ? "1" : "0",
82
+ "submit" => "1"
83
+ }
84
+ else
85
+ {
86
+ "group_id" => @project.group_id,
87
+ "package_id" => package_id,
88
+ "type_id" => xfile.bin_type_id,
89
+ "processor_id" => processor,
90
+
91
+ "step2" => "1",
92
+ "release_id" => release_id,
93
+ "submit" => "Add This File"
94
+ }
95
+ end
96
+
97
+ query = "?" + query_hash.map do |(name, value)|
98
+ [name, URI.encode(value.to_s)].join("=")
99
+ end.join("&")
100
+
101
+ data = [
102
+ "--" + BOUNDARY,
103
+ "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{xfile.basename}\"",
104
+ "Content-Type: application/octet-stream",
105
+ "Content-Transfer-Encoding: binary",
106
+ "", xfile.data, ""
107
+ ].join("\x0D\x0A")
108
+
109
+ release_headers = @headers.merge(
110
+ "Content-Type" => "multipart/form-data; boundary=#{BOUNDARY}"
111
+ )
112
+
113
+ target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
114
+ http.post(target + query, data, release_headers)
115
+ end
116
+
117
+ if first_file then
118
+ release_id = release_response.body[/release_id=(\d+)/, 1]
119
+ raise("Couldn't get release id") unless release_id
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,22 @@
1
+ module XForge
2
+
3
+ class SourceForge < Host
4
+ def initialize
5
+ super("sourceforge.net")
6
+ end
7
+
8
+ def cvs_path
9
+ "/cvsroot"
10
+ end
11
+
12
+ def cvs_host_name
13
+ "cvs.sourceforge.net"
14
+ end
15
+
16
+ def scm_web(project)
17
+ ::ScmWeb::ViewCvs.new("http://#{cvs_host_name}/viewcvs.py/#{project.name}/", project)
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,41 @@
1
+ module XForge
2
+
3
+ class XFile # :nodoc:
4
+
5
+ # extension => [mime_type, rubyforge_bin_type_id, rubyforge_src_type_id]
6
+ FILE_TYPES = {
7
+ ".deb" => ["application/octet-stream", 1000],
8
+
9
+ # all of these can be source or binary
10
+ ".rpm" => ["application/octet-stream", 2000, 5100],
11
+ ".zip" => ["application/octet-stream", 3000, 5000],
12
+ ".bz2" => ["application/octet-stream", 3100, 5010],
13
+ ".gz" => ["application/octet-stream", 3110, 5020],
14
+ ".jpg" => ["application/octet-stream", 8000],
15
+ ".jpeg" => ["application/octet-stream", 8000],
16
+ ".txt" => ["text/plain", 8100, 8100],
17
+ ".html" => ["text/html", 8200, 8200],
18
+ ".pdf" => ["application/octet-stream", 8300],
19
+ ".ebuild" => ["application/octet-stream", 1300],
20
+ ".exe" => ["application/octet-stream", 1100],
21
+ ".dmg" => ["application/octet-stream", 1200],
22
+ ".gem" => ["application/octet-stream", 1400],
23
+ ".sig" => ["application/octet-stream", 8150]
24
+ }
25
+ FILE_TYPES.default = ["application/octet-stream", 9999, 5900] # default to "other", "other source"
26
+
27
+ attr_reader :basename, :ext, :content_type, :bin_type_id, :src_type_id
28
+
29
+ def initialize(filename)
30
+ @filename = filename
31
+ @basename = File.basename(filename)
32
+ @ext = File.extname(filename)
33
+ @content_type = FILE_TYPES[@ext][0]
34
+ @bin_type_id = FILE_TYPES[@ext][1]
35
+ end
36
+
37
+ def data
38
+ File.open(@filename, "rb") { |file| file.read }
39
+ end
40
+ end
41
+ end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.8
3
3
  specification_version: 1
4
4
  name: xforge
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.4
7
- date: 2005-08-11
6
+ version: 0.1.5
7
+ date: 2005-08-12
8
8
  summary: Ruby based make-like utility.
9
9
  require_paths:
10
10
  - lib
@@ -37,8 +37,14 @@ files:
37
37
  - lib/rake/contrib/xforge.rb
38
38
  - lib/rake/contrib/xforge/base.rb
39
39
  - lib/rake/contrib/xforge/release.rb
40
+ - lib/scm_web/view_cvs.rb
41
+ - lib/xforge/host.rb
42
+ - lib/xforge/project.rb
43
+ - lib/xforge/rubyforge.rb
44
+ - lib/xforge/session.rb
45
+ - lib/xforge/sourceforge.rb
40
46
  - lib/xforge/version_parser.rb
41
- - doc/base_attrs.rdoc
47
+ - lib/xforge/xfile.rb
42
48
  test_files: []
43
49
  rdoc_options:
44
50
  - "--title"
data/doc/base_attrs.rdoc DELETED
@@ -1,2 +0,0 @@
1
- * user_name
2
- * password