jirarest2 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,21 @@
1
+ === 0.0.4 / 2012-07-17
2
+
3
+ * 1 major enhancement:
4
+
5
+ * All the methods that took Credential objects before now take Conenction objects
6
+
7
+ * 2 minor enhancements:
8
+
9
+ * added heal_uri and heal_uri! methods to try to find the right url if wanted.
10
+ * passes Connection to all other classes now and no longer credentials.
11
+
12
+ * 3 bug fixes:
13
+
14
+ * -H in create_connection works now as intended. It's even better as you can give the login URL from you browser and it will automagically exract the correct API uri in usual cases. closes #3
15
+ * Shebang should work now (please remember this gem depends on ruby1.9.1 to work, gem2deb is not able to reflect that.) closes #2
16
+ * reduced the extension of the url to "/api/rest/2" closes #1
17
+
18
+
1
19
  === 0.0.3 / 2012-07-16
2
20
 
3
21
  * 2 major enhancements:
@@ -6,7 +6,7 @@ README.md
6
6
  README.txt
7
7
  Rakefile
8
8
  bin/create_issue.rb
9
- header.copyright
9
+ copyright
10
10
  lib/config.rb
11
11
  lib/connect.rb
12
12
  lib/credentials.rb
data/README.md CHANGED
@@ -5,4 +5,11 @@ Another ruby gem for the REST2 interface of JIRA(tm)
5
5
 
6
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
7
 
8
- What works is the creation of issues with easy field types and watchers.
8
+ What works?
9
+
10
+ * creation of issues
11
+ * add watchers to the issues
12
+ * link new issues to issues that are already there
13
+ * ruby script (create-issue.rb) that enables you to do this from the command line
14
+
15
+ Ruby1.9.1 is needed! Ruby1.8 will fail.
data/README.txt CHANGED
@@ -4,15 +4,23 @@
4
4
 
5
5
  == DESCRIPTION:
6
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.
7
+ jirarest2 is yet another implementation of the JIRA(tm) REST-API[https://developer.atlassian.com/display/JIRADEV/JIRA+Remote+API+Reference] . This one for Ruby1.9.1
8
+
9
+ It is intended to be called within the shell to create and verify JIRA(tm) issues fast without a browser. There was no particular need for perfomance at the time of writing.
10
+
11
+ This implementation is still a for cry from others like http://rubygems.org/gems/jira-ruby which required oauth authentification.
12
+
13
+ The script allows you to create new issues with watchers and link those to existing issues
14
+
15
+ *Use it at your own risk. Most of the API features are not implemented.*
16
+
17
+ *Ruby1.9.1 is needed. Ruby1.8 doesn't work!*
11
18
 
12
19
 
13
20
  == FEATURES/PROBLEMS:
14
21
 
15
- Still in the very first alpha stages. You can only create new issues with watchers.
22
+ * Still in the very first alpha stages. The classes are still pretty volatile.
23
+ * The script allows you to create new issues with watchers and link those to existing issues
16
24
 
17
25
  == SYNOPSIS:
18
26
 
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ require 'hoe'
8
8
  Hoe.plugin :doofus
9
9
  # Hoe.plugin :gem_prelude_sucks
10
10
  # Hoe.plugin :gemspec
11
- # Hoe.plugin :git
11
+ Hoe.plugin :git
12
12
  # Hoe.plugin :inline
13
13
  # Hoe.plugin :manifest
14
14
  # Hoe.plugin :newgem
@@ -97,9 +97,15 @@ class ParseOptions
97
97
  scriptopts.username = u
98
98
  end
99
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
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
103
109
  end
104
110
 
105
111
  opts.on_tail("-h", "--help", "Display this screen") do
@@ -131,8 +137,6 @@ end # class ParseOptions
131
137
  @issueopts, @scriptopts = ParseOptions.parse(ARGV)
132
138
 
133
139
 
134
-
135
-
136
140
  def no_issue(type,issue)
137
141
  puts "The #{type}type you entered (\"#{issue}\") does no exist."
138
142
  puts "Maybe you entered the wrong type or made a typo? (Case is relevant!)"
@@ -153,8 +157,9 @@ def get_credentials
153
157
  @scriptopts.pass = fileconf["password"] if ( @scriptopts.pass.nil? && fileconf["password"] )
154
158
  if ( @scriptopts.url.nil? && fileconf["URL"] ) then
155
159
  @scriptopts.url = fileconf["URL"]
156
- @scriptopts.url = @scriptopts.url + "/jira/rest/api/2/"
157
160
  end
161
+ @scriptopts.url = @scriptopts.url + "/rest/api/2/"
162
+
158
163
  if @scriptopts.pass.nil? then
159
164
  @scriptopts.pass = get_password
160
165
  end
@@ -162,14 +167,34 @@ def get_credentials
162
167
  return Credentials.new(@scriptopts.url, @scriptopts.username, @scriptopts.pass)
163
168
  end
164
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
+
165
191
  =begin
166
192
  create the issue on our side
167
193
  =end
168
194
  def open_issue
169
195
  begin
170
196
  credentials = get_credentials
171
- issue=Issue.new(@issueopts.project,@issueopts.issue,credentials)
172
- # issue=Issue.new(@issueopts.project,@issueopts.issue,@scriptopts.pass,@scriptopts.username)
197
+ issue=Issue.new(@issueopts.project,@issueopts.issue,get_connection)
173
198
  rescue Jirarest2::AuthentificationError => e
174
199
  puts "Password not accepted."
175
200
  @scriptopts.pass = get_password
@@ -231,10 +256,11 @@ end
231
256
 
232
257
  def create_new_ticket(issue)
233
258
  begin
234
- result = issue.persist(get_credentials).result
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
235
261
  # Set the watchers
236
262
  if @issueopts.watchers then
237
- watcherssuccess = issue.add_watchers(get_credentials,@issueopts.watchers)
263
+ watcherssuccess = issue.add_watchers(connection,@issueopts.watchers)
238
264
  end
239
265
  rescue Jirarest2::RequiredFieldNotSetException => e
240
266
  puts "Required field \"#{e.to_s}\" not set."
@@ -246,7 +272,6 @@ def create_new_ticket(issue)
246
272
  puts "Watchers could not be set though."
247
273
  end
248
274
  if @issueopts.link then
249
- connection = Connect.new(get_credentials)
250
275
  link = IssueLink.new(connection)
251
276
  remoteIssue,linktype = @issueopts.link.split("=")
252
277
  linkresult = link.link(result["key"],remoteIssue,linktype)
@@ -1,4 +1,3 @@
1
- # <one line to give the program's name and a brief idea of what it does.>
2
1
  # Copyright (C) 2012 Cyril Bitterich
3
2
  #
4
3
  # This program is free software: you can redistribute it and/or modify
@@ -78,14 +78,60 @@ class Connect
78
78
  # Result: ["CAPTCHA_CHALLENGE; login-url=http://localhost:8080/login.jsp"]
79
79
  result.get_fields("x-authentication-denied-reason")[0] =~ /.*login-url=(.*)/
80
80
  raise Jirarest2::AuthentificationCaptchaError, $1
81
+ when Net::HTTPNotFound
82
+ raise Jirarest2::NotFoundError, result
81
83
  end
82
84
 
83
85
  return Jirarest2::Result.new(result)
84
86
  end # execute
85
87
 
88
+ =begin
89
+ Is the rest API really at the destination we think it is?
90
+ =end
91
+ def check_uri
92
+ begin
93
+ begin
94
+ ret = (execute("Get","dashboard","").code == "200")
95
+ rescue Jirarest2::NotFoundError
96
+ return false
97
+ end
98
+ end
99
+ end
86
100
 
101
+ =begin
102
+ Try to be nice. Parse the URI and see if you can find a pattern to the problem
103
+ =end
104
+ def heal_uri(url = @CONNECTURL)
105
+ splitURI = URI.split(url) # [Scheme,Userinfo,Host,Port,Registry,Path,Opaque,Query,Fragment]
106
+ splitURI[5].gsub!(/^(.*)2$/,'\12/')
107
+ splitURI[5].gsub!(/\/+/,'/') # get rid of duplicate /
108
+ splitURI[5].gsub!(/(rest\/api\/2\/)+/,'\1') # duplicate path to rest
109
+ splitURI[5].gsub!(/^(.*)\/login.jsp(\/rest\/api\/2\/)$/,'\1\2') # dedicated login page
110
+ splitURI[5].gsub!(/^(.*)\/secure\/Dashboard.jspa(\/rest\/api\/2\/)$/,'\1\2') # copied the dashboard URL (or the login Page)
111
+ if splitURI[3] then
112
+ url = splitURI[0].to_s + "://" + splitURI[2].to_s + ":" + splitURI[3].to_s + splitURI[5].to_s
113
+ else
114
+ url = splitURI[0].to_s + "://" + splitURI[2].to_s + splitURI[5].to_s
115
+ end
116
+ return url
117
+ end
87
118
  end # class
88
119
 
120
+ =begin
121
+ try to fix the connecteurl of this instance
122
+ =end
123
+ public
124
+ def heal_uri!
125
+ if ! check_uri then
126
+ @CONNECTURL = heal_uri(@CONNECTURL)
127
+ end
128
+ if check_uri then
129
+ return @CONNECTURL
130
+ else
131
+ raise Jirarest2::CouldNotHealURIError, @CONNECTURL
132
+ end
133
+ end
134
+
89
135
  =begin
90
136
 
91
137
 
@@ -25,6 +25,11 @@ module Jirarest2
25
25
  class AuthentificationError < StandardError ; end
26
26
  # Authentification failed and JIRA(tm) requires a login with captcha to continue
27
27
  class AuthentificationCaptchaError < StandardError ; end
28
+ # 404 - Results in HTML body - not JSON
29
+ class NotFoundError < StandardError ; end
30
+ # Could not heal URI
31
+ class CouldNotHealURIError < StandardError ; end
32
+
28
33
 
29
34
  ## credentials.rb
30
35
 
@@ -15,14 +15,11 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  #
17
17
 
18
- # TODO always recreating Connection is not really DRY - Find a way to fix it.
19
-
20
18
  =begin
21
19
  An Issue object contains all the data of an issue
22
20
  =end
23
21
  class Issue
24
22
 
25
- require "connect"
26
23
 
27
24
  # issue type of the issue
28
25
  attr_reader :issuetype
@@ -32,11 +29,10 @@ class Issue
32
29
  attr_reader :issuekey
33
30
 
34
31
  =begin
35
- New initialize method we take the project and the type we want to use and take login info that might exist just right with us
32
+ New initialize method we take the project and the type we want to use and a connection
36
33
  project Name of the project this issue is to live in
37
34
  =end
38
- def initialize (project,type,credentials)
39
- connection = Connect.new(credentials)
35
+ def initialize (project,type,connection)
40
36
  query = {:projectKeys => project, :issuetypeNames => type, :expand => "projects.issuetypes.fields" }
41
37
  answer = connection.execute("Get","issue/createmeta/",query)
42
38
  jhash = answer.result
@@ -229,15 +225,13 @@ TODO We are not yet able to work with "Cascading Select" fields ( "custom": "com
229
225
  =begin
230
226
  create a new ticket
231
227
  =end
232
- def persist(credentials)
228
+ def persist(connection)
233
229
  get_requireds.each { |fieldname|
234
230
  if @issuefields[fieldname]["value"].nil? then
235
231
  raise Jirarest2::RequiredFieldNotSetException, fieldname
236
232
  end
237
233
  }
238
- connection = Connect.new(credentials)
239
234
  hash = jirahash
240
- # TODO we changed the returning Value here - it's an Result object and no longer just the equivalent of Result.result
241
235
  ret = connection.execute("Post","issue/",hash)
242
236
  if ret.code == "201" then # Ticket sucessfully created
243
237
  @issuekey = ret.result["key"]
@@ -250,9 +244,8 @@ TODO We are not yet able to work with "Cascading Select" fields ( "custom": "com
250
244
  Set the watchers for this Ticket
251
245
  watchers has to be an Array
252
246
  =end
253
- def add_watchers(credentials,watchers)
247
+ def add_watchers(connection,watchers)
254
248
  success = false # Return whether we were successful with the watchers
255
- connection = Connect.new(credentials)
256
249
  watch = Watcher.new(connection,@issuekey)
257
250
  watchers.each { |person|
258
251
  success = watch.add_watcher(person)
@@ -17,7 +17,7 @@
17
17
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
- VERSION = "0.0.3"
20
+ VERSION = "0.0.4"
21
21
 
22
22
  require_relative "connect"
23
23
  require_relative "issue"
@@ -17,5 +17,42 @@ class TestConnect < MiniTest::Unit::TestCase
17
17
  query={"jql"=>"project = MFTP", "startAt"=>0, "maxResults"=>4 }
18
18
  assert 4, @con.execute("Post","search/",query).result["maxResults"]
19
19
  end
20
+
21
+ def test_check_uri
22
+ assert_equal true,@con.check_uri
23
+ cred = Credentials.new("http://localhost:2990/rest/api/2/","test","1234")
24
+ con1 = Connect.new(cred)
25
+ assert_equal false,con1.check_uri
26
+ end
27
+
28
+ def test_heal_uri
29
+ cred = Credentials.new("http://localhost:2990/jira//rest/api//2//","test","1234")
30
+ con = Connect.new(cred)
31
+ assert_equal "http://localhost:2990/jira/rest/api/2/",con.heal_uri
32
+ assert_equal "http://localhost:2990/jira/rest/api/2/",con.heal_uri("http://localhost:2990/jira/rest/api/2/rest/api/2/")
33
+ assert_equal "http://localhost:2990/jira/rest/api/2/",con.heal_uri("http://localhost:2990/jira/secure/Dashboard.jspa/rest/api/2/")
34
+ assert_equal "http://localhost:2990/rest/api/2/",con.heal_uri("http://localhost:2990/secure/Dashboard.jspa/rest/api/2/")
35
+ assert_equal "http://localhost:2990/jira/rest/api/2/",con.heal_uri("http://localhost:2990/jira/login.jsp/rest/api/2/")
36
+ assert_equal "http://localhost:2990/rest/api/2/",con.heal_uri("http://localhost:2990/login.jsp/rest/api/2/")
37
+ assert_equal "http://localhost/rest/api/2/",con.heal_uri("http://localhost/login.jsp/rest/api/2")
38
+ assert_equal "http://localhost:2990/rest/api/2/",con.heal_uri("http://localhost:2990/login.jsp/rest/api/2")
39
+ assert_equal "http://localhost:2990/jira/secure/Dashboard.jspa",con.heal_uri("http://localhost:2990/jira/secure/Dashboard.jspa") # If there is no Rest-Path at this point we have a problem
40
+ assert_equal "http://localhost:2990/secure/Dashboard.jspa",con.heal_uri("http://localhost:2990/secure/Dashboard.jspa") # If there is no Rest-Path at this point we have a problem
41
+ end
42
+
43
+ def test_heal_uri!
44
+ ## First an URL we can fix
45
+ cred = Credentials.new("http://localhost:2990/jira//rest/api//2//","test","1234")
46
+ con = Connect.new(cred)
47
+ assert_equal false,con.check_uri
48
+ assert_equal "http://localhost:2990/jira/rest/api/2/", con.heal_uri!
49
+ assert_equal true,con.check_uri
50
+ ## And now one we cant't fix
51
+ cred = Credentials.new("http://localhost:2990/secure/Dashboard.jspa","test","1234")
52
+ con = Connect.new(cred)
53
+ assert_equal false,con.check_uri
54
+ assert_raises(Jirarest2::CouldNotHealURIError){ con.heal_uri! }
55
+ assert_equal false,con.check_uri
56
+ end
20
57
 
21
58
  end
@@ -5,18 +5,19 @@ require "jirarest2"
5
5
  class TestIssue < MiniTest::Unit::TestCase
6
6
  def setup
7
7
  @credentials = Credentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
8
- @existentIssue = Issue.new("MFTP","My issue type",@credentials)
8
+ @connect = Connect.new(@credentials)
9
+ @existentIssue = Issue.new("MFTP","My issue type",@connect)
9
10
  end
10
11
 
11
12
  def testNonExistentProject
12
13
  assert_raises(Jirarest2::WrongProjectException) {
13
- nonexistentProject = Issue.new("blubber","fasel",@credentials)
14
+ nonexistentProject = Issue.new("blubber","fasel",@connect)
14
15
  }
15
16
  end
16
17
 
17
18
  def testNonExistentIssuetype
18
19
  assert_raises(Jirarest2::WrongIssuetypeException) {
19
- nonexistentIssue = Issue.new("MFTP","fasel",@credentials)
20
+ nonexistentIssue = Issue.new("MFTP","fasel",@connect)
20
21
  }
21
22
  end
22
23
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jirarest2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -50,7 +50,7 @@ cert_chain:
50
50
  -----END CERTIFICATE-----
51
51
 
52
52
  '
53
- date: 2012-07-15 00:00:00.000000000 Z
53
+ date: 2012-07-16 00:00:00.000000000 Z
54
54
  dependencies:
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: json
@@ -100,12 +100,14 @@ dependencies:
100
100
  - - ! '>='
101
101
  - !ruby/object:Gem::Version
102
102
  version: 2.9.4
103
- description: ! "jirarest2 is yet another implementation of the JIRA(tm) REST api (
104
- https://developer.atlassian.com/display/JIRADEV/JIRA+Remote+API+Reference ). \n
105
- It is intended to be called within the shell to create and verify JIRA(tm) issues
106
- fast without a browser.\n This implementation is still a for cry from others like
107
- http://rubygems.org/gems/jira-ruby which required oauth authentification. \n Use
108
- it at your own risk most of the API features are not implemented."
103
+ description: ! "jirarest2 is yet another implementation of the JIRA(tm) REST-API[https://developer.atlassian.com/display/JIRADEV/JIRA+Remote+API+Reference]
104
+ . This one for Ruby1.9.1\n\nIt is intended to be called within the shell to create
105
+ and verify JIRA(tm) issues fast without a browser. There was no particular need
106
+ for perfomance at the time of writing.\n\nThis implementation is still a for cry
107
+ from others like http://rubygems.org/gems/jira-ruby which required oauth authentification.
108
+ \n\nThe script allows you to create new issues with watchers and link those to existing
109
+ issues\n\n *Use it at your own risk. Most of the API features are not implemented.*\n\n
110
+ *Ruby1.9.1 is needed. Ruby1.8 doesn't work!*"
109
111
  email:
110
112
  - cebit-jirarest@gunnet.de
111
113
  executables:
@@ -124,7 +126,7 @@ files:
124
126
  - README.txt
125
127
  - Rakefile
126
128
  - bin/create_issue.rb
127
- - header.copyright
129
+ - copyright
128
130
  - lib/config.rb
129
131
  - lib/connect.rb
130
132
  - lib/credentials.rb
@@ -170,8 +172,7 @@ rubyforge_project: jirarest2
170
172
  rubygems_version: 1.8.24
171
173
  signing_key:
172
174
  specification_version: 3
173
- summary: jirarest2 is yet another implementation of the JIRA(tm) REST api ( https://developer.atlassian.com/display/JIRADEV/JIRA+Remote+API+Reference
174
- )
175
+ summary: jirarest2 is yet another implementation of the JIRA(tm) REST-API[https://developer.atlassian.com/display/JIRADEV/JIRA+Remote+API+Reference]
175
176
  test_files:
176
177
  - test/test_connect.rb
177
178
  - test/test_issuelinktype.rb
metadata.gz.sig CHANGED
Binary file