Class: BetterJira::Jira

Inherits:
Object
  • Object
show all
Defined in:
lib/better_jira/jira.rb

Instance Method Summary collapse

Constructor Details

#initialize(jira_url, trust_ca = nil) ⇒ Jira

Construct the object

Parameters:

  • jira_url (String)

    the base url to your jira instance, ie: jira.mycompany.com

  • trust_ca (String) (defaults to: nil)

    the path to a PEM file that contains a CA certificate to trust



10
11
12
13
14
15
# File 'lib/better_jira/jira.rb', line 10

def initialize(jira_url, trust_ca = nil) 
  @jira_url = jira_url
  @soap = SOAP::WSDLDriverFactory.new(@jira_url + "/rpc/soap/jirasoapservice-v2?wsdl").create_rpc_driver
  @client = HTTPClient.new
  @client.ssl_config.set_trust_ca(trust_ca) unless trust_ca.nil?
end

Instance Method Details

#[](key) ⇒ Object

Gets the specified issue from the jira server

See Also:



207
208
209
# File 'lib/better_jira/jira.rb', line 207

def [](key)
  get_issue(key)
end

#add_comment(key, comment, options = {}) ⇒ Object

Adds a comment to the issue specified by key

Parameters:

  • key (String)

    the issue to comment on

  • comment (String)

    the comment to use

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

Options Hash (options):

  • :body (String)

    the comment body to use, shouldn’t be used

  • :groupLevel (String)

    ?

  • :roleLevel (String)

    ?



180
181
182
183
184
# File 'lib/better_jira/jira.rb', line 180

def add_comment(key, comment, options={})
  options[:body] = comment if options[:body].nil?

  @soap.addComment(@token, key, options)
end

#available_actions(key) ⇒ Hash

Gets the available actions for an issue from the server

Parameters:

  • key (String)

    the issue to look up

Returns:

  • (Hash)

    keys are the jira id, values are the name of the action



191
192
193
194
195
# File 'lib/better_jira/jira.rb', line 191

def available_actions(key)
  BetterJira::Exceptions.wrap_soap {
    BetterJira::simple_soap_mapping(@soap.getAvailableActions(@token, key))
  }
end

#convert_custom_field_value_to_happy_jira_time(value) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/better_jira/jira.rb', line 85

def convert_custom_field_value_to_happy_jira_time(value)
  if (value != nil) then
    if (Array === value) then
      value = value.map { |x| 
        q = nil
        q = x if String === x
        q = x['id'] if SOAP::Mapping::Object === x
        q
      }
    elsif (SOAP::Mapping::Object === value) then
      value = [value['id']]
    elsif (String === value) then
      value = [value]
    elsif (DateTime === value) then
      value = [value.strftime('%d/%b/%y')]
    end
  end
end

#each_issue_from_filter(filter_id, options = {}) {|issue| ... } ⇒ Object

Iterates over all the issues in a filter, passing each JiraIssue into the block

Parameters:

  • filter_id (Integer)

    the filter to load

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

    the options to use when iterating

Options Hash (options):

  • :batch_size (Integer) — default: 50

    the number of issues to retrieve at a time

  • :exclude_if_in_filter (Integer) — default: nil

    a filter to use as an exclude list if present

Yields:

  • a block for iterating over the list

Yield Parameters:



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/better_jira/jira.rb', line 51

def each_issue_from_filter(filter_id, options ={}, &block)
  options[:batch_size] ||= 50

  exclude_issues = []

  if (options[:exclude_if_in_filter]) then
    each_issue_from_filter(options[:exclude_if_in_filter]) { |issue|
      exclude_issues << issue[:key]
    }
  end

  offset = 0
  while( (issues = @soap.getIssuesFromFilterWithLimit(@token, filter_id, offset, options[:batch_size])) != nil) 
    break if offset >= @soap.getIssueCountForFilter(@token, filter_id) 
    offset += issues.length
  
    issues.each {|issue|
      issue = JiraIssue.new(issue, self)
      block.call(issue) unless exclude_issues.include?(issue[:key])
    }
  end
end

#fields_for_action(key, action_id) ⇒ Hash

Gets the available fields for edit during an action

Parameters:

  • key (String)

    the issue to look up

  • action_id (Integer)

    the action to look up

Returns:

  • (Hash)

    keys are the jira id, values are the name of the field



217
218
219
220
221
# File 'lib/better_jira/jira.rb', line 217

def fields_for_action(key, action_id)
  BetterJira::Exceptions.wrap_soap {
    BetterJira::simple_soap_mapping(@soap.getFieldsForAction(@token, key, action_id))
  }
end

#fields_for_edit(key) ⇒ Hash

Retrieves all the fields available for edit on the particular issue key

Parameters:

  • key (String)

    the issue key to check (ie: TEST-100)

Returns:

  • (Hash)

    a hash of jira field id to name



39
40
41
# File 'lib/better_jira/jira.rb', line 39

def fields_for_edit(key)
  BetterJira::simple_soap_mapping(@soap.getFieldsForEdit(@token, key))
end

#get_issue(key) ⇒ JiraIssue

Gets the specified issue from the jira server

Parameters:

  • key (String)

    the issue key

Returns:



201
202
203
# File 'lib/better_jira/jira.rb', line 201

def get_issue(key)
  JiraIssue.new(@soap.getIssue(@token, key), self)
end

#login(username, password) ⇒ Object

Login to the jira instance

Parameters:

  • username (String)

    your username

  • password (String)

    your password

Raises:

  • if login fails



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/better_jira/jira.rb', line 23

def (username, password)
  @token = @soap.(username, password)

  destination = '/success'
  res = @client.post("#{@jira_url}/secure/Dashboard.jspa", {
    'os_username' => username,
    'os_password' => password,
    'os_destination' => destination
  })
  raise "Login Fail!" if res.status != 302 || (res.header['Location'] && res.header['Location'].first[-destination.length, destination.length] != destination)
end

#map_version_fields(project, fields, cur_depth = 0, versions = nil) ⇒ Object



223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/better_jira/jira.rb', line 223

def map_version_fields(project, fields, cur_depth = 0, versions = nil)
  versions = versions_for_project(project)

  if (cur_depth == 0 && Array === fields) then
    fields.map { |q|
      map_version_fields(project, q, cur_depth + 1, versions)
    }.flatten
  elsif (Fixnum === fields || Integer === fields)
    [fields.to_s]
  elsif (String === fields)
    versions = versions.select { |version| version.name == fields }
    versions = versions.map { |version| version['id'] }
  end
end

#progress_workflow(key, workflow_action_id, custom_field_values, opts = {}) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/better_jira/jira.rb', line 104

def progress_workflow(key, workflow_action_id, custom_field_values, opts = {})
  puts "Shit passed in" if JIRA_DEBUG
  puts "==============" if JIRA_DEBUG
  p custom_field_values if JIRA_DEBUG
  puts "" if JIRA_DEBUG



  cfvs = []
  
  unless @client.nil?
    res = @client.get("#{@jira_url}/si/jira.issueviews:issue-xml/#{key}/#{key}.xml")
    puts res.content if JIRA_DEBUG
    match = res.content.match(/<timeestimate seconds="(.*?)">(.*?)<\/timeestimate>/)
    time_estimate = "#{match[1].to_i/60}" unless match.nil?
  end


  issue = get_issue(key)
  fields = fields_for_action(key, workflow_action_id)

  puts "Issue" if JIRA_DEBUG
  p issue if JIRA_DEBUG
  puts "" if JIRA_DEBUG

  moronic_map = {
    'issuetype' => 'type',
    'versions' => 'affectsVersions'
  }
    puts "Fields" if JIRA_DEBUG
    puts "======" if JIRA_DEBUG
  fields.each {|f|

    p f if JIRA_DEBUG
    real_field_name = moronic_map[f['id']] ? moronic_map[f['id']] : f['id']
  
    if (real_field_name != '' && custom_field_values[real_field_name.to_sym] != nil)
      value = custom_field_values[real_field_name.to_sym]
    elsif (real_field_name != '' && custom_field_values[real_field_name] != nil)
      value = custom_field_values[real_field_name]
    elsif (real_field_name == 'timetracking') then
      value = time_estimate
    elsif (real_field_name =~ /customfield_/) then
      q = issue.customFieldValues.find { |c| c.customfieldId == real_field_name }
      value = q.values unless q.nil?
    else
      value = nil
      value = issue.send('[]', real_field_name) if not real_field_name.empty?
    end
  
    value = convert_custom_field_value_to_happy_jira_time(value)
  
    puts "" if JIRA_DEBUG
    p value if JIRA_DEBUG
    puts "" if JIRA_DEBUG
  
    cfvs << {:id => f['id'], :values => value}
  }

  puts "Output!" if JIRA_DEBUG
  puts "=======" if JIRA_DEBUG
  p cfvs if JIRA_DEBUG



  @soap.progressWorkflowAction(@token, key, workflow_action_id, cfvs)
end

#update_issue(key, remote_field_changes) ⇒ Object



81
82
83
# File 'lib/better_jira/jira.rb', line 81

def update_issue(key, remote_field_changes)
  @soap.updateIssue(@token, key, remote_field_changes)
end

#versions_for_project(project_key) ⇒ Object

Retrieves all of the versions for a particular project from the Jira server

Parameters:

  • project_key (String)

    the project key to look up, ie: “MYPROJ”



77
78
79
# File 'lib/better_jira/jira.rb', line 77

def versions_for_project(project_key)
  @soap.getVersions(@token, project_key).map{|x| BetterJira::JiraVersion.convert_from_soap(x)}
end