jirarest2 0.0.3

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.
@@ -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
+ #