xforge 0.2.1 → 0.3.1
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.
- data/CHANGES +10 -0
- data/README +5 -1
- data/Rakefile +3 -3
- data/lib/scm_web/view_cvs.rb +1 -0
- data/lib/tracker/jira.rb +2 -0
- data/lib/tracker/jira/host.rb +40 -0
- data/lib/tracker/jira/project.rb +41 -0
- data/lib/tracker/trac.rb +1 -0
- data/lib/tracker/trac/project.rb +37 -0
- data/lib/tracker/xforge.rb +2 -0
- data/lib/tracker/xforge/base.rb +84 -0
- data/lib/tracker/xforge/rubyforge.rb +6 -0
- data/lib/xforge.rb +3 -1
- data/lib/xforge/project.rb +1 -1
- data/lib/xforge/rubyforge.rb +9 -4
- data/lib/xforge/sourceforge.rb +4 -3
- metadata +10 -4
- data/lib/tracker/rubyforge.rb +0 -63
data/CHANGES
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
= XForge Changelog
|
2
2
|
|
3
|
+
== Version 0.3.1
|
4
|
+
|
5
|
+
This XForge release adds initial support for Trac and JIRA.
|
6
|
+
|
7
|
+
* Added support for formatting of text containing issue identifiers
|
8
|
+
* Refactored trackers into other modules
|
9
|
+
* Added support for JIRA issue tracker
|
10
|
+
* Added support for Trac's issue tracker
|
11
|
+
* Added support for diff URLs on SourceForge and RubyForge
|
12
|
+
|
3
13
|
== Version 0.2.1
|
4
14
|
|
5
15
|
This XForge release adds support for tracker meta info
|
data/README
CHANGED
@@ -30,7 +30,11 @@ Download and install XForge with the following.
|
|
30
30
|
|
31
31
|
== Usage
|
32
32
|
|
33
|
-
|
33
|
+
XForge itself is released with XForge. so check out XForge's own Rakefile (http://tinyurl.com/a23u5) and CHANGES (http://tinyurl.com/9qxxf) files for the best examples on how to use it.
|
34
|
+
|
35
|
+
XForge can parse release summary and changes from CHANGES if you format it the way XForge's own CHANGES is formatted. Also make sure your Rakefile's PKG_VERSION is in sync with the latest version specified in the CHANGES file.
|
36
|
+
|
37
|
+
If you're writing an application that interacts with XForge, check out the RDoc API.
|
34
38
|
|
35
39
|
---
|
36
40
|
|
data/Rakefile
CHANGED
@@ -24,7 +24,7 @@ require 'rake/rdoctask'
|
|
24
24
|
#
|
25
25
|
# REMEMBER TO KEEP PKG_VERSION IN SYNC WITH CHANGELOG
|
26
26
|
PKG_NAME = "xforge"
|
27
|
-
PKG_VERSION = "0.
|
27
|
+
PKG_VERSION = "0.3.1"
|
28
28
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
29
29
|
PKG_FILES = FileList[
|
30
30
|
'[A-Z]*',
|
@@ -48,7 +48,7 @@ rd = Rake::RDocTask.new("rdoc") do |rdoc|
|
|
48
48
|
# rdoc.template = 'doc/jamis.rb'
|
49
49
|
rdoc.title = "XForge"
|
50
50
|
rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'README'
|
51
|
-
rdoc.rdoc_files.include('README', 'MIT-LICENSE', '
|
51
|
+
rdoc.rdoc_files.include('README', 'MIT-LICENSE', 'CHANGES')
|
52
52
|
rdoc.rdoc_files.include('lib/**/*.rb', 'doc/**/*.rdoc')
|
53
53
|
rdoc.rdoc_files.exclude('doc/**/*_attrs.rdoc')
|
54
54
|
end
|
@@ -117,7 +117,7 @@ task :todo do
|
|
117
117
|
egrep /#.*(FIXME|TODO|TBD)/
|
118
118
|
end
|
119
119
|
|
120
|
-
task :release => [:verify_env_vars, :release_files, :publish_doc, :publish_news]
|
120
|
+
task :release => [:verify_env_vars, :release_files, :publish_doc, :publish_news, :tag]
|
121
121
|
|
122
122
|
task :verify_env_vars do
|
123
123
|
raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
|
data/lib/scm_web/view_cvs.rb
CHANGED
data/lib/tracker/jira.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'xmlrpc/client'
|
2
|
+
|
3
|
+
module Tracker
|
4
|
+
module Jira
|
5
|
+
class Host
|
6
|
+
JIRA_API = "jira1"
|
7
|
+
|
8
|
+
attr_reader :uri
|
9
|
+
|
10
|
+
def initialize(uri, username, password)
|
11
|
+
@uri, @username, @password = uri, username, password
|
12
|
+
end
|
13
|
+
|
14
|
+
def project(identifier)
|
15
|
+
Project.new(self, identifier)
|
16
|
+
end
|
17
|
+
|
18
|
+
def login
|
19
|
+
client = XMLRPC::Client.new2("#{uri}/rpc/xmlrpc")
|
20
|
+
token = client.call("#{JIRA_API}.login", @username, @password)
|
21
|
+
Session.new(client, token)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
# This wrapper around XMLRPC::Client that allows simpler method calls
|
27
|
+
# via method_missing and doesn't require to manage the token
|
28
|
+
class Session
|
29
|
+
def initialize(client, token)
|
30
|
+
@client, @token = client, token
|
31
|
+
end
|
32
|
+
|
33
|
+
def method_missing(sym, args, &block)
|
34
|
+
token_args = [@token] << args
|
35
|
+
xmlrpc_method = "#{Host::JIRA_API}.#{sym.to_s}"
|
36
|
+
@client.call(xmlrpc_method, *token_args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Tracker
|
2
|
+
module Jira
|
3
|
+
class Project
|
4
|
+
def initialize(host, identifier)
|
5
|
+
@host, @identifier = host, identifier
|
6
|
+
end
|
7
|
+
|
8
|
+
def identifier_regexp
|
9
|
+
/([A-Z]+-[\d]+)/
|
10
|
+
end
|
11
|
+
|
12
|
+
def identifier_examples
|
13
|
+
["DC-420", "PICO-12"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def uri
|
17
|
+
"#{@host.uri}/browse/#{@identifier}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def issue(issue_identifier)
|
21
|
+
session = @host.login
|
22
|
+
begin
|
23
|
+
issue = session.getIssue(issue_identifier)
|
24
|
+
Issue.new("#{@host.uri}/browse/#{issue_identifier}", issue["summary"])
|
25
|
+
rescue XMLRPC::FaultException
|
26
|
+
# Probably bad issue number
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def markup(text)
|
32
|
+
text.gsub(identifier_regexp) do |match|
|
33
|
+
issue_identifier = $1
|
34
|
+
issue = issue(issue_identifier)
|
35
|
+
issue ? "<a href=\"#{issue.uri}\">#{issue.summary}</a>" : issue_identifier
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/tracker/trac.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'tracker/trac/project'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Tracker
|
2
|
+
module Trac
|
3
|
+
class Project
|
4
|
+
def initialize(uri)
|
5
|
+
@uri = uri
|
6
|
+
end
|
7
|
+
|
8
|
+
def identifier_regexp
|
9
|
+
/#(\d+)/
|
10
|
+
end
|
11
|
+
|
12
|
+
def identifier_examples
|
13
|
+
["#1926", "#1446"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def issue(issue_identifier)
|
17
|
+
issue_uri = "#{@uri}/ticket/#{issue_identifier}"
|
18
|
+
begin
|
19
|
+
html = open(issue_uri) { |data| data.read }
|
20
|
+
summary = html[/Ticket ##{issue_identifier}\s*<\/h1>\s*<h2>([^<]*)<\/h2>/n, 1]
|
21
|
+
Issue.new(issue_uri, summary)
|
22
|
+
rescue OpenURI::HTTPError
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def markup(text)
|
28
|
+
text.gsub(identifier_regexp) do |match|
|
29
|
+
issue_identifier = $1
|
30
|
+
issue = issue(issue_identifier)
|
31
|
+
issue ? "<a href=\"#{issue.uri}\">#{issue.summary}</a>" : "\##{issue_identifier}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Tracker
|
2
|
+
module XForge
|
3
|
+
# TODO: rename to Project
|
4
|
+
class Base
|
5
|
+
attr_reader :uri, :project
|
6
|
+
|
7
|
+
def identifier_regexp
|
8
|
+
/#(\d+)/
|
9
|
+
end
|
10
|
+
|
11
|
+
# Examples of what will be recognised as issue identifiers in #markup
|
12
|
+
def identifier_examples
|
13
|
+
["#1462", "#872"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(uri, project)
|
17
|
+
@uri, @project = uri, project
|
18
|
+
end
|
19
|
+
|
20
|
+
# Finds an Issue by +identifier+
|
21
|
+
def issue(identifier)
|
22
|
+
sub_trackers = atids.collect {|atid| SubTracker.new(self, atid)}
|
23
|
+
sub_trackers.each do |sub_tracker|
|
24
|
+
issue = sub_tracker.issue(identifier)
|
25
|
+
return issue unless issue.nil?
|
26
|
+
end
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def markup(text)
|
31
|
+
text.gsub(identifier_regexp) do |match|
|
32
|
+
issue_identifier = $1
|
33
|
+
issue = issue(issue_identifier)
|
34
|
+
issue ? "<a href=\"#{issue.uri}\">#{issue.summary}</a>" : "\##{issue_identifier}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class SubTracker
|
39
|
+
attr_reader :uri
|
40
|
+
|
41
|
+
def initialize(rubyforge, atid)
|
42
|
+
@rubyforge = rubyforge
|
43
|
+
@atid = atid
|
44
|
+
# FIXME: This will only show open items.
|
45
|
+
@uri = "#{rubyforge.uri}&atid=#{atid}&func=browse"
|
46
|
+
end
|
47
|
+
|
48
|
+
def issue(identifier)
|
49
|
+
html = open(uri) { |data| data.read }
|
50
|
+
|
51
|
+
regexp = /<a href=\"\/tracker\/index.php\?func=detail&aid=#{identifier}&group_id=\d+&atid=\d+\">(.*)<\/a>/
|
52
|
+
if(html =~ regexp)
|
53
|
+
issue_uri = @rubyforge.project.group_id_uri("tracker/index.php", "&atid=#{@atid}&func=detail&aid=#{identifier}")
|
54
|
+
return Issue.new(issue_uri, $1)
|
55
|
+
end
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# The ids of the subtrackers
|
63
|
+
def atids
|
64
|
+
html = open(uri) { |data| data.read }
|
65
|
+
|
66
|
+
# TODO: there has to be a better way to extract the atids from the HTML!
|
67
|
+
atids = []
|
68
|
+
offset = 0
|
69
|
+
look_for_atid = true
|
70
|
+
while(look_for_atid)
|
71
|
+
match_data = /\/tracker\/\?atid=(\d+)&group_id=\d*&func=browse/.match(html[offset..-1])
|
72
|
+
if(match_data)
|
73
|
+
offset += match_data.begin(1)
|
74
|
+
atids << match_data[1]
|
75
|
+
else
|
76
|
+
look_for_atid = false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
atids
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/xforge.rb
CHANGED
@@ -6,6 +6,8 @@ require 'xforge/project'
|
|
6
6
|
require 'xforge/session'
|
7
7
|
require 'xforge/xfile'
|
8
8
|
require 'scm_web/view_cvs'
|
9
|
-
require 'tracker/rubyforge'
|
10
9
|
require 'tracker/issue'
|
10
|
+
require 'tracker/xforge'
|
11
|
+
require 'tracker/jira'
|
12
|
+
require 'tracker/trac'
|
11
13
|
require 'rake/contrib/xforge'
|
data/lib/xforge/project.rb
CHANGED
data/lib/xforge/rubyforge.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
module XForge
|
2
2
|
class RubyForge < Host
|
3
3
|
VIEW_CVS = "http://rubyforge.org/cgi-bin/viewcvs.cgi/"
|
4
|
-
|
4
|
+
CVSROOT = "?cvsroot=\#{project_unix_name}"
|
5
|
+
PATH_CVSROOT = "\#{path}#{CVSROOT}"
|
5
6
|
PATH_CVSROOT_REV = "#{PATH_CVSROOT}&rev=\#{revision}"
|
6
7
|
|
7
8
|
OVERVIEW = "#{VIEW_CVS}#{PATH_CVSROOT}"
|
8
|
-
RAW
|
9
|
-
HTML
|
9
|
+
RAW = "#{VIEW_CVS}*checkout*/#{PATH_CVSROOT_REV}"
|
10
|
+
HTML = "#{VIEW_CVS}#{PATH_CVSROOT_REV}&content-type=text/vnd.viewcvs-markup"
|
11
|
+
DIFF = "#{VIEW_CVS}\#{path}.diff#{CVSROOT}&r1=\#{previous_revision}&r2=\#{revision}"
|
10
12
|
|
11
13
|
def initialize
|
12
14
|
super('rubyforge.org')
|
@@ -26,7 +28,7 @@ module XForge
|
|
26
28
|
|
27
29
|
def scm_web(project)
|
28
30
|
module_regexp = /href=\"(\w+)\/\?cvsroot=#{project.unix_name}/
|
29
|
-
::ScmWeb::ViewCvs.new({:overview => OVERVIEW, :raw => RAW, :html => HTML}, project, module_regexp)
|
31
|
+
::ScmWeb::ViewCvs.new({:overview => OVERVIEW, :raw => RAW, :html => HTML, :diff => DIFF}, project, module_regexp)
|
30
32
|
end
|
31
33
|
|
32
34
|
# Regexp used to find projects' home page
|
@@ -35,5 +37,8 @@ module XForge
|
|
35
37
|
/<a href=\"(\w*:\/\/[^\"]*)\"><img src=\"\/themes\/osx\/images\/ic\/home/
|
36
38
|
end
|
37
39
|
|
40
|
+
def tracker(project)
|
41
|
+
Tracker::XForge::RubyForge.new(project.group_id_uri("tracker"), project)
|
42
|
+
end
|
38
43
|
end
|
39
44
|
end
|
data/lib/xforge/sourceforge.rb
CHANGED
@@ -5,8 +5,9 @@ module XForge
|
|
5
5
|
REV = "rev=\#{revision}"
|
6
6
|
|
7
7
|
OVERVIEW = "#{VIEW_CVS}#{PROJECT_PATH}"
|
8
|
-
RAW
|
9
|
-
HTML
|
8
|
+
RAW = "#{VIEW_CVS}*checkout*/#{PROJECT_PATH}?#{REV}"
|
9
|
+
HTML = "#{OVERVIEW}?#{REV}&view=markup"
|
10
|
+
DIFF = "#{OVERVIEW}?r1=\#{previous_revision}&r2=\#{revision}"
|
10
11
|
|
11
12
|
def initialize
|
12
13
|
super("sourceforge.net")
|
@@ -26,7 +27,7 @@ module XForge
|
|
26
27
|
|
27
28
|
def scm_web(project)
|
28
29
|
module_regexp = /viewcvs\.py\/#{project.unix_name}\/(\w+)\//
|
29
|
-
::ScmWeb::ViewCvs.new({:overview => OVERVIEW, :raw => RAW, :html => HTML}, project, module_regexp)
|
30
|
+
::ScmWeb::ViewCvs.new({:overview => OVERVIEW, :raw => RAW, :html => HTML, :diff => DIFF}, project, module_regexp)
|
30
31
|
end
|
31
32
|
|
32
33
|
# Regexp used to find projects' home page
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: xforge
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2005-08-
|
6
|
+
version: 0.3.1
|
7
|
+
date: 2005-08-15 00:00:00 -04:00
|
8
8
|
summary: Ruby based make-like utility.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -42,7 +42,14 @@ files:
|
|
42
42
|
- lib/rake/contrib/xforge/release.rb
|
43
43
|
- lib/scm_web/view_cvs.rb
|
44
44
|
- lib/tracker/issue.rb
|
45
|
-
- lib/tracker/
|
45
|
+
- lib/tracker/jira.rb
|
46
|
+
- lib/tracker/trac.rb
|
47
|
+
- lib/tracker/xforge.rb
|
48
|
+
- lib/tracker/jira/host.rb
|
49
|
+
- lib/tracker/jira/project.rb
|
50
|
+
- lib/tracker/trac/project.rb
|
51
|
+
- lib/tracker/xforge/base.rb
|
52
|
+
- lib/tracker/xforge/rubyforge.rb
|
46
53
|
- lib/xforge/host.rb
|
47
54
|
- lib/xforge/project.rb
|
48
55
|
- lib/xforge/rubyforge.rb
|
@@ -61,7 +68,6 @@ rdoc_options:
|
|
61
68
|
extra_rdoc_files:
|
62
69
|
- README
|
63
70
|
- MIT-LICENSE
|
64
|
-
- TODO
|
65
71
|
- CHANGES
|
66
72
|
executables: []
|
67
73
|
extensions: []
|
data/lib/tracker/rubyforge.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
module Tracker
|
2
|
-
class RubyForge
|
3
|
-
attr_reader :uri, :project
|
4
|
-
|
5
|
-
def initialize(uri, project)
|
6
|
-
@uri, @project = uri, project
|
7
|
-
end
|
8
|
-
|
9
|
-
def issue(identifier)
|
10
|
-
sub_trackers = atids.collect {|atid| SubTracker.new(self, atid)}
|
11
|
-
sub_trackers.each do |sub_tracker|
|
12
|
-
issue = sub_tracker.issue(identifier)
|
13
|
-
return issue unless issue.nil?
|
14
|
-
end
|
15
|
-
nil
|
16
|
-
end
|
17
|
-
|
18
|
-
class SubTracker
|
19
|
-
attr_reader :uri
|
20
|
-
|
21
|
-
def initialize(rubyforge, atid)
|
22
|
-
@rubyforge = rubyforge
|
23
|
-
@atid = atid
|
24
|
-
# FIXME: This will only show open items.
|
25
|
-
@uri = "#{rubyforge.uri}&atid=#{atid}&func=browse"
|
26
|
-
end
|
27
|
-
|
28
|
-
def issue(identifier)
|
29
|
-
html = open(uri) { |data| data.read }
|
30
|
-
|
31
|
-
regexp = /<a href=\"\/tracker\/index.php\?func=detail&aid=#{identifier}&group_id=\d+&atid=\d+\">(.*)<\/a>/
|
32
|
-
if(html =~ regexp)
|
33
|
-
issue_uri = @rubyforge.project.group_id_uri("tracker/index.php", "&atid=#{@atid}&func=detail&aid=#{identifier}")
|
34
|
-
return Issue.new(issue_uri, $1)
|
35
|
-
end
|
36
|
-
nil
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
# The ids of the subtrackers
|
43
|
-
def atids
|
44
|
-
html = open(uri) { |data| data.read }
|
45
|
-
|
46
|
-
# TODO: there has to be a better way to extract the atids from the HTML!
|
47
|
-
atids = []
|
48
|
-
offset = 0
|
49
|
-
look_for_atid = true
|
50
|
-
while(look_for_atid)
|
51
|
-
match_data = /\/tracker\/\?atid=(\d+)&group_id=\d*&func=browse/.match(html[offset..-1])
|
52
|
-
if(match_data)
|
53
|
-
offset += match_data.begin(1)
|
54
|
-
atids << match_data[1]
|
55
|
-
else
|
56
|
-
look_for_atid = false
|
57
|
-
end
|
58
|
-
end
|
59
|
-
atids
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|