jira-ruby 2.2.0 → 3.0.0.beta1
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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/CI.yml +28 -0
- data/.github/workflows/codeql.yml +100 -0
- data/.github/workflows/rubocop.yml +18 -0
- data/.rubocop.yml +188 -0
- data/Gemfile +11 -3
- data/Guardfile +2 -0
- data/README.md +121 -20
- data/Rakefile +4 -5
- data/jira-ruby.gemspec +11 -17
- data/lib/jira/base.rb +37 -28
- data/lib/jira/base_factory.rb +4 -1
- data/lib/jira/client.rb +65 -46
- data/lib/jira/has_many_proxy.rb +4 -2
- data/lib/jira/http_client.rb +18 -13
- data/lib/jira/http_error.rb +4 -0
- data/lib/jira/jwt_client.rb +18 -42
- data/lib/jira/oauth_client.rb +6 -3
- data/lib/jira/railtie.rb +2 -0
- data/lib/jira/request_client.rb +5 -1
- data/lib/jira/resource/agile.rb +7 -9
- data/lib/jira/resource/applinks.rb +5 -3
- data/lib/jira/resource/attachment.rb +43 -3
- data/lib/jira/resource/board.rb +5 -3
- data/lib/jira/resource/board_configuration.rb +2 -0
- data/lib/jira/resource/comment.rb +2 -0
- data/lib/jira/resource/component.rb +2 -0
- data/lib/jira/resource/createmeta.rb +3 -1
- data/lib/jira/resource/field.rb +9 -4
- data/lib/jira/resource/filter.rb +2 -0
- data/lib/jira/resource/issue.rb +35 -44
- data/lib/jira/resource/issue_picker_suggestions.rb +4 -1
- data/lib/jira/resource/issue_picker_suggestions_issue.rb +2 -0
- data/lib/jira/resource/issuelink.rb +2 -0
- data/lib/jira/resource/issuelinktype.rb +2 -0
- data/lib/jira/resource/issuetype.rb +2 -0
- data/lib/jira/resource/priority.rb +2 -0
- data/lib/jira/resource/project.rb +4 -2
- data/lib/jira/resource/rapidview.rb +5 -3
- data/lib/jira/resource/remotelink.rb +2 -0
- data/lib/jira/resource/resolution.rb +2 -0
- data/lib/jira/resource/serverinfo.rb +2 -0
- data/lib/jira/resource/sprint.rb +14 -23
- data/lib/jira/resource/status.rb +7 -1
- data/lib/jira/resource/status_category.rb +10 -0
- data/lib/jira/resource/suggested_issue.rb +2 -0
- data/lib/jira/resource/transition.rb +2 -0
- data/lib/jira/resource/user.rb +3 -1
- data/lib/jira/resource/version.rb +2 -0
- data/lib/jira/resource/watcher.rb +2 -1
- data/lib/jira/resource/webhook.rb +4 -2
- data/lib/jira/resource/worklog.rb +3 -2
- data/lib/jira/version.rb +3 -1
- data/lib/jira-ruby.rb +5 -3
- data/lib/tasks/generate.rake +4 -2
- data/spec/data/files/short.txt +1 -0
- data/spec/integration/attachment_spec.rb +3 -3
- data/spec/integration/comment_spec.rb +8 -8
- data/spec/integration/component_spec.rb +7 -7
- data/spec/integration/field_spec.rb +3 -3
- data/spec/integration/issue_spec.rb +20 -16
- data/spec/integration/issuelinktype_spec.rb +3 -3
- data/spec/integration/issuetype_spec.rb +3 -3
- data/spec/integration/priority_spec.rb +3 -3
- data/spec/integration/project_spec.rb +7 -7
- data/spec/integration/rapidview_spec.rb +9 -9
- data/spec/integration/resolution_spec.rb +3 -3
- data/spec/integration/status_category_spec.rb +20 -0
- data/spec/integration/status_spec.rb +4 -8
- data/spec/integration/transition_spec.rb +2 -2
- data/spec/integration/user_spec.rb +22 -8
- data/spec/integration/version_spec.rb +7 -7
- data/spec/integration/watcher_spec.rb +17 -18
- data/spec/integration/webhook.rb +5 -4
- data/spec/integration/worklog_spec.rb +8 -8
- data/spec/jira/base_factory_spec.rb +2 -1
- data/spec/jira/base_spec.rb +55 -41
- data/spec/jira/client_spec.rb +48 -34
- data/spec/jira/has_many_proxy_spec.rb +3 -3
- data/spec/jira/http_client_spec.rb +98 -26
- data/spec/jira/http_error_spec.rb +2 -2
- data/spec/jira/oauth_client_spec.rb +30 -8
- data/spec/jira/request_client_spec.rb +4 -4
- data/spec/jira/resource/agile_spec.rb +28 -28
- data/spec/jira/resource/attachment_spec.rb +142 -52
- data/spec/jira/resource/board_spec.rb +21 -20
- data/spec/jira/resource/createmeta_spec.rb +48 -48
- data/spec/jira/resource/field_spec.rb +30 -12
- data/spec/jira/resource/filter_spec.rb +4 -4
- data/spec/jira/resource/issue_picker_suggestions_spec.rb +18 -18
- data/spec/jira/resource/issue_spec.rb +44 -38
- data/spec/jira/resource/jira_picker_suggestions_issue_spec.rb +3 -3
- data/spec/jira/resource/project_factory_spec.rb +3 -2
- data/spec/jira/resource/project_spec.rb +16 -16
- data/spec/jira/resource/sprint_spec.rb +70 -3
- data/spec/jira/resource/status_spec.rb +21 -0
- data/spec/jira/resource/user_factory_spec.rb +4 -4
- data/spec/jira/resource/worklog_spec.rb +3 -3
- data/spec/mock_responses/sprint/1.json +13 -0
- data/spec/mock_responses/status/1.json +8 -1
- data/spec/mock_responses/status.json +40 -5
- data/spec/mock_responses/statuscategory/1.json +7 -0
- data/spec/mock_responses/statuscategory.json +30 -0
- data/spec/mock_responses/{user_username=admin.json → user_accountId=1234567890abcdef01234567.json} +2 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/support/clients_helper.rb +3 -5
- data/spec/support/shared_examples/integration.rb +25 -28
- metadata +25 -257
- data/.travis.yml +0 -9
- data/example.rb +0 -232
- data/http-basic-example.rb +0 -113
- data/lib/jira/resource/sprint_report.rb +0 -8
- data/lib/jira/tasks.rb +0 -0
- data/spec/jira/jwt_uri_builder_spec.rb +0 -59
data/lib/jira/resource/agile.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'cgi'
|
|
2
4
|
|
|
3
5
|
module JIRA
|
|
@@ -25,7 +27,8 @@ module JIRA
|
|
|
25
27
|
response = client.get(path_base(client) + "/board/#{board_id}/issue?#{hash_to_query_string(options)}")
|
|
26
28
|
json = parse_json(response.body)
|
|
27
29
|
# To get Issue objects with the same structure as for Issue.all
|
|
28
|
-
return {} if json['issues'].
|
|
30
|
+
return {} if json['issues'].empty?
|
|
31
|
+
|
|
29
32
|
issue_ids = json['issues'].map do |issue|
|
|
30
33
|
issue['id']
|
|
31
34
|
end
|
|
@@ -58,22 +61,17 @@ module JIRA
|
|
|
58
61
|
parse_json(response.body)
|
|
59
62
|
end
|
|
60
63
|
|
|
61
|
-
# def self.find(client, key, options = {})
|
|
62
|
-
# options[:maxResults] ||= 100
|
|
63
|
-
# fields = options[:fields].join(',') unless options[:fields].nil?
|
|
64
|
-
# response = client.get("/rest/api/latest/search?jql=sprint=#{key}&fields=#{fields}&maxResults=#{options[:maxResults]}")
|
|
65
|
-
# parse_json(response.body)
|
|
66
|
-
# end
|
|
67
|
-
|
|
68
64
|
private
|
|
69
65
|
|
|
70
66
|
def self.path_base(client)
|
|
71
|
-
client.options[:context_path]
|
|
67
|
+
"#{client.options[:context_path]}/rest/agile/1.0"
|
|
72
68
|
end
|
|
73
69
|
|
|
74
70
|
def path_base(client)
|
|
75
71
|
self.class.path_base(client)
|
|
76
72
|
end
|
|
73
|
+
|
|
74
|
+
private_class_method :path_base
|
|
77
75
|
end
|
|
78
76
|
end
|
|
79
77
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module JIRA
|
|
2
4
|
module Resource
|
|
3
5
|
class ApplicationLinkFactory < JIRA::BaseFactory # :nodoc:
|
|
@@ -5,7 +7,7 @@ module JIRA
|
|
|
5
7
|
end
|
|
6
8
|
|
|
7
9
|
class ApplicationLink < JIRA::Base
|
|
8
|
-
REST_BASE_PATH = '/rest/applinks/1.0'
|
|
10
|
+
REST_BASE_PATH = '/rest/applinks/1.0'
|
|
9
11
|
|
|
10
12
|
def self.endpoint_name
|
|
11
13
|
'listApplicationlinks'
|
|
@@ -24,12 +26,12 @@ module JIRA
|
|
|
24
26
|
json = parse_json(response.body)
|
|
25
27
|
json = json['list']
|
|
26
28
|
json.map do |attrs|
|
|
27
|
-
new(client, { attrs:
|
|
29
|
+
new(client, { attrs: }.merge(options))
|
|
28
30
|
end
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
def self.manifest(client)
|
|
32
|
-
url = full_url(client)
|
|
34
|
+
url = "#{full_url(client)}/manifest"
|
|
33
35
|
response = client.get(url)
|
|
34
36
|
json = parse_json(response.body)
|
|
35
37
|
JIRA::Base.new(client, attrs: json)
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'net/http/post/multipart'
|
|
4
|
+
require 'open-uri'
|
|
2
5
|
|
|
3
6
|
module JIRA
|
|
4
7
|
module Resource
|
|
@@ -15,18 +18,55 @@ module JIRA
|
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
def self.meta(client)
|
|
18
|
-
response = client.get(client.options[:rest_base_path]
|
|
21
|
+
response = client.get("#{client.options[:rest_base_path]}/attachment/meta")
|
|
19
22
|
parse_json(response.body)
|
|
20
23
|
end
|
|
21
24
|
|
|
25
|
+
# Opens a file streaming the download of the attachment.
|
|
26
|
+
# @example Write file contents to a file.
|
|
27
|
+
# File.open('some-filename', 'wb') do |output|
|
|
28
|
+
# download_file do |file|
|
|
29
|
+
# IO.copy_stream(file, output)
|
|
30
|
+
# end
|
|
31
|
+
# end
|
|
32
|
+
# @example Stream file contents for an HTTP response.
|
|
33
|
+
# response.headers[ "Content-Type" ] = "application/octet-stream"
|
|
34
|
+
# download_file do |file|
|
|
35
|
+
# chunk = file.read(8000)
|
|
36
|
+
# while chunk.present? do
|
|
37
|
+
# response.stream.write(chunk)
|
|
38
|
+
# chunk = file.read(8000)
|
|
39
|
+
# end
|
|
40
|
+
# end
|
|
41
|
+
# response.stream.close
|
|
42
|
+
# @param [Hash] headers Any additional headers to call Jira.
|
|
43
|
+
# @yield |file|
|
|
44
|
+
# @yieldparam [IO] file The IO object streaming the download.
|
|
45
|
+
def download_file(headers = {}, &block)
|
|
46
|
+
default_headers = client.options[:default_headers]
|
|
47
|
+
URI.parse(content).open(default_headers.merge(headers), &block)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Downloads the file contents as a string object.
|
|
51
|
+
#
|
|
52
|
+
# Note that this reads the contents into a ruby string in memory.
|
|
53
|
+
# A file might be very large so it is recommend to avoid this unless you are certain about doing so.
|
|
54
|
+
# Use the download_file method instead and avoid calling the read method without a limit.
|
|
55
|
+
#
|
|
56
|
+
# @param [Hash] headers Any additional headers to call Jira.
|
|
57
|
+
# @return [String,NilClass] The file contents.
|
|
58
|
+
def download_contents(headers = {})
|
|
59
|
+
download_file(headers, &:read)
|
|
60
|
+
end
|
|
61
|
+
|
|
22
62
|
def save!(attrs, path = url)
|
|
23
63
|
file = attrs['file'] || attrs[:file] # Keep supporting 'file' parameter as a string for backward compatibility
|
|
24
64
|
mime_type = attrs[:mimeType] || 'application/binary'
|
|
25
65
|
|
|
26
66
|
headers = { 'X-Atlassian-Token' => 'nocheck' }
|
|
27
|
-
data = { 'file' => UploadIO.new(file, mime_type, file) }
|
|
67
|
+
data = { 'file' => Multipart::Post::UploadIO.new(file, mime_type, file) }
|
|
28
68
|
|
|
29
|
-
response = client.post_multipart(path, data
|
|
69
|
+
response = client.post_multipart(path, data, headers)
|
|
30
70
|
|
|
31
71
|
set_attributes(attrs, response)
|
|
32
72
|
|
data/lib/jira/resource/board.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'cgi'
|
|
2
4
|
|
|
3
5
|
module JIRA
|
|
@@ -7,7 +9,7 @@ module JIRA
|
|
|
7
9
|
|
|
8
10
|
class Board < JIRA::Base
|
|
9
11
|
def self.all(client)
|
|
10
|
-
path = path_base(client)
|
|
12
|
+
path = "#{path_base(client)}/board"
|
|
11
13
|
response = client.get(path)
|
|
12
14
|
json = parse_json(response.body)
|
|
13
15
|
results = json['values']
|
|
@@ -74,13 +76,13 @@ module JIRA
|
|
|
74
76
|
end
|
|
75
77
|
|
|
76
78
|
def add_issue_to_backlog(issue)
|
|
77
|
-
client.post(path_base(client)
|
|
79
|
+
client.post("#{path_base(client)}/backlog/issue", { issues: [issue.id] }.to_json)
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
private
|
|
81
83
|
|
|
82
84
|
def self.path_base(client)
|
|
83
|
-
client.options[:context_path]
|
|
85
|
+
"#{client.options[:context_path]}/rest/agile/1.0"
|
|
84
86
|
end
|
|
85
87
|
|
|
86
88
|
def path_base(client)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module JIRA
|
|
2
4
|
module Resource
|
|
3
5
|
class CreatemetaFactory < JIRA::BaseFactory # :nodoc:
|
|
@@ -36,7 +38,7 @@ module JIRA
|
|
|
36
38
|
|
|
37
39
|
json = parse_json(response.body)
|
|
38
40
|
json['projects'].map do |attrs|
|
|
39
|
-
new(client, attrs:
|
|
41
|
+
new(client, attrs:)
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
end
|
data/lib/jira/resource/field.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module JIRA
|
|
2
4
|
module Resource
|
|
3
5
|
class FieldFactory < JIRA::BaseFactory # :nodoc:
|
|
@@ -26,20 +28,22 @@ module JIRA
|
|
|
26
28
|
# as a system field can't take precedence
|
|
27
29
|
fields.each do |f|
|
|
28
30
|
next if f.custom
|
|
31
|
+
|
|
29
32
|
name = safe_name(f.name)
|
|
30
33
|
field_map_reverse[f.id] = [f.name, name] # capture both the official name, and the mapped name
|
|
31
34
|
field_map[name] = f.id
|
|
32
35
|
end
|
|
33
36
|
|
|
34
|
-
fields.each do |f|
|
|
37
|
+
fields.each do |f| # rubocop:disable Style/CombinableLoops
|
|
35
38
|
next unless f.custom
|
|
39
|
+
|
|
36
40
|
name = if field_map.key? f.name
|
|
37
41
|
renamed = safer_name(f.name, f.id)
|
|
38
42
|
warn "Duplicate Field name #{f.name} #{f.id} - renaming as #{renamed}"
|
|
39
43
|
renamed
|
|
40
44
|
else
|
|
41
45
|
safe_name(f.name)
|
|
42
|
-
|
|
46
|
+
end
|
|
43
47
|
field_map_reverse[f.id] = [f.name, name] # capture both the official name, and the mapped name
|
|
44
48
|
field_map[name] = f.id
|
|
45
49
|
end
|
|
@@ -55,6 +59,7 @@ module JIRA
|
|
|
55
59
|
def self.name_to_id(client, field_name)
|
|
56
60
|
field_name = field_name.to_s
|
|
57
61
|
return field_name unless client.cache.field_map && client.cache.field_map[field_name]
|
|
62
|
+
|
|
58
63
|
client.cache.field_map[field_name]
|
|
59
64
|
end
|
|
60
65
|
|
|
@@ -66,7 +71,7 @@ module JIRA
|
|
|
66
71
|
end
|
|
67
72
|
end
|
|
68
73
|
|
|
69
|
-
def method_missing(method_name, *args, &
|
|
74
|
+
def method_missing(method_name, *args, &)
|
|
70
75
|
if attrs.key?(method_name.to_s)
|
|
71
76
|
attrs[method_name.to_s]
|
|
72
77
|
else
|
|
@@ -74,7 +79,7 @@ module JIRA
|
|
|
74
79
|
if attrs.key?(official_name)
|
|
75
80
|
attrs[official_name]
|
|
76
81
|
else
|
|
77
|
-
super
|
|
82
|
+
super
|
|
78
83
|
end
|
|
79
84
|
end
|
|
80
85
|
end
|
data/lib/jira/resource/filter.rb
CHANGED
data/lib/jira/resource/issue.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'cgi'
|
|
2
4
|
require 'json'
|
|
3
5
|
|
|
@@ -7,44 +9,25 @@ module JIRA
|
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
class Issue < JIRA::Base
|
|
10
|
-
has_one :reporter,
|
|
11
|
-
|
|
12
|
-
has_one :
|
|
13
|
-
nested_under: 'fields'
|
|
14
|
-
has_one :project, nested_under: 'fields'
|
|
15
|
-
|
|
12
|
+
has_one :reporter, class: JIRA::Resource::User, nested_under: 'fields'
|
|
13
|
+
has_one :assignee, class: JIRA::Resource::User, nested_under: 'fields'
|
|
14
|
+
has_one :project, nested_under: 'fields'
|
|
16
15
|
has_one :issuetype, nested_under: 'fields'
|
|
17
|
-
|
|
18
|
-
has_one :
|
|
19
|
-
|
|
20
|
-
has_one :status, nested_under: 'fields'
|
|
21
|
-
|
|
16
|
+
has_one :priority, nested_under: 'fields'
|
|
17
|
+
has_one :status, nested_under: 'fields'
|
|
18
|
+
has_one :resolution, nested_under: 'fields'
|
|
22
19
|
has_many :transitions
|
|
23
|
-
|
|
24
20
|
has_many :components, nested_under: 'fields'
|
|
25
|
-
|
|
26
21
|
has_many :comments, nested_under: %w[fields comment]
|
|
27
|
-
|
|
28
|
-
has_many :
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
has_many :versions, nested_under: 'fields'
|
|
32
|
-
has_many :fixVersions, class: JIRA::Resource::Version,
|
|
33
|
-
nested_under: 'fields'
|
|
34
|
-
|
|
22
|
+
has_many :attachments, nested_under: 'fields', attribute_key: 'attachment'
|
|
23
|
+
has_many :versions, nested_under: 'fields'
|
|
24
|
+
has_many :fixVersions, class: JIRA::Resource::Version, nested_under: 'fields'
|
|
35
25
|
has_many :worklogs, nested_under: %w[fields worklog]
|
|
36
|
-
has_one :sprint, class: JIRA::Resource::Sprint,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
has_many :closed_sprints, class: JIRA::Resource::Sprint,
|
|
40
|
-
nested_under: 'fields', attribute_key: 'closedSprints'
|
|
41
|
-
|
|
26
|
+
has_one :sprint, class: JIRA::Resource::Sprint, nested_under: 'fields'
|
|
27
|
+
has_many :closed_sprints, class: JIRA::Resource::Sprint, nested_under: 'fields', attribute_key: 'closedSprints'
|
|
42
28
|
has_many :issuelinks, nested_under: 'fields'
|
|
43
|
-
|
|
44
29
|
has_many :remotelink, class: JIRA::Resource::Remotelink
|
|
45
|
-
|
|
46
|
-
has_many :watchers, attribute_key: 'watches',
|
|
47
|
-
nested_under: %w[fields watches]
|
|
30
|
+
has_many :watchers, attribute_key: 'watches', nested_under: %w[fields watches]
|
|
48
31
|
|
|
49
32
|
def self.all(client)
|
|
50
33
|
start_at = 0
|
|
@@ -59,15 +42,21 @@ module JIRA
|
|
|
59
42
|
result.push(client.Issue.build(issue))
|
|
60
43
|
end
|
|
61
44
|
break if json['issues'].empty?
|
|
45
|
+
|
|
62
46
|
start_at += json['issues'].size
|
|
63
47
|
end
|
|
64
48
|
result
|
|
65
49
|
end
|
|
66
50
|
|
|
67
|
-
def self.jql(client, jql, options = { fields: nil, start_at: nil, max_results: nil, expand: nil,
|
|
51
|
+
def self.jql(client, jql, options = { fields: nil, start_at: nil, max_results: nil, expand: nil,
|
|
52
|
+
validate_query: true })
|
|
68
53
|
url = client.options[:rest_base_path] + "/search?jql=#{CGI.escape(jql)}"
|
|
69
54
|
|
|
70
|
-
|
|
55
|
+
if options[:fields]
|
|
56
|
+
url << "&fields=#{options[:fields].map do |value|
|
|
57
|
+
CGI.escape(client.Field.name_to_id(value))
|
|
58
|
+
end.join(',')}"
|
|
59
|
+
end
|
|
71
60
|
url << "&startAt=#{CGI.escape(options[:start_at].to_s)}" if options[:start_at]
|
|
72
61
|
url << "&maxResults=#{CGI.escape(options[:max_results].to_s)}" if options[:max_results]
|
|
73
62
|
url << '&validateQuery=false' if options[:validate_query] === false
|
|
@@ -79,9 +68,8 @@ module JIRA
|
|
|
79
68
|
|
|
80
69
|
response = client.get(url)
|
|
81
70
|
json = parse_json(response.body)
|
|
82
|
-
if options[:max_results] && (options[:max_results]
|
|
83
|
-
|
|
84
|
-
end
|
|
71
|
+
return json['total'] if options[:max_results] && (options[:max_results]).zero?
|
|
72
|
+
|
|
85
73
|
json['issues'].map do |issue|
|
|
86
74
|
client.Issue.build(issue)
|
|
87
75
|
end
|
|
@@ -92,14 +80,15 @@ module JIRA
|
|
|
92
80
|
# is not set
|
|
93
81
|
def fetch(reload = false, query_params = {})
|
|
94
82
|
return if expanded? && !reload
|
|
83
|
+
|
|
95
84
|
response = client.get(url_with_query_params(url, query_params))
|
|
96
85
|
set_attrs_from_response(response)
|
|
97
|
-
if @attrs && @attrs['fields'] &&
|
|
86
|
+
if @attrs && @attrs['fields'] &&
|
|
87
|
+
@attrs['fields']['worklog'] &&
|
|
88
|
+
(@attrs['fields']['worklog']['total'] > @attrs['fields']['worklog']['maxResults'])
|
|
98
89
|
worklog_url = client.options[:rest_base_path] + "/#{self.class.endpoint_name}/#{id}/worklog"
|
|
99
90
|
response = client.get(worklog_url)
|
|
100
|
-
unless response.body.nil? || (response.body.length < 2)
|
|
101
|
-
set_attrs({ 'fields' => { 'worklog' => self.class.parse_json(response.body) } }, false)
|
|
102
|
-
end
|
|
91
|
+
set_attrs({ 'fields' => { 'worklog' => self.class.parse_json(response.body) } }, false) unless response.body.nil? || (response.body.length < 2)
|
|
103
92
|
end
|
|
104
93
|
@expanded = true
|
|
105
94
|
end
|
|
@@ -113,14 +102,16 @@ module JIRA
|
|
|
113
102
|
end
|
|
114
103
|
|
|
115
104
|
def respond_to?(method_name, _include_all = false)
|
|
116
|
-
if attrs.key?('fields') && [method_name.to_s, client.Field.name_to_id(method_name)].any?
|
|
105
|
+
if attrs.key?('fields') && [method_name.to_s, client.Field.name_to_id(method_name)].any? do |k|
|
|
106
|
+
attrs['fields'].key?(k)
|
|
107
|
+
end
|
|
117
108
|
true
|
|
118
109
|
else
|
|
119
110
|
super(method_name)
|
|
120
111
|
end
|
|
121
112
|
end
|
|
122
113
|
|
|
123
|
-
def method_missing(method_name, *args, &
|
|
114
|
+
def method_missing(method_name, *args, &)
|
|
124
115
|
if attrs.key?('fields')
|
|
125
116
|
if attrs['fields'].key?(method_name.to_s)
|
|
126
117
|
attrs['fields'][method_name.to_s]
|
|
@@ -129,11 +120,11 @@ module JIRA
|
|
|
129
120
|
if attrs['fields'].key?(official_name)
|
|
130
121
|
attrs['fields'][official_name]
|
|
131
122
|
else
|
|
132
|
-
super
|
|
123
|
+
super
|
|
133
124
|
end
|
|
134
125
|
end
|
|
135
126
|
else
|
|
136
|
-
super
|
|
127
|
+
super
|
|
137
128
|
end
|
|
138
129
|
end
|
|
139
130
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module JIRA
|
|
2
4
|
module Resource
|
|
3
5
|
class IssuePickerSuggestionsFactory < JIRA::BaseFactory # :nodoc:
|
|
@@ -6,7 +8,8 @@ module JIRA
|
|
|
6
8
|
class IssuePickerSuggestions < JIRA::Base
|
|
7
9
|
has_many :sections, class: JIRA::Resource::IssuePickerSuggestionsIssue
|
|
8
10
|
|
|
9
|
-
def self.all(client, query = '', options = { current_jql: nil, current_issue_key: nil, current_project_id: nil,
|
|
11
|
+
def self.all(client, query = '', options = { current_jql: nil, current_issue_key: nil, current_project_id: nil,
|
|
12
|
+
show_sub_tasks: nil, show_sub_tasks_parent: nil })
|
|
10
13
|
url = client.options[:rest_base_path] + "/issue/picker?query=#{CGI.escape(query)}"
|
|
11
14
|
|
|
12
15
|
url << "¤tJQL=#{CGI.escape(options[:current_jql])}" if options[:current_jql]
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module JIRA
|
|
2
4
|
module Resource
|
|
3
5
|
class ProjectFactory < JIRA::BaseFactory # :nodoc:
|
|
@@ -15,7 +17,7 @@ module JIRA
|
|
|
15
17
|
|
|
16
18
|
# Returns all the issues for this project
|
|
17
19
|
def issues(options = {})
|
|
18
|
-
search_url = client.options[:rest_base_path]
|
|
20
|
+
search_url = "#{client.options[:rest_base_path]}/search"
|
|
19
21
|
query_params = { jql: "project=\"#{key}\"" }
|
|
20
22
|
query_params.update Base.query_params_for_search(options)
|
|
21
23
|
response = client.get(url_with_query_params(search_url, query_params))
|
|
@@ -26,7 +28,7 @@ module JIRA
|
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def users(start_at: nil, max_results: nil)
|
|
29
|
-
users_url = client.options[:rest_base_path]
|
|
31
|
+
users_url = "#{client.options[:rest_base_path]}/user/assignable/search"
|
|
30
32
|
query_params = { project: key_value }
|
|
31
33
|
query_params['startAt'] = start_at if start_at
|
|
32
34
|
query_params['maxResults'] = max_results if max_results
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'cgi'
|
|
2
4
|
|
|
3
5
|
module JIRA
|
|
@@ -7,7 +9,7 @@ module JIRA
|
|
|
7
9
|
|
|
8
10
|
class RapidView < JIRA::Base
|
|
9
11
|
def self.all(client)
|
|
10
|
-
response = client.get(path_base(client)
|
|
12
|
+
response = client.get("#{path_base(client)}/rapidview")
|
|
11
13
|
json = parse_json(response.body)
|
|
12
14
|
json['views'].map do |view|
|
|
13
15
|
client.RapidView.build(view)
|
|
@@ -44,7 +46,7 @@ module JIRA
|
|
|
44
46
|
|
|
45
47
|
def sprints(options = {})
|
|
46
48
|
params = { includeHistoricSprints: options.fetch(:include_historic, false),
|
|
47
|
-
includeFutureSprints:
|
|
49
|
+
includeFutureSprints: options.fetch(:include_future, false) }
|
|
48
50
|
response = client.get(path_base(client) + "/sprintquery/#{id}?#{params.to_query}")
|
|
49
51
|
json = self.class.parse_json(response.body)
|
|
50
52
|
json['sprints'].map do |sprint|
|
|
@@ -56,7 +58,7 @@ module JIRA
|
|
|
56
58
|
private
|
|
57
59
|
|
|
58
60
|
def self.path_base(client)
|
|
59
|
-
client.options[:context_path]
|
|
61
|
+
"#{client.options[:context_path]}/rest/greenhopper/1.0"
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
def path_base(client)
|
data/lib/jira/resource/sprint.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module JIRA
|
|
2
4
|
module Resource
|
|
3
5
|
class SprintFactory < JIRA::BaseFactory # :nodoc:
|
|
@@ -12,19 +14,20 @@ module JIRA
|
|
|
12
14
|
|
|
13
15
|
# get all issues of sprint
|
|
14
16
|
def issues(options = {})
|
|
15
|
-
jql =
|
|
17
|
+
jql = "sprint = #{id}"
|
|
16
18
|
jql += " and updated >= '#{options[:updated]}'" if options[:updated]
|
|
17
19
|
Issue.jql(client, jql)
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
def add_issue(issue)
|
|
21
|
-
|
|
22
|
-
response = client.post("#{agile_path}/issue", request_body)
|
|
23
|
-
true
|
|
23
|
+
add_issues([issue])
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def
|
|
27
|
-
|
|
26
|
+
def add_issues(issues)
|
|
27
|
+
issue_ids = issues.map(&:id)
|
|
28
|
+
request_body = { issues: issue_ids }.to_json
|
|
29
|
+
client.post("#{agile_path}/issue", request_body)
|
|
30
|
+
true
|
|
28
31
|
end
|
|
29
32
|
|
|
30
33
|
def start_date
|
|
@@ -42,13 +45,14 @@ module JIRA
|
|
|
42
45
|
def get_sprint_details_attribute(attribute_name)
|
|
43
46
|
attribute = instance_variable_get("@#{attribute_name}")
|
|
44
47
|
return attribute if attribute
|
|
48
|
+
|
|
45
49
|
get_sprint_details
|
|
46
50
|
instance_variable_get("@#{attribute_name}")
|
|
47
51
|
end
|
|
48
52
|
|
|
49
53
|
def get_sprint_details
|
|
50
54
|
search_url =
|
|
51
|
-
"#{client.options[:site]}#{client.options[:client_path]}/rest/
|
|
55
|
+
"#{client.options[:site]}#{client.options[:client_path]}/rest/agile/1.0/sprint/#{id}"
|
|
52
56
|
begin
|
|
53
57
|
response = client.get(search_url)
|
|
54
58
|
rescue StandardError
|
|
@@ -56,22 +60,9 @@ module JIRA
|
|
|
56
60
|
end
|
|
57
61
|
json = self.class.parse_json(response.body)
|
|
58
62
|
|
|
59
|
-
@start_date =
|
|
60
|
-
@end_date =
|
|
61
|
-
@
|
|
62
|
-
@sprint_report = client.SprintReport.build(json['contents'])
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def rapidview_id
|
|
66
|
-
return @attrs['rapidview_id'] if @attrs['rapidview_id']
|
|
67
|
-
search_url = client.options[:site] + '/secure/GHGoToBoard.jspa?sprintId=' + id.to_s
|
|
68
|
-
begin
|
|
69
|
-
response = client.get(search_url)
|
|
70
|
-
rescue JIRA::HTTPError => error
|
|
71
|
-
return unless error.response.instance_of? Net::HTTPFound
|
|
72
|
-
rapid_view_match = /rapidView=(\d+)&/.match(error.response['location'])
|
|
73
|
-
@attrs['rapidview_id'] = rapid_view_match[1] unless rapid_view_match.nil?
|
|
74
|
-
end
|
|
63
|
+
@start_date = json['startDate'] && Date.parse(json['startDate'])
|
|
64
|
+
@end_date = json['endDate'] && Date.parse(json['endDate'])
|
|
65
|
+
@complete_date = json['completeDate'] && Date.parse(json['completeDate'])
|
|
75
66
|
end
|
|
76
67
|
|
|
77
68
|
def save(attrs = {}, _path = nil)
|
data/lib/jira/resource/status.rb
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'status_category'
|
|
4
|
+
|
|
1
5
|
module JIRA
|
|
2
6
|
module Resource
|
|
3
7
|
class StatusFactory < JIRA::BaseFactory # :nodoc:
|
|
4
8
|
end
|
|
5
9
|
|
|
6
|
-
class Status < JIRA::Base
|
|
10
|
+
class Status < JIRA::Base
|
|
11
|
+
has_one :status_category, class: JIRA::Resource::StatusCategory, attribute_key: 'statusCategory'
|
|
12
|
+
end
|
|
7
13
|
end
|
|
8
14
|
end
|