jirarest2 0.0.4 → 0.0.5
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.tar.gz.sig +0 -0
- data/History.txt +19 -0
- data/Manifest.txt +4 -2
- data/README.txt +1 -1
- data/Rakefile +1 -0
- data/bin/create_issue.rb +3 -275
- data/bin/jira_create_issue.rb +366 -0
- data/lib/connect.rb +21 -24
- data/lib/credentials.rb +7 -12
- data/lib/exceptions.rb +1 -3
- data/lib/issue.rb +46 -58
- data/lib/jirarest2.rb +1 -1
- data/lib/jirarest2/result.rb +34 -30
- data/lib/madbitconfig.rb +82 -0
- data/lib/services.rb +12 -17
- data/lib/services/issuelink.rb +21 -15
- data/lib/services/issuelinktype.rb +17 -17
- data/lib/services/watcher.rb +15 -15
- data/test/data/test.config.data +3 -0
- data/test/test_madbitconfig.rb +33 -0
- metadata +30 -16
- metadata.gz.sig +0 -0
- data/lib/config.rb +0 -55
- data/lib/issuelink.rb +0 -74
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
=== 0.0.5 / 2012-07-18
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
|
5
|
+
* renamed create_issue.rb to jira_create_issue.rb to avoid (at least some) naming conflics
|
6
|
+
|
7
|
+
* 2 minor enhancements:
|
8
|
+
|
9
|
+
* Added support to write config file closes #4
|
10
|
+
* moved config to madbitconfig and Module Config to MadbitConfig to get rid of conflict with the config class from ruby.
|
11
|
+
|
12
|
+
* 1 bug fix:
|
13
|
+
|
14
|
+
* Fixed changed Module name in create_issue
|
15
|
+
|
16
|
+
* 2 unknowns:
|
17
|
+
|
18
|
+
* Reworked documentation
|
19
|
+
|
1
20
|
=== 0.0.4 / 2012-07-17
|
2
21
|
|
3
22
|
* 1 major enhancement:
|
data/Manifest.txt
CHANGED
@@ -6,23 +6,25 @@ README.md
|
|
6
6
|
README.txt
|
7
7
|
Rakefile
|
8
8
|
bin/create_issue.rb
|
9
|
+
bin/jira_create_issue.rb
|
9
10
|
copyright
|
10
|
-
lib/config.rb
|
11
11
|
lib/connect.rb
|
12
12
|
lib/credentials.rb
|
13
13
|
lib/exceptions.rb
|
14
14
|
lib/issue.rb
|
15
|
-
lib/issuelink.rb
|
16
15
|
lib/jirarest2.rb
|
17
16
|
lib/jirarest2/result.rb
|
17
|
+
lib/madbitconfig.rb
|
18
18
|
lib/services.rb
|
19
19
|
lib/services/issuelink.rb
|
20
20
|
lib/services/issuelinktype.rb
|
21
21
|
lib/services/watcher.rb
|
22
|
+
test/data/test.config.data
|
22
23
|
test/test_connect.rb
|
23
24
|
test/test_credentials.rb
|
24
25
|
test/test_issue.rb
|
25
26
|
test/test_issuelink.rb
|
26
27
|
test/test_issuelinktype.rb
|
28
|
+
test/test_madbitconfig.rb
|
27
29
|
test/test_result.rb
|
28
30
|
test/test_watcher.rb
|
data/README.txt
CHANGED
data/Rakefile
CHANGED
data/bin/create_issue.rb
CHANGED
@@ -17,279 +17,7 @@
|
|
17
17
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
puts "Sorry, I need ruby 1.9.1 or higher!"
|
24
|
-
exit1
|
25
|
-
end
|
26
|
-
|
27
|
-
require "highline/import"
|
28
|
-
require "jirarest2"
|
29
|
-
require "optparse"
|
30
|
-
require "ostruct"
|
31
|
-
require "config"
|
32
|
-
require "uri"
|
33
|
-
require "pp"
|
34
|
-
|
35
|
-
class ParseOptions
|
36
|
-
|
37
|
-
def self.required_argument(name)
|
38
|
-
puts "Argument \"#{name}\" is mandatory."
|
39
|
-
exit 1
|
40
|
-
end
|
41
|
-
|
42
|
-
=begin
|
43
|
-
parse resturn two Hashes. The first one contains the options for the issue the second one the options for the execution of the script.
|
44
|
-
=end
|
45
|
-
def self.parse(args)
|
46
|
-
issueopts = OpenStruct.new
|
47
|
-
issueopts.project = nil
|
48
|
-
issueopts.issue = nil
|
49
|
-
scriptopts = OpenStruct.new
|
50
|
-
scriptopts.show = []
|
51
|
-
scriptopts.arrayseperator = "|"
|
52
|
-
scriptopts.configfile = "~/.jiraconfig"
|
53
|
-
|
54
|
-
opts = OptionParser.new do |opts|
|
55
|
-
opts.banner = "Usage: #{__FILE__} [options]"
|
56
|
-
opts.separator ""
|
57
|
-
|
58
|
-
opts.on("-p", "--project PROJECT", "Projectname") do |p|
|
59
|
-
issueopts.project = p
|
60
|
-
issueopts
|
61
|
-
end
|
62
|
-
|
63
|
-
opts.on("-i", "--issue ISSUETYPE", "Issuetype") do |i|
|
64
|
-
issueopts.issue = i
|
65
|
-
end
|
66
|
-
|
67
|
-
opts.on("-f", "--fields", "Display the fields available for this issue") do |f|
|
68
|
-
scriptopts.show << "fields"
|
69
|
-
end
|
70
|
-
|
71
|
-
opts.on("-r", "--requireds", "Display the the mandatory content fields for this issue") do |r|
|
72
|
-
scriptopts.show << "requireds"
|
73
|
-
end
|
74
|
-
|
75
|
-
opts.on("-c", "--content x=value,y=value,z=value", Array, "List of fields to fill") do |list|
|
76
|
-
issueopts.content = list
|
77
|
-
end
|
78
|
-
|
79
|
-
opts.on("-w", "--watcher USERNAME,USERNAME", Array, "List of watchers") do |w|
|
80
|
-
issueopts.watchers = w
|
81
|
-
end
|
82
|
-
|
83
|
-
opts.on("-l", "--link ISSUE=LINKTYPE", "Key of an Issue this issue should be linked to" ) do |l|
|
84
|
-
issueopts.link = l
|
85
|
-
end
|
86
|
-
|
87
|
-
opts.on("-F", "--field-seperator CHAR", "A fieldseperator if one of the fields is an array (Default \"|\")") do |fs|
|
88
|
-
scriptopts.arrayseperator = fs
|
89
|
-
end
|
90
|
-
|
91
|
-
|
92
|
-
opts.on("--config-file CONFIGFILE", "Config file containing the jira credentials. (Default: ~/.jiraconfig)") do |conffile|
|
93
|
-
scriptopts.configfile = conffile
|
94
|
-
end
|
95
|
-
|
96
|
-
opts.on("-u", "--username USERNAME", "Your Jira Username if you don't want to use the one in the master file") do |u|
|
97
|
-
scriptopts.username = u
|
98
|
-
end
|
99
|
-
|
100
|
-
opts.on("-H", "--jira-url URL", "URL to rest api (without \"/rest/api/2\").") do |url|
|
101
|
-
uri = URI(url)
|
102
|
-
splitURI = URI.split(url)
|
103
|
-
if splitURI[3] then
|
104
|
-
url = splitURI[0].to_s + "://" + splitURI[2].to_s + ":" + splitURI[3].to_s + splitURI[5].to_s
|
105
|
-
else
|
106
|
-
url = splitURI[0].to_s + "://" + splitURI[2].to_s + splitURI[5].to_s
|
107
|
-
end
|
108
|
-
scriptopts.url = url
|
109
|
-
end
|
110
|
-
|
111
|
-
opts.on_tail("-h", "--help", "Display this screen") do
|
112
|
-
puts opts
|
113
|
-
exit
|
114
|
-
end
|
115
|
-
|
116
|
-
opts.on_tail("--version", "Show version") do
|
117
|
-
puts OptionParser::Version.join(".")
|
118
|
-
exit
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
|
123
|
-
opts.parse!(args)
|
124
|
-
|
125
|
-
if issueopts.project.nil? then
|
126
|
-
required_argument("project")
|
127
|
-
end
|
128
|
-
if issueopts.issue.nil? then
|
129
|
-
required_argument("issue")
|
130
|
-
end
|
131
|
-
return issueopts, scriptopts
|
132
|
-
end #parse()
|
133
|
-
|
134
|
-
|
135
|
-
end # class ParseOptions
|
136
|
-
|
137
|
-
@issueopts, @scriptopts = ParseOptions.parse(ARGV)
|
138
|
-
|
139
|
-
|
140
|
-
def no_issue(type,issue)
|
141
|
-
puts "The #{type}type you entered (\"#{issue}\") does no exist."
|
142
|
-
puts "Maybe you entered the wrong type or made a typo? (Case is relevant!)"
|
143
|
-
exit 1
|
144
|
-
end
|
145
|
-
|
146
|
-
def get_password
|
147
|
-
ask("Enter your password for user \"#{@scriptopts.username}\": ") { |q| q.echo = "*" }
|
148
|
-
end
|
149
|
-
|
150
|
-
=begin
|
151
|
-
Gather all the credentials and build the credentials file
|
152
|
-
=end
|
153
|
-
def get_credentials
|
154
|
-
fileconf = Config::read_configfile(@scriptopts.configfile)
|
155
|
-
# We don't want to set the calues from the configfile if we have them already set.
|
156
|
-
@scriptopts.username = fileconf["username"] if ( @scriptopts.username.nil? && fileconf["username"] )
|
157
|
-
@scriptopts.pass = fileconf["password"] if ( @scriptopts.pass.nil? && fileconf["password"] )
|
158
|
-
if ( @scriptopts.url.nil? && fileconf["URL"] ) then
|
159
|
-
@scriptopts.url = fileconf["URL"]
|
160
|
-
end
|
161
|
-
@scriptopts.url = @scriptopts.url + "/rest/api/2/"
|
162
|
-
|
163
|
-
if @scriptopts.pass.nil? then
|
164
|
-
@scriptopts.pass = get_password
|
165
|
-
end
|
166
|
-
|
167
|
-
return Credentials.new(@scriptopts.url, @scriptopts.username, @scriptopts.pass)
|
168
|
-
end
|
169
|
-
|
170
|
-
=begin
|
171
|
-
If there is already a conenction known returns that connection. If not or if the parameter is true it tries to create a new Connect object
|
172
|
-
=end
|
173
|
-
def get_connection(reconnect = false)
|
174
|
-
if ! @connection || reconnect then
|
175
|
-
begin
|
176
|
-
@connection = Connect.new(get_credentials)
|
177
|
-
@connection.heal_uri! # We want to be sure so we try to heal the connection_url if possible
|
178
|
-
return @connection
|
179
|
-
rescue Jirarest2::CouldNotHealURIError => e
|
180
|
-
puts "REST API not found at #{e.to_s}"
|
181
|
-
exit 3
|
182
|
-
end
|
183
|
-
else
|
184
|
-
return @connection
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
=begin
|
192
|
-
create the issue on our side
|
193
|
-
=end
|
194
|
-
def open_issue
|
195
|
-
begin
|
196
|
-
credentials = get_credentials
|
197
|
-
issue=Issue.new(@issueopts.project,@issueopts.issue,get_connection)
|
198
|
-
rescue Jirarest2::AuthentificationError => e
|
199
|
-
puts "Password not accepted."
|
200
|
-
@scriptopts.pass = get_password
|
201
|
-
retry
|
202
|
-
rescue Jirarest2::AuthentificationCaptchaError => e
|
203
|
-
puts "Wrong Password too many times.\nCaptcha time at #{e.to_s} to reenable your account."
|
204
|
-
exit 1
|
205
|
-
rescue Jirarest2::WrongProjectException => e
|
206
|
-
no_issue("project",e)
|
207
|
-
rescue Jirarest2::WrongIssuetypeException => e
|
208
|
-
no_issue("project",e)
|
209
|
-
end
|
210
|
-
return issue
|
211
|
-
end
|
212
|
-
|
213
|
-
def show_scheme
|
214
|
-
issue = open_issue
|
215
|
-
if @scriptopts.show.include?("fields") then
|
216
|
-
print "Available fields: "
|
217
|
-
puts issue.get_fieldnames.join(", ")
|
218
|
-
end
|
219
|
-
if @scriptopts.show.include?("requireds") then
|
220
|
-
print "Required fields: "
|
221
|
-
puts issue.get_requireds.join(", ")
|
222
|
-
end
|
223
|
-
exit
|
224
|
-
end
|
225
|
-
|
226
|
-
|
227
|
-
def prepare_new_ticket
|
228
|
-
issue = open_issue
|
229
|
-
valueNotAllowedRaised = false
|
230
|
-
@issueopts.content.each { |value|
|
231
|
-
split = value.split("=")
|
232
|
-
begin
|
233
|
-
if issue.fieldtype(split[0]) == "array" then # If the fieldtype is an array we want to use our arrayseparator to split the fields
|
234
|
-
if ! split[1].nil? then
|
235
|
-
split[1] = split[1].split(@scriptopts.arrayseperator)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
issue.set_field(split[0],split[1])
|
239
|
-
rescue Jirarest2::WrongFieldnameException => e
|
240
|
-
no_issue("field",e)
|
241
|
-
rescue Jirarest2::ValueNotAllowedException => e
|
242
|
-
puts "Value #{split[1]} not allowed for field #{split[0]}."
|
243
|
-
puts "Please use one of: \"" + e.message.join("\", \"") + "\""
|
244
|
-
valueNotAllowedRaised = true
|
245
|
-
end
|
246
|
-
}
|
247
|
-
if valueNotAllowedRaised then
|
248
|
-
raise Jirarest2::ValueNotAllowedException
|
249
|
-
end
|
250
|
-
return issue
|
251
|
-
end
|
252
|
-
|
253
|
-
def set_watchers(issue)
|
254
|
-
issue.set_watcher(credentials,@issueopts.watchers)
|
255
|
-
end
|
256
|
-
|
257
|
-
def create_new_ticket(issue)
|
258
|
-
begin
|
259
|
-
connection = get_connection # We need it so often in the next few lines that I prefer to get the result in a variable
|
260
|
-
result = issue.persist(connection).result
|
261
|
-
# Set the watchers
|
262
|
-
if @issueopts.watchers then
|
263
|
-
watcherssuccess = issue.add_watchers(connection,@issueopts.watchers)
|
264
|
-
end
|
265
|
-
rescue Jirarest2::RequiredFieldNotSetException => e
|
266
|
-
puts "Required field \"#{e.to_s}\" not set."
|
267
|
-
return 1
|
268
|
-
end
|
269
|
-
if result["key"] then
|
270
|
-
puts "Created new issue with issue id #{result["key"]} ."
|
271
|
-
if ! watcherssuccess then
|
272
|
-
puts "Watchers could not be set though."
|
273
|
-
end
|
274
|
-
if @issueopts.link then
|
275
|
-
link = IssueLink.new(connection)
|
276
|
-
remoteIssue,linktype = @issueopts.link.split("=")
|
277
|
-
linkresult = link.link(result["key"],remoteIssue,linktype)
|
278
|
-
end
|
279
|
-
return 0
|
280
|
-
elsif result["errors"] then
|
281
|
-
puts "An error occured. The error message was: #{result["errors"].to_s}"
|
282
|
-
return 2
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
|
287
|
-
# The "main function"
|
288
|
-
if @scriptopts.show != [] then
|
289
|
-
show_scheme
|
290
|
-
end
|
291
|
-
if ! @issueopts.content.nil? then # If the -c option is set. (-c and no content leads to another exception)
|
292
|
-
content = prepare_new_ticket
|
293
|
-
exit create_new_ticket(content)
|
294
|
-
end
|
20
|
+
puts "File has been renamed to jira_create_issue.rb"
|
21
|
+
newfile = File.dirname($0) + "/jira_create_issue.rb"
|
22
|
+
puts "Please use: #{newfile} #{$*.join(" ")}"
|
295
23
|
|
@@ -0,0 +1,366 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Script to create a new issue with jira.
|
4
|
+
# Copyright (C) 2012 Cyril Bitterich
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
if RUBY_VERSION < "1.9"
|
23
|
+
puts "Sorry, I need ruby 1.9.1 or higher!"
|
24
|
+
exit1
|
25
|
+
end
|
26
|
+
|
27
|
+
require "highline/import"
|
28
|
+
require "jirarest2"
|
29
|
+
require "optparse"
|
30
|
+
require "ostruct"
|
31
|
+
require "madbitconfig"
|
32
|
+
require "uri"
|
33
|
+
require "pp"
|
34
|
+
|
35
|
+
class ParseOptions
|
36
|
+
|
37
|
+
def self.required_argument(name)
|
38
|
+
puts "Argument \"#{name}\" is mandatory."
|
39
|
+
exit 1
|
40
|
+
end
|
41
|
+
|
42
|
+
=begin
|
43
|
+
parse resturn two Hashes. The first one contains the options for the issue the second one the options for the execution of the script.
|
44
|
+
=end
|
45
|
+
def self.parse(args)
|
46
|
+
issueopts = OpenStruct.new
|
47
|
+
issueopts.project = nil
|
48
|
+
issueopts.issue = nil
|
49
|
+
scriptopts = OpenStruct.new
|
50
|
+
scriptopts.show = []
|
51
|
+
scriptopts.arrayseperator = "|"
|
52
|
+
scriptopts.configfile = "~/.jiraconfig"
|
53
|
+
|
54
|
+
opts = OptionParser.new do |opts|
|
55
|
+
opts.banner = "Usage: #{__FILE__} [options]"
|
56
|
+
opts.separator ""
|
57
|
+
|
58
|
+
opts.on("-p", "--project PROJECT", "Projectname") do |p|
|
59
|
+
issueopts.project = p
|
60
|
+
issueopts
|
61
|
+
end
|
62
|
+
|
63
|
+
opts.on("-i", "--issue ISSUETYPE", "Issuetype") do |i|
|
64
|
+
issueopts.issue = i
|
65
|
+
end
|
66
|
+
|
67
|
+
opts.on("-f", "--fields", "Display the fields available for this issue") do |f|
|
68
|
+
scriptopts.show << "fields"
|
69
|
+
end
|
70
|
+
|
71
|
+
opts.on("-r", "--requireds", "Display the the mandatory content fields for this issue") do |r|
|
72
|
+
scriptopts.show << "requireds"
|
73
|
+
end
|
74
|
+
|
75
|
+
opts.on("-c", "--content x=value,y=value,z=value", Array, "List of fields to fill") do |list|
|
76
|
+
issueopts.content = list
|
77
|
+
end
|
78
|
+
|
79
|
+
opts.on("-w", "--watcher USERNAME,USERNAME", Array, "List of watchers") do |w|
|
80
|
+
issueopts.watchers = w
|
81
|
+
end
|
82
|
+
|
83
|
+
opts.on("-l", "--link ISSUE=LINKTYPE", "Key of an Issue this issue should be linked to" ) do |l|
|
84
|
+
issueopts.link = l
|
85
|
+
end
|
86
|
+
|
87
|
+
opts.on("-F", "--field-seperator CHAR", "A fieldseperator if one of the fields is an array (Default \"|\")") do |fs|
|
88
|
+
scriptopts.arrayseperator = fs
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
opts.on("--config-file CONFIGFILE", "Config file containing the jira credentials. (Default: ~/.jiraconfig)") do |conffile|
|
93
|
+
scriptopts.configfile = conffile
|
94
|
+
end
|
95
|
+
|
96
|
+
opts.on("--write-config-file", "Writes the configfile with the data given if it does not alredy exist.") do |wc|
|
97
|
+
scriptopts.writeconf = :write
|
98
|
+
end
|
99
|
+
|
100
|
+
opts.on("--force-write-config-file", "Writes the configfile with the data given even if it does alredy exist.") do |wc|
|
101
|
+
scriptopts.writeconf = :forcewrite
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
opts.on("-u", "--username USERNAME", "Your Jira Username if you don't want to use the one in the master file") do |u|
|
106
|
+
scriptopts.username = u
|
107
|
+
end
|
108
|
+
|
109
|
+
opts.on("-H", "--jira-url URL", "URL to rest api (without \"/rest/api/2\").") do |url|
|
110
|
+
uri = URI(url)
|
111
|
+
splitURI = URI.split(url)
|
112
|
+
if splitURI[3] then
|
113
|
+
url = splitURI[0].to_s + "://" + splitURI[2].to_s + ":" + splitURI[3].to_s + splitURI[5].to_s
|
114
|
+
else
|
115
|
+
url = splitURI[0].to_s + "://" + splitURI[2].to_s + splitURI[5].to_s
|
116
|
+
end
|
117
|
+
scriptopts.url = url
|
118
|
+
end
|
119
|
+
|
120
|
+
opts.on_tail("-h", "--help", "Display this screen") do
|
121
|
+
puts opts
|
122
|
+
exit
|
123
|
+
end
|
124
|
+
|
125
|
+
opts.on_tail("--version", "Show version") do
|
126
|
+
puts OptionParser::Version.join(".")
|
127
|
+
exit
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
opts.parse!(args)
|
133
|
+
|
134
|
+
if issueopts.project.nil? && scriptopts.writeconf.nil? then
|
135
|
+
required_argument("project")
|
136
|
+
end
|
137
|
+
if issueopts.issue.nil? && scriptopts.writeconf.nil? then
|
138
|
+
required_argument("issue")
|
139
|
+
end
|
140
|
+
return issueopts, scriptopts
|
141
|
+
end #parse()
|
142
|
+
|
143
|
+
|
144
|
+
end # class ParseOptions
|
145
|
+
|
146
|
+
@issueopts, @scriptopts = ParseOptions.parse(ARGV)
|
147
|
+
|
148
|
+
|
149
|
+
def no_issue(type,issue)
|
150
|
+
puts "The #{type}type you entered (\"#{issue}\") does no exist."
|
151
|
+
puts "Maybe you entered the wrong type or made a typo? (Case is relevant!)"
|
152
|
+
exit 1
|
153
|
+
end
|
154
|
+
|
155
|
+
=begin
|
156
|
+
Get the password from an interactive shell
|
157
|
+
=end
|
158
|
+
def get_password
|
159
|
+
ask("Enter your password for user \"#{@scriptopts.username}\": ") { |q|
|
160
|
+
q.echo = "*"
|
161
|
+
}
|
162
|
+
end
|
163
|
+
|
164
|
+
=begin
|
165
|
+
Gather all the credentials and build the credentials file
|
166
|
+
=end
|
167
|
+
def get_credentials
|
168
|
+
filefail = false
|
169
|
+
begin
|
170
|
+
fileconf = MadbitConfig::read_configfile(@scriptopts.configfile)
|
171
|
+
# We don't want to set the Values from the configfile if we have them already set.
|
172
|
+
@scriptopts.username = fileconf["username"] if ( @scriptopts.username.nil? && fileconf["username"] )
|
173
|
+
@scriptopts.pass = fileconf["password"] if ( @scriptopts.pass.nil? && fileconf["password"] )
|
174
|
+
if ( @scriptopts.url.nil? && fileconf["URL"] ) then
|
175
|
+
@scriptopts.url = fileconf["URL"]
|
176
|
+
end
|
177
|
+
rescue IOError => e
|
178
|
+
puts e
|
179
|
+
filefail = false
|
180
|
+
end
|
181
|
+
@scriptopts.url = @scriptopts.url + "/rest/api/2/"
|
182
|
+
|
183
|
+
|
184
|
+
if @scriptopts.pass.nil? && !( @scriptopts.username.nil?) then
|
185
|
+
@scriptopts.pass = get_password
|
186
|
+
end
|
187
|
+
|
188
|
+
missing = Array.new
|
189
|
+
missing << "URL" if @scriptopts.url.nil?
|
190
|
+
missing << "username" if @scriptopts.username.nil?
|
191
|
+
# missing << "password" if @scriptopts.pass.nil?
|
192
|
+
if missing != [] then
|
193
|
+
puts "Missing essential parameter(s) #{missing.join(",")}. Exiting..."
|
194
|
+
exit 1
|
195
|
+
else
|
196
|
+
return Credentials.new(@scriptopts.url, @scriptopts.username, @scriptopts.pass)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
=begin
|
201
|
+
If there is already a conenction known returns that connection. If not or if the parameter is true it tries to create a new Connect object
|
202
|
+
=end
|
203
|
+
def get_connection(reconnect = false)
|
204
|
+
if ! @connection || reconnect then
|
205
|
+
begin
|
206
|
+
@connection = Connect.new(get_credentials)
|
207
|
+
@connection.heal_uri! # We want to be sure so we try to heal the connection_url if possible
|
208
|
+
return @connection
|
209
|
+
rescue Jirarest2::CouldNotHealURIError => e
|
210
|
+
puts "REST API not found at #{e.to_s}"
|
211
|
+
exit 3
|
212
|
+
end
|
213
|
+
else
|
214
|
+
return @connection
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
=begin
|
219
|
+
create the issue on our side
|
220
|
+
=end
|
221
|
+
def open_issue
|
222
|
+
begin
|
223
|
+
credentials = get_credentials
|
224
|
+
issue=Issue.new(@issueopts.project,@issueopts.issue,get_connection)
|
225
|
+
rescue Jirarest2::AuthentificationError => e
|
226
|
+
puts "Password not accepted."
|
227
|
+
@scriptopts.pass = get_password
|
228
|
+
retry
|
229
|
+
rescue Jirarest2::AuthentificationCaptchaError => e
|
230
|
+
puts "Wrong Password too many times.\nCaptcha time at #{e.to_s} to reenable your account."
|
231
|
+
exit 1
|
232
|
+
rescue Jirarest2::WrongProjectException => e
|
233
|
+
no_issue("project",e)
|
234
|
+
rescue Jirarest2::WrongIssuetypeException => e
|
235
|
+
no_issue("project",e)
|
236
|
+
end
|
237
|
+
return issue
|
238
|
+
end
|
239
|
+
|
240
|
+
=begin
|
241
|
+
Show available fields and required fields
|
242
|
+
=end
|
243
|
+
def show_scheme
|
244
|
+
issue = open_issue
|
245
|
+
if @scriptopts.show.include?("fields") then
|
246
|
+
print "Available fields: "
|
247
|
+
puts issue.get_fieldnames.join(", ")
|
248
|
+
end
|
249
|
+
if @scriptopts.show.include?("requireds") then
|
250
|
+
print "Required fields: "
|
251
|
+
puts issue.get_requireds.join(", ")
|
252
|
+
end
|
253
|
+
exit
|
254
|
+
end
|
255
|
+
|
256
|
+
=begin
|
257
|
+
Prepare a new ticket. It will not be persisted yet.
|
258
|
+
=end
|
259
|
+
def prepare_new_ticket
|
260
|
+
issue = open_issue
|
261
|
+
valueNotAllowedRaised = false
|
262
|
+
@issueopts.content.each { |value|
|
263
|
+
split = value.split("=")
|
264
|
+
begin
|
265
|
+
if issue.fieldtype(split[0]) == "array" then # If the fieldtype is an array we want to use our arrayseparator to split the fields
|
266
|
+
if ! split[1].nil? then
|
267
|
+
split[1] = split[1].split(@scriptopts.arrayseperator)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
issue.set_field(split[0],split[1])
|
271
|
+
rescue Jirarest2::WrongFieldnameException => e
|
272
|
+
no_issue("field",e)
|
273
|
+
rescue Jirarest2::ValueNotAllowedException => e
|
274
|
+
puts "Value #{split[1]} not allowed for field #{split[0]}."
|
275
|
+
puts "Please use one of: \"" + e.message.join("\", \"") + "\""
|
276
|
+
valueNotAllowedRaised = true
|
277
|
+
end
|
278
|
+
}
|
279
|
+
if valueNotAllowedRaised then
|
280
|
+
raise Jirarest2::ValueNotAllowedException
|
281
|
+
end
|
282
|
+
return issue
|
283
|
+
end
|
284
|
+
|
285
|
+
=begin
|
286
|
+
a little bit to fine - could be put into the method below
|
287
|
+
=end
|
288
|
+
def set_watchers(issue)
|
289
|
+
issue.set_watcher(credentials,@issueopts.watchers)
|
290
|
+
end
|
291
|
+
|
292
|
+
=begin
|
293
|
+
do all the work to actually create a new ticket (persist, watchers, links)
|
294
|
+
=end
|
295
|
+
def create_new_ticket(issue)
|
296
|
+
begin
|
297
|
+
connection = get_connection # We need it so often in the next few lines that I prefer to get the result in a variable
|
298
|
+
result = issue.persist(connection).result
|
299
|
+
# Set the watchers
|
300
|
+
if @issueopts.watchers then
|
301
|
+
watcherssuccess = issue.add_watchers(connection,@issueopts.watchers)
|
302
|
+
end
|
303
|
+
rescue Jirarest2::RequiredFieldNotSetException => e
|
304
|
+
puts "Required field \"#{e.to_s}\" not set."
|
305
|
+
return 1
|
306
|
+
end
|
307
|
+
if result["key"] then
|
308
|
+
puts "Created new issue with issue id #{result["key"]} ."
|
309
|
+
if ! watcherssuccess && @issueopts.watchers then
|
310
|
+
puts "Watchers could not be set though."
|
311
|
+
end
|
312
|
+
if @issueopts.link then
|
313
|
+
link = IssueLink.new(connection)
|
314
|
+
remoteIssue,linktype = @issueopts.link.split("=")
|
315
|
+
linkresult = link.link(result["key"],remoteIssue,linktype)
|
316
|
+
end
|
317
|
+
return 0
|
318
|
+
elsif result["errors"] then
|
319
|
+
puts "An error occured. The error message was: #{result["errors"].to_s}"
|
320
|
+
return 2
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
=begin
|
325
|
+
called to write the config file
|
326
|
+
=end
|
327
|
+
def write_configfile
|
328
|
+
text = Hash.new
|
329
|
+
if @scriptopts.url.nil? then
|
330
|
+
text["#URL"] = "https://host.domain.com:port/path/"
|
331
|
+
else
|
332
|
+
text["URL"] = "#{@scriptopts.url}"
|
333
|
+
end
|
334
|
+
if @scriptopts.username.nil? then
|
335
|
+
text["#username"] = "USERNAME"
|
336
|
+
else
|
337
|
+
text["username"] = "#{@scriptopts.username}"
|
338
|
+
end
|
339
|
+
text["#password"] = "Your!PassW0rd"
|
340
|
+
begin
|
341
|
+
if @scriptopts.writeconf == :forcewrite then
|
342
|
+
MadbitConfig::write_configfile(@scriptopts.configfile,text,:force)
|
343
|
+
else
|
344
|
+
MadbitConfig::write_configfile(@scriptopts.configfile,text)
|
345
|
+
end
|
346
|
+
puts "Configfile written to #{@scriptopts.configfile}. Exiting."
|
347
|
+
exit 0
|
348
|
+
rescue MadbitConfig::FileExistsException => e
|
349
|
+
puts "Configfile #{e} already exists. Use \"--force-write-config-file\" to replace."
|
350
|
+
exit 1
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
|
355
|
+
# The "main function"
|
356
|
+
if @scriptopts.show != [] then
|
357
|
+
show_scheme
|
358
|
+
end
|
359
|
+
if @scriptopts.writeconf then
|
360
|
+
write_configfile
|
361
|
+
end
|
362
|
+
if ! @issueopts.content.nil? then # If the -c option is set. (-c and no content leads to another exception)
|
363
|
+
content = prepare_new_ticket
|
364
|
+
exit create_new_ticket(content)
|
365
|
+
end
|
366
|
+
|