meta_project 0.4.11 → 0.4.12

Sign up to get free protection for your applications and to get access to all the features.
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