jirarest2 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,37 @@
1
+ === 0.0.3 / 2012-07-16
2
+
3
+ * 2 major enhancements:
4
+
5
+ * Added support for linked issues
6
+ * Changed the delemiter for the "-c" (content) parameter of create_issue.rb from ":" to "=" to allow for Time fields
7
+
8
+ * 1 minor enhancement:
9
+
10
+ * Moved watcher.rb in directory service (not sure if the superclass really makes sense so)
11
+
12
+
13
+ === 0.0.2 / 2012-07-15
14
+
15
+ * 3 major enhancements:
16
+
17
+ * Added watchers to the mix. create_issue can work them now.
18
+ * Connect returns a Jirarest2::Result object now to keep the HTTP statuscodes
19
+ * Added the execute method that should get rid of get_post_response, get_get_response ...
20
+
21
+ * 3 minor enhancements:
22
+
23
+ * More documentation
24
+ * cleanup
25
+ * refactored connect to make it easier for new classes
26
+
27
+
28
+ * 1 bug fix:
29
+
30
+ * Return status codes now work as expected. (They are strings after all)
31
+
32
+ === 0.0.1 / 2012-07-12
33
+
34
+ * 1 major enhancement
35
+
36
+ * Switch to hoe and to github
37
+
@@ -0,0 +1,28 @@
1
+ .autotest
2
+ GPLv3
3
+ History.txt
4
+ Manifest.txt
5
+ README.md
6
+ README.txt
7
+ Rakefile
8
+ bin/create_issue.rb
9
+ header.copyright
10
+ lib/config.rb
11
+ lib/connect.rb
12
+ lib/credentials.rb
13
+ lib/exceptions.rb
14
+ lib/issue.rb
15
+ lib/issuelink.rb
16
+ lib/jirarest2.rb
17
+ lib/jirarest2/result.rb
18
+ lib/services.rb
19
+ lib/services/issuelink.rb
20
+ lib/services/issuelinktype.rb
21
+ lib/services/watcher.rb
22
+ test/test_connect.rb
23
+ test/test_credentials.rb
24
+ test/test_issue.rb
25
+ test/test_issuelink.rb
26
+ test/test_issuelinktype.rb
27
+ test/test_result.rb
28
+ test/test_watcher.rb
@@ -0,0 +1,8 @@
1
+ jirarest2
2
+ =========
3
+
4
+ Another ruby gem for the REST2 interface of JIRA(tm)
5
+
6
+ This is still a very early alpha state and a lot of features are not yet implemented. Classes and their work might undergo major changes. (especially "Issue")
7
+
8
+ What works is the creation of issues with easy field types and watchers.
@@ -0,0 +1,53 @@
1
+ = jirarest2
2
+
3
+ * https://github.com/cybit/jirarest2#readme
4
+
5
+ == DESCRIPTION:
6
+
7
+ jirarest2 is yet another implementation of the JIRA(tm) REST api ( https://developer.atlassian.com/display/JIRADEV/JIRA+Remote+API+Reference ).
8
+ It is intended to be called within the shell to create and verify JIRA(tm) issues fast without a browser.
9
+ This implementation is still a for cry from others like http://rubygems.org/gems/jira-ruby which required oauth authentification.
10
+ Use it at your own risk most of the API features are not implemented.
11
+
12
+
13
+ == FEATURES/PROBLEMS:
14
+
15
+ Still in the very first alpha stages. You can only create new issues with watchers.
16
+
17
+ == SYNOPSIS:
18
+
19
+ create_issue -h
20
+
21
+ == REQUIREMENTS:
22
+
23
+ * json
24
+ * highline
25
+
26
+ == INSTALL:
27
+
28
+ sudo gem install jirarest2
29
+
30
+ == DEVELOPERS:
31
+
32
+ Cyril Bitterich
33
+
34
+ == LICENSE:
35
+
36
+ (GPLv3)
37
+
38
+ Copyright (c) 2012 Cyril Bitterich
39
+
40
+
41
+ This program is free software: you can redistribute it and/or modify
42
+ it under the terms of the GNU General Public License as published by
43
+ the Free Software Foundation, either version 3 of the License, or
44
+ (at your option) any later version.
45
+
46
+ This program is distributed in the hope that it will be useful,
47
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
48
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49
+ GNU General Public License for more details.
50
+
51
+ You should have received a copy of the GNU General Public License
52
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
53
+
@@ -0,0 +1,30 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ # Hoe.plugin :compiler
7
+ # Hoe.plugin :cucumberfeatures
8
+ Hoe.plugin :doofus
9
+ # Hoe.plugin :gem_prelude_sucks
10
+ # Hoe.plugin :gemspec
11
+ # Hoe.plugin :git
12
+ # Hoe.plugin :inline
13
+ # Hoe.plugin :manifest
14
+ # Hoe.plugin :newgem
15
+ # Hoe.plugin :racc
16
+ # Hoe.plugin :rcov
17
+ # Hoe.plugin :rubyforge
18
+ # Hoe.plugin :rubygems
19
+ # Hoe.plugin :website
20
+
21
+ Hoe.spec 'jirarest2' do
22
+ developer('Cyril Bitterich', 'cebit-jirarest@gunnet.de')
23
+
24
+ extra_deps << ['json', ">= 1.6.0"]
25
+ extra_deps << ['highline', ">= 1.1.0"]
26
+
27
+ # self.rubyforge_name = 'jirarest2x' # if different than 'jirarest2'
28
+ end
29
+
30
+ # vim: syntax=ruby
@@ -0,0 +1,270 @@
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 "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 connect to jira in the browser") do |url|
101
+ uri = URI(URL)
102
+ scriptopts.url = uri.schme + "://" + uri.host + uri.port
103
+ end
104
+
105
+ opts.on_tail("-h", "--help", "Display this screen") do
106
+ puts opts
107
+ exit
108
+ end
109
+
110
+ opts.on_tail("--version", "Show version") do
111
+ puts OptionParser::Version.join(".")
112
+ exit
113
+ end
114
+ end
115
+
116
+
117
+ opts.parse!(args)
118
+
119
+ if issueopts.project.nil? then
120
+ required_argument("project")
121
+ end
122
+ if issueopts.issue.nil? then
123
+ required_argument("issue")
124
+ end
125
+ return issueopts, scriptopts
126
+ end #parse()
127
+
128
+
129
+ end # class ParseOptions
130
+
131
+ @issueopts, @scriptopts = ParseOptions.parse(ARGV)
132
+
133
+
134
+
135
+
136
+ def no_issue(type,issue)
137
+ puts "The #{type}type you entered (\"#{issue}\") does no exist."
138
+ puts "Maybe you entered the wrong type or made a typo? (Case is relevant!)"
139
+ exit 1
140
+ end
141
+
142
+ def get_password
143
+ ask("Enter your password for user \"#{@scriptopts.username}\": ") { |q| q.echo = "*" }
144
+ end
145
+
146
+ =begin
147
+ Gather all the credentials and build the credentials file
148
+ =end
149
+ def get_credentials
150
+ fileconf = Config::read_configfile(@scriptopts.configfile)
151
+ # We don't want to set the calues from the configfile if we have them already set.
152
+ @scriptopts.username = fileconf["username"] if ( @scriptopts.username.nil? && fileconf["username"] )
153
+ @scriptopts.pass = fileconf["password"] if ( @scriptopts.pass.nil? && fileconf["password"] )
154
+ if ( @scriptopts.url.nil? && fileconf["URL"] ) then
155
+ @scriptopts.url = fileconf["URL"]
156
+ @scriptopts.url = @scriptopts.url + "/jira/rest/api/2/"
157
+ end
158
+ if @scriptopts.pass.nil? then
159
+ @scriptopts.pass = get_password
160
+ end
161
+
162
+ return Credentials.new(@scriptopts.url, @scriptopts.username, @scriptopts.pass)
163
+ end
164
+
165
+ =begin
166
+ create the issue on our side
167
+ =end
168
+ def open_issue
169
+ begin
170
+ credentials = get_credentials
171
+ issue=Issue.new(@issueopts.project,@issueopts.issue,credentials)
172
+ # issue=Issue.new(@issueopts.project,@issueopts.issue,@scriptopts.pass,@scriptopts.username)
173
+ rescue Jirarest2::AuthentificationError => e
174
+ puts "Password not accepted."
175
+ @scriptopts.pass = get_password
176
+ retry
177
+ rescue Jirarest2::AuthentificationCaptchaError => e
178
+ puts "Wrong Password too many times.\nCaptcha time at #{e.to_s} to reenable your account."
179
+ exit 1
180
+ rescue Jirarest2::WrongProjectException => e
181
+ no_issue("project",e)
182
+ rescue Jirarest2::WrongIssuetypeException => e
183
+ no_issue("project",e)
184
+ end
185
+ return issue
186
+ end
187
+
188
+ def show_scheme
189
+ issue = open_issue
190
+ if @scriptopts.show.include?("fields") then
191
+ print "Available fields: "
192
+ puts issue.get_fieldnames.join(", ")
193
+ end
194
+ if @scriptopts.show.include?("requireds") then
195
+ print "Required fields: "
196
+ puts issue.get_requireds.join(", ")
197
+ end
198
+ exit
199
+ end
200
+
201
+
202
+ def prepare_new_ticket
203
+ issue = open_issue
204
+ valueNotAllowedRaised = false
205
+ @issueopts.content.each { |value|
206
+ split = value.split("=")
207
+ begin
208
+ if issue.fieldtype(split[0]) == "array" then # If the fieldtype is an array we want to use our arrayseparator to split the fields
209
+ if ! split[1].nil? then
210
+ split[1] = split[1].split(@scriptopts.arrayseperator)
211
+ end
212
+ end
213
+ issue.set_field(split[0],split[1])
214
+ rescue Jirarest2::WrongFieldnameException => e
215
+ no_issue("field",e)
216
+ rescue Jirarest2::ValueNotAllowedException => e
217
+ puts "Value #{split[1]} not allowed for field #{split[0]}."
218
+ puts "Please use one of: \"" + e.message.join("\", \"") + "\""
219
+ valueNotAllowedRaised = true
220
+ end
221
+ }
222
+ if valueNotAllowedRaised then
223
+ raise Jirarest2::ValueNotAllowedException
224
+ end
225
+ return issue
226
+ end
227
+
228
+ def set_watchers(issue)
229
+ issue.set_watcher(credentials,@issueopts.watchers)
230
+ end
231
+
232
+ def create_new_ticket(issue)
233
+ begin
234
+ result = issue.persist(get_credentials).result
235
+ # Set the watchers
236
+ if @issueopts.watchers then
237
+ watcherssuccess = issue.add_watchers(get_credentials,@issueopts.watchers)
238
+ end
239
+ rescue Jirarest2::RequiredFieldNotSetException => e
240
+ puts "Required field \"#{e.to_s}\" not set."
241
+ return 1
242
+ end
243
+ if result["key"] then
244
+ puts "Created new issue with issue id #{result["key"]} ."
245
+ if ! watcherssuccess then
246
+ puts "Watchers could not be set though."
247
+ end
248
+ if @issueopts.link then
249
+ connection = Connect.new(get_credentials)
250
+ link = IssueLink.new(connection)
251
+ remoteIssue,linktype = @issueopts.link.split("=")
252
+ linkresult = link.link(result["key"],remoteIssue,linktype)
253
+ end
254
+ return 0
255
+ elsif result["errors"] then
256
+ puts "An error occured. The error message was: #{result["errors"].to_s}"
257
+ return 2
258
+ end
259
+ end
260
+
261
+
262
+ # The "main function"
263
+ if @scriptopts.show != [] then
264
+ show_scheme
265
+ end
266
+ if ! @issueopts.content.nil? then # If the -c option is set. (-c and no content leads to another exception)
267
+ content = prepare_new_ticket
268
+ exit create_new_ticket(content)
269
+ end
270
+
@@ -0,0 +1,16 @@
1
+ # <one line to give the program's name and a brief idea of what it does.>
2
+ # Copyright (C) 2012 Cyril Bitterich
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ #