fogbugz 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/fogbugz +78 -0
- data/bin/fogbugz-areas +64 -0
- data/bin/fogbugz-assign +58 -0
- data/bin/fogbugz-categories +55 -0
- data/bin/fogbugz-close +57 -0
- data/bin/fogbugz-edit +281 -0
- data/bin/fogbugz-filter +78 -0
- data/bin/fogbugz-filters +53 -0
- data/bin/fogbugz-list +69 -0
- data/bin/fogbugz-login +60 -0
- data/bin/fogbugz-logoff +49 -0
- data/bin/fogbugz-milestones +57 -0
- data/bin/fogbugz-new +165 -0
- data/bin/fogbugz-people +57 -0
- data/bin/fogbugz-priorities +55 -0
- data/bin/fogbugz-projects +57 -0
- data/bin/fogbugz-reactivate +56 -0
- data/bin/fogbugz-reopen +56 -0
- data/bin/fogbugz-resolve +82 -0
- data/bin/fogbugz-show +147 -0
- data/bin/fogbugz-start +55 -0
- data/bin/fogbugz-statuses +62 -0
- data/bin/fogbugz-stop +50 -0
- data/lib/dummy.rb +1 -0
- metadata +119 -0
data/bin/fogbugz-people
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'typhoeus'
|
5
|
+
require 'xml'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
api_url = ENV['FOGBUGZ_API_URL']
|
9
|
+
unless api_url
|
10
|
+
puts "Environment variable FOGBUGZ_API_URL must be set."
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
api_token = ENV['FOGBUGZ_API_TOKEN']
|
15
|
+
unless api_url
|
16
|
+
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
options = {}
|
21
|
+
optparse = OptionParser.new do |opts|
|
22
|
+
opts.banner = "usage: #{File::basename(__FILE__)} [options]"
|
23
|
+
|
24
|
+
options[:verbose] = false
|
25
|
+
opts.on('-v', '--verbose', 'Output verbose debugging information') do
|
26
|
+
options[:verbose] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on_tail('-h', '--help') do
|
30
|
+
puts optparse.help
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
optparse.parse!
|
35
|
+
|
36
|
+
response = Typhoeus::Request.get(api_url,
|
37
|
+
:verbose => options[:verbose],
|
38
|
+
:params => {
|
39
|
+
:cmd => 'listPeople',
|
40
|
+
:token => api_token })
|
41
|
+
if response.code != 200
|
42
|
+
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
|
46
|
+
result = XML::Parser.string(response.body).parse
|
47
|
+
error = result.find_first('/response/error')
|
48
|
+
if error
|
49
|
+
puts "Failed with error: #{error.content}."
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
|
53
|
+
result.find('/response/people/person').each do |status|
|
54
|
+
puts format("%-30.30s %s\n",
|
55
|
+
status.find_first('sFullName').content,
|
56
|
+
status.find_first('sEmail').content).strip!
|
57
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'typhoeus'
|
5
|
+
require 'xml'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
api_url = ENV['FOGBUGZ_API_URL']
|
9
|
+
unless api_url
|
10
|
+
puts "Environment variable FOGBUGZ_API_URL must be set."
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
api_token = ENV['FOGBUGZ_API_TOKEN']
|
15
|
+
unless api_url
|
16
|
+
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
options = {}
|
21
|
+
optparse = OptionParser.new do |opts|
|
22
|
+
opts.banner = "usage: #{File::basename(__FILE__)} [options]"
|
23
|
+
|
24
|
+
options[:verbose] = false
|
25
|
+
opts.on('-v', '--verbose', 'Output verbose debugging information') do
|
26
|
+
options[:verbose] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on_tail('-h', '--help') do
|
30
|
+
puts optparse.help
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
optparse.parse!
|
35
|
+
|
36
|
+
response = Typhoeus::Request.get(api_url,
|
37
|
+
:verbose => options[:verbose],
|
38
|
+
:params => {
|
39
|
+
:cmd => 'listPriorities',
|
40
|
+
:token => api_token })
|
41
|
+
if response.code != 200
|
42
|
+
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
|
46
|
+
result = XML::Parser.string(response.body).parse
|
47
|
+
error = result.find_first('/response/error')
|
48
|
+
if error
|
49
|
+
puts "Failed with error: #{error.content}."
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
|
53
|
+
result.find('/response/priorities/priority').each do |status|
|
54
|
+
puts status.find_first('sPriority').content
|
55
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'typhoeus'
|
5
|
+
require 'xml'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
api_url = ENV['FOGBUGZ_API_URL']
|
9
|
+
unless api_url
|
10
|
+
puts "Environment variable FOGBUGZ_API_URL must be set."
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
api_token = ENV['FOGBUGZ_API_TOKEN']
|
15
|
+
unless api_url
|
16
|
+
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
options = {}
|
21
|
+
optparse = OptionParser.new do |opts|
|
22
|
+
opts.banner = "usage: #{File::basename(__FILE__)} [options]"
|
23
|
+
|
24
|
+
options[:verbose] = false
|
25
|
+
opts.on('-v', '--verbose', 'Output verbose debugging information') do
|
26
|
+
options[:verbose] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on_tail('-h', '--help') do
|
30
|
+
puts optparse.help
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
optparse.parse!
|
35
|
+
|
36
|
+
response = Typhoeus::Request.get(api_url,
|
37
|
+
:verbose => options[:verbose],
|
38
|
+
:params => {
|
39
|
+
:cmd => 'listProjects',
|
40
|
+
:token => api_token })
|
41
|
+
if response.code != 200
|
42
|
+
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
|
46
|
+
result = XML::Parser.string(response.body).parse
|
47
|
+
error = result.find_first('/response/error')
|
48
|
+
if error
|
49
|
+
puts "Failed with error: #{error.content}."
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
|
53
|
+
result.find('/response/projects/project').each do |status|
|
54
|
+
puts format("%-20.20s %s\n",
|
55
|
+
status.find_first('sPersonOwner').content,
|
56
|
+
status.find_first('sProject').content).strip!
|
57
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'typhoeus'
|
5
|
+
require 'xml'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
api_url = ENV['FOGBUGZ_API_URL']
|
9
|
+
unless api_url
|
10
|
+
puts "Environment variable FOGBUGZ_API_URL must be set."
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
api_token = ENV['FOGBUGZ_API_TOKEN']
|
15
|
+
unless api_url
|
16
|
+
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
options = {}
|
21
|
+
optparse = OptionParser.new do |opts|
|
22
|
+
opts.banner = "usage: #{File::basename(__FILE__)} [options] <case>"
|
23
|
+
|
24
|
+
options[:verbose] = false
|
25
|
+
opts.on('-v', '--verbose', 'Output verbose debugging information.') do
|
26
|
+
options[:verbose] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on_tail('-h', '--help') do
|
30
|
+
puts optparse.help
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
optparse.parse!
|
35
|
+
unless ARGV[0]
|
36
|
+
puts optparse.help
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
|
40
|
+
response = Typhoeus::Request.get(api_url,
|
41
|
+
:verbose => options[:verbose],
|
42
|
+
:params => {
|
43
|
+
:cmd => 'reactivate',
|
44
|
+
:token => api_token,
|
45
|
+
:ixBug => ARGV[0] })
|
46
|
+
if response.code != 200
|
47
|
+
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
|
51
|
+
result = XML::Parser.string(response.body).parse
|
52
|
+
error = result.find_first('/response/error')
|
53
|
+
if error
|
54
|
+
puts "Failed with error: #{error.content}."
|
55
|
+
exit 1
|
56
|
+
end
|
data/bin/fogbugz-reopen
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'typhoeus'
|
5
|
+
require 'xml'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
api_url = ENV['FOGBUGZ_API_URL']
|
9
|
+
unless api_url
|
10
|
+
puts "Environment variable FOGBUGZ_API_URL must be set."
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
api_token = ENV['FOGBUGZ_API_TOKEN']
|
15
|
+
unless api_url
|
16
|
+
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
options = {}
|
21
|
+
optparse = OptionParser.new do |opts|
|
22
|
+
opts.banner = "usage: #{File::basename(__FILE__)} [options] <case>"
|
23
|
+
|
24
|
+
options[:verbose] = false
|
25
|
+
opts.on('-v', '--verbose', 'Output verbose debugging information.') do
|
26
|
+
options[:verbose] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on_tail('-h', '--help') do
|
30
|
+
puts optparse.help
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
optparse.parse!
|
35
|
+
unless ARGV[0]
|
36
|
+
puts optparse.help
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
|
40
|
+
response = Typhoeus::Request.get(api_url,
|
41
|
+
:verbose => options[:verbose],
|
42
|
+
:params => {
|
43
|
+
:cmd => 'reopen',
|
44
|
+
:token => api_token,
|
45
|
+
:ixBug => ARGV[0] })
|
46
|
+
if response.code != 200
|
47
|
+
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
|
51
|
+
result = XML::Parser.string(response.body).parse
|
52
|
+
error = result.find_first('/response/error')
|
53
|
+
if error
|
54
|
+
puts "Failed with error: #{error.content}."
|
55
|
+
exit 1
|
56
|
+
end
|
data/bin/fogbugz-resolve
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'typhoeus'
|
5
|
+
require 'xml'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
api_url = ENV['FOGBUGZ_API_URL']
|
9
|
+
unless api_url
|
10
|
+
puts "Environment variable FOGBUGZ_API_URL must be set."
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
api_token = ENV['FOGBUGZ_API_TOKEN']
|
15
|
+
unless api_url
|
16
|
+
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
options = {}
|
21
|
+
optparse = OptionParser.new do |opts|
|
22
|
+
opts.banner = "usage: #{File::basename(__FILE__)} [options] <case> <status>"
|
23
|
+
|
24
|
+
options[:verbose] = false
|
25
|
+
opts.on('-v', '--verbose', 'Output verbose debugging information.') do
|
26
|
+
options[:verbose] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on_tail('-h', '--help') do
|
30
|
+
puts optparse.help
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
optparse.parse!
|
35
|
+
unless ARGV.length == 2
|
36
|
+
puts optparse.help
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
|
40
|
+
response = Typhoeus::Request.get(api_url,
|
41
|
+
:verbose => options[:verbose],
|
42
|
+
:params => {
|
43
|
+
:cmd => 'listStatuses',
|
44
|
+
:token => api_token,
|
45
|
+
:fResolved => 1 })
|
46
|
+
if response.code != 200
|
47
|
+
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
|
51
|
+
result = XML::Parser.string(response.body).parse
|
52
|
+
error = result.find_first('/response/error')
|
53
|
+
if error
|
54
|
+
puts "Failed with error: #{error.content}."
|
55
|
+
exit 1
|
56
|
+
end
|
57
|
+
|
58
|
+
status = result.find_first("/response/statuses/status[sStatus='#{ARGV[1]}']")
|
59
|
+
|
60
|
+
unless status
|
61
|
+
puts "#{ARGV[1]} is not a resolved status."
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
|
65
|
+
response = Typhoeus::Request.get(api_url,
|
66
|
+
:verbose => options[:verbose],
|
67
|
+
:params => {
|
68
|
+
:cmd => 'resolve',
|
69
|
+
:token => api_token,
|
70
|
+
:ixBug => ARGV[0],
|
71
|
+
:ixStatus => status.find_first('ixStatus').content })
|
72
|
+
if response.code != 200
|
73
|
+
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
74
|
+
exit 1
|
75
|
+
end
|
76
|
+
|
77
|
+
result = XML::Parser.string(response.body).parse
|
78
|
+
error = result.find_first('/response/error')
|
79
|
+
if error
|
80
|
+
puts "Failed with error: #{error.content}."
|
81
|
+
exit 1
|
82
|
+
end
|
data/bin/fogbugz-show
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'typhoeus'
|
5
|
+
require 'xml'
|
6
|
+
require 'optparse'
|
7
|
+
require 'term/ansicolor'
|
8
|
+
require 'time'
|
9
|
+
|
10
|
+
api_url = ENV['FOGBUGZ_API_URL']
|
11
|
+
unless api_url
|
12
|
+
puts "Environment variable FOGBUGZ_API_URL must be set."
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
|
16
|
+
api_token = ENV['FOGBUGZ_API_TOKEN']
|
17
|
+
unless api_url
|
18
|
+
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
options = {}
|
23
|
+
optparse = OptionParser.new do |opts|
|
24
|
+
opts.banner = "usage: #{File::basename(__FILE__)} [options] <case>"
|
25
|
+
|
26
|
+
options[:verbose] = false
|
27
|
+
opts.on('-v', '--verbose', 'Output verbose debugging information') do
|
28
|
+
options[:verbose] = true
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on_tail('-h', '--help') do
|
32
|
+
puts optparse.help
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
optparse.parse!
|
37
|
+
|
38
|
+
unless ARGV[0]
|
39
|
+
puts optparse.help
|
40
|
+
exit 1
|
41
|
+
end
|
42
|
+
|
43
|
+
response = Typhoeus::Request.get(api_url,
|
44
|
+
:verbose => options[:verbose],
|
45
|
+
:params => {
|
46
|
+
:cmd => 'search',
|
47
|
+
:token => api_token,
|
48
|
+
:cols => 'ixBug,ixBugParent,tags,sTitle,sProject,sArea,sFixFor,sCategory,sPersonAssignedTo,sPriority,hrsCurrEst,events',
|
49
|
+
:q => ARGV[0] })
|
50
|
+
if response.code != 200
|
51
|
+
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
52
|
+
exit 1
|
53
|
+
end
|
54
|
+
|
55
|
+
result = XML::Parser.string(response.body).parse
|
56
|
+
error = result.find_first('/response/error')
|
57
|
+
if error
|
58
|
+
puts "Failed with error: #{error.content}."
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
|
62
|
+
r = STDOUT.isatty ? Term::ANSIColor::reset : ''
|
63
|
+
g = STDOUT.isatty ? Term::ANSIColor::green : ''
|
64
|
+
b = STDOUT.isatty ? Term::ANSIColor::blue : ''
|
65
|
+
|
66
|
+
bug = result.find_first "/response/cases/case[@ixBug='#{ARGV[0]}']"
|
67
|
+
unless bug
|
68
|
+
puts "Case #{ARGV[0]} does not exist."
|
69
|
+
exit 1
|
70
|
+
end
|
71
|
+
|
72
|
+
puts "#{b}case: #{r}#{ARGV[0]}"
|
73
|
+
|
74
|
+
sTitle = bug.find_first('sTitle')
|
75
|
+
if sTitle and sTitle.content and not sTitle.content.empty?
|
76
|
+
puts "#{b}title: #{r}#{sTitle.content}"
|
77
|
+
end
|
78
|
+
|
79
|
+
sPersonAssignedTo = bug.find_first('sPersonAssignedTo')
|
80
|
+
if sPersonAssignedTo and sPersonAssignedTo.content and
|
81
|
+
not sPersonAssignedTo.content.empty?
|
82
|
+
puts "#{b}assignee: #{r}#{sPersonAssignedTo.content}"
|
83
|
+
end
|
84
|
+
|
85
|
+
ixBugParent = bug.find_first('ixBugParent')
|
86
|
+
if ixBugParent and ixBugParent.content and not ixBugParent.content.empty? and
|
87
|
+
ixBugParent.content != '0'
|
88
|
+
puts "#{b}parent: #{r}#{ixBugParent.content}"
|
89
|
+
end
|
90
|
+
|
91
|
+
tags = bug.find('tags/tag').collect { |tag| tag.content }
|
92
|
+
if tags and not tags.empty?
|
93
|
+
puts "#{b}tags: #{r}[#{tags.join(', ')}]"
|
94
|
+
end
|
95
|
+
|
96
|
+
sProject = bug.find_first('sProject')
|
97
|
+
if sProject and sProject.content and not sProject.content.empty?
|
98
|
+
puts "#{b}project: #{r}#{sProject.content}"
|
99
|
+
end
|
100
|
+
|
101
|
+
sArea = bug.find_first('sArea')
|
102
|
+
if sArea and sArea.content and not sArea.content.empty?
|
103
|
+
puts "#{b}area: #{r}#{sArea.content}"
|
104
|
+
end
|
105
|
+
|
106
|
+
sFixFor = bug.find_first('sFixFor')
|
107
|
+
if sFixFor and sFixFor.content and not sFixFor.content.empty?
|
108
|
+
puts "#{b}milestone: #{r}#{sFixFor.content}"
|
109
|
+
end
|
110
|
+
|
111
|
+
sCategory = bug.find_first('sCategory')
|
112
|
+
if sCategory and sCategory.content and not sCategory.content.empty?
|
113
|
+
puts "#{b}category: #{r}#{sCategory.content}"
|
114
|
+
end
|
115
|
+
|
116
|
+
sPriority = bug.find_first('sPriority')
|
117
|
+
if sPriority and sPriority.content and not sPriority.content.empty?
|
118
|
+
puts "#{b}priority: #{r}#{sPriority.content}"
|
119
|
+
end
|
120
|
+
|
121
|
+
hrsCurrEst = bug.find_first('hrsCurrEst')
|
122
|
+
if hrsCurrEst and hrsCurrEst.content and not hrsCurrEst.content.empty? and
|
123
|
+
hrsCurrEst.content != '0'
|
124
|
+
puts "#{b}estimate: #{r}#{hrsCurrEst.content}"
|
125
|
+
end
|
126
|
+
|
127
|
+
puts "\n"
|
128
|
+
bug.find('events/event').each do |event|
|
129
|
+
evtDescription = event.find_first('evtDescription')
|
130
|
+
if evtDescription and evtDescription.content and
|
131
|
+
not evtDescription.content.empty?
|
132
|
+
time = Time.parse(event.find_first('dt').content).localtime
|
133
|
+
printf("#{g}%s at %s on %s.\n", evtDescription.content,
|
134
|
+
time.strftime('%-l:%M %p'), time.strftime('%A, %B %e %Y'))
|
135
|
+
end
|
136
|
+
|
137
|
+
sChanges = event.find_first('sChanges')
|
138
|
+
if sChanges and sChanges.content and not sChanges.content.empty?
|
139
|
+
puts "#{b}#{sChanges.content}"
|
140
|
+
end
|
141
|
+
|
142
|
+
summary = event.find_first('s')
|
143
|
+
if summary and summary.content and not summary.content.empty?
|
144
|
+
puts "#{r}#{summary.content}"
|
145
|
+
end
|
146
|
+
puts "#{r}"
|
147
|
+
end
|