meta_project 0.4.11 → 0.4.12

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 (49) hide show
  1. data/CHANGES +277 -269
  2. data/MIT-LICENSE +21 -21
  3. data/README +126 -126
  4. data/Rakefile +152 -152
  5. data/doc/base_attrs.rdoc +2 -2
  6. data/lib/meta_project.rb +11 -10
  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 +32 -0
  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 -48
  20. data/lib/meta_project/project/xforge/session.rb +177 -191
  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 -79
  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 -32
  33. data/lib/meta_project/tracker/issue.rb +56 -52
  34. data/lib/meta_project/tracker/jira.rb +2 -2
  35. data/lib/meta_project/tracker/jira/jira_issues.rb +34 -33
  36. data/lib/meta_project/tracker/jira/jira_tracker.rb +123 -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 -105
  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 +3 -3
  49. data/TODO +0 -9
@@ -1 +1 @@
1
- require 'meta_project/tracker/trac/trac_tracker'
1
+ require 'meta_project/tracker/trac/trac_tracker'
@@ -1,33 +1,33 @@
1
- module MetaProject
2
- module Tracker
3
- module Trac
4
- class TracTracker < Base
5
- include DigitIssues
6
-
7
- attr_accessor :trac_base_url
8
-
9
- def initialize(trac_base_url=nil)
10
- @trac_base_url = trac_base_url
11
- end
12
-
13
- def overview
14
- "#{@trac_base_url}/report"
15
- end
16
-
17
- def materialize(issue)
18
- begin
19
- url = "#{@trac_base_url}/ticket/#{issue.identifier}"
20
- html = better_open(url).read
21
- summary = html[/Ticket ##{issue.identifier}\s*<\/h1>\s*<h2>([^<]*)<\/h2>/n, 1]
22
- issue.attributes[:summary] = summary
23
- issue.attributes[:url] = url
24
- rescue OpenURI::HTTPError => e
25
- STDERR.puts e.message
26
- end
27
- issue
28
- end
29
-
30
- end
31
- end
32
- end
1
+ module MetaProject
2
+ module Tracker
3
+ module Trac
4
+ class TracTracker < Base
5
+ include DigitIssues
6
+
7
+ attr_accessor :trac_base_url
8
+
9
+ def initialize(trac_base_url=nil)
10
+ @trac_base_url = trac_base_url
11
+ end
12
+
13
+ def overview
14
+ "#{@trac_base_url}/report"
15
+ end
16
+
17
+ def materialize(issue)
18
+ begin
19
+ url = "#{@trac_base_url}/ticket/#{issue.identifier}"
20
+ html = better_open(url).read
21
+ summary = html[/Ticket ##{issue.identifier}\s*<\/h1>\s*<h2>([^<]*)<\/h2>/n, 1]
22
+ issue.attributes[:summary] = summary
23
+ issue.attributes[:url] = url
24
+ rescue OpenURI::HTTPError => e
25
+ STDERR.puts e.message
26
+ end
27
+ issue
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
33
  end
@@ -1,3 +1,3 @@
1
- require 'meta_project/tracker/xforge/xforge_tracker'
2
- require 'meta_project/tracker/xforge/ruby_forge_tracker'
3
- require 'meta_project/tracker/xforge/source_forge_tracker'
1
+ require 'meta_project/tracker/xforge/xforge_tracker'
2
+ require 'meta_project/tracker/xforge/ruby_forge_tracker'
3
+ require 'meta_project/tracker/xforge/source_forge_tracker'
@@ -1,17 +1,17 @@
1
- module MetaProject
2
- module Tracker
3
- module XForge
4
- class RubyForgeTracker < XForgeTracker
5
-
6
- def subtracker_pattern
7
- /\/tracker\/\?atid=(\d+)&group_id=\d*&func=browse/
8
- end
9
-
10
- def issue_summary_pattern(identifier)
11
- /<a href=\"\/tracker\/index.php\?func=detail&aid=#{identifier}&group_id=\d+&atid=\d+\">([^<]*)<\/a>/
12
- end
13
-
14
- end
15
- end
16
- end
17
- end
1
+ module MetaProject
2
+ module Tracker
3
+ module XForge
4
+ class RubyForgeTracker < XForgeTracker
5
+
6
+ def subtracker_pattern
7
+ /\/tracker\/\?atid=(\d+)&group_id=\d*&func=browse/
8
+ end
9
+
10
+ def issue_summary_pattern(identifier)
11
+ /<a href=\"\/tracker\/index.php\?func=detail&aid=#{identifier}&group_id=\d+&atid=\d+\">([^<]*)<\/a>/
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,17 +1,17 @@
1
- module MetaProject
2
- module Tracker
3
- module XForge
4
- class SourceForgeTracker < XForgeTracker
5
-
6
- def subtracker_pattern
7
- /\/tracker\/\?atid=(\d+)&amp;group_id=\d*&amp;func=browse/
8
- end
9
-
10
- def issue_summary_pattern(identifier)
11
- /<a href=\"\/tracker\/index.php\?func=detail&amp;aid=#{identifier}&amp;group_id=\d+&amp;atid=\d+\">([^<]*)<\/a>/
12
- end
13
-
14
- end
15
- end
16
- end
17
- end
1
+ module MetaProject
2
+ module Tracker
3
+ module XForge
4
+ class SourceForgeTracker < XForgeTracker
5
+
6
+ def subtracker_pattern
7
+ /\/tracker\/\?atid=(\d+)&amp;group_id=\d*&amp;func=browse/
8
+ end
9
+
10
+ def issue_summary_pattern(identifier)
11
+ /<a href=\"\/tracker\/index.php\?func=detail&amp;aid=#{identifier}&amp;group_id=\d+&amp;atid=\d+\">([^<]*)<\/a>/
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,106 +1,191 @@
1
-
2
- require 'meta_project/tracker/base'
3
- require 'meta_project/tracker/digit_issues'
4
- require 'meta_project/tracker/issue'
5
-
6
- module MetaProject
7
- module Tracker
8
- module XForge
9
- class XForgeTracker < Base
10
- include DigitIssues
11
-
12
- attr_accessor :overview, :project
13
-
14
- # TODO: don't pass in project!! pass in hostname and id! This won't work from DC!!
15
- def initialize(overview=nil, project=nil)
16
- @overview, @project = overview, project
17
- end
18
-
19
- # Finds an Issue by +identifier+
20
- def issue(identifier)
21
- sub_trackers = atids.collect {|atid| SubTracker.new(self, atid)}
22
- sub_trackers.each do |sub_tracker|
23
- issue = sub_tracker.issue(identifier)
24
- return issue unless issue.nil?
25
- end
26
- nil
27
- end
28
-
29
- def materialize(issue)
30
- issue
31
- end
32
-
33
- class SubTracker
34
-
35
- def initialize(tracker, atid)
36
- @tracker = tracker
37
- @atid = atid
38
- # FIXME: This will only show open items.
39
- @uri = "#{tracker.overview}&atid=#{atid}&func=browse"
40
- end
41
-
42
- def issue(identifier)
43
- html = better_open(@uri).read
44
-
45
- issue_summary_pattern = @tracker.issue_summary_pattern(identifier)
46
- if(html =~ issue_summary_pattern)
47
- issue_url = @tracker.project.group_id_uri("tracker/index.php", "&atid=#{@atid}&func=detail&aid=#{identifier}")
48
- issue_summary = $1.strip
49
- return Issue.new(@tracker, :summary => issue_summary, :url => issue_url)
50
- end
51
- nil
52
- end
53
- end
54
-
55
- private
56
-
57
- # The ids of the subtrackers
58
- def atids
59
- # headers = {
60
- # "User-Agent" => "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4",
61
- # "Accept" => "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
62
- # "Accept-Language" => "en-us,en;q=0.5",
63
- # "Accept-Encoding" => "gzip,deflate",
64
- # "Accept-Charset" => "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
65
- # "Keep-Alive" => "300",
66
- # "Connection" => "close",
67
- # "X-Requested-With" => "XMLHttpRequest",
68
- # "X-Prototype-Version" => "1.3.1",
69
- # "Content-Type" => "application/x-www-form-urlencoded",
70
- # "Content-Length" => "0",
71
- # "Cookie" => "author=AnonymousCoward; _session_id=975a583d513190522ce3aeba315552d0",
72
- # "Pragma" => "no-cache",
73
- # "Cache-Control" => "no-cache"
74
- # }
75
-
76
- html = better_open(overview).read
77
- STDERR.puts "The HTML returned from #{overview} was empty! This might be because the server is trying to fool us" if html == ""
78
-
79
- # TODO: there has to be a better way to extract the atids from the HTML!
80
- atids = []
81
- offset = 0
82
- look_for_atid = true
83
- while(look_for_atid)
84
- match_data = subtracker_pattern.match(html[offset..-1])
85
- if(match_data)
86
- offset += match_data.begin(1)
87
- atids << match_data[1]
88
- else
89
- look_for_atid = false
90
- end
91
- end
92
- if atids.empty?
93
- debug_file = "xforge_tracker_debug.html"
94
- File.open(debug_file, "w"){|io| io.write html}
95
- STDERR.puts "WARNING: No subtrackers found at #{overview}."
96
- STDERR.puts "I was looking for /#{subtracker_pattern.source}/"
97
- STDERR.puts "Please consider filing a bug report at http://rubyforge.org/tracker/?atid=3161&group_id=801&func=browse"
98
- STDERR.puts "The HTML has been saved to #{debug_file}"
99
- end
100
- atids
101
- end
102
-
103
- end
104
- end
105
- end
1
+
2
+ require 'meta_project/tracker/base'
3
+ require 'meta_project/tracker/digit_issues'
4
+ require 'meta_project/tracker/issue'
5
+
6
+ module MetaProject
7
+ module Tracker
8
+ module XForge
9
+ class XForgeTracker < Base
10
+ include DigitIssues
11
+
12
+ attr_accessor :overview, :project
13
+
14
+ # TODO: don't pass in project!! pass in hostname and id! This won't work from DC!!
15
+ def initialize(overview=nil, project=nil)
16
+ @overview, @project = overview, project
17
+ end
18
+
19
+ # Finds an Issue by +identifier+
20
+ def issue(identifier)
21
+ sub_trackers.each do |sub_tracker|
22
+ issue = sub_tracker.issue(identifier)
23
+ return issue unless issue.nil?
24
+ end
25
+ nil
26
+ end
27
+
28
+ def materialize(issue)
29
+ issue
30
+ end
31
+
32
+ def create(issue, user_name, password)
33
+ # TODO: get the subtracker atid or name from the issue's options
34
+ subtracker = sub_trackers[0]
35
+ subtracker.create(issue, user_name, password)
36
+ end
37
+
38
+ class SubTracker
39
+ include HTTP::Multipart
40
+
41
+ # Issue modification constants
42
+ OPEN = 1
43
+ CLOSED = 2
44
+ DELETED = 3
45
+
46
+ def initialize(tracker, atid)
47
+ @tracker = tracker
48
+ @atid = atid
49
+ # FIXME: This will only show open items.
50
+ @baseurl = "#{tracker.overview}&atid=#{atid}"
51
+ @overview = "#{@baseurl}&func=browse"
52
+ end
53
+
54
+ def issue(identifier)
55
+ html = better_open(@overview).read
56
+
57
+ issue_summary_pattern = @tracker.issue_summary_pattern(identifier)
58
+ if(html =~ issue_summary_pattern)
59
+ issue_url = @tracker.project.group_id_uri("tracker/index.php", "&atid=#{@atid}&func=detail&aid=#{identifier}")
60
+ issue_summary = $1.strip
61
+ return Issue.new(self, :identifier => identifier,:summary => issue_summary, :url => issue_url)
62
+ else
63
+ nil
64
+ end
65
+ end
66
+
67
+ def create(issue, user_name, password)
68
+ session = @tracker.project.login(user_name, password)
69
+
70
+ Net::HTTP.start(@tracker.project.host, 80) do |http|
71
+ query_hash = {
72
+ "func" => "postadd",
73
+ "category_id" => "100", # seems to be standard for all trackers
74
+ "artifact_group_id" => "100", # seems to be standard for all trackers
75
+ "summary" => issue.summary,
76
+ "details" => issue.detail,
77
+ "user_email" => "",
78
+ }
79
+
80
+ target = "/news/submit.php" #TODO: use this?
81
+ response = post_multipart(http, @baseurl, query_hash, session.request_headers)
82
+
83
+ # the post brings us back to the overview page, where the new issue is the last one
84
+ response.body.scan(/aid=([\d]+)/) do |a|
85
+ issue.attributes[:identifier] = a[0]
86
+ end
87
+ end
88
+ issue
89
+ end
90
+
91
+ def close(issue, user_name, password)
92
+ modify(issue, user_name, password, CLOSED)
93
+ end
94
+
95
+ def delete(issue, user_name, password)
96
+ modify(issue, user_name, password, DELETE)
97
+ end
98
+
99
+ private
100
+
101
+ def modify(issue, user_name, password, status)
102
+ session = @tracker.project.login(user_name, password)
103
+
104
+ Net::HTTP.start(@tracker.project.host, 80) do |http|
105
+ query_hash = {
106
+ "group_id" => @tracker.project.group_id,
107
+ "atid" => @atid,
108
+ "func" => "postmod",
109
+ "$result[]" => "",
110
+ "artifact_id" => issue.identifier,
111
+ "new_artifact_type_id" => @atid,
112
+ "category_id" => "100", # None
113
+ "artifact_group_id" => "100", # None
114
+ "assigned_to" => "100", # None
115
+ "priority" => "3", # None
116
+ "status_id" => status,
117
+ "resolution_id" => "100",
118
+ "canned_respnse" => "100",
119
+ "summary" => issue.summary,
120
+ "details" => issue.detail
121
+ }
122
+
123
+ target = "/tracker/index.php"
124
+ response = post_multipart(http, target, query_hash, session.request_headers)
125
+
126
+ close_pattern = /Updated successfully/
127
+ unless(response.body =~ close_pattern)
128
+ File.open("xforge_close.html", "w") {|io| io.write response.body}
129
+ STDERR.puts "WARNING: Failed to close issue \##{issue.identifier}. I was looking for /#{close_pattern.source}/. Response written to xforge_close.html"
130
+ end
131
+ end
132
+ issue
133
+ end
134
+ end
135
+
136
+ private
137
+
138
+ def sub_trackers
139
+ @sub_trackers ||= atids.collect {|atid| SubTracker.new(self, atid)}
140
+ end
141
+
142
+ # The ids of the subtrackers
143
+ def atids
144
+ # headers = {
145
+ # "User-Agent" => "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4",
146
+ # "Accept" => "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
147
+ # "Accept-Language" => "en-us,en;q=0.5",
148
+ # "Accept-Encoding" => "gzip,deflate",
149
+ # "Accept-Charset" => "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
150
+ # "Keep-Alive" => "300",
151
+ # "Connection" => "close",
152
+ # "X-Requested-With" => "XMLHttpRequest",
153
+ # "X-Prototype-Version" => "1.3.1",
154
+ # "Content-Type" => "application/x-www-form-urlencoded",
155
+ # "Content-Length" => "0",
156
+ # "Cookie" => "author=AnonymousCoward; _session_id=975a583d513190522ce3aeba315552d0",
157
+ # "Pragma" => "no-cache",
158
+ # "Cache-Control" => "no-cache"
159
+ # }
160
+
161
+ html = better_open(overview).read
162
+ STDERR.puts "The HTML returned from #{overview} was empty! This might be because the server is trying to fool us" if html == ""
163
+
164
+ # TODO: there has to be a better way to extract the atids from the HTML!
165
+ atids = []
166
+ offset = 0
167
+ look_for_atid = true
168
+ while(look_for_atid)
169
+ match_data = subtracker_pattern.match(html[offset..-1])
170
+ if(match_data)
171
+ offset += match_data.begin(1)
172
+ atids << match_data[1]
173
+ else
174
+ look_for_atid = false
175
+ end
176
+ end
177
+ if atids.empty?
178
+ debug_file = "xforge_tracker_debug.html"
179
+ File.open(debug_file, "w"){|io| io.write html}
180
+ STDERR.puts "WARNING: No subtrackers found at #{overview}."
181
+ STDERR.puts "I was looking for /#{subtracker_pattern.source}/"
182
+ STDERR.puts "Please consider filing a bug report at http://rubyforge.org/tracker/?atid=3161&group_id=801&func=browse"
183
+ STDERR.puts "The HTML has been saved to #{debug_file}"
184
+ end
185
+ atids
186
+ end
187
+
188
+ end
189
+ end
190
+ end
106
191
  end
@@ -1,52 +1,52 @@
1
- module MetaProject
2
- class VersionParser
3
- def parse(changes_file, version)
4
- release_notes_first = nil
5
- changes_first = nil
6
- changes_last = nil
7
-
8
- lines = File.open(changes_file).readlines
9
- state = nil
10
- lines.each_with_index do |line, n|
11
- # parse state
12
- if (line =~ /^==/ && state == :in_release_notes && state != :done)
13
- changes_first = changes_last = n
14
- state = :done
15
- end
16
- if line =~ /#{version}/ && state.nil?
17
- state = :in_release_notes
18
- release_notes_first = n+1
19
- end
20
- if (line =~ /^\*/ && state == :in_release_notes)
21
- state = :in_changes
22
- changes_first = changes_last = n
23
- end
24
- if (line =~ /^\*/ && state == :in_changes)
25
- changes_last = n
26
- end
27
- if (line =~ /^==/ && state == :in_changes)
28
- state = :done
29
- end
30
- end
31
-
32
- release_notes = lines[release_notes_first..changes_first-1].join("")
33
- raise "Release notes for #{version} couldn't be parsed from #{changes_file}" if release_notes.strip == ""
34
-
35
- release_changes = lines[changes_first..changes_last].collect do |line|
36
- line.length >= 2 ? line[2..-1].chomp : line
37
- end
38
- raise "Release changes for #{version} couldn't be parsed from #{changes_file}" if release_changes.length == 0
39
-
40
- Version.new(release_notes, release_changes)
41
- end
42
- end
43
-
44
- class Version
45
- attr_reader :release_notes # String
46
- attr_reader :release_changes # Array of String
47
-
48
- def initialize(release_notes, release_changes)
49
- @release_notes, @release_changes = release_notes, release_changes
50
- end
51
- end
52
- end
1
+ module MetaProject
2
+ class VersionParser
3
+ def parse(changes_file, version)
4
+ release_notes_first = nil
5
+ changes_first = nil
6
+ changes_last = nil
7
+
8
+ lines = File.open(changes_file).readlines
9
+ state = nil
10
+ lines.each_with_index do |line, n|
11
+ # parse state
12
+ if (line =~ /^==/ && state == :in_release_notes && state != :done)
13
+ changes_first = changes_last = n
14
+ state = :done
15
+ end
16
+ if line =~ /#{version}/ && state.nil?
17
+ state = :in_release_notes
18
+ release_notes_first = n+1
19
+ end
20
+ if (line =~ /^\*/ && state == :in_release_notes)
21
+ state = :in_changes
22
+ changes_first = changes_last = n
23
+ end
24
+ if (line =~ /^\*/ && state == :in_changes)
25
+ changes_last = n
26
+ end
27
+ if (line =~ /^==/ && state == :in_changes)
28
+ state = :done
29
+ end
30
+ end
31
+
32
+ release_notes = lines[release_notes_first..changes_first-1].join("")
33
+ raise "Release notes for #{version} couldn't be parsed from #{changes_file}" if release_notes.strip == ""
34
+
35
+ release_changes = lines[changes_first..changes_last].collect do |line|
36
+ line.length >= 2 ? line[2..-1].chomp : line
37
+ end
38
+ raise "Release changes for #{version} couldn't be parsed from #{changes_file}" if release_changes.length == 0
39
+
40
+ Version.new(release_notes, release_changes)
41
+ end
42
+ end
43
+
44
+ class Version
45
+ attr_reader :release_notes # String
46
+ attr_reader :release_changes # Array of String
47
+
48
+ def initialize(release_notes, release_changes)
49
+ @release_notes, @release_changes = release_notes, release_changes
50
+ end
51
+ end
52
+ end