rtrac 1.0.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/History.txt +5 -0
- data/Manifest.txt +14 -0
- data/README.txt +54 -0
- data/Rakefile +15 -0
- data/bin/rtrac +7 -0
- data/lib/rtrac.rb +15 -0
- data/lib/rtrac/base.rb +190 -0
- data/lib/rtrac/ticket.rb +96 -0
- data/lib/rtrac/util.rb +165 -0
- data/test/test_base.rb +49 -0
- data/test/test_helper.rb +4 -0
- data/test/test_rtrac.rb +0 -0
- data/test/test_ticket.rb +37 -0
- metadata +79 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.txt
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
rtrac
|
|
2
|
+
by Josh Stephenson
|
|
3
|
+
http://rtrac.rubyforge.org
|
|
4
|
+
|
|
5
|
+
== DESCRIPTION:
|
|
6
|
+
|
|
7
|
+
Trac API wrappers
|
|
8
|
+
|
|
9
|
+
== FEATURES/PROBLEMS:
|
|
10
|
+
|
|
11
|
+
Ticket access for Trac
|
|
12
|
+
|
|
13
|
+
== SYNOPSIS:
|
|
14
|
+
|
|
15
|
+
Rtrac::Base.get_by_milestone(milestone).each do |id|
|
|
16
|
+
# grab the ticket's data
|
|
17
|
+
tick = Rtrac::Ticket.new(id)
|
|
18
|
+
iteration_hash[:total] += tick.severity.to_i
|
|
19
|
+
iteration_hash[:tickets] << {:id => id, :points => tick.severity.to_i, :status => tick.status, :updated_at =>Time.parse(tick.updated_at.to_s)}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
== REQUIREMENTS:
|
|
23
|
+
|
|
24
|
+
active_support
|
|
25
|
+
hoe
|
|
26
|
+
|
|
27
|
+
== INSTALL:
|
|
28
|
+
|
|
29
|
+
sudo gem install rtrac
|
|
30
|
+
|
|
31
|
+
== LICENSE:
|
|
32
|
+
|
|
33
|
+
(The MIT License)
|
|
34
|
+
|
|
35
|
+
Copyright (c) 2007 Josh Stephenson
|
|
36
|
+
|
|
37
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
38
|
+
a copy of this software and associated documentation files (the
|
|
39
|
+
'Software'), to deal in the Software without restriction, including
|
|
40
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
41
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
42
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
43
|
+
the following conditions:
|
|
44
|
+
|
|
45
|
+
The above copyright notice and this permission notice shall be
|
|
46
|
+
included in all copies or substantial portions of the Software.
|
|
47
|
+
|
|
48
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
49
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
50
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
51
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
52
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
53
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
54
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'hoe'
|
|
3
|
+
require './lib/rtrac.rb'
|
|
4
|
+
|
|
5
|
+
Hoe.new('rtrac', Rtrac::Config.version) do |p|
|
|
6
|
+
p.rubyforge_name = 'rtrac'
|
|
7
|
+
p.author = 'Josh Stephenson'
|
|
8
|
+
p.email = 'josh@elctech.com'
|
|
9
|
+
p.summary = 'Trac wrapper with command line tool'
|
|
10
|
+
p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
|
11
|
+
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
|
12
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# vim: syntax=Ruby
|
data/bin/rtrac
ADDED
data/lib/rtrac.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
|
2
|
+
module Rtrac
|
|
3
|
+
class Config
|
|
4
|
+
def self.version
|
|
5
|
+
'1.0.1'
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
require 'rubygems'
|
|
10
|
+
require 'yaml'
|
|
11
|
+
require 'active_support'
|
|
12
|
+
require 'xmlrpc/client'
|
|
13
|
+
require 'rtrac/base'
|
|
14
|
+
require 'rtrac/ticket'
|
|
15
|
+
require 'rtrac/util'
|
data/lib/rtrac/base.rb
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
module Rtrac
|
|
2
|
+
class Base
|
|
3
|
+
|
|
4
|
+
cattr_accessor :connection, :config
|
|
5
|
+
|
|
6
|
+
class << self
|
|
7
|
+
# handles the sending of queries to Trac with exception handling
|
|
8
|
+
def send_query(*args)
|
|
9
|
+
begin
|
|
10
|
+
connection.call(*args)
|
|
11
|
+
rescue
|
|
12
|
+
# print a standard error
|
|
13
|
+
logger.error "Error connecting to Trac API"
|
|
14
|
+
if logger.level > Logger::INFO
|
|
15
|
+
logger.error $@
|
|
16
|
+
end
|
|
17
|
+
exit
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def connection
|
|
22
|
+
@connection ||= self.open_connection
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# list all methods supported by the trac api
|
|
26
|
+
def list_methods
|
|
27
|
+
send_query('system.listMethods')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def custom(*args)
|
|
31
|
+
send_query(*args)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get_by_milestone(milestone)
|
|
35
|
+
send_query('ticket.query', "milestone=#{milestone.strip}")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# returns method help
|
|
39
|
+
def method_help(method)
|
|
40
|
+
send_query('system.methodHelp', method)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Returns an array of ticket ids
|
|
44
|
+
# Valid order types include:
|
|
45
|
+
def get_tickets(count, order = :priority)
|
|
46
|
+
extract_account_info
|
|
47
|
+
order = :priority unless columns.include?(order)
|
|
48
|
+
send_query('ticket.query', "order=#{order.to_s}")[0,count].collect{ |id| id }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#:stopdoc:
|
|
52
|
+
def open_connection
|
|
53
|
+
if (options = extract_account_info)
|
|
54
|
+
@username, @password, @url = options
|
|
55
|
+
uri = URI.parse @url
|
|
56
|
+
#puts "Connecting to \"#{@url}\" using username \"#{@username}\" and password \"#{@password}\""
|
|
57
|
+
@connection = XMLRPC::Client.new3(:host => uri.host, :path => "#{uri.path}/login/xmlrpc", :user => @username, :password => @password, :use_ssl => true)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def extract_account_info
|
|
62
|
+
username = password = url = columns = nil
|
|
63
|
+
configuration_options.each do |key, value|
|
|
64
|
+
if key.to_sym == :username
|
|
65
|
+
username = value.to_s
|
|
66
|
+
elsif key.to_sym == :password
|
|
67
|
+
password = value.to_s
|
|
68
|
+
elsif key.to_sym == :url
|
|
69
|
+
url = value.to_s
|
|
70
|
+
elsif key.to_sym == :columns
|
|
71
|
+
@columns = value.to_a
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
if invalid_config?(username, password, url, @columns)
|
|
75
|
+
logger.error "Invalid configuration options. Please edit your #{config_path} file accordingly."
|
|
76
|
+
return false
|
|
77
|
+
end
|
|
78
|
+
[username, password, url, @columns]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def configuration_options
|
|
82
|
+
return @configuration_options unless @configuration_options.nil?
|
|
83
|
+
if self.config.nil?
|
|
84
|
+
@configuration_options = find_or_create_config
|
|
85
|
+
else
|
|
86
|
+
if File.exist?(config)
|
|
87
|
+
@configuration_options = YAML::load(open(config))
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
@configuration_options
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def invalid_config?(username, password, url, columns)
|
|
94
|
+
username.empty? || password.empty? || columns.empty? || ![url =~ /^http(s|):\/\/.+/i].any?
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def columns
|
|
98
|
+
extract_account_info
|
|
99
|
+
@columns ||= required_columns + optional_columns
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def required_columns
|
|
103
|
+
extract_account_info
|
|
104
|
+
@configuration_options["columns"]["required"]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def optional_columns
|
|
108
|
+
extract_account_info
|
|
109
|
+
@configuration_options["columns"]["optional"]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def find_or_create_config
|
|
113
|
+
begin
|
|
114
|
+
config = YAML::load(open(config_path))
|
|
115
|
+
rescue
|
|
116
|
+
create_new_config
|
|
117
|
+
end
|
|
118
|
+
config
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def home_dir
|
|
122
|
+
ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def config_path
|
|
126
|
+
if RAILS_ROOT
|
|
127
|
+
File.join(RAILS_ROOT, 'config', Rtrac::Configuration.options[:config_filename])
|
|
128
|
+
else
|
|
129
|
+
File.join(home_dir, ".#{Rtrac::Configuration.options[:config_filename]}") # hide it if it goes in home
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def create_new_config
|
|
134
|
+
file = File.open(config_path, "w+")
|
|
135
|
+
file.write(Rtrac::Configuration.options[:default_config_file])
|
|
136
|
+
file.flush
|
|
137
|
+
file.close
|
|
138
|
+
logger.info "No config file found in #{home_dir}
|
|
139
|
+
A new one has been created. Please edit it before continuing
|
|
140
|
+
#{config_path}
|
|
141
|
+
"
|
|
142
|
+
exit
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def logger
|
|
146
|
+
if @logger.nil?
|
|
147
|
+
@logger = Logger.new(STDERR)
|
|
148
|
+
@logger.level = Logger::INFO
|
|
149
|
+
end
|
|
150
|
+
@logger
|
|
151
|
+
end
|
|
152
|
+
#:start_doc:
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
class Configuration
|
|
156
|
+
class << self
|
|
157
|
+
def options
|
|
158
|
+
{:default_config_file => default_config_file, :config_filename => 'rtrac.yml'}
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def default_config_file
|
|
162
|
+
default_config_file=<<CONFIG
|
|
163
|
+
username:
|
|
164
|
+
password:
|
|
165
|
+
url:
|
|
166
|
+
columns:
|
|
167
|
+
required:
|
|
168
|
+
- :summary
|
|
169
|
+
- :description
|
|
170
|
+
optional:
|
|
171
|
+
- :type
|
|
172
|
+
- :time
|
|
173
|
+
- :changetime
|
|
174
|
+
- :component
|
|
175
|
+
- :severity
|
|
176
|
+
- :priority
|
|
177
|
+
- :owner
|
|
178
|
+
- :reporter
|
|
179
|
+
- :cc
|
|
180
|
+
- :version
|
|
181
|
+
- :milestone
|
|
182
|
+
- :status
|
|
183
|
+
- :resolution
|
|
184
|
+
- :keywords
|
|
185
|
+
CONFIG
|
|
186
|
+
default_config_file
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
data/lib/rtrac/ticket.rb
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module Rtrac
|
|
2
|
+
class TicketError < StandardError; end
|
|
3
|
+
class Ticket < Rtrac::Base
|
|
4
|
+
|
|
5
|
+
attr_accessor :trac_id
|
|
6
|
+
|
|
7
|
+
def initialize(trac_id, logger = nil)
|
|
8
|
+
@logger = logger
|
|
9
|
+
@trac_id = trac_id
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def created_at
|
|
13
|
+
Time.at(ticket_attributes[1].to_i)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def updated_at
|
|
17
|
+
Time.at(+ticket_attributes[2].to_i)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def attributes
|
|
21
|
+
extended_attributes = ticket_attributes[3].symbolize_keys!
|
|
22
|
+
{:id => ticket_attributes[0], :created_at => ticket_attributes[1], :updated_at => ticket_attributes[2]}.merge(extended_attributes)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def attributes=(attributes)
|
|
26
|
+
@ticket_attributes = attributes
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# ticket description
|
|
30
|
+
def description
|
|
31
|
+
method_missing(:description)
|
|
32
|
+
end
|
|
33
|
+
alias_method :body, :description
|
|
34
|
+
|
|
35
|
+
# ticket summary
|
|
36
|
+
def summary
|
|
37
|
+
method_missing(:summary)
|
|
38
|
+
end
|
|
39
|
+
alias_method :title, :summary
|
|
40
|
+
|
|
41
|
+
# update a ticket with a comment and attributes
|
|
42
|
+
def update(comment, attributes = {})
|
|
43
|
+
sendable_attributes = attributes
|
|
44
|
+
sendable_attributes.delete(:created_at) && sendable_attributes.delete(:updated_at)
|
|
45
|
+
self.class.send_query('ticket.update', @trac_id, comment, sendable_attributes)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# create a new ticket
|
|
49
|
+
def self.create(title, description, attributes = {})
|
|
50
|
+
send_query('ticket.create', title, description, attributes)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# delete a ticket forever
|
|
54
|
+
def self.destroy(trac_id)
|
|
55
|
+
send_query('ticket.delete', trac_id)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def to_s
|
|
59
|
+
"#{summary}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
protected
|
|
63
|
+
|
|
64
|
+
def method_missing(method)
|
|
65
|
+
if attributes.has_key?(method)
|
|
66
|
+
attributes[method]
|
|
67
|
+
else
|
|
68
|
+
logger.debug "No attribute found for #{method}"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# returns a hash of ticket attributes
|
|
73
|
+
def get
|
|
74
|
+
self.class.send_query('ticket.get', @trac_id)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def ticket_attributes
|
|
78
|
+
@ticket_attributes ||= get
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def logger
|
|
82
|
+
@logger ||= Logger.new(STDERR)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
class Hash
|
|
87
|
+
def symbolize_keys!
|
|
88
|
+
keys.each do |key|
|
|
89
|
+
unless key.is_a?(Symbol) || (new_key = key.to_sym).nil?
|
|
90
|
+
self[new_key] = self[key]
|
|
91
|
+
delete(key)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
self
|
|
95
|
+
end
|
|
96
|
+
end
|
data/lib/rtrac/util.rb
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
module Rtrac
|
|
2
|
+
class Util < Rtrac::Base
|
|
3
|
+
VALID_COMMANDS = [:list, :show, :update, :delete, :create]
|
|
4
|
+
|
|
5
|
+
class << self
|
|
6
|
+
def run!
|
|
7
|
+
if ARGV.include?('--debug')
|
|
8
|
+
@logger = Logger.new(STDERR)
|
|
9
|
+
@logger.level = Logger::DEBUG
|
|
10
|
+
ARGV.delete('--debug')
|
|
11
|
+
end
|
|
12
|
+
command = ARGV.shift
|
|
13
|
+
if command.nil?
|
|
14
|
+
usage
|
|
15
|
+
else
|
|
16
|
+
case command.to_sym
|
|
17
|
+
when :list
|
|
18
|
+
list(ARGV.shift, ARGV.shift)
|
|
19
|
+
when :show
|
|
20
|
+
show(ARGV.shift)
|
|
21
|
+
when :update
|
|
22
|
+
update(ARGV.shift)
|
|
23
|
+
when :delete
|
|
24
|
+
delete(ARGV.shift)
|
|
25
|
+
when :close
|
|
26
|
+
close(ARGV.shift)
|
|
27
|
+
when :create
|
|
28
|
+
create
|
|
29
|
+
else
|
|
30
|
+
usage
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def list(count, order = 'priority')
|
|
36
|
+
Rtrac::Base.get_tickets(count.to_i, order).each do |id|
|
|
37
|
+
tick = Rtrac::Ticket.new(id)
|
|
38
|
+
keys = tick.attributes.keys.reject{|k| k == :id || k == :type }
|
|
39
|
+
|
|
40
|
+
keys.each do |key|
|
|
41
|
+
puts "#{key.to_s[0,16].rjust(16, ' ')}: #{tick.send(key).to_s[0,60].rjust(60, ' ')}"
|
|
42
|
+
end
|
|
43
|
+
puts ""
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def show(id)
|
|
48
|
+
usage if id.nil?
|
|
49
|
+
tick = get_ticket(id)
|
|
50
|
+
display(tick)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def delete(id)
|
|
54
|
+
if(Rtrac::Ticket.destroy(id)).to_i.zero?
|
|
55
|
+
puts 'Deleted'
|
|
56
|
+
else
|
|
57
|
+
puts 'Error deleting ticket.'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def create
|
|
62
|
+
required_attributes = {}
|
|
63
|
+
optional_attributes = {}
|
|
64
|
+
read_required_attributes(required_attributes)
|
|
65
|
+
read_optional_attributes(optional_attributes)
|
|
66
|
+
required_attributes = required_attributes.values
|
|
67
|
+
puts Rtrac::Ticket.create(required_attributes.shift, required_attributes.shift, optional_attributes)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def update(id)
|
|
71
|
+
tick = get_ticket(id)
|
|
72
|
+
all_attributes = tick.attributes
|
|
73
|
+
read_optional_attributes(all_attributes, true)
|
|
74
|
+
comment = read_value(:comment)
|
|
75
|
+
resp = tick.update(comment, all_attributes)
|
|
76
|
+
# tick.attributes = all_attributes
|
|
77
|
+
# display(tick)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def read_required_attributes(attribute_hash)
|
|
81
|
+
self.required_columns.each do |attr|
|
|
82
|
+
while attribute_hash[attr].nil?
|
|
83
|
+
puts "#{attr.to_s.capitalize}: "
|
|
84
|
+
value = STDIN.readline
|
|
85
|
+
attribute_hash[attr] = value
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def read_optional_attributes(attribute_hash, conflate = false)
|
|
91
|
+
cols = conflate ? self.required_columns + self.optional_columns : self.optional_columns
|
|
92
|
+
display_menu(attribute_hash, cols)
|
|
93
|
+
until (num = STDIN.readline.strip).empty?
|
|
94
|
+
num = num.to_i
|
|
95
|
+
attribute = cols[num-1]
|
|
96
|
+
attribute_hash[cols[num-1]] = read_value(attribute)
|
|
97
|
+
display_menu(attribute_hash, cols)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def read_value(attribute)
|
|
102
|
+
puts "#{attribute.to_s.capitalize}: "
|
|
103
|
+
STDIN.readline.strip
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def display_menu(attribute_hash, cols)
|
|
107
|
+
puts "Enter the number of an attribute to fill in or <Enter> to submit"
|
|
108
|
+
cols.each_with_index do |attr, idx|
|
|
109
|
+
puts "#{idx+1}. #{attr.to_s.capitalize} => #{attribute_hash[attr]}"
|
|
110
|
+
end
|
|
111
|
+
puts ""
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def close(id, comment = nil)
|
|
115
|
+
raise NotImplementedError
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def get_ticket(id)
|
|
119
|
+
@tick ||= Rtrac::Ticket.new(id, @logger)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def display(tick)
|
|
123
|
+
if tick.is_a?(Rtrac::Ticket)
|
|
124
|
+
display_ticket(tick)
|
|
125
|
+
else
|
|
126
|
+
display_ticket_from_hash(tick)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def display_ticket(tick)
|
|
131
|
+
# reject #id and #type or ruby will choke!
|
|
132
|
+
keys = tick.attributes.keys.reject{|k| k == :id || k == :type }
|
|
133
|
+
|
|
134
|
+
keys.each do |key|
|
|
135
|
+
# we'll send the method to the ticket so dates are parsed
|
|
136
|
+
puts "#{key.to_s[0,16].rjust(16, ' ')}: #{tick.send(key).to_s[0,60].rjust(60, ' ')}"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def display_ticket_from_hash(attributes)
|
|
141
|
+
# reject #id and #type or ruby will choke!
|
|
142
|
+
keys = attributes.keys.reject{|k| k == :id || k == :type }
|
|
143
|
+
|
|
144
|
+
keys.each do |key|
|
|
145
|
+
# we'll send the method to the ticket so dates are parsed
|
|
146
|
+
puts "#{key.to_s[0,16].rjust(16, ' ')}: #{tick.attributes[key].to_s[0,60].rjust(60, ' ')}"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def usage
|
|
151
|
+
usage=<<USAGE
|
|
152
|
+
rtrac COMMAND [OPTIONS]
|
|
153
|
+
COMMANDS:
|
|
154
|
+
list [COUNT] [PRIORITY]
|
|
155
|
+
show ID
|
|
156
|
+
create
|
|
157
|
+
update ID
|
|
158
|
+
delete ID
|
|
159
|
+
USAGE
|
|
160
|
+
puts usage
|
|
161
|
+
exit
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
data/test/test_base.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
|
2
|
+
|
|
3
|
+
class RtracBaseTest < Test::Unit::TestCase
|
|
4
|
+
# def test_send_query_should_open_connection
|
|
5
|
+
# XMLRPC::Client.expects(:new3).returns(stub())
|
|
6
|
+
# Rtrac::Base.expects(:open_connection).returns(stub(:call => ''))
|
|
7
|
+
# Rtrac::Base.send_query('foo')
|
|
8
|
+
# end
|
|
9
|
+
#
|
|
10
|
+
# def test_open_connection_should_hit_xmlrpc
|
|
11
|
+
# Rtrac::Base.send_query('foo')
|
|
12
|
+
# end
|
|
13
|
+
|
|
14
|
+
def test_connection
|
|
15
|
+
Rtrac::Base.expects(:open_connection)
|
|
16
|
+
Rtrac::Base.connection
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_list_methods
|
|
20
|
+
Rtrac::Base.expects(:send_query)
|
|
21
|
+
Rtrac::Base.list_methods
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_get_tickets
|
|
25
|
+
Rtrac::Base.expects(:send_query)
|
|
26
|
+
Rtrac::Base.list_methods
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_open_connection
|
|
30
|
+
XMLRPC::Client.expects(:new3)
|
|
31
|
+
URI.expects(:parse).returns(stub(:host => 'foo.com', :path => 'foo'))
|
|
32
|
+
Rtrac::Base.send(:open_connection)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_extract_account_info
|
|
36
|
+
Rtrac::Base.expects(:configuration_options).returns({:username => 'foo', :password => '123', :url => 'http://wush.net/trac/foo'})
|
|
37
|
+
Rtrac::Base.expects(:invalid_config?).returns(false)
|
|
38
|
+
Rtrac::Base.send(:extract_account_info)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_valid_config
|
|
42
|
+
assert_equal false, Rtrac::Base.send(:invalid_config?, 'foo', 'bar', 'http://wush.net/trac/foo', ['foo'])
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_invalid_config
|
|
46
|
+
assert Rtrac::Base.send(:invalid_config?, 'foo', 'bar', 'ttp://wush.net/trac/foo', ['foo'])
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
data/test/test_helper.rb
ADDED
data/test/test_rtrac.rb
ADDED
|
File without changes
|
data/test/test_ticket.rb
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
|
2
|
+
|
|
3
|
+
class TestTicket < Test::Unit::TestCase
|
|
4
|
+
def test_attributes
|
|
5
|
+
tick = Rtrac::Ticket.new(1)
|
|
6
|
+
tick.stubs(:ticket_attributes).returns(['1', 1195317367, 1195317367, {'summary' => 'test summary', 'description' => 'test description'}])
|
|
7
|
+
assert_equal tick.attributes, {:id => '1', :created_at => 1195317367, :updated_at => 1195317367, :summary => 'test summary', :description => 'test description'}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_setting_attributes
|
|
11
|
+
tick = Rtrac::Ticket.new(1)
|
|
12
|
+
tick.attributes = {:foo => 'foo'}
|
|
13
|
+
assert_equal tick.instance_variable_get(:@ticket_attributes), {:foo => 'foo'}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_update_should_remove_updated_at_and_created_at
|
|
17
|
+
tick = Rtrac::Ticket.new(1, {:summary => 'foo', :created_at => 'foo', :updated_at => 'foo'})
|
|
18
|
+
Rtrac::Ticket.expects(:send_query).with('ticket.update', 1, 'Testing Comment', {:summary => 'foo'}).returns(true)
|
|
19
|
+
tick.update('Testing Comment', {:summary => 'foo', :created_at => 'foo', :updated_at => 'foo'})
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_create
|
|
23
|
+
Rtrac::Ticket.expects(:send_query).with('ticket.create', 'Test Title', 'Test Description', {:foo => 'foo'})
|
|
24
|
+
Rtrac::Ticket.create('Test Title', 'Test Description', {:foo => 'foo'})
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_destroy
|
|
28
|
+
Rtrac::Ticket.expects(:send_query).with('ticket.delete', 1)
|
|
29
|
+
Rtrac::Ticket.destroy(1)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_get
|
|
33
|
+
tick = Rtrac::Ticket.new(1)
|
|
34
|
+
Rtrac::Ticket.expects(:send_query).with('ticket.get', 1)
|
|
35
|
+
tick.send(:get)
|
|
36
|
+
end
|
|
37
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rtrac
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Josh Stephenson
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2008-03-08 23:00:00 -08:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: hoe
|
|
17
|
+
version_requirement:
|
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
19
|
+
requirements:
|
|
20
|
+
- - ">="
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: 1.5.0
|
|
23
|
+
version:
|
|
24
|
+
description: "== FEATURES/PROBLEMS: Ticket access for Trac == SYNOPSIS: Rtrac::Base.get_by_milestone(milestone).each do |id| # grab the ticket's data tick = Rtrac::Ticket.new(id) iteration_hash[:total] += tick.severity.to_i iteration_hash[:tickets] << {:id => id, :points => tick.severity.to_i, :status => tick.status, :updated_at =>Time.parse(tick.updated_at.to_s)} end == REQUIREMENTS: active_support hoe"
|
|
25
|
+
email: josh@elctech.com
|
|
26
|
+
executables:
|
|
27
|
+
- rtrac
|
|
28
|
+
extensions: []
|
|
29
|
+
|
|
30
|
+
extra_rdoc_files:
|
|
31
|
+
- History.txt
|
|
32
|
+
- Manifest.txt
|
|
33
|
+
- README.txt
|
|
34
|
+
files:
|
|
35
|
+
- History.txt
|
|
36
|
+
- Manifest.txt
|
|
37
|
+
- README.txt
|
|
38
|
+
- Rakefile
|
|
39
|
+
- bin/rtrac
|
|
40
|
+
- lib/rtrac.rb
|
|
41
|
+
- lib/rtrac/util.rb
|
|
42
|
+
- lib/rtrac/base.rb
|
|
43
|
+
- lib/rtrac/ticket.rb
|
|
44
|
+
- test/test_helper.rb
|
|
45
|
+
- test/test_rtrac.rb
|
|
46
|
+
- test/test_base.rb
|
|
47
|
+
- test/test_ticket.rb
|
|
48
|
+
has_rdoc: true
|
|
49
|
+
homepage: " by Josh Stephenson"
|
|
50
|
+
post_install_message:
|
|
51
|
+
rdoc_options:
|
|
52
|
+
- --main
|
|
53
|
+
- README.txt
|
|
54
|
+
require_paths:
|
|
55
|
+
- lib
|
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: "0"
|
|
61
|
+
version:
|
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: "0"
|
|
67
|
+
version:
|
|
68
|
+
requirements: []
|
|
69
|
+
|
|
70
|
+
rubyforge_project: rtrac
|
|
71
|
+
rubygems_version: 1.0.1
|
|
72
|
+
signing_key:
|
|
73
|
+
specification_version: 2
|
|
74
|
+
summary: Trac wrapper with command line tool
|
|
75
|
+
test_files:
|
|
76
|
+
- test/test_base.rb
|
|
77
|
+
- test/test_helper.rb
|
|
78
|
+
- test/test_rtrac.rb
|
|
79
|
+
- test/test_ticket.rb
|