fogbugz 1.0.1 → 1.0.2
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/bin/fogbugz-areas +19 -27
- data/bin/fogbugz-assign +17 -19
- data/bin/fogbugz-categories +17 -19
- data/bin/fogbugz-close +16 -18
- data/bin/fogbugz-edit +84 -84
- data/bin/fogbugz-filter +30 -27
- data/bin/fogbugz-filters +23 -17
- data/bin/fogbugz-list +25 -27
- data/bin/fogbugz-login +24 -22
- data/bin/fogbugz-logoff +15 -15
- data/bin/fogbugz-milestones +20 -21
- data/bin/fogbugz-new +28 -29
- data/bin/fogbugz-people +18 -20
- data/bin/fogbugz-priorities +18 -19
- data/bin/fogbugz-projects +18 -20
- data/bin/fogbugz-reactivate +16 -18
- data/bin/fogbugz-reopen +16 -18
- data/bin/fogbugz-resolve +30 -30
- data/bin/fogbugz-show +70 -71
- data/bin/fogbugz-start +16 -17
- data/bin/fogbugz-statuses +19 -21
- data/bin/fogbugz-stop +15 -16
- metadata +4 -28
data/bin/fogbugz-areas
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
5
|
-
require '
|
4
|
+
require 'net/https'
|
5
|
+
require 'uri'
|
6
|
+
require 'rexml/document'
|
6
7
|
require 'optparse'
|
7
8
|
|
8
9
|
api_url = ENV['FOGBUGZ_API_URL']
|
@@ -12,7 +13,7 @@ unless api_url
|
|
12
13
|
end
|
13
14
|
|
14
15
|
api_token = ENV['FOGBUGZ_API_TOKEN']
|
15
|
-
unless
|
16
|
+
unless api_token
|
16
17
|
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
17
18
|
exit 1
|
18
19
|
end
|
@@ -21,44 +22,35 @@ options = {}
|
|
21
22
|
optparse = OptionParser.new do |opts|
|
22
23
|
opts.banner = "usage: #{File::basename(__FILE__)} [options]"
|
23
24
|
|
24
|
-
options[:verbose] = false
|
25
|
-
opts.on('-v', '--verbose', 'Output verbose debugging information') do
|
26
|
-
options[:verbose] = true
|
27
|
-
end
|
28
|
-
|
29
25
|
opts.on_tail('-h', '--help') do
|
30
26
|
puts optparse.help
|
31
27
|
exit 1
|
32
28
|
end
|
33
|
-
|
34
|
-
options[:project] = nil
|
35
|
-
opts.on('--project=<project>', 'Filter by project.') do |project|
|
36
|
-
options[:project] = project
|
37
|
-
end
|
38
29
|
end
|
39
30
|
optparse.parse!
|
40
31
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
32
|
+
uri = URI format("#{api_url}?cmd=listAreas&token=%s", URI.escape(api_token))
|
33
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
34
|
+
if uri.scheme == 'https'
|
35
|
+
http.use_ssl = true
|
36
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
37
|
+
end
|
38
|
+
response = http.start { |h| h.request Net::HTTP::Get.new(uri.request_uri) }
|
39
|
+
if response.code != '200'
|
48
40
|
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
49
41
|
exit 1
|
50
42
|
end
|
51
43
|
|
52
|
-
result =
|
53
|
-
error = result.
|
44
|
+
result = REXML::Document.new(response.body)
|
45
|
+
error = result.elements['/response/error']
|
54
46
|
if error
|
55
|
-
puts "Failed with error: #{error.
|
47
|
+
puts "Failed with error: #{error.text}."
|
56
48
|
exit 1
|
57
49
|
end
|
58
50
|
|
59
|
-
result.
|
51
|
+
result.elements.each('/response/areas/area') do |area|
|
60
52
|
puts format("%-20.20s %-20.20s %s\n",
|
61
|
-
|
62
|
-
|
63
|
-
|
53
|
+
area.elements['sPersonOwner'].text,
|
54
|
+
area.elements['sProject'].text,
|
55
|
+
area.elements['sArea'].text).strip!
|
64
56
|
end
|
data/bin/fogbugz-assign
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
5
|
-
require '
|
4
|
+
require 'net/https'
|
5
|
+
require 'uri'
|
6
|
+
require 'rexml/document'
|
6
7
|
require 'optparse'
|
7
8
|
|
8
9
|
api_url = ENV['FOGBUGZ_API_URL']
|
@@ -12,7 +13,7 @@ unless api_url
|
|
12
13
|
end
|
13
14
|
|
14
15
|
api_token = ENV['FOGBUGZ_API_TOKEN']
|
15
|
-
unless
|
16
|
+
unless api_token
|
16
17
|
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
17
18
|
exit 1
|
18
19
|
end
|
@@ -21,11 +22,6 @@ options = {}
|
|
21
22
|
optparse = OptionParser.new do |opts|
|
22
23
|
opts.banner = "usage: #{File::basename(__FILE__)} [options] <case> <assignee>"
|
23
24
|
|
24
|
-
options[:verbose] = false
|
25
|
-
opts.on('-v', '--verbose', 'Output verbose debugging information.') do
|
26
|
-
options[:verbose] = true
|
27
|
-
end
|
28
|
-
|
29
25
|
opts.on_tail('-h', '--help') do
|
30
26
|
puts optparse.help
|
31
27
|
exit 1
|
@@ -38,21 +34,23 @@ unless ARGV.length == 2
|
|
38
34
|
exit 1
|
39
35
|
end
|
40
36
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
37
|
+
uri = URI format("#{api_url}?cmd=assign&token=%s&ixBug=%s&sPersonAssignedTo=%s",
|
38
|
+
URI.escape(api_token), URI.escape(ARGV[0]),
|
39
|
+
URI.escape(ARGV[1]))
|
40
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
41
|
+
if uri.scheme == 'https'
|
42
|
+
http.use_ssl = true
|
43
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
44
|
+
end
|
45
|
+
response = http.start { |h| h.request Net::HTTP::Get.new(uri.request_uri) }
|
46
|
+
if response.code != '200'
|
49
47
|
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
50
48
|
exit 1
|
51
49
|
end
|
52
50
|
|
53
|
-
result =
|
54
|
-
error = result.
|
51
|
+
result = REXML::Document.new(response.body)
|
52
|
+
error = result.elements['/response/error']
|
55
53
|
if error
|
56
|
-
puts "Failed with error: #{error.
|
54
|
+
puts "Failed with error: #{error.text}."
|
57
55
|
exit 1
|
58
56
|
end
|
data/bin/fogbugz-categories
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
5
|
-
require '
|
4
|
+
require 'net/https'
|
5
|
+
require 'uri'
|
6
|
+
require 'rexml/document'
|
6
7
|
require 'optparse'
|
7
8
|
|
8
9
|
api_url = ENV['FOGBUGZ_API_URL']
|
@@ -12,7 +13,7 @@ unless api_url
|
|
12
13
|
end
|
13
14
|
|
14
15
|
api_token = ENV['FOGBUGZ_API_TOKEN']
|
15
|
-
unless
|
16
|
+
unless api_token
|
16
17
|
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
17
18
|
exit 1
|
18
19
|
end
|
@@ -21,11 +22,6 @@ options = {}
|
|
21
22
|
optparse = OptionParser.new do |opts|
|
22
23
|
opts.banner = "usage: #{File::basename(__FILE__)} [options]"
|
23
24
|
|
24
|
-
options[:verbose] = false
|
25
|
-
opts.on('-v', '--verbose', 'Output verbose debugging information') do
|
26
|
-
options[:verbose] = true
|
27
|
-
end
|
28
|
-
|
29
25
|
opts.on_tail('-h', '--help') do
|
30
26
|
puts optparse.help
|
31
27
|
exit 1
|
@@ -33,23 +29,25 @@ optparse = OptionParser.new do |opts|
|
|
33
29
|
end
|
34
30
|
optparse.parse!
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
32
|
+
uri = URI format("#{api_url}?cmd=listCategories&token=%s", URI.escape(api_token))
|
33
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
34
|
+
if uri.scheme == 'https'
|
35
|
+
http.use_ssl = true
|
36
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
37
|
+
end
|
38
|
+
response = http.start { |h| h.request Net::HTTP::Get.new(uri.request_uri) }
|
39
|
+
if response.code != '200'
|
42
40
|
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
43
41
|
exit 1
|
44
42
|
end
|
45
43
|
|
46
|
-
result =
|
47
|
-
error = result.
|
44
|
+
result = REXML::Document.new(response.body)
|
45
|
+
error = result.elements['/response/error']
|
48
46
|
if error
|
49
|
-
puts "Failed with error: #{error.
|
47
|
+
puts "Failed with error: #{error.text}."
|
50
48
|
exit 1
|
51
49
|
end
|
52
50
|
|
53
|
-
result.
|
54
|
-
puts
|
51
|
+
result.elements.each('/response/categories/category') do |category|
|
52
|
+
puts category.elements['sCategory'].text
|
55
53
|
end
|
data/bin/fogbugz-close
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
5
|
-
require '
|
4
|
+
require 'net/https'
|
5
|
+
require 'uri'
|
6
|
+
require 'rexml/document'
|
6
7
|
require 'optparse'
|
7
8
|
|
8
9
|
api_url = ENV['FOGBUGZ_API_URL']
|
@@ -12,7 +13,7 @@ unless api_url
|
|
12
13
|
end
|
13
14
|
|
14
15
|
api_token = ENV['FOGBUGZ_API_TOKEN']
|
15
|
-
unless
|
16
|
+
unless api_token
|
16
17
|
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
17
18
|
exit 1
|
18
19
|
end
|
@@ -21,11 +22,6 @@ options = {}
|
|
21
22
|
optparse = OptionParser.new do |opts|
|
22
23
|
opts.banner = "usage: #{File::basename(__FILE__)} [options] <case>"
|
23
24
|
|
24
|
-
options[:verbose] = false
|
25
|
-
opts.on('-v', '--verbose', 'Output verbose debugging information.') do
|
26
|
-
options[:verbose] = true
|
27
|
-
end
|
28
|
-
|
29
25
|
opts.on_tail('-h', '--help') do
|
30
26
|
puts optparse.help
|
31
27
|
exit 1
|
@@ -38,20 +34,22 @@ unless ARGV[0]
|
|
38
34
|
exit 1
|
39
35
|
end
|
40
36
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
37
|
+
uri = URI format("#{api_url}?cmd=close&token=%s&ixBug=%s",
|
38
|
+
URI.escape(api_token), URI.escape(ARGV[0]))
|
39
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
40
|
+
if uri.scheme == 'https'
|
41
|
+
http.use_ssl = true
|
42
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
43
|
+
end
|
44
|
+
response = http.start { |h| h.request Net::HTTP::Get.new(uri.request_uri) }
|
45
|
+
if response.code != '200'
|
48
46
|
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
49
47
|
exit 1
|
50
48
|
end
|
51
49
|
|
52
|
-
result =
|
53
|
-
error = result.
|
50
|
+
result = REXML::Document.new(response.body)
|
51
|
+
error = result.elements['/response/error']
|
54
52
|
if error
|
55
|
-
puts "Failed with error: #{error.
|
53
|
+
puts "Failed with error: #{error.text}."
|
56
54
|
exit 1
|
57
55
|
end
|
data/bin/fogbugz-edit
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
5
|
-
require '
|
4
|
+
require 'net/https'
|
5
|
+
require 'uri'
|
6
|
+
require 'rexml/document'
|
6
7
|
require 'tempfile'
|
7
8
|
require 'optparse'
|
8
9
|
require 'yaml'
|
@@ -15,7 +16,7 @@ unless api_url
|
|
15
16
|
end
|
16
17
|
|
17
18
|
api_token = ENV['FOGBUGZ_API_TOKEN']
|
18
|
-
unless
|
19
|
+
unless api_token
|
19
20
|
puts "Environment variable FOGBUGZ_API_TOKEN must be set."
|
20
21
|
exit 1
|
21
22
|
end
|
@@ -26,11 +27,6 @@ options = {}
|
|
26
27
|
optparse = OptionParser.new do |opts|
|
27
28
|
opts.banner = "usage: #{File::basename(__FILE__)} [options] <case>"
|
28
29
|
|
29
|
-
options[:verbose] = false
|
30
|
-
opts.on('-v', '--verbose', 'Output verbose debugging information') do
|
31
|
-
options[:verbose] = true
|
32
|
-
end
|
33
|
-
|
34
30
|
opts.on_tail('-h', '--help') do
|
35
31
|
puts optparse.help
|
36
32
|
exit 1
|
@@ -56,26 +52,28 @@ unless ARGV.length == 1
|
|
56
52
|
end
|
57
53
|
case_id = ARGV[0]
|
58
54
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
55
|
+
uri = URI format("#{api_url}?cmd=search&token=%s&cols=%s&q=%s&max=1",
|
56
|
+
URI.escape(api_token), URI.escape('ixBug,ixBugParent,tags,sTitle,sProject,sArea,sFixFor,sCategory,sPersonAssignedTo,sPriority,hrsCurrEst,events'),
|
57
|
+
URI.escape(case_id))
|
58
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
59
|
+
if uri.scheme == 'https'
|
60
|
+
http.use_ssl = true
|
61
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
62
|
+
end
|
63
|
+
response = http.start { |h| h.request Net::HTTP::Get.new(uri.request_uri) }
|
64
|
+
if response.code != '200'
|
67
65
|
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
68
66
|
exit 1
|
69
67
|
end
|
70
68
|
|
71
|
-
result =
|
72
|
-
error = result.
|
69
|
+
result = REXML::Document.new(response.body)
|
70
|
+
error = result.elements['/response/error']
|
73
71
|
if error
|
74
|
-
puts "Failed with error: #{error.
|
72
|
+
puts "Failed with error: #{error.text}."
|
75
73
|
exit 1
|
76
74
|
end
|
77
75
|
|
78
|
-
bug = result.
|
76
|
+
bug = result.elements["/response/cases/case[@ixBug='#{case_id}']"]
|
79
77
|
unless bug
|
80
78
|
puts "Case #{case_id} does not exist."
|
81
79
|
exit 1
|
@@ -103,99 +101,99 @@ else
|
|
103
101
|
# Fill in metadata for the case.
|
104
102
|
HERE
|
105
103
|
|
106
|
-
sTitle = bug.
|
107
|
-
if sTitle and sTitle.
|
108
|
-
template << "# title: #{sTitle.
|
104
|
+
sTitle = bug.elements['sTitle']
|
105
|
+
if sTitle and sTitle.text and not sTitle.text.empty?
|
106
|
+
template << "# title: #{sTitle.text}\n"
|
109
107
|
else
|
110
108
|
template << "# title: <title>\n"
|
111
109
|
end
|
112
110
|
|
113
|
-
sPersonAssignedTo = bug.
|
114
|
-
if sPersonAssignedTo and sPersonAssignedTo.
|
115
|
-
not sPersonAssignedTo.
|
116
|
-
template << "# assignee: #{sPersonAssignedTo.
|
111
|
+
sPersonAssignedTo = bug.elements['sPersonAssignedTo']
|
112
|
+
if sPersonAssignedTo and sPersonAssignedTo.text and
|
113
|
+
not sPersonAssignedTo.text.empty?
|
114
|
+
template << "# assignee: #{sPersonAssignedTo.text}\n"
|
117
115
|
else
|
118
116
|
template << "# assignee: <person>\n"
|
119
117
|
end
|
120
118
|
|
121
|
-
ixBugParent = bug.
|
122
|
-
if ixBugParent and ixBugParent.
|
123
|
-
ixBugParent.
|
124
|
-
template << "# parent: #{ixBugParent.
|
119
|
+
ixBugParent = bug.elements['ixBugParent']
|
120
|
+
if ixBugParent and ixBugParent.text and not ixBugParent.text.empty? and
|
121
|
+
ixBugParent.text != '0'
|
122
|
+
template << "# parent: #{ixBugParent.text}\n"
|
125
123
|
else
|
126
124
|
template << "# parent: <case>\n"
|
127
125
|
end
|
128
126
|
|
129
|
-
tags = bug.
|
127
|
+
tags = bug.elements.collect('tags/tag') { |tag| tag.text }
|
130
128
|
if tags and not tags.empty?
|
131
129
|
template << "# tags: [#{tags.join(', ')}]\n"
|
132
130
|
else
|
133
131
|
template << "# tags: [bug, enhancement]\n"
|
134
132
|
end
|
135
133
|
|
136
|
-
sProject = bug.
|
137
|
-
if sProject and sProject.
|
138
|
-
template << "# project: #{sProject.
|
134
|
+
sProject = bug.elements['sProject']
|
135
|
+
if sProject and sProject.text and not sProject.text.empty?
|
136
|
+
template << "# project: #{sProject.text}\n"
|
139
137
|
else
|
140
138
|
template << "# project: <project>\n"
|
141
139
|
end
|
142
140
|
|
143
|
-
sArea = bug.
|
144
|
-
if sArea and sArea.
|
145
|
-
template << "# area: #{sArea.
|
141
|
+
sArea = bug.elements['sArea']
|
142
|
+
if sArea and sArea.text and not sArea.text.empty?
|
143
|
+
template << "# area: #{sArea.text}\n"
|
146
144
|
else
|
147
145
|
template << "# area: <area>\n"
|
148
146
|
end
|
149
147
|
|
150
|
-
sFixFor = bug.
|
151
|
-
if sFixFor and sFixFor.
|
152
|
-
template << "# milestone: #{sFixFor.
|
148
|
+
sFixFor = bug.elements['sFixFor']
|
149
|
+
if sFixFor and sFixFor.text and not sFixFor.text.empty?
|
150
|
+
template << "# milestone: #{sFixFor.text}\n"
|
153
151
|
else
|
154
152
|
template << "# milestone: <milestone>"
|
155
153
|
end
|
156
154
|
|
157
|
-
sCategory = bug.
|
158
|
-
if sCategory and sCategory.
|
159
|
-
template << "# category: #{sCategory.
|
155
|
+
sCategory = bug.elements['sCategory']
|
156
|
+
if sCategory and sCategory.text and not sCategory.text.empty?
|
157
|
+
template << "# category: #{sCategory.text}\n"
|
160
158
|
else
|
161
159
|
template << "# category: <category>"
|
162
160
|
end
|
163
161
|
|
164
|
-
sPriority = bug.
|
165
|
-
if sPriority and sPriority.
|
166
|
-
template << "# priority: #{sPriority.
|
162
|
+
sPriority = bug.elements['sPriority']
|
163
|
+
if sPriority and sPriority.text and not sPriority.text.empty?
|
164
|
+
template << "# priority: #{sPriority.text}\n"
|
167
165
|
else
|
168
166
|
template << "# priority: <priority>"
|
169
167
|
end
|
170
168
|
|
171
|
-
hrsCurrEst = bug.
|
172
|
-
if hrsCurrEst and hrsCurrEst.
|
173
|
-
hrsCurrEst.
|
174
|
-
template << "# estimate: #{hrsCurrEst.
|
169
|
+
hrsCurrEst = bug.elements['hrsCurrEst']
|
170
|
+
if hrsCurrEst and hrsCurrEst.text and not hrsCurrEst.text.empty? and
|
171
|
+
hrsCurrEst.text != '0'
|
172
|
+
template << "# estimate: #{hrsCurrEst.text}\n"
|
175
173
|
else
|
176
174
|
template << "# estimate: <estimate>\n"
|
177
175
|
end
|
178
176
|
|
179
177
|
template << "\n"
|
180
|
-
bug.
|
181
|
-
evtDescription = event.
|
182
|
-
if evtDescription and evtDescription.
|
183
|
-
not evtDescription.
|
184
|
-
time = Time.parse(event.
|
185
|
-
template << format("# %s at %s on %s.\n", evtDescription.
|
178
|
+
bug.elements.each('events/event') do |event|
|
179
|
+
evtDescription = event.elements['evtDescription']
|
180
|
+
if evtDescription and evtDescription.text and
|
181
|
+
not evtDescription.text.empty?
|
182
|
+
time = Time.parse(event.elements['dt'].text).localtime
|
183
|
+
template << format("# %s at %s on %s.\n", evtDescription.text,
|
186
184
|
time.strftime('%-l:%M %p'),
|
187
185
|
time.strftime('%A, %B %e %Y'))
|
188
186
|
end
|
189
187
|
|
190
|
-
sChanges = event.
|
191
|
-
if sChanges and sChanges.
|
192
|
-
commented = sChanges.
|
188
|
+
sChanges = event.elements['sChanges']
|
189
|
+
if sChanges and sChanges.text and not sChanges.text.empty?
|
190
|
+
commented = sChanges.text.gsub(/\n/, "\n# ")
|
193
191
|
template << "# #{commented}\n"
|
194
192
|
end
|
195
193
|
|
196
|
-
summary = event.
|
197
|
-
if summary and summary.
|
198
|
-
commented = summary.
|
194
|
+
summary = event.elements['s']
|
195
|
+
if summary and summary.text and not summary.text.empty?
|
196
|
+
commented = summary.text.gsub(/\n/, "\n# ")
|
199
197
|
template << "# #{commented}\n"
|
200
198
|
end
|
201
199
|
template << "\n"
|
@@ -251,31 +249,33 @@ if not data or data.empty?
|
|
251
249
|
exit 1
|
252
250
|
end
|
253
251
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
252
|
+
uri = URI format("#{api_url}?cmd=edit&token=%s&ixBug=%s%s%s%s%s%s%s%s%s%s%s%s",
|
253
|
+
URI.escape(api_token), URI.escape(case_id),
|
254
|
+
data['title'] ? URI.escape(data['title'].to_s) : '',
|
255
|
+
data['parent'] ? URI.escape(data['parent'].to_s) : '',
|
256
|
+
data['tags'] ? URI.escape(data['tags'].join(',')) : '',
|
257
|
+
data['project'] ? URI.escape(data['project'].to_s) : '',
|
258
|
+
data['area'] ? URI.escape(data['area'].to_s) : '',
|
259
|
+
data['milestone'] ? URI.escape(data['milestone'].to_s) : '',
|
260
|
+
data['category'] ? URI.escape(data['category'].to_s) : '',
|
261
|
+
data['assignee'] ? URI.escape(data['assignee'].to_s) : '',
|
262
|
+
data['priority'] ? URI.escape(data['priority'].to_s) : '',
|
263
|
+
data['estimate'] ? URI.escape(data['estimate'].to_s) : '',
|
264
|
+
data['body'] ? URI.escape(data['body'].to_s) : '')
|
265
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
266
|
+
if uri.scheme == 'https'
|
267
|
+
http.use_ssl = true
|
268
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
269
|
+
end
|
270
|
+
response = http.start { |h| h.request Net::HTTP::Get.new(uri.request_uri) }
|
271
|
+
if response.code != '200'
|
272
272
|
puts "HTTP request to #{api_url} failed with code #{response.code}."
|
273
273
|
exit 1
|
274
274
|
end
|
275
275
|
|
276
|
-
result =
|
277
|
-
error = result.
|
276
|
+
result = REXML::Document.new(response.body)
|
277
|
+
error = result.elements['/response/error']
|
278
278
|
if error
|
279
|
-
puts "Failed with error: #{error.
|
279
|
+
puts "Failed with error: #{error.text}."
|
280
280
|
exit 1
|
281
281
|
end
|