xforge 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/CHANGES +34 -0
  2. data/Rakefile +5 -5
  3. data/lib/meta_project.rb +6 -0
  4. data/lib/meta_project/project.rb +4 -0
  5. data/lib/meta_project/project/base.rb +7 -0
  6. data/lib/meta_project/project/codehaus.rb +1 -0
  7. data/lib/meta_project/project/codehaus/codehaus_project_svn.rb +26 -0
  8. data/lib/meta_project/project/trac.rb +1 -0
  9. data/lib/meta_project/project/trac/trac_project.rb +26 -0
  10. data/lib/meta_project/project/xforge.rb +5 -0
  11. data/lib/meta_project/project/xforge/ruby_forge.rb +46 -0
  12. data/lib/meta_project/project/xforge/session.rb +162 -0
  13. data/lib/meta_project/project/xforge/source_forge.rb +46 -0
  14. data/lib/meta_project/project/xforge/xfile.rb +45 -0
  15. data/lib/meta_project/project/xforge/xforge_base.rb +76 -0
  16. data/lib/meta_project/project_analyzer.rb +36 -0
  17. data/lib/meta_project/scm_web.rb +53 -0
  18. data/lib/meta_project/tracker.rb +6 -0
  19. data/lib/meta_project/tracker/base.rb +18 -0
  20. data/lib/meta_project/tracker/digit_issues.rb +24 -0
  21. data/lib/meta_project/tracker/issue.rb +11 -0
  22. data/lib/meta_project/tracker/jira.rb +1 -0
  23. data/lib/meta_project/tracker/jira/jira_tracker.rb +68 -0
  24. data/lib/meta_project/tracker/trac.rb +1 -0
  25. data/lib/meta_project/tracker/trac/trac_tracker.rb +29 -0
  26. data/lib/meta_project/tracker/xforge.rb +3 -0
  27. data/lib/meta_project/tracker/xforge/ruby_forge_tracker.rb +17 -0
  28. data/lib/meta_project/tracker/xforge/source_forge_tracker.rb +17 -0
  29. data/lib/meta_project/tracker/xforge/xforge_tracker.rb +83 -0
  30. data/lib/{xforge → meta_project}/version_parser.rb +6 -6
  31. data/lib/rake/contrib/xforge/base.rb +2 -3
  32. data/lib/rake/contrib/xforge/news_publisher.rb +1 -5
  33. data/lib/rake/contrib/xforge/release.rb +3 -7
  34. data/lib/xforge.rb +0 -1
  35. metadata +30 -27
  36. data/lib/scm_web/base.rb +0 -12
  37. data/lib/scm_web/file_uri.rb +0 -21
  38. data/lib/scm_web/view_cvs.rb +0 -44
  39. data/lib/tracker/base.rb +0 -16
  40. data/lib/tracker/bugzilla/project.rb +0 -8
  41. data/lib/tracker/digit_issues.rb +0 -22
  42. data/lib/tracker/fog_bugz/project.rb +0 -8
  43. data/lib/tracker/issue.rb +0 -9
  44. data/lib/tracker/jira.rb +0 -2
  45. data/lib/tracker/jira/host.rb +0 -40
  46. data/lib/tracker/jira/project.rb +0 -43
  47. data/lib/tracker/mantis/project.rb +0 -8
  48. data/lib/tracker/scarab/project.rb +0 -8
  49. data/lib/tracker/trac.rb +0 -1
  50. data/lib/tracker/trac/project.rb +0 -35
  51. data/lib/tracker/xforge.rb +0 -2
  52. data/lib/tracker/xforge/base.rb +0 -77
  53. data/lib/tracker/xforge/rubyforge.rb +0 -7
  54. data/lib/xforge/host.rb +0 -26
  55. data/lib/xforge/project.rb +0 -87
  56. data/lib/xforge/rubyforge.rb +0 -50
  57. data/lib/xforge/session.rb +0 -158
  58. data/lib/xforge/sourceforge.rb +0 -46
  59. data/lib/xforge/xfile.rb +0 -41
data/CHANGES CHANGED
@@ -1,5 +1,39 @@
1
1
  = XForge Changelog
2
2
 
3
+ == Version 0.4.0
4
+
5
+ This release of XForge completely reorganises classes and modules into a more
6
+ coherent API for accessing projects' issue trackers, scms and scm browsers. The toplevel
7
+ namespace is now MetaProject.
8
+
9
+ The new ScmWeb class now supports *any* scm browser through its flexible
10
+ configuration options.
11
+
12
+ In order to easily gather information from various hosting services, XForge comes with a ProjectAnalyzer
13
+ class, which given an scm browser URL will discover the associated issue tracker, preconfigured scm_web,
14
+ project home page and of course, an RSCM object.
15
+
16
+ Supported project sources:
17
+ - RubyForge.org
18
+ - SourceForge.org
19
+ - Codehaus.org
20
+ - Trac projects
21
+
22
+ Supported issue trackers:
23
+ - RubyForge.org
24
+ - SourceForge.org
25
+ - JIRA
26
+ - Trac projects
27
+
28
+ Supported SCM browsers:
29
+ - *Any* scm browser through its flexible configuration options.
30
+
31
+ Supported SCMs:
32
+ - Any SCM implemented in the <a href="http://rscm.rubyforge.org/">RSCM</a> project.
33
+
34
+ The QRS Rake tasks for releasing files and news on RubyForge has changed slightly. Please refer to XForge's
35
+ own Rakefile for details.
36
+
3
37
  == Version 0.3.5
4
38
 
5
39
  This is a bugfix release that fixes some bugs in ViewCvs.
data/Rakefile CHANGED
@@ -7,7 +7,7 @@
7
7
  # MIT-LICENSE for details.
8
8
 
9
9
  $:.unshift('lib')
10
- require 'xforge'
10
+ require 'meta_project'
11
11
  require 'rake/gempackagetask'
12
12
  require 'rake/contrib/rubyforgepublisher'
13
13
  require 'rake/contrib/xforge'
@@ -24,7 +24,7 @@ require 'rake/rdoctask'
24
24
  #
25
25
  # REMEMBER TO KEEP PKG_VERSION IN SYNC WITH THE CHANGES FILE!
26
26
  PKG_NAME = "xforge"
27
- PKG_VERSION = "0.3.5"
27
+ PKG_VERSION = "0.4.0"
28
28
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
29
29
  PKG_FILES = FileList[
30
30
  '[A-Z]*',
@@ -114,7 +114,7 @@ end
114
114
 
115
115
  desc "Look for TODO and FIXME tags in the code"
116
116
  task :todo do
117
- egrep /#.*(FIXME|TODO|TBD)/
117
+ egrep /#.*(FIXME|TODO|TBD|DEPRECATED)/
118
118
  end
119
119
 
120
120
  task :release => [:verify_env_vars, :release_files, :publish_doc, :publish_news, :tag]
@@ -135,7 +135,7 @@ task :release_files => [:gem] do
135
135
  "pkg/#{PKG_FILE_NAME}.gem"
136
136
  ]
137
137
 
138
- Rake::XForge::Release.new(PKG_NAME) do |release|
138
+ Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new(PKG_NAME)) do |release|
139
139
  # Never hardcode user name and password in the Rakefile!
140
140
  release.user_name = ENV['RUBYFORGE_USER']
141
141
  release.password = ENV['RUBYFORGE_PASSWORD']
@@ -151,7 +151,7 @@ task :publish_news => [:gem] do
151
151
  "pkg/#{PKG_FILE_NAME}.gem"
152
152
  ]
153
153
 
154
- Rake::XForge::NewsPublisher.new(PKG_NAME) do |news|
154
+ Rake::XForge::NewsPublisher.new(MetaProject::Project::XForge::RubyForge.new(PKG_NAME)) do |news|
155
155
  # Never hardcode user name and password in the Rakefile!
156
156
  news.user_name = ENV['RUBYFORGE_USER']
157
157
  news.password = ENV['RUBYFORGE_PASSWORD']
@@ -0,0 +1,6 @@
1
+ require 'meta_project/project_analyzer'
2
+ require 'meta_project/project'
3
+ require 'meta_project/tracker'
4
+ require 'meta_project/scm_web'
5
+ require 'meta_project/version_parser'
6
+ require 'rake/contrib/xforge'
@@ -0,0 +1,4 @@
1
+ require 'meta_project/project/base'
2
+ require 'meta_project/project/xforge'
3
+ require 'meta_project/project/trac'
4
+ require 'meta_project/project/codehaus'
@@ -0,0 +1,7 @@
1
+ module MetaProject
2
+ module Project
3
+ class Base
4
+ attr_reader :scm, :scm_web, :tracker
5
+ end
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ require 'meta_project/project/codehaus/codehaus_project_svn'
@@ -0,0 +1,26 @@
1
+ module MetaProject
2
+ module Project
3
+ module Codehaus
4
+ class CodehausProjectSvn < Base
5
+
6
+ def initialize(project_id, svn_path, jira_id)
7
+ @scm = RSCM::Subversion.new("svn://svn.#{project_id}.codehaus.org/#{project_id}/scm/#{svn_path}", svn_path)
8
+ @tracker = ::MetaProject::Tracker::Jira::JiraTracker.new("http://jira.codehaus.org", jira_id)
9
+
10
+ overview = "http://svn.#{project_id}.codehaus.org/#{svn_path}/"
11
+ history = "#{overview}\#{path}"
12
+ raw = "#{history}?rev=\#{revision}"
13
+ html = "#{raw}&view=markup"
14
+ # http://svn.picocontainer.codehaus.org/java/picocontainer/trunk/container/project.xml?r1=2220&r2=2234&p1=java/picocontainer/trunk/container/project.xml&p2=java/picocontainer/trunk/container/project.xml
15
+ diff = "#{history}?r1=\#{previous_revision}&r2=\#{revision}&p1=#{svn_path}/\#{path}&p2=#{svn_path}/\#{path}"
16
+ @scm_web = ScmWeb.new(overview, history, raw, html, diff)
17
+ end
18
+
19
+ def home_page
20
+ "http://#{@project_id}.codehaus.org/"
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1 @@
1
+ require 'meta_project/project/trac/trac_project'
@@ -0,0 +1,26 @@
1
+ module MetaProject
2
+ module Project
3
+ module Trac
4
+ class TracProject < Base
5
+
6
+ def initialize(trac_base_url, svn_root_url, svn_path)
7
+ @trac_base_url = trac_base_url
8
+ @scm = RSCM::Subversion.new("#{svn_root_url}#{svn_path}", svn_path)
9
+ @tracker = ::MetaProject::Tracker::Trac::TracTracker.new(trac_base_url)
10
+
11
+ overview = "#{trac_base_url}/browser/#{svn_path}/"
12
+ history = "#{trac_base_url}/log/#{svn_path}/\#{path}"
13
+ html = "#{trac_base_url}/file/#{svn_path}/\#{path}?rev=\#{revision}"
14
+ raw = "#{html}&format=txt"
15
+ diff = "#{trac_base_url}/changeset/\#{revision}"
16
+ @scm_web = ScmWeb.new(overview, history, raw, html, diff)
17
+ end
18
+
19
+ def home_page
20
+ "#{@trac_base_url}/wiki"
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ require 'meta_project/project/xforge/xforge_base'
2
+ require 'meta_project/project/xforge/session'
3
+ require 'meta_project/project/xforge/xfile'
4
+ require 'meta_project/project/xforge/ruby_forge'
5
+ require 'meta_project/project/xforge/source_forge'
@@ -0,0 +1,46 @@
1
+ require 'meta_project/tracker/xforge'
2
+
3
+ module MetaProject
4
+ module Project
5
+ module XForge
6
+ class RubyForge < XForgeBase
7
+
8
+ def initialize(unix_name, cvs_mod=nil)
9
+ super("rubyforge.org", unix_name, cvs_mod)
10
+ end
11
+
12
+ def tracker_class
13
+ ::MetaProject::Tracker::XForge::RubyForgeTracker
14
+ end
15
+
16
+ protected
17
+
18
+ def create_cvs(unix_name, mod)
19
+ RSCM::Cvs.new(":pserver:anonymous@rubyforge.org:/var/cvs/#{unix_name}", mod)
20
+ end
21
+
22
+ def create_view_cvs(unix_name, mod)
23
+ view_cvs = "http://rubyforge.org/cgi-bin/viewcvs.cgi/"
24
+ cvsroot = "?cvsroot=#{unix_name}"
25
+ path_cvs_root = "#{mod}/\#{path}#{cvsroot}"
26
+ path_cvs_root_rev = "#{path_cvs_root}&rev=\#{revision}"
27
+
28
+ overview = "#{view_cvs}#{mod}/#{cvsroot}"
29
+ history = "#{view_cvs}#{path_cvs_root}"
30
+ raw = "#{view_cvs}*checkout*/#{path_cvs_root_rev}"
31
+ html = "#{view_cvs}#{path_cvs_root_rev}&content-type=text/vnd.viewcvs-markup"
32
+ diff = "#{view_cvs}#{mod}/\#{path}.diff#{cvsroot}&r1=\#{previous_revision}&r2=\#{revision}"
33
+
34
+ ScmWeb.new(overview, history, raw, html, diff)
35
+ end
36
+
37
+ # Regexp used to find projects' home page
38
+ def home_page_regexp
39
+ # This seems a little volatile
40
+ /<a href=\"(\w*:\/\/[^\"]*)\"><img src=\"\/themes\/osx\/images\/ic\/home/
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,162 @@
1
+ require 'net/http'
2
+ require 'open-uri'
3
+
4
+ module MetaProject
5
+ module Project
6
+ module XForge
7
+
8
+ # A Session object allows authenticated interaction with a Project, such as releasing files.
9
+ #
10
+ # A Session object can be obtained via Project.login
11
+ #
12
+ class Session
13
+
14
+ # Simple enumeration of processors. Used from Session.release
15
+ class Processor
16
+ I386 = 1000
17
+ IA64 = 6000
18
+ ALPHA = 7000
19
+ ANY = 8000
20
+ PPC = 2000
21
+ MIPS = 3000
22
+ SPARC = 4000
23
+ ULTRA_SPARC = 5000
24
+ OTHER_PLATFORM = 9999
25
+ end
26
+
27
+ BOUNDARY = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
28
+
29
+ def initialize(host, project, cookie) # :nodoc:
30
+ @host = host
31
+ @project = project
32
+ @headers = { "Cookie" => cookie }
33
+ end
34
+
35
+ # The package_id of our project
36
+ def package_id
37
+ unless(@package_id)
38
+ release_uri = "http://#{@host}/frs/admin/?group_id=#{@project.group_id}"
39
+ release_data = open(release_uri, @headers) { |data| data.read }
40
+ @package_id = release_data[/[?&]package_id=(\d+)/, 1]
41
+ raise "Couldn't get package_id" unless @package_id
42
+ end
43
+ @package_id
44
+ end
45
+
46
+ # Creates a new release containing the files specified by +filenames+ (Array) and named +release_name+.
47
+ # Optional parameters are +processor+ (which should be one of the Processor constants), +release_notes+,
48
+ # +release_changes+ and +preformatted+ which will appear on the releas page of the associated project.
49
+ #
50
+ def release(release_name, filenames, release_notes="", release_changes="", preformatted=true, processor=Processor::ANY)
51
+ release_date = Time.now.strftime("%Y-%m-%d %H:%M")
52
+ release_id = nil
53
+
54
+ puts "About to release '#{release_name}'"
55
+ puts "Files:"
56
+ puts " " + filenames.join("\n ")
57
+ puts "\nRelease Notes:\n"
58
+ puts release_notes
59
+ puts "\nRelease Changes:\n"
60
+ puts release_changes
61
+ puts "\nRelease Settings:\n"
62
+ puts "Preformatted: #{preformatted}"
63
+ puts "Processor: #{processor}"
64
+ puts "\nStarting release..."
65
+
66
+ xfiles = filenames.collect{|filename| XFile.new(filename)}
67
+ xfiles.each_with_index do |xfile, i|
68
+ first_file = i==0
69
+ puts "Releasing #{xfile.basename}..."
70
+
71
+ release_response = Net::HTTP.start(@host, 80) do |http|
72
+ query_hash = if first_file then
73
+ {
74
+ "group_id" => @project.group_id,
75
+ "package_id" => package_id,
76
+ "type_id" => xfile.bin_type_id,
77
+ "processor_id" => processor,
78
+
79
+ "release_name" => release_name,
80
+ "release_date" => release_date,
81
+ "release_notes" => release_notes,
82
+ "release_changes" => release_changes,
83
+ "preformatted" => preformatted ? "1" : "0",
84
+ "submit" => "1"
85
+ }
86
+ else
87
+ {
88
+ "group_id" => @project.group_id,
89
+ "package_id" => package_id,
90
+ "type_id" => xfile.bin_type_id,
91
+ "processor_id" => processor,
92
+
93
+ "step2" => "1",
94
+ "release_id" => release_id,
95
+ "submit" => "Add This File"
96
+ }
97
+ end
98
+
99
+ query = query(query_hash)
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
+ 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, 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
+ puts "Done!"
123
+ end
124
+
125
+ def publish_news(subject, details)
126
+ puts "About to publish news"
127
+ puts "Subject: '#{subject}'"
128
+ puts "Details:"
129
+ puts details
130
+ puts ""
131
+
132
+ release_response = Net::HTTP.start(@host.name, 80) do |http|
133
+ query_hash = {
134
+ "group_id" => @project.group_id,
135
+ "package_id" => package_id,
136
+ "post_changes" => "y",
137
+ "summary" => subject,
138
+ "details" => details
139
+ }
140
+
141
+ target = "/news/submit.php"
142
+ headers = @headers.merge(
143
+ "Content-Type" => "multipart/form-data"
144
+ )
145
+ http.post(target + query(query_hash), "", headers)
146
+
147
+ end
148
+ puts "Done!"
149
+ end
150
+
151
+ private
152
+
153
+ def query(query_hash)
154
+ "?" + query_hash.map do |(name, value)|
155
+ [name, URI.encode(value.to_s)].join("=")
156
+ end.join("&")
157
+ end
158
+
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,46 @@
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
+ overview = "#{view_cvs}#{unix_name_mod}/"
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
+ ScmWeb.new(overview, history, raw, html, diff)
35
+ end
36
+
37
+ # Regexp used to find projects' home page
38
+ def home_page_regexp
39
+ # This seems a little volatile
40
+ /<A href=\"(\w*:\/\/[^\"]*)\">&nbsp;Project Home Page<\/A>/
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +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
45
+ end