meta_project 0.4.12 → 0.4.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/CHANGES +283 -277
  2. data/MIT-LICENSE +21 -21
  3. data/README +130 -126
  4. data/Rakefile +152 -152
  5. data/doc/base_attrs.rdoc +2 -2
  6. data/lib/meta_project.rb +11 -11
  7. data/lib/meta_project/core_ext/open_uri.rb +22 -22
  8. data/lib/meta_project/core_ext/pathname.rb +36 -36
  9. data/lib/meta_project/core_ext/string.rb +4 -4
  10. data/lib/meta_project/http/multipart.rb +31 -31
  11. data/lib/meta_project/patois/parser.rb +98 -98
  12. data/lib/meta_project/project.rb +4 -4
  13. data/lib/meta_project/project/base.rb +8 -8
  14. data/lib/meta_project/project/codehaus.rb +1 -1
  15. data/lib/meta_project/project/codehaus/codehaus_project_svn.rb +30 -30
  16. data/lib/meta_project/project/trac.rb +1 -1
  17. data/lib/meta_project/project/trac/trac_project.rb +53 -53
  18. data/lib/meta_project/project/xforge.rb +5 -5
  19. data/lib/meta_project/project/xforge/ruby_forge.rb +46 -46
  20. data/lib/meta_project/project/xforge/session.rb +177 -177
  21. data/lib/meta_project/project/xforge/source_forge.rb +49 -49
  22. data/lib/meta_project/project/xforge/xfile.rb +44 -44
  23. data/lib/meta_project/project/xforge/xforge_base.rb +81 -81
  24. data/lib/meta_project/project_analyzer.rb +35 -35
  25. data/lib/meta_project/release/freshmeat.rb +267 -267
  26. data/lib/meta_project/release/raa.rb +572 -572
  27. data/lib/meta_project/scm_web.rb +1 -1
  28. data/lib/meta_project/scm_web/browser.rb +111 -111
  29. data/lib/meta_project/scm_web/pathname.rb +88 -88
  30. data/lib/meta_project/tracker.rb +6 -6
  31. data/lib/meta_project/tracker/base.rb +23 -23
  32. data/lib/meta_project/tracker/digit_issues.rb +33 -33
  33. data/lib/meta_project/tracker/issue.rb +56 -56
  34. data/lib/meta_project/tracker/jira.rb +2 -2
  35. data/lib/meta_project/tracker/jira/jira_issues.rb +34 -34
  36. data/lib/meta_project/tracker/jira/jira_tracker.rb +148 -123
  37. data/lib/meta_project/tracker/trac.rb +1 -1
  38. data/lib/meta_project/tracker/trac/trac_tracker.rb +32 -32
  39. data/lib/meta_project/tracker/xforge.rb +3 -3
  40. data/lib/meta_project/tracker/xforge/ruby_forge_tracker.rb +17 -17
  41. data/lib/meta_project/tracker/xforge/source_forge_tracker.rb +17 -17
  42. data/lib/meta_project/tracker/xforge/xforge_tracker.rb +190 -190
  43. data/lib/meta_project/version_parser.rb +52 -52
  44. data/lib/rake/contrib/xforge.rb +3 -3
  45. data/lib/rake/contrib/xforge/base.rb +64 -64
  46. data/lib/rake/contrib/xforge/news_publisher.rb +97 -97
  47. data/lib/rake/contrib/xforge/release.rb +134 -134
  48. metadata +4 -3
@@ -1,34 +1,34 @@
1
- module MetaProject
2
- module Tracker
3
- # This module should be included by trackers that follow a digit-based issue scheme.
4
- # TODO: Make issue_pattern and command_pattern attributes so they can be modified. Provide examples.
5
- module DigitIssues
6
- # Patois issue pattern
7
- def issue_pattern
8
- @issue_pattern ||= /\#([\d]+)/
9
- end
10
- module_function :issue_pattern
11
-
12
- # Patois command pattern
13
- def command_pattern
14
- @command_pattern ||= /([A-Za-z]*).?(\#[\d]+(?:(?:[, &]*|\s?and\s?)\#[\d]+)*)/
15
- end
16
- module_function :command_pattern
17
-
18
- def identifier_examples
19
- ["#1926", "#1446"]
20
- end
21
-
22
- # TODO: find a way to extract just the issue summaries so they can be stored in dc as an array
23
- # embedded in the revision object. that way we don't alter the original commit message
24
- def markup(text)
25
- text.gsub(issue_pattern) do |match|
26
- issue_identifier = $1
27
- issue = issue(issue_identifier)
28
- link_text = (issue && issue.summary && issue.summary.strip! != "") ? "#{issue_identifier}: #{issue.summary}" : issue_identifier
29
- (issue && issue.url) ? "<a href=\"#{issue.url}\">\##{link_text}</a>" : "\##{issue_identifier}"
30
- end
31
- end
32
- end
33
- end
1
+ module MetaProject
2
+ module Tracker
3
+ # This module should be included by trackers that follow a digit-based issue scheme.
4
+ # TODO: Make issue_pattern and command_pattern attributes so they can be modified. Provide examples.
5
+ module DigitIssues
6
+ # Patois issue pattern
7
+ def issue_pattern
8
+ @issue_pattern ||= /\#([\d]+)/
9
+ end
10
+ module_function :issue_pattern
11
+
12
+ # Patois command pattern
13
+ def command_pattern
14
+ @command_pattern ||= /([A-Za-z]*).?(\#[\d]+(?:(?:[, &]*|\s?and\s?)\#[\d]+)*)/
15
+ end
16
+ module_function :command_pattern
17
+
18
+ def identifier_examples
19
+ ["#1926", "#1446"]
20
+ end
21
+
22
+ # TODO: find a way to extract just the issue summaries so they can be stored in dc as an array
23
+ # embedded in the revision object. that way we don't alter the original commit message
24
+ def markup(text)
25
+ text.gsub(issue_pattern) do |match|
26
+ issue_identifier = $1
27
+ issue = issue(issue_identifier)
28
+ link_text = (issue && issue.summary && issue.summary.strip! != "") ? "#{issue_identifier}: #{issue.summary}" : issue_identifier
29
+ (issue && issue.url) ? "<a href=\"#{issue.url}\">\##{link_text}</a>" : "\##{issue_identifier}"
30
+ end
31
+ end
32
+ end
33
+ end
34
34
  end
@@ -1,57 +1,57 @@
1
- module MetaProject
2
- module Tracker
3
-
4
- # An issue represents an entry in an issue tracker such as a bug report or
5
- # feature request.
6
- class Issue
7
- attr_reader :attributes
8
-
9
- def initialize(tracker, attributes={})
10
- @tracker = tracker
11
- @attributes = attributes
12
- end
13
-
14
- # An URL pointing to the issue in the associated tracker, or nil if
15
- # the issue doesn't exist.
16
- def url
17
- @tracker.materialize(self) unless @attributes[:url]
18
- @attributes[:url]
19
- end
20
-
21
- # The id of the issue in the tracker
22
- def identifier
23
- @tracker.materialize(self) unless @attributes[:identifier]
24
- @attributes[:identifier]
25
- end
26
-
27
- # The summary of the issue (typically a one-liner)
28
- def summary
29
- @tracker.materialize(self) unless @attributes[:summary]
30
- @attributes[:summary]
31
- end
32
-
33
- # The details of the issue (typically several lines)
34
- def detail
35
- @tracker.materialize(self) unless @attributes[:detail]
36
- @attributes[:detail]
37
- end
38
-
39
- # Adds a comment (consisting of the +detail+) to the issue
40
- def update(user_name, password)
41
- @tracker.update(self, user_name, password)
42
- end
43
-
44
- # Creates a new issue (consisting of the +summary+ and +detail+)
45
- def create(user_name, password)
46
- raise "Summary not set" unless summary
47
- raise "Detail not set" unless detail
48
- @tracker.create(self, user_name, password)
49
- end
50
-
51
- # Closes the issue (adding a comment consisting of the +detail+)
52
- def close(user_name, password)
53
- @tracker.close(self, user_name, password)
54
- end
55
- end
56
- end
1
+ module MetaProject
2
+ module Tracker
3
+
4
+ # An issue represents an entry in an issue tracker such as a bug report or
5
+ # feature request.
6
+ class Issue
7
+ attr_reader :attributes
8
+
9
+ def initialize(tracker, attributes={})
10
+ @tracker = tracker
11
+ @attributes = attributes
12
+ end
13
+
14
+ # An URL pointing to the issue in the associated tracker, or nil if
15
+ # the issue doesn't exist.
16
+ def url
17
+ @tracker.materialize(self) unless @attributes[:url]
18
+ @attributes[:url]
19
+ end
20
+
21
+ # The id of the issue in the tracker
22
+ def identifier
23
+ @tracker.materialize(self) unless @attributes[:identifier]
24
+ @attributes[:identifier]
25
+ end
26
+
27
+ # The summary of the issue (typically a one-liner)
28
+ def summary
29
+ @tracker.materialize(self) unless @attributes[:summary]
30
+ @attributes[:summary]
31
+ end
32
+
33
+ # The details of the issue (typically several lines)
34
+ def detail
35
+ @tracker.materialize(self) unless @attributes[:detail]
36
+ @attributes[:detail]
37
+ end
38
+
39
+ # Adds a comment (consisting of the +detail+) to the issue
40
+ def update(user_name, password)
41
+ @tracker.update(self, user_name, password)
42
+ end
43
+
44
+ # Creates a new issue (consisting of the +summary+ and +detail+)
45
+ def create(user_name, password)
46
+ raise "Summary not set" unless summary
47
+ raise "Detail not set" unless detail
48
+ @tracker.create(self, user_name, password)
49
+ end
50
+
51
+ # Closes the issue (adding a comment consisting of the +detail+)
52
+ def close(user_name, password)
53
+ @tracker.close(self, user_name, password)
54
+ end
55
+ end
56
+ end
57
57
  end
@@ -1,2 +1,2 @@
1
- require 'meta_project/tracker/jira/jira_issues'
2
- require 'meta_project/tracker/jira/jira_tracker'
1
+ require 'meta_project/tracker/jira/jira_issues'
2
+ require 'meta_project/tracker/jira/jira_tracker'
@@ -1,35 +1,35 @@
1
- module MetaProject
2
- module Tracker
3
- module Jira
4
- # This module should be included by trackers that follow a digit-based issue scheme
5
- module JiraIssues
6
-
7
- # Patois issue pattern
8
- def issue_pattern
9
- /([A-Za-z]+-[\d]+)/
10
- end
11
- module_function :issue_pattern
12
-
13
- # Patois command pattern
14
- def command_pattern
15
- /([A-Za-z]*).?([A-Za-z]+-[\d]+(?:(?:[, &]*|\s?and\s?)[A-Za-z]+-[\d]+)*)/
16
- end
17
- module_function :command_pattern
18
-
19
- def identifier_examples
20
- ["DC-420", "pico-12"]
21
- end
22
-
23
- def markup(text)
24
- text.gsub(issue_pattern) do |match|
25
- issue_identifier = $1.upcase
26
- issue = issue(issue_identifier)
27
- link_text = (issue.summary && issue.summary.strip! != "") ? "#{issue_identifier}: #{issue.summary}" : issue_identifier
28
- issue.url ? "<a href=\"#{issue.url}\">#{link_text}</a>" : issue_identifier
29
- end
30
- end
31
-
32
- end
33
- end
34
- end
1
+ module MetaProject
2
+ module Tracker
3
+ module Jira
4
+ # This module should be included by trackers that follow a digit-based issue scheme
5
+ module JiraIssues
6
+
7
+ # Patois issue pattern
8
+ def issue_pattern
9
+ /([A-Za-z]+-[\d]+)/
10
+ end
11
+ module_function :issue_pattern
12
+
13
+ # Patois command pattern
14
+ def command_pattern
15
+ /([A-Za-z]*).?([A-Za-z]+-[\d]+(?:(?:[, &]*|\s?and\s?)[A-Za-z]+-[\d]+)*)/
16
+ end
17
+ module_function :command_pattern
18
+
19
+ def identifier_examples
20
+ ["DC-420", "pico-12"]
21
+ end
22
+
23
+ def markup(text)
24
+ text.gsub(issue_pattern) do |match|
25
+ issue_identifier = $1.upcase
26
+ issue = issue(issue_identifier)
27
+ link_text = (issue.summary && issue.summary.strip! != "") ? "#{issue_identifier}: #{issue.summary}" : issue_identifier
28
+ issue.url ? "<a href=\"#{issue.url}\">#{link_text}</a>" : issue_identifier
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
35
  end
@@ -1,124 +1,149 @@
1
- require 'xmlrpc/client'
2
-
3
- module MetaProject
4
- module Tracker
5
- module Jira
6
-
7
- # Interface to JIRA. Uses the XML-RPC API defined at:
8
- #
9
- # http://confluence.atlassian.com/pages/viewpage.action?pageId=9623
10
- # http://confluence.atlassian.com/pages/viewpage.action?pageId=1035
11
- # http://www.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/index.html?com/atlassian/jira/rpc/xmlrpc/XmlRpcService.html
12
- class JiraTracker < Base
13
-
14
- include JiraIssues
15
- JIRA_API = "jira1"
16
-
17
- attr_accessor :jira_base_url, :jira_project_id
18
-
19
- # Creates a new JiraTracker. In order to successfully get issue info (via XMLRPC),
20
- # two env vars must be defined. Example:
21
- #
22
- # JiraTracker.new("http://jira.codehaus.org", "DC")
23
- #
24
- # Then the following must be defined:
25
- #
26
- # JIRA_CODEHAUS_ORG_JIRA_USER
27
- # JIRA_CODEHAUS_ORG_JIRA_PASSWORD
28
- # TODO: pass in to ctor instead. do this somewhere else!
29
- def initialize(jira_base_url=nil, jira_project_id=nil)
30
- @jira_base_url, @jira_project_id = jira_base_url, jira_project_id
31
- end
32
-
33
- def overview
34
- "#{@jira_base_url}/browse/#{@jira_project_id}"
35
- end
36
-
37
- def create(issue)
38
- issue_struct = {
39
- "project" => @jira_project_id,
40
- "summary" => issue.summary,
41
- "description" => issue.detail,
42
- "type" => 2, # magic number!
43
- "priority" => 1
44
- }
45
- login do |session|
46
- issue_struct = session.createIssue(issue_struct)
47
- issue.attributes[:identifier] = issue_struct["key"]
48
- issue
49
- end
50
- end
51
-
52
- def materialize(issue)
53
- issue.attributes[:identifier] = issue.attributes[:identifier].upcase
54
-
55
- # Getting summary and detail requires login
56
- begin
57
- login do |session|
58
- issue_struct = session.getIssue(issue.identifier)
59
- issue.attributes[:url] = "#{@jira_base_url}/browse/#{issue.identifier}"
60
- issue.attributes[:summary] = issue_struct["summary"].strip
61
- issue.attributes[:detail] = issue_struct["description"].strip
62
- end
63
- rescue JiraEnvVarException => e
64
- # Couldn't log in because of missing login info. Assume issue exists
65
- issue.attributes[:url] = "#{@jira_base_url}/browse/#{issue.identifier}"
66
- STDERR.puts("WARNING: #{e.message}")
67
- rescue XMLRPC::FaultException => e
68
- # Probably bad issue number. Don't set URL.
69
- STDERR.puts("WARNING: Exception from JIRA: #{e.faultCode}, #{e.faultString} Issue id: #{issue.identifier}")
70
- end
71
- issue
72
- end
73
-
74
- private
75
-
76
- def login
77
- client = XMLRPC::Client.new2("#{@jira_base_url}/rpc/xmlrpc")
78
- token = client.call("#{JIRA_API}.login", user, password)
79
- yield Session.new(client, token)
80
- end
81
-
82
- def user
83
- var = "#{login_env_var_prefix}_JIRA_USER"
84
- ENV[var] || missing_env_var(var)
85
- end
86
-
87
- def password
88
- var = "#{login_env_var_prefix}_JIRA_PASSWORD"
89
- ENV[var] || missing_env_var(var)
90
- end
91
-
92
- def login_env_var_prefix
93
- if(jira_base_url =~ /http:\/\/([^\/]+)/)
94
- $1.gsub(/\./, "_").upcase
95
- else
96
- raise "Bad jira_base_url: #{jira_base_url}"
97
- end
98
- end
99
-
100
- def missing_env_var(var)
101
- raise JiraEnvVarException.new("Couldn't log in to JIRA at #{@rooturl}: The " +
102
- "#{var} environment variable must be set in order to communicate with JIRA")
103
- end
104
-
105
- class JiraEnvVarException < Exception
106
- end
107
-
108
- # This wrapper around XMLRPC::Client that allows simpler method calls
109
- # via method_missing and doesn't require to manage the token
110
- class Session
111
- def initialize(client, token)
112
- @client, @token = client, token
113
- end
114
-
115
- def method_missing(sym, *args, &block)
116
- token_args = [@token] + args
117
- xmlrpc_method = "#{JIRA_API}.#{sym.to_s}"
118
- @client.call(xmlrpc_method, *token_args)
119
- end
120
- end
121
- end
122
- end
123
- end
1
+ require 'xmlrpc/client'
2
+
3
+ module MetaProject
4
+ module Tracker
5
+ module Jira
6
+
7
+ # Interface to JIRA. Uses the XML-RPC API defined at:
8
+ #
9
+ # http://www.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/com/atlassian/jira/rpc/xmlrpc/XmlRpcService.html
10
+ # http://confluence.atlassian.com/pages/viewpage.action?pageId=9623
11
+ # http://confluence.atlassian.com/pages/viewpage.action?pageId=1035
12
+ class JiraTracker < Base
13
+
14
+ include JiraIssues
15
+ JIRA_API = "jira1"
16
+
17
+ attr_accessor :jira_base_url, :jira_project_id
18
+
19
+ # Creates a new JiraTracker. In order to successfully get issue info (via XMLRPC),
20
+ # two env vars must be defined. Example:
21
+ #
22
+ # JiraTracker.new("http://jira.codehaus.org", "DC")
23
+ #
24
+ # Then the following must be defined:
25
+ #
26
+ # JIRA_CODEHAUS_ORG_JIRA_USER
27
+ # JIRA_CODEHAUS_ORG_JIRA_PASSWORD
28
+ # TODO: pass in to ctor instead. do this somewhere else!
29
+ def initialize(jira_base_url=nil, jira_project_id=nil)
30
+ @jira_base_url, @jira_project_id = jira_base_url, jira_project_id
31
+ end
32
+
33
+ def overview
34
+ "#{@jira_base_url}/browse/#{@jira_project_id}"
35
+ end
36
+
37
+ def create(issue)
38
+ issue_struct = {
39
+ "project" => @jira_project_id,
40
+ "summary" => issue.summary,
41
+ "description" => issue.detail,
42
+ "type" => 2, # magic number!
43
+ "priority" => 1
44
+ }
45
+ login do |session|
46
+ issue_struct = session.createIssue(issue_struct)
47
+ issue.attributes[:identifier] = issue_struct["key"]
48
+ issue
49
+ end
50
+ end
51
+
52
+ def close(issue)
53
+ begin
54
+ issue_struct = {
55
+ "project" => @jira_project_id,
56
+ "summary" => issue.summary,
57
+ "description" => issue.detail,
58
+ "type" => 2, # magic number!
59
+ "priority" => 1,
60
+ "status" => 6 # magic number for closed? do we have to look it up?
61
+ }
62
+ login do |session|
63
+ # TODO: Can't close JIRA issue.
64
+ # The following method:
65
+ # http://www.atlassian.com/software/jira/docs/api/rpc-jira-plugin/latest/com/atlassian/jira/rpc/xmlrpc/XmlRpcService.html#updateIssue(java.lang.String,%20java.lang.String,%20java.util.Hashtable)
66
+ # doesn't seem to exist on the JIRA on Codehaus (older version probably)
67
+ issue_struct = session.updateIssue(issue.identifier, issue_struct)
68
+ issue.attributes[:identifier] = issue_struct["key"]
69
+ issue
70
+ end
71
+ rescue XMLRPC::FaultException => e
72
+ # Probably bad issue number. Don't set URL.
73
+ STDERR.puts("WARNING: Exception from JIRA while closing issue #{issue.identifier}: #{e.faultCode}, #{e.faultString}")
74
+ end
75
+ end
76
+
77
+ def materialize(issue)
78
+ issue.attributes[:identifier] = issue.attributes[:identifier].upcase
79
+
80
+ # Getting summary and detail requires login
81
+ begin
82
+ login do |session|
83
+ issue_struct = session.getIssue(issue.identifier)
84
+ issue.attributes[:url] = "#{@jira_base_url}/browse/#{issue.identifier}"
85
+ issue.attributes[:summary] = issue_struct["summary"] ? issue_struct["summary"].strip : nil
86
+ issue.attributes[:detail] = issue_struct["description"] ? issue_struct["description"].strip : nil
87
+ end
88
+ rescue JiraEnvVarException => e
89
+ # Couldn't log in because of missing login info. Assume issue exists
90
+ issue.attributes[:url] = "#{@jira_base_url}/browse/#{issue.identifier}"
91
+ STDERR.puts("WARNING: #{e.message}")
92
+ rescue XMLRPC::FaultException => e
93
+ # Probably bad issue number. Don't set URL.
94
+ STDERR.puts("WARNING: Exception from JIRA while loading issue details for #{issue.identifier}: #{e.faultCode}, #{e.faultString}")
95
+ end
96
+ issue
97
+ end
98
+
99
+ private
100
+
101
+ def login
102
+ client = XMLRPC::Client.new2("#{@jira_base_url}/rpc/xmlrpc")
103
+ token = client.call("#{JIRA_API}.login", user, password)
104
+ yield Session.new(client, token)
105
+ end
106
+
107
+ def user
108
+ var = "#{login_env_var_prefix}_JIRA_USER"
109
+ ENV[var] || missing_env_var(var)
110
+ end
111
+
112
+ def password
113
+ var = "#{login_env_var_prefix}_JIRA_PASSWORD"
114
+ ENV[var] || missing_env_var(var)
115
+ end
116
+
117
+ def login_env_var_prefix
118
+ if(jira_base_url =~ /http:\/\/([^\/]+)/)
119
+ $1.gsub(/\./, "_").upcase
120
+ else
121
+ raise "Bad jira_base_url: #{jira_base_url}"
122
+ end
123
+ end
124
+
125
+ def missing_env_var(var)
126
+ raise JiraEnvVarException.new("Couldn't log in to JIRA at #{@rooturl}: The " +
127
+ "#{var} environment variable must be set in order to communicate with JIRA")
128
+ end
129
+
130
+ class JiraEnvVarException < Exception
131
+ end
132
+
133
+ # This wrapper around XMLRPC::Client that allows simpler method calls
134
+ # via method_missing and doesn't require to manage the token
135
+ class Session
136
+ def initialize(client, token)
137
+ @client, @token = client, token
138
+ end
139
+
140
+ def method_missing(sym, *args, &block)
141
+ token_args = [@token] + args
142
+ xmlrpc_method = "#{JIRA_API}.#{sym.to_s}"
143
+ @client.call(xmlrpc_method, *token_args)
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
124
149
  end