jiralicious 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/jiralicious.rb +11 -0
- data/lib/jiralicious/base.rb +68 -6
- data/lib/jiralicious/basic_session.rb +7 -0
- data/lib/jiralicious/configuration.rb +22 -0
- data/lib/jiralicious/cookie_session.rb +16 -1
- data/lib/jiralicious/custom_field_option.rb +16 -2
- data/lib/jiralicious/field.rb +11 -3
- data/lib/jiralicious/issue.rb +82 -6
- data/lib/jiralicious/issue/comment.rb +49 -1
- data/lib/jiralicious/issue/fields.rb +59 -4
- data/lib/jiralicious/issue/transitions.rb +58 -17
- data/lib/jiralicious/issue/watchers.rb +28 -3
- data/lib/jiralicious/parsers/field_parser.rb +13 -0
- data/lib/jiralicious/project.rb +18 -5
- data/lib/jiralicious/search.rb +4 -0
- data/lib/jiralicious/search_result.rb +17 -0
- data/lib/jiralicious/session.rb +13 -0
- data/lib/jiralicious/version.rb +2 -1
- data/spec/comment_spec.rb +3 -3
- data/spec/issue_spec.rb +2 -2
- data/spec/watchers_spec.rb +1 -1
- metadata +2 -2
data/lib/jiralicious.rb
CHANGED
@@ -22,15 +22,26 @@ require 'jiralicious/basic_session'
|
|
22
22
|
require 'jiralicious/cookie_session'
|
23
23
|
require 'jiralicious/configuration'
|
24
24
|
|
25
|
+
##
|
26
|
+
# The Jiralicious module standard options and methods
|
27
|
+
#
|
25
28
|
module Jiralicious
|
29
|
+
# Adds Configuration functionality
|
26
30
|
extend Configuration
|
31
|
+
# Adds self functionality
|
27
32
|
extend self
|
28
33
|
|
34
|
+
##
|
35
|
+
# Processes the session information and returns the current session object
|
36
|
+
#
|
29
37
|
def session
|
30
38
|
session_type = "#{self.auth_type.to_s.capitalize}Session"
|
31
39
|
@session ||= Jiralicious.const_get(session_type).new
|
32
40
|
end
|
33
41
|
|
42
|
+
##
|
43
|
+
# Returns the currently defined Rest API path
|
44
|
+
#
|
34
45
|
def rest_path
|
35
46
|
"#{self.uri}/rest/api/#{self.api_version}"
|
36
47
|
end
|
data/lib/jiralicious/base.rb
CHANGED
@@ -1,13 +1,27 @@
|
|
1
|
-
#
|
2
|
-
# and open the template in the editor.
|
1
|
+
# encoding: utf-8
|
3
2
|
require "uri"
|
4
3
|
module Jiralicious
|
4
|
+
##
|
5
|
+
# The Base class encapsulates all of the default functionality necessary in order
|
6
|
+
# to properly manage the Hashie::Trash object within the Jiralicious framework.
|
7
|
+
#
|
5
8
|
class Base < Hashie::Trash
|
9
|
+
|
10
|
+
##
|
11
|
+
# Includes functionality from FieldParser
|
12
|
+
#
|
6
13
|
include Jiralicious::Parsers::FieldParser
|
7
14
|
|
15
|
+
##
|
16
|
+
# Used to identify if the class has been loaded
|
17
|
+
#
|
8
18
|
attr_accessor :loaded
|
9
19
|
|
10
|
-
|
20
|
+
##
|
21
|
+
# Trash Extention properties_from_hash
|
22
|
+
# Adds an underscore (_) before a numeric field.
|
23
|
+
# This ensures that numeric fields will be treated as strings.
|
24
|
+
#
|
11
25
|
def properties_from_hash(hash)
|
12
26
|
hash.inject({}) do |newhash, (k, v)|
|
13
27
|
k = k.gsub("-", "_")
|
@@ -18,8 +32,11 @@ module Jiralicious
|
|
18
32
|
end
|
19
33
|
end
|
20
34
|
|
21
|
-
### Class Methods ###
|
22
35
|
class << self
|
36
|
+
##
|
37
|
+
# Finds the specified key in relation to the current class. This is based on the
|
38
|
+
# inheritance and will create an error if called from the Base Class directly.
|
39
|
+
#
|
23
40
|
def find(key, options = {})
|
24
41
|
response = fetch({:key => key})
|
25
42
|
if options[:reload] == true
|
@@ -29,20 +46,36 @@ module Jiralicious
|
|
29
46
|
end
|
30
47
|
end
|
31
48
|
|
49
|
+
##
|
50
|
+
# Searches for all objects of the inheritance class. This method can create very large
|
51
|
+
# datasets and is not recommended for any request that could slow down either Jira or
|
52
|
+
# the Ruby application.
|
53
|
+
#
|
32
54
|
def find_all
|
33
55
|
response = fetch()
|
34
56
|
new(response)
|
35
57
|
end
|
36
58
|
|
59
|
+
##
|
60
|
+
# Generates the endpoint_name based on the current inheritance class.
|
61
|
+
#
|
37
62
|
def endpoint_name
|
38
63
|
self.name.split('::').last.downcase
|
39
64
|
end
|
40
65
|
|
66
|
+
##
|
67
|
+
# Generates the parent_name based on the current inheritance class.
|
68
|
+
#
|
41
69
|
def parent_name
|
42
70
|
arr = self.name.split('::')
|
43
71
|
arr[arr.length-2].downcase
|
44
72
|
end
|
45
73
|
|
74
|
+
##
|
75
|
+
# uses the options to build the URI options necessary to handle the request.
|
76
|
+
# Some options are defaulted if not explicit while others are only necessary
|
77
|
+
# under specific conditions.
|
78
|
+
#
|
46
79
|
def fetch(options = {})
|
47
80
|
options[:method] = :get unless [:get, :post, :put, :delete].include?(options[:method])
|
48
81
|
options[:parent_uri] = "#{parent_name}/#{options[:parent_key]}/" unless options[:parent].nil?
|
@@ -59,6 +92,10 @@ module Jiralicious
|
|
59
92
|
Jiralicious.session.request(options[:method], options[:url_uri], :handler => handler, :body => options[:body_uri].to_json)
|
60
93
|
end
|
61
94
|
|
95
|
+
##
|
96
|
+
# Configures the default handler. This can be overridden in
|
97
|
+
# the child class to provide additional error handling.
|
98
|
+
#
|
62
99
|
def handler
|
63
100
|
Proc.new do |response|
|
64
101
|
case response.code
|
@@ -77,26 +114,48 @@ module Jiralicious
|
|
77
114
|
alias :all :find_all
|
78
115
|
end
|
79
116
|
|
80
|
-
|
117
|
+
##
|
118
|
+
# Generates the endpoint_name based on the current inheritance class.
|
119
|
+
#
|
81
120
|
def endpoint_name
|
82
121
|
self.class.endpoint_name
|
83
122
|
end
|
84
123
|
|
124
|
+
##
|
125
|
+
# Generates the parent_name based on the current inheritance class.
|
126
|
+
#
|
85
127
|
def parent_name
|
86
128
|
self.class.parent_name
|
87
129
|
end
|
88
130
|
|
131
|
+
##
|
132
|
+
# Searches for all objects of the inheritance class. This method can create very large
|
133
|
+
# datasets and is not recommended for any request that could slow down either Jira or
|
134
|
+
# the Ruby application.
|
135
|
+
#
|
89
136
|
def all
|
90
137
|
self.class.all
|
91
138
|
end
|
92
139
|
|
140
|
+
##
|
141
|
+
# Returns the the logical form of the loaded member. This used
|
142
|
+
# to determine if the object is loaded and ready for usage.
|
143
|
+
#
|
93
144
|
def loaded?
|
94
|
-
self.loaded
|
145
|
+
!!self.loaded
|
95
146
|
end
|
96
147
|
|
148
|
+
##
|
149
|
+
# Default reload method is blank. For classes that implement lazy loading
|
150
|
+
# this method will be overridden with the necessary functionality.
|
151
|
+
#
|
97
152
|
def reload
|
98
153
|
end
|
99
154
|
|
155
|
+
##
|
156
|
+
# Overrides the default method_missing check. This override is used in lazy
|
157
|
+
# loading to ensure that the requested field or method is truly unavailable.
|
158
|
+
#
|
100
159
|
def method_missing(meth, *args, &block)
|
101
160
|
if !loaded?
|
102
161
|
self.loaded = true
|
@@ -107,6 +166,9 @@ module Jiralicious
|
|
107
166
|
end
|
108
167
|
end
|
109
168
|
|
169
|
+
##
|
170
|
+
# Validates if the provided object is a numeric value
|
171
|
+
#
|
110
172
|
def numeric?(object)
|
111
173
|
true if Float(object) rescue false
|
112
174
|
end
|
@@ -1,5 +1,12 @@
|
|
1
1
|
module Jiralicious
|
2
|
+
##
|
3
|
+
# The BasicSesion class extends the default Session class by forcing
|
4
|
+
# basic_auth to be fired prior to any other action.
|
5
|
+
#
|
2
6
|
class BasicSession < Session
|
7
|
+
##
|
8
|
+
# Fires off the basic_auth with the local username and password.
|
9
|
+
#
|
3
10
|
def before_request
|
4
11
|
self.class.basic_auth(Jiralicious.username, Jiralicious.password)
|
5
12
|
end
|
@@ -2,17 +2,25 @@
|
|
2
2
|
require 'ostruct'
|
3
3
|
module Jiralicious
|
4
4
|
module Configuration
|
5
|
+
# Array of available attributes
|
5
6
|
VALID_OPTIONS = [:username, :password, :uri, :api_version, :auth_type]
|
7
|
+
# Default user name set prior to login attempt
|
6
8
|
DEFAULT_USERNAME = nil
|
9
|
+
# Default password set prior to login attempt
|
7
10
|
DEFAULT_PASSWORD = nil
|
11
|
+
# Authentication is either :basic or :cookie (depricated)
|
8
12
|
DEFAULT_AUTH_TYPE = :basic
|
13
|
+
# Default URI set prior to login attempt
|
9
14
|
DEFAULT_URI = nil
|
15
|
+
# Default API Version can be set any valid version or "latest"
|
10
16
|
DEFAULT_API_VERSION = "latest"
|
11
17
|
|
18
|
+
# Enables block configuration mode
|
12
19
|
def configure
|
13
20
|
yield self
|
14
21
|
end
|
15
22
|
|
23
|
+
# Provides access to the array of attributes
|
16
24
|
attr_accessor *VALID_OPTIONS
|
17
25
|
|
18
26
|
# Reset when extended into class
|
@@ -20,12 +28,14 @@ module Jiralicious
|
|
20
28
|
base.reset
|
21
29
|
end
|
22
30
|
|
31
|
+
# Pass options to set the values
|
23
32
|
def options
|
24
33
|
VALID_OPTIONS.inject({}) do |option, key|
|
25
34
|
option.merge!(key => send(key))
|
26
35
|
end
|
27
36
|
end
|
28
37
|
|
38
|
+
# Resets all attributes to default values
|
29
39
|
def reset
|
30
40
|
self.username = DEFAULT_USERNAME
|
31
41
|
self.password = DEFAULT_PASSWORD
|
@@ -34,6 +44,18 @@ module Jiralicious
|
|
34
44
|
self.auth_type = DEFAULT_AUTH_TYPE
|
35
45
|
end
|
36
46
|
|
47
|
+
##
|
48
|
+
# Loads the provided YML file.
|
49
|
+
#
|
50
|
+
# Can provide either direct or relational path to the file. It is recommended to send a direct path
|
51
|
+
# due to dynamic loading and/or different file locations due to different deployment methods.
|
52
|
+
#
|
53
|
+
# [Direct Path] /usr/project/somepath_to_file/jira.yml
|
54
|
+
#
|
55
|
+
# [Relational Path] Rails.root.to_s + "/config/jira.yml"
|
56
|
+
#
|
57
|
+
# "./config/jira.yml"
|
58
|
+
#
|
37
59
|
def load_yml(yml_file)
|
38
60
|
if File.exist?(yml_file)
|
39
61
|
yml_cfg = OpenStruct.new(YAML.load_file(yml_file))
|
@@ -1,17 +1,26 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
3
2
|
module Jiralicious
|
3
|
+
##
|
4
|
+
# The CookieSesssion class extends the Session class with the
|
5
|
+
# functionality of utilizing cookies for authorization management.
|
6
|
+
#
|
7
|
+
# Deprecated:: CookieSession is deprecated as of version 0.2.0
|
8
|
+
#
|
4
9
|
class CookieSession < Session
|
10
|
+
# Adds attributes to the CookieSession
|
5
11
|
attr_accessor :authenticating, :session, :login_info
|
6
12
|
|
13
|
+
# Checks to see if session is active
|
7
14
|
def alive?
|
8
15
|
@session && @login_info
|
9
16
|
end
|
10
17
|
|
18
|
+
# Provides login information on every request
|
11
19
|
def before_request
|
12
20
|
self.login if require_login? && !@authenticating
|
13
21
|
end
|
14
22
|
|
23
|
+
# Handles the response from the request
|
15
24
|
def after_request(response)
|
16
25
|
unless @authenticating
|
17
26
|
if captcha_required(response)
|
@@ -26,6 +35,7 @@ module Jiralicious
|
|
26
35
|
@authenticating = false
|
27
36
|
end
|
28
37
|
|
38
|
+
# Authenticates the login
|
29
39
|
def login
|
30
40
|
@authenticating = true
|
31
41
|
handler = Proc.new do |response|
|
@@ -54,6 +64,7 @@ module Jiralicious
|
|
54
64
|
|
55
65
|
end
|
56
66
|
|
67
|
+
# Logs out of the API
|
57
68
|
def logout
|
58
69
|
handler = Proc.new do |request|
|
59
70
|
if response.code == 204
|
@@ -74,6 +85,7 @@ module Jiralicious
|
|
74
85
|
|
75
86
|
private
|
76
87
|
|
88
|
+
# Handles Captcha if necessary
|
77
89
|
def captcha_required(response)
|
78
90
|
response.code == 401 &&
|
79
91
|
# Fakeweb lowercases headers automatically. :(
|
@@ -81,14 +93,17 @@ module Jiralicious
|
|
81
93
|
response.headers["x-seraph-loginreason"] == "AUTHENTICATION_DENIED")
|
82
94
|
end
|
83
95
|
|
96
|
+
# Throws if cookie is invalid
|
84
97
|
def cookie_invalid(response)
|
85
98
|
response.code == 401 && response.body =~ /cookie/i
|
86
99
|
end
|
87
100
|
|
101
|
+
# Checks to see if login is required
|
88
102
|
def require_login?
|
89
103
|
!(Jiralicious.username.empty? && Jiralicious.password.empty?) && !alive?
|
90
104
|
end
|
91
105
|
|
106
|
+
# Resets the current Session
|
92
107
|
def clear_session
|
93
108
|
@session = @login_info = nil
|
94
109
|
end
|
@@ -1,7 +1,14 @@
|
|
1
|
-
#
|
2
|
-
# and open the template in the editor.
|
1
|
+
# encoding: utf-8
|
3
2
|
module Jiralicious
|
3
|
+
##
|
4
|
+
# The CustomFieldOption provides a list of available custom field options. This method is
|
5
|
+
# used in lazy loading and can be used to validate options prior to updating the issue.
|
6
|
+
#
|
4
7
|
class CustomFieldOption < Jiralicious::Base
|
8
|
+
|
9
|
+
##
|
10
|
+
# Initialization Method
|
11
|
+
#
|
5
12
|
def initialize(decoded_json, default = nil, &blk)
|
6
13
|
@loaded = false
|
7
14
|
if decoded_json.is_a? Hash
|
@@ -13,10 +20,17 @@ module Jiralicious
|
|
13
20
|
end
|
14
21
|
|
15
22
|
class << self
|
23
|
+
##
|
24
|
+
# Overrides the auto-generated endpoint_name from Base.
|
25
|
+
# This is necessary due to lower camel case naming convention.
|
26
|
+
#
|
16
27
|
def endpoint_name
|
17
28
|
"customFieldOption"
|
18
29
|
end
|
19
30
|
|
31
|
+
##
|
32
|
+
# Retrieves the options based on the ID
|
33
|
+
#
|
20
34
|
def find(id, options = {})
|
21
35
|
response = fetch({:key => id})
|
22
36
|
response.parsed_response['id'] = id
|
data/lib/jiralicious/field.rb
CHANGED
@@ -1,8 +1,16 @@
|
|
1
|
-
#
|
2
|
-
# and open the template in the editor.
|
1
|
+
# encoding: utf-8
|
3
2
|
module Jiralicious
|
3
|
+
##
|
4
|
+
# The Field class is used in multiple classes as a support object. This class
|
5
|
+
# is designed as a Object Oriented Method of viewing the Jira JSON/Hash.
|
6
|
+
#
|
4
7
|
class Field < Jiralicious::Base
|
5
|
-
|
8
|
+
##
|
9
|
+
# Initialization Method
|
10
|
+
#
|
11
|
+
# Builds the dynamic Field object from either a Hash or Array. The decoded JSON object can be nested
|
12
|
+
# as deep as necessary but it is recommended that JSON objects are no deeper then 5 levels maximum.
|
13
|
+
#
|
6
14
|
def initialize(decoded_json, default = nil, &blk)
|
7
15
|
@loaded = false
|
8
16
|
if decoded_json.is_a? Hash
|
data/lib/jiralicious/issue.rb
CHANGED
@@ -1,20 +1,36 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Jiralicious
|
3
|
+
##
|
4
|
+
# The Issue class rolls up all functionality of issues from jira. This class contains methods to manage
|
5
|
+
# Issues from Ruby via the API. Several child classes are added in order to facilitate several different
|
6
|
+
# aspects of managing the issues.
|
7
|
+
#
|
3
8
|
class Issue < Jiralicious::Base
|
4
9
|
|
10
|
+
# Provides access to the Jira Key field
|
5
11
|
property :jira_key, :from => :key
|
12
|
+
# Provides access to the expand fields
|
6
13
|
property :expand
|
14
|
+
# Provides access to the self string
|
7
15
|
property :jira_self, :from => :self
|
16
|
+
# Provides access to the field list
|
8
17
|
property :fields
|
18
|
+
# Provides access to transitions
|
9
19
|
property :transitions
|
20
|
+
# Provides access to the Jira id
|
10
21
|
property :id
|
22
|
+
# Contains the Fields Class
|
11
23
|
attr_accessor :fields
|
24
|
+
# Contains the Comments Class
|
12
25
|
attr_accessor :comments
|
26
|
+
# Contains the Watchers Class
|
13
27
|
attr_accessor :watchers
|
28
|
+
# Contains the createmeta
|
14
29
|
attr_accessor :createmeta
|
30
|
+
# Contains the editmeta
|
15
31
|
attr_accessor :editmeta
|
16
32
|
|
17
|
-
|
33
|
+
# Initialization Method
|
18
34
|
def initialize(decoded_json = nil, default = nil, &blk)
|
19
35
|
@loaded = false
|
20
36
|
if (!decoded_json.nil?)
|
@@ -24,16 +40,22 @@ module Jiralicious
|
|
24
40
|
@fields = Fields.new(self['fields']) if self['fields']
|
25
41
|
@comments = Comment.find_by_key(self.jira_key)
|
26
42
|
@watchers = Watchers.find_by_key(self.jira_key)
|
43
|
+
@transitions = Transitions.new(self.jira_key)
|
27
44
|
@loaded = true
|
28
45
|
end
|
29
46
|
end
|
30
47
|
@fields = Fields.new if @fields.nil?
|
31
48
|
@comments = Comment.new if @comments.nil?
|
32
49
|
@watchers = Watchers.new if @watchers.nil?
|
50
|
+
@transitions = Transitions.new if @transitions.nil?
|
33
51
|
@createmeta = nil
|
34
52
|
@editmeta = nil
|
35
53
|
end
|
36
54
|
|
55
|
+
##
|
56
|
+
# Imports all data from a decoded hash. This function is used when a blank
|
57
|
+
# issue is created but needs to be loaded from a JSON string at a later time.
|
58
|
+
#
|
37
59
|
def load(decoded_hash, default = nil)
|
38
60
|
decoded_hash.each do |k,v|
|
39
61
|
self[:"#{k}"] = v
|
@@ -49,45 +71,77 @@ module Jiralicious
|
|
49
71
|
end
|
50
72
|
end
|
51
73
|
|
74
|
+
##
|
75
|
+
# Forces the Jira Issue to reload with current or updated
|
76
|
+
# information. This method is used in lazy loading methods.
|
77
|
+
#
|
52
78
|
def reload
|
53
79
|
load(self.class.find(self.jira_key, {:reload => true}).parsed_response)
|
54
80
|
end
|
55
81
|
|
56
|
-
|
57
|
-
### Class Methods ###
|
58
82
|
class << self
|
83
|
+
##
|
84
|
+
# Adds specified assignee to the Jira Issue.
|
85
|
+
#
|
59
86
|
def assignee(name, key)
|
60
87
|
name = {"name" => name} if name.is_a? String
|
61
88
|
fetch({:method => :put, :key => "#{key}/assignee", :body => name})
|
62
89
|
end
|
63
90
|
|
91
|
+
##
|
92
|
+
# Creates a new issue. This method is not recommended
|
93
|
+
# for direct access but is provided for advanced users.
|
94
|
+
#
|
64
95
|
def create(issue)
|
65
96
|
fetch({:method => :post, :body => issue})
|
66
97
|
end
|
67
98
|
|
99
|
+
##
|
100
|
+
# Removes/Deletes the Issue from the Jira Project. It is not recommended to delete issues however the
|
101
|
+
# functionality is provided. It is recommended to override this function to throw an error or warning
|
102
|
+
# to maintain data integrity in systems that do not allow deleting from a remote location.
|
103
|
+
#
|
68
104
|
def remove(key, options = {})
|
69
105
|
fetch({:method => :delete, :body_to_params => true, :key => key, :body => options})
|
70
106
|
end
|
71
107
|
|
108
|
+
##
|
109
|
+
# Updates the specified issue based on the provided HASH. It is not recommended
|
110
|
+
# to access this method directly but is provided for advanced users.
|
111
|
+
#
|
72
112
|
def update(issue, key)
|
73
113
|
fetch({:method => :put, :key => key, :body => issue})
|
74
114
|
end
|
75
115
|
|
116
|
+
##
|
117
|
+
# Retrieves the create meta for the Jira Project based on Issue Types.
|
118
|
+
# Can be used to validate or filter create requests to minimize errors.
|
119
|
+
#
|
76
120
|
def createmeta(projectkeys, issuetypeids = nil)
|
77
121
|
response = fetch({:body_to_params => true, :key => "createmeta", :body => {:expand => "projects.issuetypes.fields.", :projectKeys => projectkeys, :issuetypeIds => issuetypeids}})
|
78
122
|
return Field.new(response.parsed_response)
|
79
123
|
end
|
80
124
|
|
125
|
+
##
|
126
|
+
# Retrieves the edit meta for the Jira Issue. Can be used
|
127
|
+
# to validate or filter create requests to minimize errors.
|
128
|
+
#
|
81
129
|
def editmeta(key)
|
82
130
|
response = fetch({:key => "#{key}/editmeta"})
|
83
131
|
response.parsed_response["key"] = key
|
84
132
|
Field.new(response.parsed_response)
|
85
133
|
end
|
86
134
|
|
135
|
+
##
|
136
|
+
# Legacy method to retrieve transitions manually.
|
137
|
+
#
|
87
138
|
def get_transitions(transitions_url)
|
88
139
|
Jiralicious.session.request(:get, transitions_url, :handler => handler)
|
89
140
|
end
|
90
141
|
|
142
|
+
##
|
143
|
+
# Legacy method to process transitions manually.
|
144
|
+
#
|
91
145
|
def transition(transitions_url, data)
|
92
146
|
Jiralicious.session.request(:post, transitions_url,
|
93
147
|
:handler => handler,
|
@@ -95,16 +149,24 @@ module Jiralicious
|
|
95
149
|
end
|
96
150
|
end
|
97
151
|
|
98
|
-
|
99
|
-
|
152
|
+
##
|
153
|
+
# Method to assign an assignee by name in a current issue.
|
154
|
+
#
|
100
155
|
def set_assignee(name)
|
101
156
|
self.class.assignee(name, self.jira_key)
|
102
157
|
end
|
103
158
|
|
159
|
+
##
|
160
|
+
# Method to remove or delete the current issue.
|
161
|
+
#
|
104
162
|
def remove(options = {})
|
105
163
|
self.class.remove(self.jira_key, options)
|
106
164
|
end
|
107
165
|
|
166
|
+
##
|
167
|
+
# Retrieves the create meta for the Jira Project based on Issue Types.
|
168
|
+
# Can be used to validate or filter create requests to minimize errors.
|
169
|
+
#
|
108
170
|
def createmeta
|
109
171
|
if @createmeta.nil?
|
110
172
|
@createmeta = self.class.createmeta(self.jira_key.split("-")[0])
|
@@ -112,6 +174,10 @@ module Jiralicious
|
|
112
174
|
@createmeta
|
113
175
|
end
|
114
176
|
|
177
|
+
##
|
178
|
+
# Retrieves the edit meta for the Jira Issue. Can be used
|
179
|
+
# to validate or filter create requests to minimize errors.
|
180
|
+
#
|
115
181
|
def editmeta
|
116
182
|
if @editmeta.nil?
|
117
183
|
@editmeta = self.class.editmeta(self.jira_key)
|
@@ -119,6 +185,9 @@ module Jiralicious
|
|
119
185
|
@editmeta
|
120
186
|
end
|
121
187
|
|
188
|
+
##
|
189
|
+
# Saves the current Issue but does not update itself.
|
190
|
+
#
|
122
191
|
def save
|
123
192
|
if loaded?
|
124
193
|
self.class.update(@fields.format_for_update, self.jira_key)
|
@@ -127,7 +196,14 @@ module Jiralicious
|
|
127
196
|
response = self.class.create(@fields.format_for_create)
|
128
197
|
key = response.parsed_response['key']
|
129
198
|
end
|
130
|
-
|
199
|
+
return key
|
200
|
+
end
|
201
|
+
|
202
|
+
##
|
203
|
+
# Saves the current Issue and reloads to ensure it is upto date.
|
204
|
+
#
|
205
|
+
def save!
|
206
|
+
load(self.class.find(save, {:reload => true}).parsed_response)
|
131
207
|
end
|
132
208
|
end
|
133
209
|
end
|
@@ -1,19 +1,38 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Jiralicious
|
3
3
|
class Issue
|
4
|
+
##
|
5
|
+
# The Comment class retrieves and controls the functionality
|
6
|
+
# of Comments associated with an Issue.
|
7
|
+
#
|
4
8
|
class Comment < Jiralicious::Base
|
5
|
-
|
9
|
+
# Related Issue Key
|
6
10
|
attr_accessor :jira_key
|
7
11
|
|
12
|
+
##
|
13
|
+
# Initialization Method
|
14
|
+
#
|
8
15
|
def initialize(decoded_json = nil, default = nil, &blk)
|
9
16
|
if (decoded_json != nil)
|
10
17
|
properties_from_hash(decoded_json)
|
11
18
|
super(decoded_json)
|
12
19
|
parse!(decoded_json)
|
20
|
+
if self.respond_to?("comments")
|
21
|
+
if self.comments.is_a? Array
|
22
|
+
a = {}
|
23
|
+
self.comments.each do |comment|
|
24
|
+
a["_#{comment['id']}"] = Comment.new(comment)
|
25
|
+
end
|
26
|
+
self.comments = a
|
27
|
+
end
|
28
|
+
end
|
13
29
|
end
|
14
30
|
end
|
15
31
|
|
16
32
|
class << self
|
33
|
+
##
|
34
|
+
# Retrieves the Comments based on the Issue Key
|
35
|
+
#
|
17
36
|
def find_by_key(key, options = {})
|
18
37
|
response = fetch({:parent => parent_name, :parent_key => key})
|
19
38
|
a = new(response)
|
@@ -21,6 +40,9 @@ module Jiralicious
|
|
21
40
|
return a
|
22
41
|
end
|
23
42
|
|
43
|
+
##
|
44
|
+
# Retrieves the Comment based on the Issue Key and Comment ID
|
45
|
+
#
|
24
46
|
def find_by_key_and_id(key, id, options = {})
|
25
47
|
response = fetch({:parent => parent_name, :parent_key => key, :key => id})
|
26
48
|
a = new(response)
|
@@ -28,32 +50,58 @@ module Jiralicious
|
|
28
50
|
return a
|
29
51
|
end
|
30
52
|
|
53
|
+
##
|
54
|
+
# Adds a new Comment to the Issue
|
55
|
+
#
|
31
56
|
def add(comment, key)
|
32
57
|
fetch({:method => :post, :body => comment, :parent => parent_name, :parent_key => key})
|
33
58
|
end
|
34
59
|
|
60
|
+
##
|
61
|
+
# Updates a Comment based on Issue Key and Comment ID
|
62
|
+
#
|
35
63
|
def edit(comment, key, id)
|
36
64
|
fetch({:method => :put, :key => id, :body => comment, :parent => parent_name, :parent_key => key})
|
37
65
|
end
|
38
66
|
|
67
|
+
##
|
68
|
+
# Removes/Deletes the Comment from the Jira Issue. It is not recommended to delete comments however the functionality is provided.
|
69
|
+
# it is recommended to override this function to throw an error or warning
|
70
|
+
# to maintain data integrity in systems that do not allow deleting from a
|
71
|
+
# remote location.
|
72
|
+
#
|
39
73
|
def remove(key, id)
|
40
74
|
fetch({:method => :delete, :body_to_params => true, :key => id, :parent => parent_name, :parent_key => key})
|
41
75
|
|
42
76
|
end
|
43
77
|
end
|
44
78
|
|
79
|
+
##
|
80
|
+
# Retrieves the Comment based on the loaded Issue and Comment ID
|
81
|
+
#
|
45
82
|
def find_by_id(id, options = {})
|
46
83
|
self.class.find_by_key_and_id(@jira_key, id)
|
47
84
|
end
|
48
85
|
|
86
|
+
##
|
87
|
+
# Adds a new Comment to the loaded Issue
|
88
|
+
#
|
49
89
|
def add(comment)
|
50
90
|
self.class.add(comment, @jira_key)
|
51
91
|
end
|
52
92
|
|
93
|
+
##
|
94
|
+
# Updates a Comment based on loaded Issue and Comment
|
95
|
+
#
|
53
96
|
def edit(comment)
|
54
97
|
self.class.edit(comment, @jira_key, self.id)
|
55
98
|
end
|
56
99
|
|
100
|
+
##
|
101
|
+
# Removes/Deletes the Comment from the Jira Issue. It is not recommended to delete comments;
|
102
|
+
# However, the functionality is provided. It is recommended to override this function to throw an error or
|
103
|
+
# warning to maintain data integrity in systems that do not allow deleting from a remote location.
|
104
|
+
#
|
57
105
|
def remove(id = self.id)
|
58
106
|
self.class.remove(@jira_key, id)
|
59
107
|
end
|
@@ -1,30 +1,52 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Jiralicious
|
3
3
|
class Issue
|
4
|
+
##
|
5
|
+
# The Fields class provides functionality to the Issue class that allows it to easily
|
6
|
+
# update or create issues. The class retains the original and the proposed information
|
7
|
+
# which could be used for cross validation prior to posting an update.
|
8
|
+
#
|
4
9
|
class Fields
|
10
|
+
# The fields that will be updated or created
|
5
11
|
attr_accessor :fields_update
|
12
|
+
# The current fields when a ticket was loaded
|
6
13
|
attr_accessor :fields_current
|
7
14
|
|
15
|
+
##
|
16
|
+
# Initialization Method
|
17
|
+
#
|
8
18
|
def initialize(fc = nil)
|
9
19
|
@fields_current = (fc == nil) ? Hash.new : fc
|
10
20
|
@fields_update = Hash.new
|
11
21
|
end
|
12
22
|
|
23
|
+
##
|
24
|
+
# Returns the count of fields being updated.
|
25
|
+
#
|
13
26
|
def count
|
14
27
|
return @fields_update.count
|
15
28
|
end
|
16
29
|
|
30
|
+
##
|
31
|
+
# Returns the length of fields being updated.
|
32
|
+
#
|
17
33
|
def length
|
18
34
|
return @fields_update.length
|
19
35
|
end
|
20
36
|
|
37
|
+
##
|
38
|
+
# Adds a comment to the field list
|
39
|
+
#
|
21
40
|
def add_comment(comment)
|
22
|
-
if !(@fields_update['comment'].
|
41
|
+
if !(@fields_update['comment'].is_a? Array)
|
23
42
|
@fields_update['comment'] = Array.new
|
24
43
|
end
|
25
44
|
@fields_update['comment'].push({"add" => {"body" => comment}})
|
26
45
|
end
|
27
46
|
|
47
|
+
##
|
48
|
+
# Appends the current String with the provided value
|
49
|
+
#
|
28
50
|
def append_s(field, value)
|
29
51
|
if (@fields_update[field] == nil)
|
30
52
|
@fields_update[field] = @fields_current[field] unless @fields_current.nil?
|
@@ -33,46 +55,75 @@ module Jiralicious
|
|
33
55
|
@fields_update[field] += " " + value.to_s
|
34
56
|
end
|
35
57
|
|
58
|
+
##
|
59
|
+
# Appends the current Array with the provided value
|
60
|
+
#
|
36
61
|
def append_a(field, value)
|
37
62
|
@fields_update[field] = @fields_current[field] if (@fields_update[field] == nil)
|
38
63
|
@fields_update[field] = Array.new if !(@fields_update[field].is_a? Array)
|
39
64
|
if value.is_a? String
|
40
|
-
@fields_update[field].push(value)
|
65
|
+
@fields_update[field].push(value) unless @fields_update[field].include? value
|
41
66
|
else
|
42
|
-
@fields_update[field]
|
67
|
+
@fields_update[field] |= value
|
43
68
|
end
|
44
69
|
end
|
45
70
|
|
71
|
+
##
|
72
|
+
# Appends the current Hash with the provided value
|
73
|
+
#
|
46
74
|
def append_h(field, hash)
|
47
75
|
@fields_update[field] = @fields_current[field] if (@fields_update[field] == nil)
|
48
76
|
@fields_update[field] = Hash.new if !(@fields_update[field].is_a? Hash)
|
49
77
|
@fields_update[field].merge!(hash)
|
50
78
|
end
|
51
79
|
|
80
|
+
##
|
81
|
+
# Sets the field key with the provided value.
|
82
|
+
#
|
52
83
|
def set(field, value)
|
53
84
|
@fields_update[field] = value
|
54
85
|
end
|
55
86
|
|
87
|
+
##
|
88
|
+
# Sets the field with a name hash.
|
89
|
+
# This is necessary for some objects in Jira.
|
90
|
+
#
|
56
91
|
def set_name(field, value)
|
57
92
|
@fields_update[field] = {"name" => value}
|
58
93
|
end
|
59
94
|
|
95
|
+
##
|
96
|
+
# Sets the field with a id hash.
|
97
|
+
# This is necessary for some objects in Jira.
|
98
|
+
#
|
60
99
|
def set_id(field, value)
|
61
100
|
@fields_update[field] = {"id" => value}
|
62
101
|
end
|
63
|
-
|
102
|
+
##
|
103
|
+
# Fills the fields_current object with the provided Hash.
|
104
|
+
#
|
64
105
|
def set_current(fc)
|
65
106
|
@fields_current = fc if fc.type == Hash
|
66
107
|
end
|
67
108
|
|
109
|
+
##
|
110
|
+
# Returns the current fields object
|
111
|
+
#
|
68
112
|
def current
|
69
113
|
return @fields_current
|
70
114
|
end
|
71
115
|
|
116
|
+
##
|
117
|
+
# Returns the updated fields object
|
118
|
+
#
|
72
119
|
def updated
|
73
120
|
return @fields_update
|
74
121
|
end
|
75
122
|
|
123
|
+
##
|
124
|
+
# Formats the fields_update object correctly
|
125
|
+
# for Jira to perform an update request.
|
126
|
+
#
|
76
127
|
def format_for_update
|
77
128
|
up = Hash.new
|
78
129
|
@fields_update.each do |k, v|
|
@@ -85,6 +136,10 @@ module Jiralicious
|
|
85
136
|
return {"update" => up}
|
86
137
|
end
|
87
138
|
|
139
|
+
##
|
140
|
+
# Formats the fields_update object correctly
|
141
|
+
# for Jira to perform an create request.
|
142
|
+
#
|
88
143
|
def format_for_create
|
89
144
|
return {"fields" => @fields_update}
|
90
145
|
end
|
@@ -1,31 +1,50 @@
|
|
1
|
-
#
|
2
|
-
# and open the template in the editor.
|
1
|
+
# encoding: utf-8
|
3
2
|
module Jiralicious
|
4
3
|
class Issue
|
4
|
+
##
|
5
|
+
# The Transitions Class provides all of the functionality to retrieve,
|
6
|
+
# and use a transition associated with an Issue.
|
7
|
+
#
|
5
8
|
class Transitions < Jiralicious::Base
|
6
9
|
|
10
|
+
# Contains the meta data to process a Transaction
|
7
11
|
attr_accessor :meta
|
8
12
|
|
9
|
-
|
13
|
+
##
|
14
|
+
# Initialization Method
|
15
|
+
#
|
16
|
+
def initialize(decoded_json = nil, default = nil, &blk)
|
10
17
|
@loaded = false
|
11
18
|
@meta = nil
|
12
|
-
if decoded_json.is_a?
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
if decoded_json.is_a? Array
|
20
|
+
if decoded_json.length == 1
|
21
|
+
decoded_json = decoded_json[0]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
unless decoded_json.nil?
|
25
|
+
if decoded_json.is_a? String
|
26
|
+
self.class.property :jira_key
|
27
|
+
self.jira_key = decoded_json
|
28
|
+
elsif decoded_json.is_a? Hash
|
29
|
+
properties_from_hash(decoded_json)
|
30
|
+
super(decoded_json)
|
31
|
+
parse!(decoded_json)
|
32
|
+
@loaded = true
|
33
|
+
else
|
34
|
+
self.class.property :jira_key
|
35
|
+
self.jira_key = default
|
36
|
+
decoded_json.each do |list|
|
37
|
+
self.class.property :"id_#{list['id']}"
|
38
|
+
self.merge!({"id_#{list['id']}" => self.class.new(list)})
|
39
|
+
end
|
23
40
|
end
|
24
41
|
end
|
25
42
|
end
|
26
43
|
|
27
44
|
class << self
|
28
|
-
|
45
|
+
##
|
46
|
+
# Retrieves the associated Transitions based on the Issue Key
|
47
|
+
#
|
29
48
|
def find(key, options = {})
|
30
49
|
response = fetch({:parent => parent_name, :parent_key => key})
|
31
50
|
response.parsed_response['transitions'].each do |t|
|
@@ -35,13 +54,21 @@ module Jiralicious
|
|
35
54
|
return a
|
36
55
|
end
|
37
56
|
|
57
|
+
##
|
58
|
+
# Retrieves the Transition based on the Issue Key and Transition ID
|
59
|
+
#
|
38
60
|
def find_by_key_and_id(key, id, options = {})
|
39
|
-
response = fetch({:
|
40
|
-
response.parsed_response['
|
61
|
+
response = fetch({:parent => parent_name, :parent_key => key, :body => {"transitionId" => id}, :body_to_params => true })
|
62
|
+
response.parsed_response['transitions'].each do |t|
|
63
|
+
t['jira_key'] = key
|
64
|
+
end
|
41
65
|
a = new(response.parsed_response['transitions'])
|
42
66
|
return a
|
43
67
|
end
|
44
68
|
|
69
|
+
##
|
70
|
+
# Processes the Transition based on the provided options
|
71
|
+
#
|
45
72
|
def go(key, id, options = {})
|
46
73
|
transition = {"transition" => {"id" => id}}
|
47
74
|
if options[:comment].is_a? String
|
@@ -59,6 +86,10 @@ module Jiralicious
|
|
59
86
|
fetch({:method => :post, :parent => parent_name, :parent_key => key, :body => transition})
|
60
87
|
end
|
61
88
|
|
89
|
+
##
|
90
|
+
# Retrieves the meta data for the Transition based on the
|
91
|
+
# options, Issue Key and Transition ID provided.
|
92
|
+
#
|
62
93
|
def meta(key, id, options = {})
|
63
94
|
response = fetch({:method => :get, :parent => parent_name, :parent_key => key, :body_to_params => true,
|
64
95
|
:body => {"transitionId" => id, "expand" => "transitions.fields"}})
|
@@ -72,14 +103,24 @@ module Jiralicious
|
|
72
103
|
alias :find_all :find
|
73
104
|
end
|
74
105
|
|
106
|
+
##
|
107
|
+
# Retrieves the associated Transitions based on the Issue Key
|
108
|
+
#
|
75
109
|
def all
|
76
110
|
self.class.all(self.jira_key) if self.jira_key
|
77
111
|
end
|
78
112
|
|
113
|
+
##
|
114
|
+
# Processes the Transition based on the provided options
|
115
|
+
#
|
79
116
|
def go(options = {})
|
80
117
|
self.class.go(self.jira_key, self.id, options)
|
81
118
|
end
|
82
119
|
|
120
|
+
##
|
121
|
+
# Retrieves the meta data for the Transition based on the
|
122
|
+
# options, Issue Key and Transition ID provided.
|
123
|
+
#
|
83
124
|
def meta
|
84
125
|
if @meta.nil?
|
85
126
|
l = self.class.meta(self.jira_key, self.id, {:return => true})
|
@@ -1,11 +1,18 @@
|
|
1
|
-
#
|
2
|
-
# and open the template in the editor.
|
1
|
+
# encoding: utf-8
|
3
2
|
module Jiralicious
|
4
3
|
class Issue
|
4
|
+
##
|
5
|
+
# The Watchers class is used to manage the watchers on an issue.
|
6
|
+
#
|
5
7
|
class Watchers < Jiralicious::Base
|
6
|
-
|
8
|
+
##
|
9
|
+
# Holds the Issue Key
|
10
|
+
#
|
7
11
|
attr_accessor :jira_key
|
8
12
|
|
13
|
+
##
|
14
|
+
# Initialization Method
|
15
|
+
#
|
9
16
|
def initialize(decoded_json = nil, default = nil, &blk)
|
10
17
|
if (decoded_json != nil)
|
11
18
|
properties_from_hash(decoded_json)
|
@@ -15,6 +22,9 @@ module Jiralicious
|
|
15
22
|
end
|
16
23
|
|
17
24
|
class << self
|
25
|
+
##
|
26
|
+
# Finds all watchers based on the provided Issue Key
|
27
|
+
#
|
18
28
|
def find_by_key(key)
|
19
29
|
response = fetch({:parent => parent_name, :parent_key => key})
|
20
30
|
a = new(response)
|
@@ -22,23 +32,38 @@ module Jiralicious
|
|
22
32
|
return a
|
23
33
|
end
|
24
34
|
|
35
|
+
##
|
36
|
+
# Adds a new Watcher to the Issue
|
37
|
+
#
|
25
38
|
def add(name, key)
|
26
39
|
fetch({:method => :post, :body => name, :body_override => true, :parent => parent_name, :parent_key => key})
|
27
40
|
end
|
28
41
|
|
42
|
+
##
|
43
|
+
# Removes/Deletes a Watcher from the Issue
|
44
|
+
#
|
29
45
|
def remove(name, key)
|
30
46
|
fetch({:method => :delete, :body_to_params => true, :body => {:username => name}, :parent => parent_name, :parent_key => key})
|
31
47
|
end
|
32
48
|
end
|
33
49
|
|
50
|
+
##
|
51
|
+
# Finds all watchers based on the provided Issue Key
|
52
|
+
#
|
34
53
|
def find
|
35
54
|
self.class.find_by_key(@jira_key)
|
36
55
|
end
|
37
56
|
|
57
|
+
##
|
58
|
+
# Adds a new Watcher to the Issue
|
59
|
+
#
|
38
60
|
def add(name)
|
39
61
|
self.class.add(name, @jira_key)
|
40
62
|
end
|
41
63
|
|
64
|
+
##
|
65
|
+
# Removes/Deletes a Watcher from the Issue
|
66
|
+
#
|
42
67
|
def remove(name)
|
43
68
|
self.class.remove(name, @jira_key)
|
44
69
|
end
|
@@ -1,7 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Jiralicious
|
3
3
|
module Parsers
|
4
|
+
##
|
5
|
+
# The FieldParser module is an extention that assists in
|
6
|
+
# managing hash parsing and implementation.
|
7
|
+
#
|
4
8
|
module FieldParser
|
9
|
+
##
|
10
|
+
# Parses an Array or Hash into the current class object.
|
11
|
+
#
|
5
12
|
def parse!(fields)
|
6
13
|
unless fields.is_a?(Hash)
|
7
14
|
raise ArgumentError
|
@@ -32,12 +39,18 @@ module Jiralicious
|
|
32
39
|
|
33
40
|
private
|
34
41
|
|
42
|
+
##
|
43
|
+
# Normalizes key names
|
44
|
+
#
|
35
45
|
def normalize(name)
|
36
46
|
name.gsub(/(\w+)([A-Z].*)/, '\1_\2').
|
37
47
|
gsub(/\W/, "_").
|
38
48
|
downcase
|
39
49
|
end
|
40
50
|
|
51
|
+
##
|
52
|
+
# Converts Array or Hash to a Mash object
|
53
|
+
#
|
41
54
|
def mashify(data)
|
42
55
|
if data.is_a?(Array)
|
43
56
|
data.map { |d| mashify(d) }
|
data/lib/jiralicious/project.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
#
|
2
|
-
# and open the template in the editor.
|
1
|
+
# encoding: utf-8
|
3
2
|
module Jiralicious
|
3
|
+
##
|
4
|
+
# The Project class rolls up the basic functionality for
|
5
|
+
# managing Projects within Jira through the Rest API.
|
6
|
+
#
|
4
7
|
class Project < Jiralicious::Base
|
5
|
-
|
6
|
-
attr_accessor :issues
|
7
8
|
|
8
|
-
|
9
|
+
##
|
10
|
+
# Initialization Method
|
11
|
+
#
|
9
12
|
def initialize(decoded_json, default = nil, &blk)
|
10
13
|
@loaded = false
|
11
14
|
if decoded_json.is_a? Hash
|
@@ -22,6 +25,11 @@ module Jiralicious
|
|
22
25
|
end
|
23
26
|
|
24
27
|
class << self
|
28
|
+
##
|
29
|
+
# Returns a list of issues within the project. The issue list is limited
|
30
|
+
# to only return the issue ID and KEY values to minimize the amount of
|
31
|
+
# data being returned This is used in lazy loading methodology.
|
32
|
+
#
|
25
33
|
def issue_list(key)
|
26
34
|
response = Jiralicious.search("project=#{key}", {:fields => ["id", "key"]})
|
27
35
|
i_out = Issue.new
|
@@ -34,6 +42,11 @@ module Jiralicious
|
|
34
42
|
end
|
35
43
|
end
|
36
44
|
|
45
|
+
##
|
46
|
+
# Issues loads the issue list into the current Project.
|
47
|
+
# It also acts as a reference for lazy loading of issues.
|
48
|
+
#
|
49
|
+
attr_accessor :issues
|
37
50
|
def issues
|
38
51
|
if @issues == nil
|
39
52
|
@issues = self.class.issue_list(self.key)
|
data/lib/jiralicious/search.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Jiralicious
|
3
|
+
##
|
4
|
+
# Provides the interface to access the JQL search functionality.
|
5
|
+
# Uses the same syntax as Rest interface for JQL criteria.
|
6
|
+
#
|
3
7
|
def search(jql, options = {})
|
4
8
|
options[:start_at] ||= 0
|
5
9
|
options[:max_results] ||= 50
|
@@ -1,19 +1,36 @@
|
|
1
1
|
module Jiralicious
|
2
|
+
##
|
3
|
+
# The SearchResult class organizes the response from the Jira API
|
4
|
+
# In a way that is easily parsable into Issues.
|
5
|
+
#
|
2
6
|
class SearchResult
|
7
|
+
# Attributes available for usage regarding the current position in the list
|
3
8
|
attr_reader :offset, :num_results
|
4
9
|
|
10
|
+
##
|
11
|
+
# Initialization Method
|
12
|
+
#
|
13
|
+
# Parses the hash into attributes.
|
14
|
+
#
|
5
15
|
def initialize(search_data)
|
6
16
|
@issues = search_data["issues"]
|
7
17
|
@offset = search_data["startAt"]
|
8
18
|
@num_results = search_data["total"]
|
9
19
|
end
|
10
20
|
|
21
|
+
##
|
22
|
+
# Loads the different issues through the map. This is not recommended for large objects
|
23
|
+
# as it can be troublesome to load multiple Issues to locate the desired one. If the user needs to have all of the information available on each issue this method works perfectly for that process.
|
24
|
+
#
|
11
25
|
def issues
|
12
26
|
@issues.map do |issue|
|
13
27
|
Jiralicious::Issue.find(issue["key"])
|
14
28
|
end
|
15
29
|
end
|
16
30
|
|
31
|
+
##
|
32
|
+
# Returns the Issues attribute without loading the extra information. Ideal for a quick scan of the Hash prior to selecting the correct Issue. This method is also used in the lazy loading methodology.
|
33
|
+
#
|
17
34
|
def issues_raw
|
18
35
|
@issues
|
19
36
|
end
|
data/lib/jiralicious/session.rb
CHANGED
@@ -2,12 +2,21 @@
|
|
2
2
|
require 'jiralicious/configuration'
|
3
3
|
|
4
4
|
module Jiralicious
|
5
|
+
##
|
6
|
+
# The Session class handles the interactions with the Jira Rest API
|
7
|
+
# Through the HTTParty gem.
|
8
|
+
#
|
5
9
|
class Session
|
6
10
|
include HTTParty
|
7
11
|
|
12
|
+
# Sets the default format to JSON for send and return
|
8
13
|
format :json
|
14
|
+
# Sets the default headers to application/json for send and return
|
9
15
|
headers 'Content-Type' => 'application/json'
|
10
16
|
|
17
|
+
##
|
18
|
+
# Main access method to request data from the Jira API
|
19
|
+
#
|
11
20
|
def request(method, *options)
|
12
21
|
if options.last.is_a?(Hash) && options.last[:handler]
|
13
22
|
response_handler = options.last.delete(:handler)
|
@@ -25,6 +34,10 @@ module Jiralicious
|
|
25
34
|
|
26
35
|
private
|
27
36
|
|
37
|
+
##
|
38
|
+
# Configures the default handler. This can be overridden in
|
39
|
+
# the child class to provide additional error handling.
|
40
|
+
#
|
28
41
|
def handler
|
29
42
|
Proc.new do |response|
|
30
43
|
case response
|
data/lib/jiralicious/version.rb
CHANGED
data/spec/comment_spec.rb
CHANGED
@@ -33,14 +33,14 @@ describe Jiralicious, "search" do
|
|
33
33
|
:status => "204")
|
34
34
|
end
|
35
35
|
|
36
|
-
it "finds by
|
36
|
+
it "finds by issue key" do
|
37
37
|
comments = Jiralicious::Issue::Comment.find_by_key("EX-1")
|
38
38
|
comments.should be_instance_of(Jiralicious::Issue::Comment)
|
39
39
|
comments.comments.count.should == 1
|
40
|
-
comments.comments[
|
40
|
+
comments.comments.first[1].id.should == "10000"
|
41
41
|
end
|
42
42
|
|
43
|
-
it "finds by
|
43
|
+
it "finds by issue key and comment id" do
|
44
44
|
comments = Jiralicious::Issue::Comment.find_by_key_and_id("EX-1", "10000")
|
45
45
|
comments.should be_instance_of(Jiralicious::Issue::Comment)
|
46
46
|
comments.id.should == "10000"
|
data/spec/issue_spec.rb
CHANGED
@@ -134,7 +134,7 @@ describe Jiralicious::Issue, "Managing Issues" do
|
|
134
134
|
issue.fields.set("labels", ["new_label_p"])
|
135
135
|
issue.fields.set("environment", "example of environment")
|
136
136
|
issue.fields.set("description", "example of the description extending")
|
137
|
-
issue.save
|
137
|
+
issue.save!
|
138
138
|
issue.jira_key.should == 'EX-2'
|
139
139
|
issue.comments.comments.count.should == 0
|
140
140
|
issue.watchers.watchers.count.should == 1
|
@@ -142,7 +142,7 @@ describe Jiralicious::Issue, "Managing Issues" do
|
|
142
142
|
|
143
143
|
it "updates a new issue" do
|
144
144
|
issue = Jiralicious::Issue.find("EX-3")
|
145
|
-
issue.fields.append_a("labels", "test_label")
|
145
|
+
issue.fields.append_a("labels", ["test_label"])
|
146
146
|
issue.fields.append_s("description", " updated description ")
|
147
147
|
issue.save
|
148
148
|
issue.jira_key.should == 'EX-3'
|
data/spec/watchers_spec.rb
CHANGED
@@ -24,7 +24,7 @@ describe Jiralicious, "search" do
|
|
24
24
|
:status => "204")
|
25
25
|
end
|
26
26
|
|
27
|
-
it "finds by
|
27
|
+
it "finds by issue key" do
|
28
28
|
watchers = Jiralicious::Issue::Watchers.find_by_key("EX-1")
|
29
29
|
watchers.should be_instance_of(Jiralicious::Issue::Watchers)
|
30
30
|
watchers.watchers.count.should == 1
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jiralicious
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: crack
|