meta_project 0.4.12 → 0.4.13
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 +283 -277
- data/MIT-LICENSE +21 -21
- data/README +130 -126
- data/Rakefile +152 -152
- data/doc/base_attrs.rdoc +2 -2
- data/lib/meta_project.rb +11 -11
- data/lib/meta_project/core_ext/open_uri.rb +22 -22
- data/lib/meta_project/core_ext/pathname.rb +36 -36
- data/lib/meta_project/core_ext/string.rb +4 -4
- data/lib/meta_project/http/multipart.rb +31 -31
- data/lib/meta_project/patois/parser.rb +98 -98
- data/lib/meta_project/project.rb +4 -4
- data/lib/meta_project/project/base.rb +8 -8
- data/lib/meta_project/project/codehaus.rb +1 -1
- data/lib/meta_project/project/codehaus/codehaus_project_svn.rb +30 -30
- data/lib/meta_project/project/trac.rb +1 -1
- data/lib/meta_project/project/trac/trac_project.rb +53 -53
- data/lib/meta_project/project/xforge.rb +5 -5
- data/lib/meta_project/project/xforge/ruby_forge.rb +46 -46
- data/lib/meta_project/project/xforge/session.rb +177 -177
- data/lib/meta_project/project/xforge/source_forge.rb +49 -49
- data/lib/meta_project/project/xforge/xfile.rb +44 -44
- data/lib/meta_project/project/xforge/xforge_base.rb +81 -81
- data/lib/meta_project/project_analyzer.rb +35 -35
- data/lib/meta_project/release/freshmeat.rb +267 -267
- data/lib/meta_project/release/raa.rb +572 -572
- data/lib/meta_project/scm_web.rb +1 -1
- data/lib/meta_project/scm_web/browser.rb +111 -111
- data/lib/meta_project/scm_web/pathname.rb +88 -88
- data/lib/meta_project/tracker.rb +6 -6
- data/lib/meta_project/tracker/base.rb +23 -23
- data/lib/meta_project/tracker/digit_issues.rb +33 -33
- data/lib/meta_project/tracker/issue.rb +56 -56
- data/lib/meta_project/tracker/jira.rb +2 -2
- data/lib/meta_project/tracker/jira/jira_issues.rb +34 -34
- data/lib/meta_project/tracker/jira/jira_tracker.rb +148 -123
- data/lib/meta_project/tracker/trac.rb +1 -1
- data/lib/meta_project/tracker/trac/trac_tracker.rb +32 -32
- data/lib/meta_project/tracker/xforge.rb +3 -3
- data/lib/meta_project/tracker/xforge/ruby_forge_tracker.rb +17 -17
- data/lib/meta_project/tracker/xforge/source_forge_tracker.rb +17 -17
- data/lib/meta_project/tracker/xforge/xforge_tracker.rb +190 -190
- data/lib/meta_project/version_parser.rb +52 -52
- data/lib/rake/contrib/xforge.rb +3 -3
- data/lib/rake/contrib/xforge/base.rb +64 -64
- data/lib/rake/contrib/xforge/news_publisher.rb +97 -97
- data/lib/rake/contrib/xforge/release.rb +134 -134
- metadata +4 -3
@@ -1,50 +1,50 @@
|
|
1
|
-
require 'meta_project/tracker/xforge'
|
2
|
-
|
3
|
-
module MetaProject
|
4
|
-
module Project
|
5
|
-
module XForge
|
6
|
-
class SourceForge < XForgeBase
|
7
|
-
|
8
|
-
def initialize(unix_name, cvs_mod=nil)
|
9
|
-
super("sourceforge.net", unix_name, cvs_mod)
|
10
|
-
end
|
11
|
-
|
12
|
-
def tracker_class
|
13
|
-
::MetaProject::Tracker::XForge::SourceForgeTracker
|
14
|
-
end
|
15
|
-
|
16
|
-
protected
|
17
|
-
|
18
|
-
def create_cvs(unix_name, mod)
|
19
|
-
RSCM::Cvs.new(":pserver:anonymous@cvs.sourceforge.net:/cvsroot/#{unix_name}", mod)
|
20
|
-
end
|
21
|
-
|
22
|
-
def create_view_cvs(unix_name, mod)
|
23
|
-
view_cvs = "http://cvs.sourceforge.net/viewcvs.py/"
|
24
|
-
unix_name_mod = "#{unix_name}/#{mod}"
|
25
|
-
project_path = "#{unix_name_mod}/\#{path}"
|
26
|
-
rev = "rev=\#{revision}"
|
27
|
-
|
28
|
-
dir = "#{view_cvs}#{project_path}"
|
29
|
-
history = "#{view_cvs}#{project_path}"
|
30
|
-
raw = "#{view_cvs}*checkout*/#{project_path}?#{rev}"
|
31
|
-
html = "#{history}?#{rev}&view=markup"
|
32
|
-
diff = "#{history}?r1=\#{previous_revision}&r2=\#{revision}"
|
33
|
-
|
34
|
-
|
35
|
-
child_dirs_pattern = /<img src="\/icons\/small\/dir.gif"\s+alt="\(dir\)"\s+border=0\s+width=16\s+height=16>[\r\n\s]*([^\/]+)\/<\/a>/
|
36
|
-
child_files_pattern = /href="[^\?]+\/([^\?]+)\?rev=([^&]+)&view=log">/
|
37
|
-
|
38
|
-
ScmWeb::Browser.new(dir, history, raw, html, diff, child_dirs_pattern, child_files_pattern)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Regexp used to find projects' home page
|
42
|
-
def home_page_regexp
|
43
|
-
# This seems a little volatile
|
44
|
-
/<A href=\"(\w*:\/\/[^\"]*)\"> Project Home Page<\/A>/
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
1
|
+
require 'meta_project/tracker/xforge'
|
2
|
+
|
3
|
+
module MetaProject
|
4
|
+
module Project
|
5
|
+
module XForge
|
6
|
+
class SourceForge < XForgeBase
|
7
|
+
|
8
|
+
def initialize(unix_name, cvs_mod=nil)
|
9
|
+
super("sourceforge.net", unix_name, cvs_mod)
|
10
|
+
end
|
11
|
+
|
12
|
+
def tracker_class
|
13
|
+
::MetaProject::Tracker::XForge::SourceForgeTracker
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def create_cvs(unix_name, mod)
|
19
|
+
RSCM::Cvs.new(":pserver:anonymous@cvs.sourceforge.net:/cvsroot/#{unix_name}", mod)
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_view_cvs(unix_name, mod)
|
23
|
+
view_cvs = "http://cvs.sourceforge.net/viewcvs.py/"
|
24
|
+
unix_name_mod = "#{unix_name}/#{mod}"
|
25
|
+
project_path = "#{unix_name_mod}/\#{path}"
|
26
|
+
rev = "rev=\#{revision}"
|
27
|
+
|
28
|
+
dir = "#{view_cvs}#{project_path}"
|
29
|
+
history = "#{view_cvs}#{project_path}"
|
30
|
+
raw = "#{view_cvs}*checkout*/#{project_path}?#{rev}"
|
31
|
+
html = "#{history}?#{rev}&view=markup"
|
32
|
+
diff = "#{history}?r1=\#{previous_revision}&r2=\#{revision}"
|
33
|
+
|
34
|
+
|
35
|
+
child_dirs_pattern = /<img src="\/icons\/small\/dir.gif"\s+alt="\(dir\)"\s+border=0\s+width=16\s+height=16>[\r\n\s]*([^\/]+)\/<\/a>/
|
36
|
+
child_files_pattern = /href="[^\?]+\/([^\?]+)\?rev=([^&]+)&view=log">/
|
37
|
+
|
38
|
+
ScmWeb::Browser.new(dir, history, raw, html, diff, child_dirs_pattern, child_files_pattern)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Regexp used to find projects' home page
|
42
|
+
def home_page_regexp
|
43
|
+
# This seems a little volatile
|
44
|
+
/<A href=\"(\w*:\/\/[^\"]*)\"> Project Home Page<\/A>/
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
50
|
end
|
@@ -1,45 +1,45 @@
|
|
1
|
-
module MetaProject
|
2
|
-
module Project
|
3
|
-
module XForge
|
4
|
-
|
5
|
-
class XFile # :nodoc:
|
6
|
-
|
7
|
-
# extension => [mime_type, rubyforge_bin_type_id, rubyforge_src_type_id]
|
8
|
-
FILE_TYPES = {
|
9
|
-
".deb" => ["application/octet-stream", 1000],
|
10
|
-
|
11
|
-
# all of these can be source or binary
|
12
|
-
".rpm" => ["application/octet-stream", 2000, 5100],
|
13
|
-
".zip" => ["application/octet-stream", 3000, 5000],
|
14
|
-
".bz2" => ["application/octet-stream", 3100, 5010],
|
15
|
-
".gz" => ["application/octet-stream", 3110, 5020],
|
16
|
-
".jpg" => ["application/octet-stream", 8000],
|
17
|
-
".jpeg" => ["application/octet-stream", 8000],
|
18
|
-
".txt" => ["text/plain", 8100, 8100],
|
19
|
-
".html" => ["text/html", 8200, 8200],
|
20
|
-
".pdf" => ["application/octet-stream", 8300],
|
21
|
-
".ebuild" => ["application/octet-stream", 1300],
|
22
|
-
".exe" => ["application/octet-stream", 1100],
|
23
|
-
".dmg" => ["application/octet-stream", 1200],
|
24
|
-
".gem" => ["application/octet-stream", 1400],
|
25
|
-
".sig" => ["application/octet-stream", 8150]
|
26
|
-
}
|
27
|
-
FILE_TYPES.default = ["application/octet-stream", 9999, 5900] # default to "other", "other source"
|
28
|
-
|
29
|
-
attr_reader :basename, :ext, :content_type, :bin_type_id, :src_type_id
|
30
|
-
|
31
|
-
def initialize(filename)
|
32
|
-
@filename = filename
|
33
|
-
@basename = File.basename(filename)
|
34
|
-
@ext = File.extname(filename)
|
35
|
-
@content_type = FILE_TYPES[@ext][0]
|
36
|
-
@bin_type_id = FILE_TYPES[@ext][1]
|
37
|
-
end
|
38
|
-
|
39
|
-
def data
|
40
|
-
File.open(@filename, "rb") { |file| file.read }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
1
|
+
module MetaProject
|
2
|
+
module Project
|
3
|
+
module XForge
|
4
|
+
|
5
|
+
class XFile # :nodoc:
|
6
|
+
|
7
|
+
# extension => [mime_type, rubyforge_bin_type_id, rubyforge_src_type_id]
|
8
|
+
FILE_TYPES = {
|
9
|
+
".deb" => ["application/octet-stream", 1000],
|
10
|
+
|
11
|
+
# all of these can be source or binary
|
12
|
+
".rpm" => ["application/octet-stream", 2000, 5100],
|
13
|
+
".zip" => ["application/octet-stream", 3000, 5000],
|
14
|
+
".bz2" => ["application/octet-stream", 3100, 5010],
|
15
|
+
".gz" => ["application/octet-stream", 3110, 5020],
|
16
|
+
".jpg" => ["application/octet-stream", 8000],
|
17
|
+
".jpeg" => ["application/octet-stream", 8000],
|
18
|
+
".txt" => ["text/plain", 8100, 8100],
|
19
|
+
".html" => ["text/html", 8200, 8200],
|
20
|
+
".pdf" => ["application/octet-stream", 8300],
|
21
|
+
".ebuild" => ["application/octet-stream", 1300],
|
22
|
+
".exe" => ["application/octet-stream", 1100],
|
23
|
+
".dmg" => ["application/octet-stream", 1200],
|
24
|
+
".gem" => ["application/octet-stream", 1400],
|
25
|
+
".sig" => ["application/octet-stream", 8150]
|
26
|
+
}
|
27
|
+
FILE_TYPES.default = ["application/octet-stream", 9999, 5900] # default to "other", "other source"
|
28
|
+
|
29
|
+
attr_reader :basename, :ext, :content_type, :bin_type_id, :src_type_id
|
30
|
+
|
31
|
+
def initialize(filename)
|
32
|
+
@filename = filename
|
33
|
+
@basename = File.basename(filename)
|
34
|
+
@ext = File.extname(filename)
|
35
|
+
@content_type = FILE_TYPES[@ext][0]
|
36
|
+
@bin_type_id = FILE_TYPES[@ext][1]
|
37
|
+
end
|
38
|
+
|
39
|
+
def data
|
40
|
+
File.open(@filename, "rb") { |file| file.read }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
45
|
end
|
@@ -1,81 +1,81 @@
|
|
1
|
-
module MetaProject
|
2
|
-
module Project
|
3
|
-
module XForge
|
4
|
-
class XForgeBase < Base
|
5
|
-
|
6
|
-
attr_reader :host, :unix_name
|
7
|
-
|
8
|
-
# TODO: hash based constructor (big now)
|
9
|
-
def initialize(host, unix_name, cvs_mod)
|
10
|
-
@host = host
|
11
|
-
@unix_name = unix_name
|
12
|
-
@name = unix_name
|
13
|
-
@cvs_mod = cvs_mod
|
14
|
-
|
15
|
-
@tracker = tracker_class.new(group_id_uri("tracker"), self)
|
16
|
-
|
17
|
-
unless(cvs_mod.nil?)
|
18
|
-
@scm = create_cvs(unix_name, @cvs_mod)
|
19
|
-
@scm_web = create_view_cvs(unix_name, @cvs_mod)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_yaml_properties
|
24
|
-
["@host", "@unix_name"]
|
25
|
-
end
|
26
|
-
|
27
|
-
# Logs in and returns a Session
|
28
|
-
def login(user_name, password)
|
29
|
-
http = Net::HTTP.new(@host, 80)
|
30
|
-
|
31
|
-
login_response = http.start do |http|
|
32
|
-
data = [
|
33
|
-
"login=1",
|
34
|
-
"form_loginname=#{user_name}",
|
35
|
-
"form_pw=#{password}"
|
36
|
-
].join("&")
|
37
|
-
http.post("/account/login.php", data)
|
38
|
-
end
|
39
|
-
|
40
|
-
cookie = login_response["set-cookie"]
|
41
|
-
raise "Login failed" unless cookie
|
42
|
-
Session.new(@host, self, cookie)
|
43
|
-
end
|
44
|
-
|
45
|
-
# The group_id of this project
|
46
|
-
def group_id
|
47
|
-
unless(@group_id)
|
48
|
-
html = better_open(xforge_project_url).read
|
49
|
-
group_id_pattern = /project\/memberlist.php\?group_id=(\d+)/
|
50
|
-
@group_id = html[group_id_pattern, 1]
|
51
|
-
raise "Couldn't get group_id from #{xforge_project_url}. I was looking for /#{group_id_pattern.source}/" unless @group_id
|
52
|
-
end
|
53
|
-
@group_id
|
54
|
-
end
|
55
|
-
|
56
|
-
def xforge_project_url
|
57
|
-
"http://#{@host}/projects/#{@unix_name}/"
|
58
|
-
end
|
59
|
-
|
60
|
-
def group_id_uri(path, postfix="")
|
61
|
-
"http://#{@host}/#{path}/?group_id=#{group_id}#{postfix}"
|
62
|
-
end
|
63
|
-
|
64
|
-
# The home page of this project
|
65
|
-
def home_page
|
66
|
-
unless(@home_page)
|
67
|
-
html = better_open(xforge_project_url).read
|
68
|
-
@home_page = html[home_page_regexp, 1]
|
69
|
-
unless @home_page
|
70
|
-
STDERR.puts "WARNING: Couldn't get home_page from #{xforge_project_url}. I was looking for /#{home_page_regexp.source}/"
|
71
|
-
STDERR.puts "Will use #{xforge_project_url} as home page instead."
|
72
|
-
@home_page = xforge_project_url
|
73
|
-
end
|
74
|
-
end
|
75
|
-
@home_page
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
1
|
+
module MetaProject
|
2
|
+
module Project
|
3
|
+
module XForge
|
4
|
+
class XForgeBase < Base
|
5
|
+
|
6
|
+
attr_reader :host, :unix_name
|
7
|
+
|
8
|
+
# TODO: hash based constructor (big now)
|
9
|
+
def initialize(host, unix_name, cvs_mod)
|
10
|
+
@host = host
|
11
|
+
@unix_name = unix_name
|
12
|
+
@name = unix_name
|
13
|
+
@cvs_mod = cvs_mod
|
14
|
+
|
15
|
+
@tracker = tracker_class.new(group_id_uri("tracker"), self)
|
16
|
+
|
17
|
+
unless(cvs_mod.nil?)
|
18
|
+
@scm = create_cvs(unix_name, @cvs_mod)
|
19
|
+
@scm_web = create_view_cvs(unix_name, @cvs_mod)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_yaml_properties
|
24
|
+
["@host", "@unix_name"]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Logs in and returns a Session
|
28
|
+
def login(user_name, password)
|
29
|
+
http = Net::HTTP.new(@host, 80)
|
30
|
+
|
31
|
+
login_response = http.start do |http|
|
32
|
+
data = [
|
33
|
+
"login=1",
|
34
|
+
"form_loginname=#{user_name}",
|
35
|
+
"form_pw=#{password}"
|
36
|
+
].join("&")
|
37
|
+
http.post("/account/login.php", data)
|
38
|
+
end
|
39
|
+
|
40
|
+
cookie = login_response["set-cookie"]
|
41
|
+
raise "Login failed" unless cookie
|
42
|
+
Session.new(@host, self, cookie)
|
43
|
+
end
|
44
|
+
|
45
|
+
# The group_id of this project
|
46
|
+
def group_id
|
47
|
+
unless(@group_id)
|
48
|
+
html = better_open(xforge_project_url).read
|
49
|
+
group_id_pattern = /project\/memberlist.php\?group_id=(\d+)/
|
50
|
+
@group_id = html[group_id_pattern, 1]
|
51
|
+
raise "Couldn't get group_id from #{xforge_project_url}. I was looking for /#{group_id_pattern.source}/" unless @group_id
|
52
|
+
end
|
53
|
+
@group_id
|
54
|
+
end
|
55
|
+
|
56
|
+
def xforge_project_url
|
57
|
+
"http://#{@host}/projects/#{@unix_name}/"
|
58
|
+
end
|
59
|
+
|
60
|
+
def group_id_uri(path, postfix="")
|
61
|
+
"http://#{@host}/#{path}/?group_id=#{group_id}#{postfix}"
|
62
|
+
end
|
63
|
+
|
64
|
+
# The home page of this project
|
65
|
+
def home_page
|
66
|
+
unless(@home_page)
|
67
|
+
html = better_open(xforge_project_url).read
|
68
|
+
@home_page = html[home_page_regexp, 1]
|
69
|
+
unless @home_page
|
70
|
+
STDERR.puts "WARNING: Couldn't get home_page from #{xforge_project_url}. I was looking for /#{home_page_regexp.source}/"
|
71
|
+
STDERR.puts "Will use #{xforge_project_url} as home page instead."
|
72
|
+
@home_page = xforge_project_url
|
73
|
+
end
|
74
|
+
end
|
75
|
+
@home_page
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -1,36 +1,36 @@
|
|
1
|
-
module MetaProject
|
2
|
-
module ProjectAnalyzer
|
3
|
-
# Creates a project from an scm web url. The project has a +tracker+, +scm+ and +scm_web+.
|
4
|
-
def project_from_scm_web(url, options=nil)
|
5
|
-
# RubyForge
|
6
|
-
if(url =~ /http:\/\/rubyforge.org\/cgi-bin\/viewcvs.cgi\/(.*)[\/]?\?cvsroot=(.*)/)
|
7
|
-
unix_name = $2
|
8
|
-
mod = $1[-1..-1] == "/" ? $1[0..-2] : $1
|
9
|
-
return Project::XForge::RubyForge.new(unix_name, mod)
|
10
|
-
end
|
11
|
-
|
12
|
-
# SourceForge
|
13
|
-
if(url =~ /http:\/\/cvs.sourceforge.net\/viewcvs.py\/([^\/]*)\/(.*)/)
|
14
|
-
unix_name = $1
|
15
|
-
mod = $2[-1..-1] == "/" ? $2[0..-2] : $2
|
16
|
-
return Project::XForge::SourceForge.new(unix_name, mod)
|
17
|
-
end
|
18
|
-
|
19
|
-
# Trac
|
20
|
-
if(url =~ /(http:\/\/.*)\/browser\/(.*)/)
|
21
|
-
trac_base_url = $1
|
22
|
-
svn_path = $2[-1..-1] == "/" ? $2[0..-2] : $2
|
23
|
-
return Project::Trac::TracProject.new(trac_base_url, options[:trac_svn_root_url], svn_path)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Codehaus SVN
|
27
|
-
if(url =~ /http:\/\/svn.(.*).codehaus.org\/(.*)/)
|
28
|
-
unix_name = $1
|
29
|
-
svn_path = $2[-1..-1] == "/" ? $2[0..-2] : $2
|
30
|
-
return Project::Codehaus::CodehausProjectSvn.new(unix_name, svn_path, options[:jira_project_id])
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
1
|
+
module MetaProject
|
2
|
+
module ProjectAnalyzer
|
3
|
+
# Creates a project from an scm web url. The project has a +tracker+, +scm+ and +scm_web+.
|
4
|
+
def project_from_scm_web(url, options=nil)
|
5
|
+
# RubyForge
|
6
|
+
if(url =~ /http:\/\/rubyforge.org\/cgi-bin\/viewcvs.cgi\/(.*)[\/]?\?cvsroot=(.*)/)
|
7
|
+
unix_name = $2
|
8
|
+
mod = $1[-1..-1] == "/" ? $1[0..-2] : $1
|
9
|
+
return Project::XForge::RubyForge.new(unix_name, mod)
|
10
|
+
end
|
11
|
+
|
12
|
+
# SourceForge
|
13
|
+
if(url =~ /http:\/\/cvs.sourceforge.net\/viewcvs.py\/([^\/]*)\/(.*)/)
|
14
|
+
unix_name = $1
|
15
|
+
mod = $2[-1..-1] == "/" ? $2[0..-2] : $2
|
16
|
+
return Project::XForge::SourceForge.new(unix_name, mod)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Trac
|
20
|
+
if(url =~ /(http:\/\/.*)\/browser\/(.*)/)
|
21
|
+
trac_base_url = $1
|
22
|
+
svn_path = $2[-1..-1] == "/" ? $2[0..-2] : $2
|
23
|
+
return Project::Trac::TracProject.new(trac_base_url, options[:trac_svn_root_url], svn_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Codehaus SVN
|
27
|
+
if(url =~ /http:\/\/svn.(.*).codehaus.org\/(.*)/)
|
28
|
+
unix_name = $1
|
29
|
+
svn_path = $2[-1..-1] == "/" ? $2[0..-2] : $2
|
30
|
+
return Project::Codehaus::CodehausProjectSvn.new(unix_name, svn_path, options[:jira_project_id])
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
36
|
end
|
@@ -1,267 +1,267 @@
|
|
1
|
-
# Copyright (C) 2005 Thomas Leitner
|
2
|
-
#
|
3
|
-
# See LICENCE for details
|
4
|
-
|
5
|
-
require "xmlrpc/client"
|
6
|
-
require 'yaml'
|
7
|
-
|
8
|
-
module DevTools
|
9
|
-
|
10
|
-
module Freshmeat
|
11
|
-
|
12
|
-
class FreshmeatException < StandardError; end
|
13
|
-
|
14
|
-
# Describes a freshmeat project.
|
15
|
-
class Project
|
16
|
-
|
17
|
-
# The short name of the project
|
18
|
-
attr_reader :shortName
|
19
|
-
|
20
|
-
# The full name of the project
|
21
|
-
attr_reader :fullName
|
22
|
-
|
23
|
-
# The status of the project (alpha, beta, ...)
|
24
|
-
attr_reader :status
|
25
|
-
|
26
|
-
# The current version string of the project
|
27
|
-
attr_reader :version
|
28
|
-
|
29
|
-
def initialize( shortName, fullName, status, version )
|
30
|
-
@shortName, @fullName, @status, @version = shortName, fullName, status, version
|
31
|
-
end
|
32
|
-
|
33
|
-
def to_s
|
34
|
-
"Project: short name = #{@shortName}, full name = #{@fullName}, status = #{@status}, version = #{@version}"
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
# Provides information about a release.
|
40
|
-
class ReleaseInfo
|
41
|
-
|
42
|
-
# Version string of release
|
43
|
-
attr_reader :version
|
44
|
-
|
45
|
-
# Change list of release
|
46
|
-
attr_reader :changes
|
47
|
-
|
48
|
-
# Release focus
|
49
|
-
attr_reader :release_focus
|
50
|
-
|
51
|
-
# True, if hidden from frontpage
|
52
|
-
attr_reader :hidden
|
53
|
-
|
54
|
-
# Returns a new ReleaseInfo object
|
55
|
-
def initialize( version, changes, release_focus, hidden )
|
56
|
-
@version, @changes, @release_focus, @hidden = version, changes, release_focus, hidden
|
57
|
-
end
|
58
|
-
|
59
|
-
def to_s
|
60
|
-
"ReleaseInfo: version = #{@version}, release focus = #{ReleaseFocusID::NAMES[@release_focus]}, hidden = #{hidden}\nChanges = #{@changes}"
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
# Holds all information about a release which should be published.
|
66
|
-
class Release
|
67
|
-
|
68
|
-
#Project name to submit a release for
|
69
|
-
attr_accessor :project_name
|
70
|
-
|
71
|
-
#Branch name to submit a release for
|
72
|
-
attr_accessor :branch_name
|
73
|
-
|
74
|
-
#Version string of new release
|
75
|
-
attr_accessor :version
|
76
|
-
|
77
|
-
#Changes list, no HTML, character limit 600 chars
|
78
|
-
attr_accessor :changes
|
79
|
-
|
80
|
-
#Release focus ID of new release
|
81
|
-
attr_accessor :release_focus
|
82
|
-
|
83
|
-
#Set to 'Y' if release is to be hidden from frontpage, everything else does not hide it
|
84
|
-
attr_accessor :hide_from_frontpage
|
85
|
-
|
86
|
-
#Optional: Branch license
|
87
|
-
attr_accessor :license
|
88
|
-
|
89
|
-
#Optional: Homepage
|
90
|
-
attr_accessor :url_homepage
|
91
|
-
|
92
|
-
#Optional: Tar/GZ
|
93
|
-
attr_accessor :url_tgz
|
94
|
-
|
95
|
-
#Optional: Tar/BZ2
|
96
|
-
attr_accessor :url_bz2
|
97
|
-
|
98
|
-
#Optional: Zip
|
99
|
-
attr_accessor :url_zip
|
100
|
-
|
101
|
-
#Optional: Changelog
|
102
|
-
attr_accessor :url_changelog
|
103
|
-
|
104
|
-
#Optional: RPM package
|
105
|
-
attr_accessor :url_rpm
|
106
|
-
|
107
|
-
#Optional: Debian package
|
108
|
-
attr_accessor :url_deb
|
109
|
-
|
110
|
-
#Optional: OS X package
|
111
|
-
attr_accessor :url_osx
|
112
|
-
|
113
|
-
#Optional: BSD Ports URL
|
114
|
-
attr_accessor :url_bsdport
|
115
|
-
|
116
|
-
#Optional: Purchase
|
117
|
-
attr_accessor :url_purchase
|
118
|
-
|
119
|
-
#Optional: CVS tree (cvsweb)
|
120
|
-
attr_accessor :url_cvs
|
121
|
-
|
122
|
-
#Optional: Mailing list archive
|
123
|
-
attr_accessor :url_list
|
124
|
-
|
125
|
-
#Optional: Mirror site
|
126
|
-
attr_accessor :url_mirror
|
127
|
-
|
128
|
-
#Optional: Demo site
|
129
|
-
attr_accessor :url_demo
|
130
|
-
|
131
|
-
def self.from_data( data=nil )
|
132
|
-
YAML::load( data )
|
133
|
-
end
|
134
|
-
|
135
|
-
def to_rpc_data
|
136
|
-
rpc_data = {}
|
137
|
-
instance_variables.each do |iv|
|
138
|
-
rpc_data[iv[1..-1]] = eval( iv )
|
139
|
-
end
|
140
|
-
rpc_data
|
141
|
-
end
|
142
|
-
|
143
|
-
def to_yaml_type
|
144
|
-
"!thomasleitner,2005/FreshmeatRelease"
|
145
|
-
end
|
146
|
-
|
147
|
-
YAML::add_domain_type( 'thomasleitner,2005', 'FreshmeatRelease' ) do |type, val|
|
148
|
-
YAML::object_maker( Release, val )
|
149
|
-
end
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
# Provides constants for all release focus ids
|
154
|
-
module ReleaseFocusID
|
155
|
-
NA = 0
|
156
|
-
INITIAL_ANNOUNCEMENT = 1
|
157
|
-
DOCUMENTATION = 2
|
158
|
-
CODE_CLEANUP = 3
|
159
|
-
MINOR_FEATURES = 4
|
160
|
-
MAJOR_FEATURES = 5
|
161
|
-
MINOR_BUGFIXES = 6
|
162
|
-
MAJOR_BUGFIXES = 7
|
163
|
-
MINOR_SECFIXES = 8
|
164
|
-
MAJOR_SECFIXES = 9
|
165
|
-
|
166
|
-
NAMES = {0=>'N/A',
|
167
|
-
1=>'Initial freshmeat announcement',
|
168
|
-
2=>'Documentation',
|
169
|
-
3=>'Code cleanup',
|
170
|
-
4=>'Minor feature enhancements',
|
171
|
-
5=>'Major feature enhancements',
|
172
|
-
6=>'Minor bugfixes',
|
173
|
-
7=>'Major bugfixes',
|
174
|
-
8=>'Minor security fixes',
|
175
|
-
9=>'Major security fixes'
|
176
|
-
}
|
177
|
-
end
|
178
|
-
|
179
|
-
|
180
|
-
# Provides access to the Freshmeat XML-RPC API via a nice interface.
|
181
|
-
# API reference at http://freshmeat.net/faq/view/49/
|
182
|
-
#
|
183
|
-
# Example:
|
184
|
-
#
|
185
|
-
# fm = DevTools::FreshmeatService.new( username, password )
|
186
|
-
# fm.get_project_list.each do |p|
|
187
|
-
# puts p
|
188
|
-
# branches = fm.get_branch_list( p.shortName )
|
189
|
-
# puts branches.inspect
|
190
|
-
# release = fm.get_release( p.shortName, branches[0], p.version )
|
191
|
-
# puts release
|
192
|
-
# end
|
193
|
-
# puts fm.logout
|
194
|
-
class FreshmeatService
|
195
|
-
|
196
|
-
# The URL for the Freshmeat RPC service
|
197
|
-
RPCURL = 'http://freshmeat.net/xmlrpc/'
|
198
|
-
|
199
|
-
# The major version of the freshmeat API with which this library works
|
200
|
-
API_VERSION_MAJOR = '1'
|
201
|
-
|
202
|
-
# The minor version of the freshmeat API with which this library works
|
203
|
-
API_VERSION_MINOR = '03'
|
204
|
-
|
205
|
-
# Use +username+ and +password+ to log into Freshmeat service.
|
206
|
-
def initialize( username, password )
|
207
|
-
@session = XMLRPC::Client.new2( RPCURL )
|
208
|
-
ret = @session.call( :login, :username=>username, :password=>password )
|
209
|
-
@sid = ret['SID']
|
210
|
-
major, minor = ret['API Version'].split( '.' )
|
211
|
-
if major != API_VERSION_MAJOR or minor < API_VERSION_MINOR
|
212
|
-
raise FreshmeatException, 'Incompatible API versions'
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
# Returns all available licenses
|
217
|
-
def self.get_licenses
|
218
|
-
XMLRPC::Client.new2( RPCURL ).call( :fetch_available_licenses )
|
219
|
-
end
|
220
|
-
|
221
|
-
# Returns all available release focus types
|
222
|
-
def self.get_release_focus_types
|
223
|
-
XMLRPC::Client.new2( RPCURL ).call( :fetch_available_release_foci )
|
224
|
-
end
|
225
|
-
|
226
|
-
# Returns an array of Project objects which are assigned to the logged in user
|
227
|
-
def get_project_list
|
228
|
-
ret = @session.call( :fetch_project_list, :SID=>@sid )
|
229
|
-
ret.collect! {|p| Project.new( p['projectname_short'], p['projectname_full'], p['project_status'], p['project_version'] ) }
|
230
|
-
end
|
231
|
-
|
232
|
-
# Returns an array of branch names for the project +project+.
|
233
|
-
def get_branch_list( project )
|
234
|
-
@session.call( :fetch_branch_list, :SID=>@sid, :project_name=>project )
|
235
|
-
end
|
236
|
-
|
237
|
-
# Returns a ReleaseInfo object which has the information about the requested release.
|
238
|
-
def get_release( project, branch, version )
|
239
|
-
ret = @session.call( :fetch_release, :SID=>@sid, :project_name=>project, :branch_name=>branch, :version=>version )
|
240
|
-
releaseFocus = ret['release_focus'].split( ' - ' )[0].to_i
|
241
|
-
hidden = (ret['hide_from_frontpage'] == 'Y' )
|
242
|
-
ReleaseInfo.new( ret['version'], ret['changes'], releaseFocus, hidden )
|
243
|
-
end
|
244
|
-
|
245
|
-
# Publishes a new release of a project. The parameter +release+ has to be a Release object!
|
246
|
-
def publish_release( release )
|
247
|
-
ret = @session.call( :publish_release, {:SID=>@sid}.update( release.to_rpc_data ) )
|
248
|
-
ret['OK'] == 'submission successful'
|
249
|
-
end
|
250
|
-
|
251
|
-
# Withdraws the specified release.
|
252
|
-
def withdraw_release( project, branch, version )
|
253
|
-
ret = @session.call( :withdraw_release, :SID=>@sid, :project_name=>project, :branch_name=>branch, :version=>version )
|
254
|
-
ret['OK'] == 'Withdraw successful.'
|
255
|
-
end
|
256
|
-
|
257
|
-
# Logs out from the Freshmeat service.
|
258
|
-
def logout
|
259
|
-
ok, ret = @session.call2( :logout, :SID=>@sid )
|
260
|
-
ok && ret['OK'] == 'Logout successful.'
|
261
|
-
end
|
262
|
-
|
263
|
-
end
|
264
|
-
|
265
|
-
end
|
266
|
-
|
267
|
-
end
|
1
|
+
# Copyright (C) 2005 Thomas Leitner
|
2
|
+
#
|
3
|
+
# See LICENCE for details
|
4
|
+
|
5
|
+
require "xmlrpc/client"
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
module DevTools
|
9
|
+
|
10
|
+
module Freshmeat
|
11
|
+
|
12
|
+
class FreshmeatException < StandardError; end
|
13
|
+
|
14
|
+
# Describes a freshmeat project.
|
15
|
+
class Project
|
16
|
+
|
17
|
+
# The short name of the project
|
18
|
+
attr_reader :shortName
|
19
|
+
|
20
|
+
# The full name of the project
|
21
|
+
attr_reader :fullName
|
22
|
+
|
23
|
+
# The status of the project (alpha, beta, ...)
|
24
|
+
attr_reader :status
|
25
|
+
|
26
|
+
# The current version string of the project
|
27
|
+
attr_reader :version
|
28
|
+
|
29
|
+
def initialize( shortName, fullName, status, version )
|
30
|
+
@shortName, @fullName, @status, @version = shortName, fullName, status, version
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
"Project: short name = #{@shortName}, full name = #{@fullName}, status = #{@status}, version = #{@version}"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
# Provides information about a release.
|
40
|
+
class ReleaseInfo
|
41
|
+
|
42
|
+
# Version string of release
|
43
|
+
attr_reader :version
|
44
|
+
|
45
|
+
# Change list of release
|
46
|
+
attr_reader :changes
|
47
|
+
|
48
|
+
# Release focus
|
49
|
+
attr_reader :release_focus
|
50
|
+
|
51
|
+
# True, if hidden from frontpage
|
52
|
+
attr_reader :hidden
|
53
|
+
|
54
|
+
# Returns a new ReleaseInfo object
|
55
|
+
def initialize( version, changes, release_focus, hidden )
|
56
|
+
@version, @changes, @release_focus, @hidden = version, changes, release_focus, hidden
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
"ReleaseInfo: version = #{@version}, release focus = #{ReleaseFocusID::NAMES[@release_focus]}, hidden = #{hidden}\nChanges = #{@changes}"
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
# Holds all information about a release which should be published.
|
66
|
+
class Release
|
67
|
+
|
68
|
+
#Project name to submit a release for
|
69
|
+
attr_accessor :project_name
|
70
|
+
|
71
|
+
#Branch name to submit a release for
|
72
|
+
attr_accessor :branch_name
|
73
|
+
|
74
|
+
#Version string of new release
|
75
|
+
attr_accessor :version
|
76
|
+
|
77
|
+
#Changes list, no HTML, character limit 600 chars
|
78
|
+
attr_accessor :changes
|
79
|
+
|
80
|
+
#Release focus ID of new release
|
81
|
+
attr_accessor :release_focus
|
82
|
+
|
83
|
+
#Set to 'Y' if release is to be hidden from frontpage, everything else does not hide it
|
84
|
+
attr_accessor :hide_from_frontpage
|
85
|
+
|
86
|
+
#Optional: Branch license
|
87
|
+
attr_accessor :license
|
88
|
+
|
89
|
+
#Optional: Homepage
|
90
|
+
attr_accessor :url_homepage
|
91
|
+
|
92
|
+
#Optional: Tar/GZ
|
93
|
+
attr_accessor :url_tgz
|
94
|
+
|
95
|
+
#Optional: Tar/BZ2
|
96
|
+
attr_accessor :url_bz2
|
97
|
+
|
98
|
+
#Optional: Zip
|
99
|
+
attr_accessor :url_zip
|
100
|
+
|
101
|
+
#Optional: Changelog
|
102
|
+
attr_accessor :url_changelog
|
103
|
+
|
104
|
+
#Optional: RPM package
|
105
|
+
attr_accessor :url_rpm
|
106
|
+
|
107
|
+
#Optional: Debian package
|
108
|
+
attr_accessor :url_deb
|
109
|
+
|
110
|
+
#Optional: OS X package
|
111
|
+
attr_accessor :url_osx
|
112
|
+
|
113
|
+
#Optional: BSD Ports URL
|
114
|
+
attr_accessor :url_bsdport
|
115
|
+
|
116
|
+
#Optional: Purchase
|
117
|
+
attr_accessor :url_purchase
|
118
|
+
|
119
|
+
#Optional: CVS tree (cvsweb)
|
120
|
+
attr_accessor :url_cvs
|
121
|
+
|
122
|
+
#Optional: Mailing list archive
|
123
|
+
attr_accessor :url_list
|
124
|
+
|
125
|
+
#Optional: Mirror site
|
126
|
+
attr_accessor :url_mirror
|
127
|
+
|
128
|
+
#Optional: Demo site
|
129
|
+
attr_accessor :url_demo
|
130
|
+
|
131
|
+
def self.from_data( data=nil )
|
132
|
+
YAML::load( data )
|
133
|
+
end
|
134
|
+
|
135
|
+
def to_rpc_data
|
136
|
+
rpc_data = {}
|
137
|
+
instance_variables.each do |iv|
|
138
|
+
rpc_data[iv[1..-1]] = eval( iv )
|
139
|
+
end
|
140
|
+
rpc_data
|
141
|
+
end
|
142
|
+
|
143
|
+
def to_yaml_type
|
144
|
+
"!thomasleitner,2005/FreshmeatRelease"
|
145
|
+
end
|
146
|
+
|
147
|
+
YAML::add_domain_type( 'thomasleitner,2005', 'FreshmeatRelease' ) do |type, val|
|
148
|
+
YAML::object_maker( Release, val )
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
# Provides constants for all release focus ids
|
154
|
+
module ReleaseFocusID
|
155
|
+
NA = 0
|
156
|
+
INITIAL_ANNOUNCEMENT = 1
|
157
|
+
DOCUMENTATION = 2
|
158
|
+
CODE_CLEANUP = 3
|
159
|
+
MINOR_FEATURES = 4
|
160
|
+
MAJOR_FEATURES = 5
|
161
|
+
MINOR_BUGFIXES = 6
|
162
|
+
MAJOR_BUGFIXES = 7
|
163
|
+
MINOR_SECFIXES = 8
|
164
|
+
MAJOR_SECFIXES = 9
|
165
|
+
|
166
|
+
NAMES = {0=>'N/A',
|
167
|
+
1=>'Initial freshmeat announcement',
|
168
|
+
2=>'Documentation',
|
169
|
+
3=>'Code cleanup',
|
170
|
+
4=>'Minor feature enhancements',
|
171
|
+
5=>'Major feature enhancements',
|
172
|
+
6=>'Minor bugfixes',
|
173
|
+
7=>'Major bugfixes',
|
174
|
+
8=>'Minor security fixes',
|
175
|
+
9=>'Major security fixes'
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
# Provides access to the Freshmeat XML-RPC API via a nice interface.
|
181
|
+
# API reference at http://freshmeat.net/faq/view/49/
|
182
|
+
#
|
183
|
+
# Example:
|
184
|
+
#
|
185
|
+
# fm = DevTools::FreshmeatService.new( username, password )
|
186
|
+
# fm.get_project_list.each do |p|
|
187
|
+
# puts p
|
188
|
+
# branches = fm.get_branch_list( p.shortName )
|
189
|
+
# puts branches.inspect
|
190
|
+
# release = fm.get_release( p.shortName, branches[0], p.version )
|
191
|
+
# puts release
|
192
|
+
# end
|
193
|
+
# puts fm.logout
|
194
|
+
class FreshmeatService
|
195
|
+
|
196
|
+
# The URL for the Freshmeat RPC service
|
197
|
+
RPCURL = 'http://freshmeat.net/xmlrpc/'
|
198
|
+
|
199
|
+
# The major version of the freshmeat API with which this library works
|
200
|
+
API_VERSION_MAJOR = '1'
|
201
|
+
|
202
|
+
# The minor version of the freshmeat API with which this library works
|
203
|
+
API_VERSION_MINOR = '03'
|
204
|
+
|
205
|
+
# Use +username+ and +password+ to log into Freshmeat service.
|
206
|
+
def initialize( username, password )
|
207
|
+
@session = XMLRPC::Client.new2( RPCURL )
|
208
|
+
ret = @session.call( :login, :username=>username, :password=>password )
|
209
|
+
@sid = ret['SID']
|
210
|
+
major, minor = ret['API Version'].split( '.' )
|
211
|
+
if major != API_VERSION_MAJOR or minor < API_VERSION_MINOR
|
212
|
+
raise FreshmeatException, 'Incompatible API versions'
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Returns all available licenses
|
217
|
+
def self.get_licenses
|
218
|
+
XMLRPC::Client.new2( RPCURL ).call( :fetch_available_licenses )
|
219
|
+
end
|
220
|
+
|
221
|
+
# Returns all available release focus types
|
222
|
+
def self.get_release_focus_types
|
223
|
+
XMLRPC::Client.new2( RPCURL ).call( :fetch_available_release_foci )
|
224
|
+
end
|
225
|
+
|
226
|
+
# Returns an array of Project objects which are assigned to the logged in user
|
227
|
+
def get_project_list
|
228
|
+
ret = @session.call( :fetch_project_list, :SID=>@sid )
|
229
|
+
ret.collect! {|p| Project.new( p['projectname_short'], p['projectname_full'], p['project_status'], p['project_version'] ) }
|
230
|
+
end
|
231
|
+
|
232
|
+
# Returns an array of branch names for the project +project+.
|
233
|
+
def get_branch_list( project )
|
234
|
+
@session.call( :fetch_branch_list, :SID=>@sid, :project_name=>project )
|
235
|
+
end
|
236
|
+
|
237
|
+
# Returns a ReleaseInfo object which has the information about the requested release.
|
238
|
+
def get_release( project, branch, version )
|
239
|
+
ret = @session.call( :fetch_release, :SID=>@sid, :project_name=>project, :branch_name=>branch, :version=>version )
|
240
|
+
releaseFocus = ret['release_focus'].split( ' - ' )[0].to_i
|
241
|
+
hidden = (ret['hide_from_frontpage'] == 'Y' )
|
242
|
+
ReleaseInfo.new( ret['version'], ret['changes'], releaseFocus, hidden )
|
243
|
+
end
|
244
|
+
|
245
|
+
# Publishes a new release of a project. The parameter +release+ has to be a Release object!
|
246
|
+
def publish_release( release )
|
247
|
+
ret = @session.call( :publish_release, {:SID=>@sid}.update( release.to_rpc_data ) )
|
248
|
+
ret['OK'] == 'submission successful'
|
249
|
+
end
|
250
|
+
|
251
|
+
# Withdraws the specified release.
|
252
|
+
def withdraw_release( project, branch, version )
|
253
|
+
ret = @session.call( :withdraw_release, :SID=>@sid, :project_name=>project, :branch_name=>branch, :version=>version )
|
254
|
+
ret['OK'] == 'Withdraw successful.'
|
255
|
+
end
|
256
|
+
|
257
|
+
# Logs out from the Freshmeat service.
|
258
|
+
def logout
|
259
|
+
ok, ret = @session.call2( :logout, :SID=>@sid )
|
260
|
+
ok && ret['OK'] == 'Logout successful.'
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
|
267
|
+
end
|