jirarest2 0.0.6 → 0.0.7

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.
@@ -17,374 +17,7 @@
17
17
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
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("-C", "--content-file FILENAME", "JSON formatted file (or \"-\" for STDIN) with the contents of -c (Pipes work only if URL,username AND password are in the CONFIGFILE!)") do |contentfile|
80
- scriptopts.contentfile = contentfile
81
- end
82
-
83
- opts.on("-w", "--watcher USERNAME,USERNAME", Array, "List of watchers") do |w|
84
- issueopts.watchers = w
85
- end
86
-
87
- opts.on("-l", "--link ISSUE=LINKTYPE", "Key of an Issue this issue should be linked to" ) do |l|
88
- issueopts.link = l
89
- end
90
-
91
- opts.on("-F", "--field-seperator CHAR", "A fieldseperator if one of the fields is an array (Default \"|\")") do |fs|
92
- scriptopts.arrayseperator = fs
93
- end
94
-
95
-
96
- opts.on("--config-file CONFIGFILE", "Config file containing the jira credentials. (Default: ~/.jiraconfig)") do |conffile|
97
- scriptopts.configfile = conffile
98
- end
99
-
100
- opts.on("--write-config-file", "Writes the configfile with the data given if it does not alredy exist.") do |wc|
101
- scriptopts.writeconf = :write
102
- end
103
-
104
- opts.on("--force-write-config-file", "Writes the configfile with the data given even if it does alredy exist.") do |wc|
105
- scriptopts.writeconf = :forcewrite
106
- end
107
-
108
-
109
- opts.on("-u", "--username USERNAME", "Your Jira Username if you don't want to use the one in the master file") do |u|
110
- scriptopts.username = u
111
- end
112
-
113
- opts.on("-H", "--jira-url URL", "URL to rest api (without \"/rest/api/2\").") do |url|
114
- uri = URI(url)
115
- splitURI = URI.split(url)
116
- if splitURI[3] then
117
- url = splitURI[0].to_s + "://" + splitURI[2].to_s + ":" + splitURI[3].to_s + splitURI[5].to_s
118
- else
119
- url = splitURI[0].to_s + "://" + splitURI[2].to_s + splitURI[5].to_s
120
- end
121
- scriptopts.url = url
122
- end
123
-
124
- opts.on_tail("-h", "--help", "Display this screen") do
125
- puts opts
126
- exit
127
- end
128
-
129
- opts.on_tail("--version", "Show version") do
130
- puts OptionParser::Version.join(".")
131
- exit
132
- end
133
- end
134
-
135
-
136
- opts.parse!(args)
137
-
138
- if issueopts.project.nil? && scriptopts.writeconf.nil? then
139
- required_argument("project")
140
- end
141
- if issueopts.issue.nil? && scriptopts.writeconf.nil? then
142
- required_argument("issue")
143
- end
144
- return issueopts, scriptopts
145
- end #parse()
146
-
147
-
148
- end # class ParseOptions
149
-
150
- @issueopts, @scriptopts = ParseOptions.parse(ARGV)
151
-
152
-
153
- def no_issue(type,issue)
154
- puts "The #{type}type you entered (\"#{issue}\") does no exist."
155
- puts "Maybe you entered the wrong type or made a typo? (Case is relevant!)"
156
- exit 1
157
- end
158
-
159
- =begin
160
- Get the password from an interactive shell
161
- =end
162
- def get_password
163
- ask("Enter your password for user \"#{@scriptopts.username}\": ") { |q|
164
- q.echo = "*"
165
- }
166
- end
167
-
168
- =begin
169
- Gather all the credentials and build the credentials file
170
- =end
171
- def get_credentials
172
- filefail = false
173
- begin
174
- fileconf = MadbitConfig::read_configfile(@scriptopts.configfile)
175
- # We don't want to set the Values from the configfile if we have them already set.
176
- @scriptopts.username = fileconf["username"] if ( @scriptopts.username.nil? && fileconf["username"] )
177
- @scriptopts.pass = fileconf["password"] if ( @scriptopts.pass.nil? && fileconf["password"] )
178
- if ( @scriptopts.url.nil? && fileconf["URL"] ) then
179
- @scriptopts.url = fileconf["URL"]
180
- end
181
- rescue IOError => e
182
- puts e
183
- filefail = false
184
- end
185
- @scriptopts.url = @scriptopts.url + "/rest/api/2/"
186
-
187
-
188
- if @scriptopts.pass.nil? && !( @scriptopts.username.nil?) then
189
- @scriptopts.pass = get_password
190
- end
191
-
192
- missing = Array.new
193
- missing << "URL" if @scriptopts.url.nil?
194
- missing << "username" if @scriptopts.username.nil?
195
- # missing << "password" if @scriptopts.pass.nil?
196
- if missing != [] then
197
- puts "Missing essential parameter(s) #{missing.join(",")}. Exiting..."
198
- exit 1
199
- else
200
- return Credentials.new(@scriptopts.url, @scriptopts.username, @scriptopts.pass)
201
- end
202
- end
203
-
204
- =begin
205
- 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
206
- =end
207
- def get_connection(reconnect = false)
208
- if ! @connection || reconnect then
209
- begin
210
- @connection = Connect.new(get_credentials)
211
- @connection.heal_uri! # We want to be sure so we try to heal the connection_url if possible
212
- return @connection
213
- rescue Jirarest2::CouldNotHealURIError => e
214
- puts "REST API not found at #{e.to_s}"
215
- exit 3
216
- end
217
- else
218
- return @connection
219
- end
220
- end
221
-
222
- =begin
223
- create the issue on our side
224
- =end
225
- def open_issue
226
- begin
227
- credentials = get_credentials
228
- issue=Issue.new(@issueopts.project,@issueopts.issue,get_connection)
229
- rescue Jirarest2::AuthentificationError => e
230
- puts "Password not accepted."
231
- @scriptopts.pass = get_password
232
- retry
233
- rescue Jirarest2::AuthentificationCaptchaError => e
234
- puts "Wrong Password too many times.\nCaptcha time at #{e.to_s} to reenable your account."
235
- exit 1
236
- rescue Jirarest2::WrongProjectException => e
237
- no_issue("project",e)
238
- rescue Jirarest2::WrongIssuetypeException => e
239
- no_issue("project",e)
240
- end
241
- return issue
242
- end
243
-
244
- =begin
245
- Show available fields and required fields
246
- =end
247
- def show_scheme
248
- issue = open_issue
249
- if @scriptopts.show.include?("fields") then
250
- print "Available fields: "
251
- puts issue.get_fieldnames.join(", ")
252
- end
253
- if @scriptopts.show.include?("requireds") then
254
- print "Required fields: "
255
- puts issue.get_requireds.join(", ")
256
- end
257
- exit
258
- end
259
-
260
- # Split the content from the command line parameter "-c"
261
- def split_content(issue)
262
- fields = Hash.new
263
- @issueopts.content.each { |value|
264
- split = value.split("=")
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
- fields[split[0]] = split[1]
271
- }
272
- return fields
273
- end
274
-
275
- # Prepare a new ticket. It will not be persisted yet.
276
- def prepare_new_ticket
277
- issue = open_issue
278
- begin
279
- if @scriptopts.contentfile then
280
- #Input from file or STDIN
281
- puts "Your Input now"
282
- fields = MadbitConfig::read_configfile(@scriptopts.contentfile)
283
- else
284
- #Input from the command line
285
- fields = split_content(issue)
286
- end
287
- valueNotAllowedRaised = false
288
- fields.each { |name,value|
289
- issue.set_field(name,value)
290
- }
291
- rescue JSON::ParserError => e
292
- raise JSON::ParserError, e # Maybe I want to make this nice sometimes
293
- rescue Jirarest2::WrongFieldnameException => e
294
- no_issue("field",e)
295
- rescue Jirarest2::ValueNotAllowedException => e
296
- puts "Value #{split[1]} not allowed for field #{split[0]}."
297
- puts "Please use one of: \"" + e.message.join("\", \"") + "\""
298
- valueNotAllowedRaised = true
299
- end
300
- =begin
301
- }
302
- =end
303
- if valueNotAllowedRaised then
304
- raise Jirarest2::ValueNotAllowedException
305
- end
306
- return issue
307
- end
308
-
309
- =begin
310
- a little bit to fine - could be put into the method below
311
- =end
312
- def set_watchers(issue)
313
- issue.set_watcher(credentials,@issueopts.watchers)
314
- end
315
-
316
- =begin
317
- do all the work to actually create a new ticket (persist, watchers, links)
318
- =end
319
- def create_new_ticket(issue)
320
- begin
321
- connection = get_connection # We need it so often in the next few lines that I prefer to get the result in a variable
322
- result = issue.persist(connection).result
323
- # Set the watchers
324
- if @issueopts.watchers then
325
- watcherssuccess = issue.add_watchers(connection,@issueopts.watchers)
326
- end
327
- rescue Jirarest2::RequiredFieldNotSetException => e
328
- puts "Required field \"#{e.to_s}\" not set."
329
- return 1
330
- end
331
- if result["key"] then
332
- puts "Created new issue with issue id #{result["key"]} ."
333
- if ! watcherssuccess && @issueopts.watchers then
334
- puts "Watchers could not be set though."
335
- end
336
- if @issueopts.link then
337
- link = IssueLink.new(connection)
338
- remoteIssue,linktype = @issueopts.link.split("=")
339
- linkresult = link.link(result["key"],remoteIssue,linktype)
340
- end
341
- return 0
342
- elsif result["errors"] then
343
- puts "An error occured. The error message was: #{result["errors"].to_s}"
344
- return 2
345
- end
346
- end
347
-
348
- =begin
349
- called to write the config file
350
- =end
351
- def write_configfile
352
- text = Hash.new
353
- if @scriptopts.url.nil? then
354
- text["#URL"] = "https://host.domain.com:port/path/"
355
- else
356
- text["URL"] = "#{@scriptopts.url}"
357
- end
358
- if @scriptopts.username.nil? then
359
- text["#username"] = "USERNAME"
360
- else
361
- text["username"] = "#{@scriptopts.username}"
362
- end
363
- text["#password"] = "Your!PassW0rd"
364
- begin
365
- if @scriptopts.writeconf == :forcewrite then
366
- MadbitConfig::write_configfile(@scriptopts.configfile,text,:force)
367
- else
368
- MadbitConfig::write_configfile(@scriptopts.configfile,text)
369
- end
370
- puts "Configfile written to #{@scriptopts.configfile}. Exiting."
371
- exit 0
372
- rescue MadbitConfig::FileExistsException => e
373
- puts "Configfile #{e} already exists. Use \"--force-write-config-file\" to replace."
374
- exit 1
375
- end
376
- end
377
-
378
-
379
- # The "main function"
380
- if @scriptopts.show != [] then
381
- show_scheme
382
- end
383
- if @scriptopts.writeconf then
384
- write_configfile
385
- end
386
- if ! @issueopts.content.nil? then # If the -c option is set. (-c and no content leads to another exception)
387
- content = prepare_new_ticket
388
- exit create_new_ticket(content)
389
- end
20
+ puts "File has been renamed to jira_create_issue"
21
+ newfile = File.dirname($0) + "/jira_create_issue"
22
+ puts "Please use: #{newfile} #{$*.join(" ")}"
390
23
 
@@ -17,12 +17,12 @@
17
17
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
- VERSION = "0.0.6"
20
+ VERSION = "0.0.7"
21
21
 
22
- require_relative "connect"
23
- require_relative "issue"
24
- require_relative "credentials"
25
- require_relative "exceptions"
26
- require_relative "services/watcher"
27
- require_relative "services"
28
- require_relative "services/issuelink"
22
+ require_relative "jirarest2/connect"
23
+ require_relative "jirarest2/issue"
24
+ require_relative "jirarest2/credentials"
25
+ require_relative "jirarest2/exceptions"
26
+ require_relative "jirarest2/services/watcher"
27
+ require_relative "jirarest2/services"
28
+ require_relative "jirarest2/services/issuelink"
@@ -17,7 +17,7 @@
17
17
 
18
18
 
19
19
  require 'net/http'
20
- require 'exceptions'
20
+ require 'jirarest2/exceptions'
21
21
  require 'jirarest2/result'
22
22
  require "pp"
23
23
 
@@ -47,14 +47,14 @@ class Issue
47
47
  @issuetype = ""
48
48
  jhash["projects"].each { |value|
49
49
  @project = value["key"]
50
- value["issuetypes"].each { |value|
51
- @issuetype = value["name"]
52
- value["fields"].delete("project") #The project key is duplicate and will make us live harder afterwards. It is marked as required but nothing happens if this key is not set.
53
- value["fields"].each { |key,value|
50
+ value["issuetypes"].each { |value1|
51
+ @issuetype = value1["name"]
52
+ value1["fields"].delete("project") #The project key is duplicate and will make us live harder afterwards. It is marked as required but nothing happens if this key is not set.
53
+ value1["fields"].each { |key,value2|
54
54
  fields = Hash.new
55
55
  fields["id"] = key
56
- if value["name"] then
57
- name = value["name"]
56
+ if value2["name"] then
57
+ name = value2["name"]
58
58
  else
59
59
  name = key
60
60
  end
@@ -62,22 +62,22 @@ class Issue
62
62
  if value["allowedValues"] then
63
63
  # With custom fields the identifier is "value" with the built in ones it's "name"
64
64
  identifier = "name"
65
- if value["schema"]["custom"] then
65
+ if value2["schema"]["custom"] then
66
66
  identifier = "value"
67
67
  end
68
68
  allowedValues = Array.new
69
- value["allowedValues"].each { |value|
70
- allowedValues << value[identifier]
71
- }
69
+ value2["allowedValues"].each { |value3|
70
+ allowedValues << value3[identifier]
71
+ } # value3
72
72
  fields["allowedValuesIdentifier"] = identifier
73
73
  fields["allowedValues"] = allowedValues
74
74
  end
75
- fields["required"] = value["required"]
76
- fields["type"] = value["schema"]["type"]
75
+ fields["required"] = value2["required"]
76
+ fields["type"] = value2["schema"]["type"]
77
77
  @issuefields[name] = fields if name != "Issue Type" # "Issue Type" is not really a required field as we have to assign it at another place anyway
78
- }
79
- }
80
- }
78
+ } # value1
79
+ } # value
80
+ } # jhash
81
81
  end
82
82
 
83
83
  # @param [String] field Name of the field