Class: JIRA::Resource::Issue

Inherits:
Base
  • Object
show all
Defined in:
lib/jira/resource/issue.rb,
lib/jira/resource/issuelink.rb

Overview

This class provides the Issue object <-> REST mapping for JIRA::Resource::Issue derived class, i.e. the Create, Retrieve, Update, Delete lifecycle methods.

Lifecycle methods

Retrieving all issues

client.Issue.all

Retrieving a single issue

options = { expand: 'editmeta' }
issue = client.Issue.find("SUP-3000", options)

Creating a new issue

issue = client.Issue.build(fields: { summary: 'New issue', project: { key: 'SUP' }, issuetype: { name: 'Bug' } })
issue.save

Updating an issue

issue = client.Issue.find("SUP-3000")
issue.save(fields: { summary: 'Updated issue' })

Deleting an issue

issue = client.Issue.find("SUP-3000")
issue.delete

Constant Summary

Constants inherited from Base

Base::QUERY_PARAMS_FOR_SEARCH, Base::QUERY_PARAMS_FOR_SINGLE_FETCH

Instance Attribute Summary

Attributes inherited from Base

#attrs, #client, #deleted, #expanded

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

belongs_to, belongs_to_relationships, collection_attributes_are_nested, #collection_path, collection_path, #delete, endpoint_name, #has_errors?, has_many, has_one, hash_to_query_string, #id, #initialize, key_attribute, #key_value, maybe_nested_attribute, nested_collections, #new_record?, parse_json, #patched_url, #path_component, query_params_for_search, query_params_for_single_fetch, #save, #save!, #set_attrs, #set_attrs_from_response, singular_path, #to_json, #to_s, #to_sym, #url, url_with_query_params

Constructor Details

This class inherits a constructor from JIRA::Base

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/jira/resource/issue.rb', line 196

def method_missing(method_name, *args, &)
  if attrs.key?('fields')
    if attrs['fields'].key?(method_name.to_s)
      attrs['fields'][method_name.to_s]
    else
      official_name = client.Field.name_to_id(method_name)
      if attrs['fields'].key?(official_name)
        attrs['fields'][official_name]
      else
        super
      end
    end
  else
    super
  end
end

Class Method Details

.all(client) ⇒ Array<JIRA::Resource::Issue>

Get collection of issues.

Parameters:

Returns:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/jira/resource/issue.rb', line 64

def self.all(client)
  start_at = 0
  max_results = 1000
  result = []
  loop do
    url = client.options[:rest_base_path] +
          "/search/jql?expand=transitions.fields&maxResults=#{max_results}&startAt=#{start_at}"
    response = client.get(url)
    json = parse_json(response.body)
    json['issues'].map do |issue|
      result.push(client.Issue.build(issue))
    end
    break if json['issues'].empty?

    start_at += json['issues'].size
  end
  result
end

.build(attrs = {}) ⇒ JIRA::Resource::Issue

Constructs a new issue object.

Parameters:

  • attrs (Hash) (defaults to: {})

    the attributes to initialize the issue with

Returns:



# File 'lib/jira/resource/issue.rb', line 213

.find(client, key, options = {}) ⇒ JIRA::Resource::Issue

Gets/fetches an issue from JIRA.

Note: attachments are not fetched by default.

JIRA::Resource::Issue.find(client, “SUP-3000”, { fields: %w[summary description attachment created ] } )

Examples:

Find an issue

Parameters:

  • client (JIRA::Client)
  • key (String)

    the key of the issue to find

  • options (Hash) (defaults to: {})

    the options to find the issue with

Options Hash (options):

  • :fields (String)

    the fields to include in the response

Returns:



# File 'lib/jira/resource/issue.rb', line 213

.jql(client, jql, options = { fields: nil, max_results: nil, expand: nil, reconcile_issues: nil }) ⇒ Array<JIRA::Resource::Issue>

Get issues using JQL query.

Parameters:

  • client (JIRA::Client)
  • jql (String)

    the JQL query string to search with

  • options (Hash) (defaults to: { fields: nil, max_results: nil, expand: nil, reconcile_issues: nil })

    Jira API options for the search

Returns:



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/jira/resource/issue.rb', line 88

def self.jql(client, jql, options = { fields: nil, max_results: nil, expand: nil, reconcile_issues: nil })
  issues = []
  total = nil
  next_page_token = nil
  is_last = false

  until is_last
    result = jql_paged(client, jql, options.merge(next_page_token:))

    issues.concat(result[:issues])
    total = result[:total]
    next_page_token = result[:next_page_token]
    is_last = next_page_token.nil?
  end
  options[:max_results]&.zero? ? total : issues
end

.jql_paged(client, jql, options = { fields: nil, max_results: nil, expand: nil, reconcile_issues: nil, next_page_token: nil }) ⇒ Hash

Get paged issues using JQL query.

Parameters:

  • jql (String)

    the JQL query string to search with

  • options (Hash) (defaults to: { fields: nil, max_results: nil, expand: nil, reconcile_issues: nil, next_page_token: nil })

    Jira API options for the search, including next_page_token

Returns:

  • (Hash)

    with format { issues: [JIRA::Resource::Issue], next_page_token: [String], total: [Integer] }



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/jira/resource/issue.rb', line 109

def self.jql_paged(client, jql, options = { fields: nil, max_results: nil, expand: nil, reconcile_issues: nil, next_page_token: nil })
  url = jql_url(client, jql, options)
  next_page_token = options[:next_page_token]
  max_results = options[:max_results]

  issues = []

  page_url = url.dup
  page_url << "&nextPageToken=#{next_page_token}" if next_page_token

  response = client.get(page_url)
  json = parse_json(response.body)
  total = json['total']

  unless max_results&.zero?
    next_page_token = json['nextPageToken']
    json['issues'].map do |issue|
      issues << client.Issue.build(issue)
    end
  end

  { issues:, next_page_token:, total: }
end

.jql_url(client, jql, options) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/jira/resource/issue.rb', line 133

def self.jql_url(client, jql, options)
  url = client.options[:rest_base_path] + "/search/jql?jql=#{CGI.escape(jql)}"

  if options[:fields]
    url << "&fields=#{options[:fields].map do |value|
                        CGI.escape(client.Field.name_to_id(value))
                      end.join(',')}"
  end
  url << "&maxResults=#{CGI.escape(options[:max_results].to_s)}" if options[:max_results]
  url << "&reconcileIssues=#{CGI.escape(options[:reconcile_issues].to_s)}" if options[:reconcile_issues]

  if options[:expand]
    options[:expand] = [options[:expand]] if options[:expand].is_a?(String)
    url << "&expand=#{options[:expand].to_a.map { |value| CGI.escape(value.to_s) }.join(',')}"
  end
  url
end

Instance Method Details

#editmetaObject



176
177
178
179
180
181
182
# File 'lib/jira/resource/issue.rb', line 176

def editmeta
  editmeta_url = client.options[:rest_base_path] + "/#{self.class.endpoint_name}/#{key}/editmeta"

  response = client.get(editmeta_url)
  json = self.class.parse_json(response.body)
  json['fields']
end

#fetch(reload = false, query_params = {}) ⇒ void

This method returns an undefined value.

Fetches the attributes for the specified resource from JIRA unless the resource is already expanded and the optional force reload flag is not set

Parameters:

  • reload (Boolean) (defaults to: false)
  • query_params (Hash) (defaults to: {})

Options Hash (query_params):

  • :fields (String)
  • :expand (String)
  • :startAt (Integer)
  • :maxResults (Integer)


161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/jira/resource/issue.rb', line 161

def fetch(reload = false, query_params = {})
  return if expanded? && !reload

  response = client.get(url_with_query_params(url, query_params))
  set_attrs_from_response(response)
  if @attrs && @attrs['fields'] &&
     @attrs['fields']['worklog'] &&
     (@attrs['fields']['worklog']['total'] > @attrs['fields']['worklog']['maxResults'])
    worklog_url = client.options[:rest_base_path] + "/#{self.class.endpoint_name}/#{id}/worklog"
    response = client.get(worklog_url)
    set_attrs({ 'fields' => { 'worklog' => self.class.parse_json(response.body) } }, false) unless response.body.nil? || (response.body.length < 2)
  end
  @expanded = true
end