xforge 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES ADDED
@@ -0,0 +1,5 @@
1
+ = XForge Changelog
2
+
3
+ == Version 0.1.0
4
+
5
+ * Added support for file releases
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2005 Aslak Hellesoy
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README ADDED
@@ -0,0 +1,55 @@
1
+ = XForge
2
+
3
+ This package contains XForge, a simple library to interact with RubyForge,
4
+ SourceForge, GForge or other SourceForge clones.
5
+
6
+ XForge has the following features:
7
+
8
+ * Look up projects by unix name (no need to worry about group_id or package_id).
9
+
10
+ * Upload new releases (with multiple files if desired).
11
+
12
+ * Rake integration.
13
+
14
+ == Download/Installation
15
+
16
+ The latest version of XForge can be found at
17
+
18
+ * http://rubyforge.org/project/showfiles.php?group_id=801
19
+
20
+ Download and install XForge with the following.
21
+
22
+ gem install xforge
23
+
24
+ (You may need administrative privileges for this).
25
+
26
+ == Usage
27
+
28
+ See XForge and Rake::XForge::Release.
29
+
30
+ ---
31
+
32
+ == Credits
33
+
34
+ [<b>Aslak Hellesoy</b>] Maintainer of this project.
35
+
36
+ [<b>David Heinemeier Hansson</b>] For the HTTP POST code and the idea to parse ids from project pages.
37
+
38
+ [<b>Jim Weirich</b>] For Rake, making XForge functionality more available to Ruby developers.
39
+
40
+ == Support
41
+
42
+ The XForge homepage is http://xforge.rubyforge.org. You can find the XForge
43
+ RubyForge page at http://rubyforge.org/projects/xforge.
44
+
45
+ Feel free to submit patches, bug reports or feature requests via XForge's issue tracker on RubyForge.
46
+
47
+ For other information, feel free to ask on the ruby-talk mailing list
48
+ (which is mirrored to comp.lang.ruby) or contact
49
+ aslak hellesoy gmail com.
50
+
51
+ == License
52
+
53
+ XForge is available under an MIT-style license.
54
+
55
+ :include: MIT-LICENSE
@@ -0,0 +1,113 @@
1
+ # Rakefile for XForge -*- ruby -*-
2
+
3
+ # Copyright 2003, 2004 by Jim Weirich (jim@weirichhouse.org)
4
+ # All rights reserved.
5
+
6
+ # This file is may be distributed under an MIT style license. See
7
+ # MIT-LICENSE for details.
8
+
9
+ $:.unshift('lib')
10
+ require 'xforge'
11
+ require 'rake/gempackagetask'
12
+ require 'rake/clean'
13
+ require 'rake/testtask'
14
+ require 'rake/rdoctask'
15
+
16
+ # Create a task to build the RDOC documentation tree.
17
+ rd = Rake::RDocTask.new("rdoc") { |rdoc|
18
+ rdoc.rdoc_dir = 'html'
19
+ # rdoc.template = 'kilmer'
20
+ # rdoc.template = 'css2'
21
+ # rdoc.template = 'doc/jamis.rb'
22
+ rdoc.title = "XForge"
23
+ rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'README'
24
+ rdoc.rdoc_files.include('README', 'MIT-LICENSE', 'TODO', 'CHANGES')
25
+ rdoc.rdoc_files.include('lib/**/*.rb', 'doc/**/*.rdoc')
26
+ }
27
+
28
+ # ====================================================================
29
+ # Create a task that will package the Rake software into distributable
30
+ # tar, zip and gem files.
31
+
32
+ PKG_VERSION = "0.1"
33
+ PKG_FILES = FileList[
34
+ '[A-Z]*',
35
+ 'lib/**/*.rb',
36
+ 'doc/**/*'
37
+ ]
38
+
39
+ if ! defined?(Gem)
40
+ puts "Package Target requires RubyGEMs"
41
+ else
42
+ spec = Gem::Specification.new do |s|
43
+
44
+ #### Basic information.
45
+
46
+ s.name = 'xforge'
47
+ s.version = PKG_VERSION
48
+ s.summary = "Ruby based make-like utility."
49
+ s.description = <<-EOF
50
+ XForge is a simple library to interact with RubyForge, SourceForge, GForge or other SourceForge clones.
51
+ EOF
52
+
53
+ s.files = PKG_FILES.to_a
54
+ s.require_path = 'lib'
55
+
56
+ #### Documentation and testing.
57
+
58
+ s.has_rdoc = true
59
+ s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
60
+ s.rdoc_options <<
61
+ '--title' << 'XForge' <<
62
+ '--main' << 'README' <<
63
+ '--line-numbers'
64
+
65
+ #### Author and project details.
66
+
67
+ s.author = "Aslak Hellesoy"
68
+ s.email = "aslak.hellesoy@gmail.com"
69
+ s.homepage = "http://xforge.rubyforge.org"
70
+ s.rubyforge_project = "xforge"
71
+ end
72
+
73
+ Rake::GemPackageTask.new(spec) do |pkg|
74
+ pkg.need_zip = true
75
+ pkg.need_tar = true
76
+ end
77
+ end
78
+
79
+ # Support Tasks ------------------------------------------------------
80
+
81
+ def egrep(pattern)
82
+ Dir['**/*.rb'].each do |fn|
83
+ count = 0
84
+ open(fn) do |f|
85
+ while line = f.gets
86
+ count += 1
87
+ if line =~ pattern
88
+ puts "#{fn}:#{count}:#{line}"
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ desc "Look for TODO and FIXME tags in the code"
96
+ task :todo do
97
+ egrep /#.*(FIXME|TODO|TBD)/
98
+ end
99
+
100
+ task :release => [:gem] do
101
+ release_files = FileList[
102
+ 'pkg/*.gem',
103
+ 'CHANGES'
104
+ ]
105
+
106
+ Rake::XForge::Release.new('xforge') do |xf|
107
+ # Never hardcode user name and password in the Rakefile!
108
+ xf.user_name = ENV['RUBYFORGE_USER']
109
+ xf.password = ENV['RUBYFORGE_PASSWORD']
110
+ xf.files = release_files.to_a
111
+ xf.release_name = "XForge 0.1"
112
+ end
113
+ end
data/TODO ADDED
@@ -0,0 +1,9 @@
1
+ = XForge Project -- To Do List
2
+
3
+ Send suggestions for this list to mailto:aslak.hellesoy@gmail.org.
4
+
5
+ === To Do
6
+ * Retrieve SCM info as RSCM objects
7
+ * Retrieve tracker info
8
+
9
+ (moved DONE list to CHANGES file)
@@ -0,0 +1,2 @@
1
+ require 'rake/contrib/xforge/base'
2
+ require 'rake/contrib/xforge/release'
@@ -0,0 +1,43 @@
1
+ module Rake
2
+ module XForge
3
+
4
+ # Base class for XForge tasks
5
+ class Base
6
+ attr_writer :user_name, :password
7
+
8
+ def initialize(project_name, xforge_host="rubyforge.org")
9
+ @project_name = project_name
10
+ @host = ::XForge::Host.new(xforge_host)
11
+
12
+ set_defaults
13
+
14
+ if(block_given?)
15
+ yield self
16
+ execute
17
+ end
18
+ end
19
+
20
+ protected
21
+
22
+ def set_defaults
23
+ end
24
+
25
+ def user_name
26
+ if(@user_name.nil?)
27
+ print "#{@host.name} user: "
28
+ @user_name = STDIN.gets.chomp
29
+ end
30
+ @user_name
31
+ end
32
+
33
+ def password
34
+ if(@password.nil?)
35
+ print "#{@host.name} password: "
36
+ @password = STDIN.gets.chomp
37
+ end
38
+ @password
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,71 @@
1
+ require 'rake/contrib/xforge/release'
2
+
3
+ module Rake
4
+ module XForge
5
+
6
+ # This Rake task releases files to RubyForge or other SourceForge clones. In its most simple usage it looks like:
7
+ #
8
+ # # Create a new release of the xforge project on Rubyforge.
9
+ # task :release => [:gem] do
10
+ # Rake::XForge::Release.new('xforge') {}
11
+ # end
12
+ #
13
+ # The previous example will use defaults where it can. It will prompt you for your RubyForge user name
14
+ # and password before it uploads all gems under the pkg folder and creates a RubyForge release.
15
+ #
16
+ # While defaults are nice, you may want a little more control. You can specify additional attributes:
17
+ #
18
+ # :include: base_attrs.rdoc
19
+ # * files - an array of files that should go into the release
20
+ # * release_name - name of the release
21
+ #
22
+ # Example:
23
+ #
24
+ # task :release => [:gem] do
25
+ # release_files = FileList[
26
+ # 'pkg/*.gem',
27
+ # 'CHANGES'
28
+ # ]
29
+ #
30
+ # Rake::XForge::Release.new('xforge') do |xf|
31
+ # # Never hardcode user name and password in the Rakefile!
32
+ # xf.user_name = ENV['RUBYFORGE_USER']
33
+ # xf.password = ENV['RUBYFORGE_PASSWORD']
34
+ # xf.files = release_files.to_a
35
+ # xf.release_name = "XForge 0.1"
36
+ # end
37
+ # end
38
+ #
39
+ # This can be invoked with
40
+ #
41
+ # rake release RUBYFORGE_USER=aslak_hellesoy RUBYFORGE_PASSWORD=nahnotreal
42
+ #
43
+ # If you don't like blocks, you can do like this:
44
+ #
45
+ # task :release => [:gem] do
46
+ # xf = Rake::XForge::Release.new('xforge')
47
+ # ... # Set additional attributes
48
+ # xf.execute
49
+ # end
50
+ #
51
+ class Release < Base
52
+
53
+ attr_accessor :files, :release_name
54
+
55
+ protected
56
+
57
+ def set_defaults
58
+ @files = ["pkg/#{PKG_FILE_NAME}.gem"] if defined? PKG_FILE_NAME
59
+ @release_name = "#{PKG_NAME}-#{PKG_VERSION}" if (defined? PKG_NAME && defined? PKG_VERSION)
60
+ end
61
+
62
+ def execute
63
+ project = @host.project(@project_name)
64
+ u = user_name
65
+ session = project.login(u, password)
66
+ session.release(@files, @release_name)
67
+ end
68
+
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,218 @@
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(filenames, release_name, processor=Processor::ANY, release_notes="", release_changes="", preformatted=true)
105
+ release_date = Time.now.strftime("%Y-%m-%d %H:%M")
106
+
107
+ xfiles = filenames.collect{|filename| XFile.new(filename)}
108
+ xfiles.each_with_index do |xfile, i|
109
+ first_file = i==0
110
+ puts "Releasing #{xfile.basename}..."
111
+
112
+ release_response = Net::HTTP.start(@host.name, 80) do |http|
113
+ query_hash = if first_file then
114
+ {
115
+ "group_id" => @project.group_id,
116
+ "package_id" => package_id,
117
+ "type_id" => xfile.bin_type_id,
118
+ "processor_id" => processor,
119
+
120
+ "release_name" => release_name,
121
+ "release_date" => release_date,
122
+ "release_notes" => release_notes,
123
+ "release_changes" => release_changes,
124
+ "preformatted" => preformatted ? "1" : "0",
125
+ "submit" => "1"
126
+ }
127
+ else
128
+ {
129
+ "group_id" => @project.group_id,
130
+ "package_id" => package_id,
131
+ "type_id" => xfile.bin_type_id,
132
+ "processor_id" => processor,
133
+
134
+ "step2" => "1",
135
+ "release_id" => release_id,
136
+ "submit" => "Add This File"
137
+ }
138
+ end
139
+
140
+ query = "?" + query_hash.map do |(name, value)|
141
+ [name, URI.encode(value.to_s)].join("=")
142
+ end.join("&")
143
+
144
+ data = [
145
+ "--" + BOUNDARY,
146
+ "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{xfile.basename}\"",
147
+ "Content-Type: application/octet-stream",
148
+ "Content-Transfer-Encoding: binary",
149
+ "", xfile.data, ""
150
+ ].join("\x0D\x0A")
151
+
152
+ release_headers = @headers.merge(
153
+ "Content-Type" => "multipart/form-data; boundary=#{BOUNDARY}"
154
+ )
155
+
156
+ target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
157
+ http.post(target + query, data, release_headers)
158
+ end
159
+
160
+ if first_file then
161
+ release_id = release_response.body[/release_id=(\d+)/, 1]
162
+ raise("Couldn't get release id") unless release_id
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ # Simple enumeration of processors. Used from Session.release
169
+ class Processor
170
+ I386 = 1000
171
+ IA64 = 6000
172
+ ALPHA = 7000
173
+ ANY = 8000
174
+ PPC = 2000
175
+ MIPS = 3000
176
+ SPARC = 4000
177
+ ULTRA_SPARC = 5000
178
+ OTHER_PLATFORM = 9999
179
+ end
180
+
181
+ class XFile # :nodoc:
182
+ # extension => [mime_type, rubyforge_bin_type_id, rubyforge_src_type_id]
183
+ FILE_TYPES = {
184
+ ".deb" => ["application/octet-stream", 1000],
185
+
186
+ # all of these can be source or binary
187
+ ".rpm" => ["application/octet-stream", 2000, 5100],
188
+ ".zip" => ["application/octet-stream", 3000, 5000],
189
+ ".bz2" => ["application/octet-stream", 3100, 5010],
190
+ ".gz" => ["application/octet-stream", 3110, 5020],
191
+ ".jpg" => ["application/octet-stream", 8000],
192
+ ".jpeg" => ["application/octet-stream", 8000],
193
+ ".txt" => ["text/plain", 8100],
194
+ ".html" => ["text/html", 8200],
195
+ ".pdf" => ["application/octet-stream", 8300],
196
+ ".ebuild" => ["application/octet-stream", 1300],
197
+ ".exe" => ["application/octet-stream", 1100],
198
+ ".dmg" => ["application/octet-stream", 1200],
199
+ ".gem" => ["application/octet-stream", 1400],
200
+ ".sig" => ["application/octet-stream", 8150]
201
+ }
202
+ FILE_TYPES.default = ["application/octet-stream", 9999, 5900] # default to "other", "other source"
203
+
204
+ attr_reader :basename, :ext, :content_type, :bin_type_id, :src_type_id
205
+
206
+ def initialize(filename)
207
+ @filename = filename
208
+ @basename = File.basename(filename)
209
+ @ext = File.extname(filename)
210
+ @content_type = FILE_TYPES[@ext][0]
211
+ @bin_type_id = FILE_TYPES[@ext][1]
212
+ end
213
+
214
+ def data
215
+ File.open(@filename, "rb") { |file| file.read }
216
+ end
217
+ end
218
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.8
3
+ specification_version: 1
4
+ name: xforge
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.1"
7
+ date: 2005-07-18
8
+ summary: Ruby based make-like utility.
9
+ require_paths:
10
+ - lib
11
+ email: aslak.hellesoy@gmail.com
12
+ homepage: http://xforge.rubyforge.org
13
+ rubyforge_project: xforge
14
+ description: "XForge is a simple library to interact with RubyForge, SourceForge, GForge or
15
+ other SourceForge clones."
16
+ autorequire:
17
+ default_executable:
18
+ bindir: bin
19
+ has_rdoc: true
20
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
21
+ requirements:
22
+ -
23
+ - ">"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.0.0
26
+ version:
27
+ platform: ruby
28
+ authors:
29
+ - Aslak Hellesoy
30
+ files:
31
+ - CHANGES
32
+ - MIT-LICENSE
33
+ - Rakefile
34
+ - README
35
+ - TODO
36
+ - lib/xforge.rb
37
+ - lib/rake/contrib/xforge.rb
38
+ - lib/rake/contrib/xforge/base.rb
39
+ - lib/rake/contrib/xforge/release.rb
40
+ test_files: []
41
+ rdoc_options:
42
+ - "--title"
43
+ - XForge
44
+ - "--main"
45
+ - README
46
+ - "--line-numbers"
47
+ extra_rdoc_files:
48
+ - README
49
+ - MIT-LICENSE
50
+ - TODO
51
+ - CHANGES
52
+ executables: []
53
+ extensions: []
54
+ requirements: []
55
+ dependencies: []