xforge 0.3.5 → 0.4.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/CHANGES +34 -0
- data/Rakefile +5 -5
- data/lib/meta_project.rb +6 -0
- data/lib/meta_project/project.rb +4 -0
- data/lib/meta_project/project/base.rb +7 -0
- data/lib/meta_project/project/codehaus.rb +1 -0
- data/lib/meta_project/project/codehaus/codehaus_project_svn.rb +26 -0
- data/lib/meta_project/project/trac.rb +1 -0
- data/lib/meta_project/project/trac/trac_project.rb +26 -0
- data/lib/meta_project/project/xforge.rb +5 -0
- data/lib/meta_project/project/xforge/ruby_forge.rb +46 -0
- data/lib/meta_project/project/xforge/session.rb +162 -0
- data/lib/meta_project/project/xforge/source_forge.rb +46 -0
- data/lib/meta_project/project/xforge/xfile.rb +45 -0
- data/lib/meta_project/project/xforge/xforge_base.rb +76 -0
- data/lib/meta_project/project_analyzer.rb +36 -0
- data/lib/meta_project/scm_web.rb +53 -0
- data/lib/meta_project/tracker.rb +6 -0
- data/lib/meta_project/tracker/base.rb +18 -0
- data/lib/meta_project/tracker/digit_issues.rb +24 -0
- data/lib/meta_project/tracker/issue.rb +11 -0
- data/lib/meta_project/tracker/jira.rb +1 -0
- data/lib/meta_project/tracker/jira/jira_tracker.rb +68 -0
- data/lib/meta_project/tracker/trac.rb +1 -0
- data/lib/meta_project/tracker/trac/trac_tracker.rb +29 -0
- data/lib/meta_project/tracker/xforge.rb +3 -0
- data/lib/meta_project/tracker/xforge/ruby_forge_tracker.rb +17 -0
- data/lib/meta_project/tracker/xforge/source_forge_tracker.rb +17 -0
- data/lib/meta_project/tracker/xforge/xforge_tracker.rb +83 -0
- data/lib/{xforge → meta_project}/version_parser.rb +6 -6
- data/lib/rake/contrib/xforge/base.rb +2 -3
- data/lib/rake/contrib/xforge/news_publisher.rb +1 -5
- data/lib/rake/contrib/xforge/release.rb +3 -7
- data/lib/xforge.rb +0 -1
- metadata +30 -27
- data/lib/scm_web/base.rb +0 -12
- data/lib/scm_web/file_uri.rb +0 -21
- data/lib/scm_web/view_cvs.rb +0 -44
- data/lib/tracker/base.rb +0 -16
- data/lib/tracker/bugzilla/project.rb +0 -8
- data/lib/tracker/digit_issues.rb +0 -22
- data/lib/tracker/fog_bugz/project.rb +0 -8
- data/lib/tracker/issue.rb +0 -9
- data/lib/tracker/jira.rb +0 -2
- data/lib/tracker/jira/host.rb +0 -40
- data/lib/tracker/jira/project.rb +0 -43
- data/lib/tracker/mantis/project.rb +0 -8
- data/lib/tracker/scarab/project.rb +0 -8
- data/lib/tracker/trac.rb +0 -1
- data/lib/tracker/trac/project.rb +0 -35
- data/lib/tracker/xforge.rb +0 -2
- data/lib/tracker/xforge/base.rb +0 -77
- data/lib/tracker/xforge/rubyforge.rb +0 -7
- data/lib/xforge/host.rb +0 -26
- data/lib/xforge/project.rb +0 -87
- data/lib/xforge/rubyforge.rb +0 -50
- data/lib/xforge/session.rb +0 -158
- data/lib/xforge/sourceforge.rb +0 -46
- data/lib/xforge/xfile.rb +0 -41
data/lib/tracker/trac/project.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
module Tracker
|
2
|
-
module Trac
|
3
|
-
class TracProject < Base
|
4
|
-
include DigitIssues
|
5
|
-
include ::ScmWeb::FileUri
|
6
|
-
|
7
|
-
attr_accessor :uri, :svn_path
|
8
|
-
def initialize(uri=nil, svn_path=nil)
|
9
|
-
@uri, @svn_path = uri, svn_path
|
10
|
-
end
|
11
|
-
|
12
|
-
def issue(issue_identifier)
|
13
|
-
issue_uri = "#{@uri}/ticket/#{issue_identifier}"
|
14
|
-
begin
|
15
|
-
html = open(issue_uri) { |data| data.read }
|
16
|
-
summary = html[/Ticket ##{issue_identifier}\s*<\/h1>\s*<h2>([^<]*)<\/h2>/n, 1]
|
17
|
-
Issue.new(issue_uri, summary)
|
18
|
-
rescue OpenURI::HTTPError
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
OVERVIEW = "\#{@uri}/log/\#{@svn_path}/\#{path}"
|
24
|
-
HTML = "\#{@uri}/file/\#{@svn_path}/\#{path}?rev=\#{revision}"
|
25
|
-
RAW = "#{HTML}&format=txt"
|
26
|
-
DIFF = "\#{@uri}/changeset/\#{revision}"
|
27
|
-
URI_SPECS = {"overview" => OVERVIEW, "raw" => RAW, "html" => HTML, "diff" => DIFF}
|
28
|
-
|
29
|
-
def uri_specs
|
30
|
-
URI_SPECS
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/tracker/xforge.rb
DELETED
data/lib/tracker/xforge/base.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
module Tracker
|
2
|
-
module XForge
|
3
|
-
# TODO: rename to Project
|
4
|
-
class Base < ::Tracker::Base
|
5
|
-
include DigitIssues
|
6
|
-
|
7
|
-
attr_accessor :uri, :project
|
8
|
-
|
9
|
-
def initialize(uri=nil, project=nil)
|
10
|
-
@uri, @project = uri, project
|
11
|
-
end
|
12
|
-
|
13
|
-
# Finds an Issue by +identifier+
|
14
|
-
def issue(identifier)
|
15
|
-
sub_trackers = atids.collect {|atid| SubTracker.new(self, atid)}
|
16
|
-
sub_trackers.each do |sub_tracker|
|
17
|
-
issue = sub_tracker.issue(identifier)
|
18
|
-
return issue unless issue.nil?
|
19
|
-
end
|
20
|
-
nil
|
21
|
-
end
|
22
|
-
|
23
|
-
def markup(text)
|
24
|
-
text.gsub(identifier_regexp) do |match|
|
25
|
-
issue_identifier = $1
|
26
|
-
issue = issue(issue_identifier)
|
27
|
-
issue ? "<a href=\"#{issue.uri}\">#{issue.summary}</a>" : "\##{issue_identifier}"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class SubTracker
|
32
|
-
attr_reader :uri
|
33
|
-
|
34
|
-
def initialize(rubyforge, atid)
|
35
|
-
@rubyforge = rubyforge
|
36
|
-
@atid = atid
|
37
|
-
# FIXME: This will only show open items.
|
38
|
-
@uri = "#{rubyforge.uri}&atid=#{atid}&func=browse"
|
39
|
-
end
|
40
|
-
|
41
|
-
def issue(identifier)
|
42
|
-
html = open(uri) { |data| data.read }
|
43
|
-
|
44
|
-
regexp = /<a href=\"\/tracker\/index.php\?func=detail&aid=#{identifier}&group_id=\d+&atid=\d+\">(.*)<\/a>/
|
45
|
-
if(html =~ regexp)
|
46
|
-
issue_uri = @rubyforge.project.group_id_uri("tracker/index.php", "&atid=#{@atid}&func=detail&aid=#{identifier}")
|
47
|
-
return Issue.new(issue_uri, $1)
|
48
|
-
end
|
49
|
-
nil
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
# The ids of the subtrackers
|
56
|
-
def atids
|
57
|
-
html = open(uri) { |data| data.read }
|
58
|
-
|
59
|
-
# TODO: there has to be a better way to extract the atids from the HTML!
|
60
|
-
atids = []
|
61
|
-
offset = 0
|
62
|
-
look_for_atid = true
|
63
|
-
while(look_for_atid)
|
64
|
-
match_data = /\/tracker\/\?atid=(\d+)&group_id=\d*&func=browse/.match(html[offset..-1])
|
65
|
-
if(match_data)
|
66
|
-
offset += match_data.begin(1)
|
67
|
-
atids << match_data[1]
|
68
|
-
else
|
69
|
-
look_for_atid = false
|
70
|
-
end
|
71
|
-
end
|
72
|
-
atids
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
data/lib/xforge/host.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module XForge
|
2
|
-
# A Host represents a proxy to a server. Most of the time
|
3
|
-
# you don't want to use this class directly, but rather one
|
4
|
-
# of its subclasses. Example:
|
5
|
-
#
|
6
|
-
# require 'xforge'
|
7
|
-
#
|
8
|
-
# rubyforge = XForge::RubyForge.new
|
9
|
-
# xforge = rubyforge.project('xforge')
|
10
|
-
# session = xforge.login(my_user, my_password)
|
11
|
-
# session.release(["pkg/xforge-0.1.gem"], "XForge-0.1")
|
12
|
-
#
|
13
|
-
class Host
|
14
|
-
attr_reader :name
|
15
|
-
|
16
|
-
# Create a new Host proxy located at IP +name+.
|
17
|
-
def initialize(name)
|
18
|
-
@name = name
|
19
|
-
end
|
20
|
-
|
21
|
-
# Returns the Project with the given +unix_name+.
|
22
|
-
def project(unix_name)
|
23
|
-
Project.new(self, unix_name)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/lib/xforge/project.rb
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'net/https'
|
3
|
-
require 'open-uri'
|
4
|
-
|
5
|
-
module XForge
|
6
|
-
|
7
|
-
# A Project is an interface to a hosted project.
|
8
|
-
class Project
|
9
|
-
|
10
|
-
attr_reader :host, :unix_name
|
11
|
-
|
12
|
-
def initialize(host, unix_name)
|
13
|
-
@host = host
|
14
|
-
@unix_name = unix_name
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_yaml_properties
|
18
|
-
["@host", "@unix_name"]
|
19
|
-
end
|
20
|
-
|
21
|
-
# Logs in and returns a Session
|
22
|
-
def login(user_name, password)
|
23
|
-
http = Net::HTTP.new(@host.name, host.login_port)
|
24
|
-
|
25
|
-
# Can't get this to work, so login doesn't work on SourceForge yet!
|
26
|
-
# http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=net%2Fhttps.rb
|
27
|
-
if(host.login_port == 443)
|
28
|
-
http.use_ssl = true
|
29
|
-
http.ca_file = '/usr/share/ssl/cert.pem'
|
30
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
31
|
-
http.verify_depth = 5
|
32
|
-
end
|
33
|
-
|
34
|
-
login_response = http.start do |http|
|
35
|
-
data = [
|
36
|
-
"login=1",
|
37
|
-
"form_loginname=#{user_name}",
|
38
|
-
"form_pw=#{password}"
|
39
|
-
].join("&")
|
40
|
-
http.post("/account/login.php", data)
|
41
|
-
end
|
42
|
-
|
43
|
-
cookie = login_response["set-cookie"]
|
44
|
-
raise "Login failed" unless cookie
|
45
|
-
Session.new(@host, self, cookie)
|
46
|
-
end
|
47
|
-
|
48
|
-
# The group_id of this project
|
49
|
-
def group_id
|
50
|
-
unless(@group_id)
|
51
|
-
regexp = /stats\/[?&]group_id=(\d+)/
|
52
|
-
html = open(project_uri) { |data| data.read }
|
53
|
-
@group_id = html[regexp, 1]
|
54
|
-
raise "Couldn't get group_id" unless @group_id
|
55
|
-
end
|
56
|
-
@group_id
|
57
|
-
end
|
58
|
-
|
59
|
-
# The scm browser of this project
|
60
|
-
def scm_web
|
61
|
-
@scm_web ||= host.scm_web(self)
|
62
|
-
end
|
63
|
-
|
64
|
-
def project_uri
|
65
|
-
"http://#{@host.name}/projects/#{@unix_name}/"
|
66
|
-
end
|
67
|
-
|
68
|
-
def group_id_uri(path, postfix="")
|
69
|
-
"http://#{@host.name}/#{path}/?group_id=#{group_id}#{postfix}"
|
70
|
-
end
|
71
|
-
|
72
|
-
# The home page of this project
|
73
|
-
def home_page_uri
|
74
|
-
unless(@home_page)
|
75
|
-
html = open(project_uri) { |data| data.read }
|
76
|
-
@home_page = html[@host.home_page_regexp, 1]
|
77
|
-
raise "Couldn't get home_page" unless @home_page
|
78
|
-
end
|
79
|
-
@home_page
|
80
|
-
end
|
81
|
-
|
82
|
-
def tracker
|
83
|
-
@tracker ||= @host.tracker(self)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
data/lib/xforge/rubyforge.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
module XForge
|
2
|
-
class RubyForge < Host
|
3
|
-
def initialize
|
4
|
-
super('rubyforge.org')
|
5
|
-
end
|
6
|
-
|
7
|
-
def login_port
|
8
|
-
80
|
9
|
-
end
|
10
|
-
|
11
|
-
def cvs_server_path(project_unix_name)
|
12
|
-
"/var/cvs/#{project_unix_name}"
|
13
|
-
end
|
14
|
-
|
15
|
-
def cvs_host_name
|
16
|
-
name
|
17
|
-
end
|
18
|
-
|
19
|
-
def scm_web(project)
|
20
|
-
view_cvs = "http://rubyforge.org/cgi-bin/viewcvs.cgi/"
|
21
|
-
cvsroot = "?cvsroot=#{project.unix_name}"
|
22
|
-
path_cvs_root = "\#{path}#{cvsroot}"
|
23
|
-
path_cvs_root_rev = "#{path_cvs_root}&rev=\#{revision}"
|
24
|
-
|
25
|
-
overview = "#{view_cvs}#{path_cvs_root}"
|
26
|
-
raw = "#{view_cvs}*checkout*/#{path_cvs_root_rev}"
|
27
|
-
html = "#{view_cvs}#{path_cvs_root_rev}&content-type=text/vnd.viewcvs-markup"
|
28
|
-
diff = "#{view_cvs}\#{path}.diff#{cvsroot}&r1=\#{previous_revision}&r2=\#{revision}"
|
29
|
-
|
30
|
-
module_regexp = /href=\"(.+)\/\?cvsroot=#{project.unix_name}/
|
31
|
-
::ScmWeb::ViewCvs.new(
|
32
|
-
{"overview" => overview, "raw" => raw, "html" => html, "diff" => diff},
|
33
|
-
cvs_host_name,
|
34
|
-
cvs_server_path(project.unix_name),
|
35
|
-
project.unix_name,
|
36
|
-
module_regexp
|
37
|
-
)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Regexp used to find projects' home page
|
41
|
-
def home_page_regexp
|
42
|
-
# This seems a little volatile
|
43
|
-
/<a href=\"(\w*:\/\/[^\"]*)\"><img src=\"\/themes\/osx\/images\/ic\/home/
|
44
|
-
end
|
45
|
-
|
46
|
-
def tracker(project)
|
47
|
-
Tracker::XForge::RubyForgeProject.new(project.group_id_uri("tracker"), project)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
data/lib/xforge/session.rb
DELETED
@@ -1,158 +0,0 @@
|
|
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(query_hash)
|
98
|
-
|
99
|
-
data = [
|
100
|
-
"--" + BOUNDARY,
|
101
|
-
"Content-Disposition: form-data; name=\"userfile\"; filename=\"#{xfile.basename}\"",
|
102
|
-
"Content-Type: application/octet-stream",
|
103
|
-
"Content-Transfer-Encoding: binary",
|
104
|
-
"", xfile.data, ""
|
105
|
-
].join("\x0D\x0A")
|
106
|
-
|
107
|
-
headers = @headers.merge(
|
108
|
-
"Content-Type" => "multipart/form-data; boundary=#{BOUNDARY}"
|
109
|
-
)
|
110
|
-
|
111
|
-
target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
|
112
|
-
http.post(target + query, data, headers)
|
113
|
-
end
|
114
|
-
|
115
|
-
if first_file then
|
116
|
-
release_id = release_response.body[/release_id=(\d+)/, 1]
|
117
|
-
raise("Couldn't get release id") unless release_id
|
118
|
-
end
|
119
|
-
end
|
120
|
-
puts "Done!"
|
121
|
-
end
|
122
|
-
|
123
|
-
def publish_news(subject, details)
|
124
|
-
puts "About to publish news"
|
125
|
-
puts "Subject: '#{subject}'"
|
126
|
-
puts "Details:"
|
127
|
-
puts details
|
128
|
-
puts ""
|
129
|
-
|
130
|
-
release_response = Net::HTTP.start(@host.name, 80) do |http|
|
131
|
-
query_hash = {
|
132
|
-
"group_id" => @project.group_id,
|
133
|
-
"package_id" => package_id,
|
134
|
-
"post_changes" => "y",
|
135
|
-
"summary" => subject,
|
136
|
-
"details" => details
|
137
|
-
}
|
138
|
-
|
139
|
-
target = "/news/submit.php"
|
140
|
-
headers = @headers.merge(
|
141
|
-
"Content-Type" => "multipart/form-data"
|
142
|
-
)
|
143
|
-
http.post(target + query(query_hash), "", headers)
|
144
|
-
|
145
|
-
end
|
146
|
-
puts "Done!"
|
147
|
-
end
|
148
|
-
|
149
|
-
private
|
150
|
-
|
151
|
-
def query(query_hash)
|
152
|
-
"?" + query_hash.map do |(name, value)|
|
153
|
-
[name, URI.encode(value.to_s)].join("=")
|
154
|
-
end.join("&")
|
155
|
-
end
|
156
|
-
|
157
|
-
end
|
158
|
-
end
|