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.
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