jirametrics 2.17.1 → 2.18pre1
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.
Potentially problematic release.
This version of jirametrics might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/jirametrics/downloader.rb +26 -0
- data/lib/jirametrics/downloader_for_cloud.rb +2 -66
- data/lib/jirametrics/downloader_for_data_center.rb +2 -24
- data/lib/jirametrics/exporter.rb +3 -3
- data/lib/jirametrics/issue.rb +1 -5
- data/lib/jirametrics/jira_gateway.rb +10 -18
- data/lib/jirametrics.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 71833b8102c5a57b1b36fcc86f023c768b81680a64d24c851f40641d0c6bdeb8
|
|
4
|
+
data.tar.gz: 8dade5e4c90dcdb32e90fb97931da7f2d6ea734b27f988af455dd9414af54545
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e873d82bd16d851d8ccc382ed05cf352699686019f0bfcc5e5c1a2d63fffe74c1a62cb81b08566f3d6cdb6b1ef89e0e9aa0f725b7b8f1d5b47f4c06231b3f50f
|
|
7
|
+
data.tar.gz: bf4bdccb8f78bf2b594dc6131611777d7148d5aa5556317518fe975c41a08699df73528f6ee87ce1d2a19dd7da6a1ab45b480f782f55227e666a4b25a1059fb0
|
|
@@ -350,6 +350,32 @@ class Downloader
|
|
|
350
350
|
)
|
|
351
351
|
end
|
|
352
352
|
|
|
353
|
+
def bulk_fetch_issues issue_datas:, board:, in_initial_query:
|
|
354
|
+
log " Downloading #{issue_datas.size} issues", both: true
|
|
355
|
+
payload = {
|
|
356
|
+
'expand' => [
|
|
357
|
+
'changelog'
|
|
358
|
+
],
|
|
359
|
+
'fields' => ['*all'],
|
|
360
|
+
'issueIdsOrKeys' => issue_datas.collect(&:key)
|
|
361
|
+
}
|
|
362
|
+
response = @jira_gateway.post_request(
|
|
363
|
+
relative_url: issue_bulk_fetch_api,
|
|
364
|
+
payload: JSON.generate(payload)
|
|
365
|
+
)
|
|
366
|
+
response['issues'].each do |issue_json|
|
|
367
|
+
issue_json['exporter'] = {
|
|
368
|
+
'in_initial_query' => in_initial_query
|
|
369
|
+
}
|
|
370
|
+
issue = Issue.new(raw: issue_json, board: board)
|
|
371
|
+
data = issue_datas.find { |d| d.key == issue.key }
|
|
372
|
+
data.up_to_date = true
|
|
373
|
+
data.last_modified = issue.updated
|
|
374
|
+
data.issue = issue
|
|
375
|
+
end
|
|
376
|
+
issue_datas
|
|
377
|
+
end
|
|
378
|
+
|
|
353
379
|
def delete_issues_from_cache_that_are_not_in_server issue_data_hash:, path:
|
|
354
380
|
# The gotcha with deleted issues is that they just stop being returned in queries
|
|
355
381
|
# and we have no way to know that they should be removed from our local cache.
|
|
@@ -44,71 +44,7 @@ class DownloaderForCloud < Downloader
|
|
|
44
44
|
hash
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
def
|
|
48
|
-
|
|
49
|
-
# that only returns the "recent" changes, not all of them. So now we get the issue
|
|
50
|
-
# without changes and then make a second call for that changes. Then we insert it
|
|
51
|
-
# into the raw issue as if it had been there all along.
|
|
52
|
-
log " Downloading #{issue_datas.size} issues", both: true
|
|
53
|
-
payload = {
|
|
54
|
-
'fields' => ['*all'],
|
|
55
|
-
'issueIdsOrKeys' => issue_datas.collect(&:key)
|
|
56
|
-
}
|
|
57
|
-
response = @jira_gateway.post_request(
|
|
58
|
-
relative_url: '/rest/api/3/issue/bulkfetch',
|
|
59
|
-
payload: JSON.generate(payload)
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
attach_changelog_to_issues issue_datas: issue_datas, issue_jsons: response['issues']
|
|
63
|
-
|
|
64
|
-
response['issues'].each do |issue_json|
|
|
65
|
-
issue_json['exporter'] = {
|
|
66
|
-
'in_initial_query' => in_initial_query
|
|
67
|
-
}
|
|
68
|
-
issue = Issue.new(raw: issue_json, board: board)
|
|
69
|
-
data = issue_datas.find { |d| d.key == issue.key }
|
|
70
|
-
data.up_to_date = true
|
|
71
|
-
data.last_modified = issue.updated
|
|
72
|
-
data.issue = issue
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
issue_datas
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def attach_changelog_to_issues issue_datas:, issue_jsons:
|
|
79
|
-
max_results = 10_000 # The max jira accepts is 10K
|
|
80
|
-
payload = {
|
|
81
|
-
'issueIdsOrKeys' => issue_datas.collect(&:key),
|
|
82
|
-
'maxResults' => max_results
|
|
83
|
-
}
|
|
84
|
-
loop do
|
|
85
|
-
response = @jira_gateway.post_request(
|
|
86
|
-
relative_url: '/rest/api/3/changelog/bulkfetch',
|
|
87
|
-
payload: JSON.generate(payload)
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
response['issueChangeLogs'].each do |issue_change_log|
|
|
91
|
-
issue_id = issue_change_log['issueId']
|
|
92
|
-
json = issue_jsons.find { |json| json['id'] == issue_id }
|
|
93
|
-
|
|
94
|
-
unless json['changelog']
|
|
95
|
-
# If this is our first time in, there won't be a changelog section
|
|
96
|
-
json['changelog'] = {
|
|
97
|
-
'startAt' => 0,
|
|
98
|
-
'maxResults' => max_results,
|
|
99
|
-
'total' => 0,
|
|
100
|
-
'histories' => []
|
|
101
|
-
}
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
new_changes = issue_change_log['changeHistories']
|
|
105
|
-
json['changelog']['total'] += new_changes.size
|
|
106
|
-
json['changelog']['histories'] += new_changes
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
next_page_token = response['nextPageToken']
|
|
110
|
-
payload['nextPageToken'] = next_page_token
|
|
111
|
-
break if next_page_token.nil?
|
|
112
|
-
end
|
|
47
|
+
def issue_bulk_fetch_api
|
|
48
|
+
'/rest/api/3/issue/bulkfetch'
|
|
113
49
|
end
|
|
114
50
|
end
|
|
@@ -40,29 +40,7 @@ class DownloaderForDataCenter < Downloader
|
|
|
40
40
|
hash
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
payload = {
|
|
46
|
-
'expand' => [
|
|
47
|
-
'changelog'
|
|
48
|
-
],
|
|
49
|
-
'fields' => ['*all'],
|
|
50
|
-
'issueIdsOrKeys' => issue_datas.collect(&:key)
|
|
51
|
-
}
|
|
52
|
-
response = @jira_gateway.post_request(
|
|
53
|
-
relative_url: '/rest/api/2/issue/bulkfetch',
|
|
54
|
-
payload: JSON.generate(payload)
|
|
55
|
-
)
|
|
56
|
-
response['issues'].each do |issue_json|
|
|
57
|
-
issue_json['exporter'] = {
|
|
58
|
-
'in_initial_query' => in_initial_query
|
|
59
|
-
}
|
|
60
|
-
issue = Issue.new(raw: issue_json, board: board)
|
|
61
|
-
data = issue_datas.find { |d| d.key == issue.key }
|
|
62
|
-
data.up_to_date = true
|
|
63
|
-
data.last_modified = issue.updated
|
|
64
|
-
data.issue = issue
|
|
65
|
-
end
|
|
66
|
-
issue_datas
|
|
43
|
+
def issue_bulk_fetch_api
|
|
44
|
+
'/rest/api/2/issue/bulkfetch'
|
|
67
45
|
end
|
|
68
46
|
end
|
data/lib/jirametrics/exporter.rb
CHANGED
|
@@ -65,14 +65,14 @@ class Exporter
|
|
|
65
65
|
puts "Full output from downloader in #{file_system.logfile_name}"
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
def info
|
|
68
|
+
def info keys, name_filter:
|
|
69
69
|
selected = []
|
|
70
70
|
each_project_config(name_filter: name_filter) do |project|
|
|
71
71
|
project.evaluate_next_level
|
|
72
72
|
|
|
73
73
|
project.run load_only: true
|
|
74
74
|
project.issues.each do |issue|
|
|
75
|
-
selected << [project, issue] if
|
|
75
|
+
selected << [project, issue] if keys.include? issue.key
|
|
76
76
|
end
|
|
77
77
|
rescue => e # rubocop:disable Style/RescueStandardError
|
|
78
78
|
# This happens when we're attempting to load an aggregated project because it hasn't been
|
|
@@ -81,7 +81,7 @@ class Exporter
|
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
if selected.empty?
|
|
84
|
-
file_system.log "No issues found to match #{
|
|
84
|
+
file_system.log "No issues found to match #{keys.collect(&:inspect).join(', ')}"
|
|
85
85
|
else
|
|
86
86
|
selected.each do |project, issue|
|
|
87
87
|
file_system.log "\nProject #{project.name}", also_write_to_stderr: true
|
data/lib/jirametrics/issue.rb
CHANGED
|
@@ -212,11 +212,7 @@ class Issue
|
|
|
212
212
|
end
|
|
213
213
|
|
|
214
214
|
def parse_time text
|
|
215
|
-
|
|
216
|
-
Time.parse(text).getlocal(@timezone_offset)
|
|
217
|
-
else
|
|
218
|
-
Time.at(text / 1000).getlocal(@timezone_offset)
|
|
219
|
-
end
|
|
215
|
+
Time.parse(text).getlocal(@timezone_offset)
|
|
220
216
|
end
|
|
221
217
|
|
|
222
218
|
def created
|
|
@@ -7,7 +7,7 @@ require 'open3'
|
|
|
7
7
|
|
|
8
8
|
class JiraGateway
|
|
9
9
|
attr_accessor :ignore_ssl_errors
|
|
10
|
-
attr_reader :jira_url, :settings
|
|
10
|
+
attr_reader :jira_url, :settings
|
|
11
11
|
|
|
12
12
|
def initialize file_system:, jira_config:, settings:
|
|
13
13
|
@file_system = file_system
|
|
@@ -18,23 +18,15 @@ class JiraGateway
|
|
|
18
18
|
|
|
19
19
|
def post_request relative_url:, payload:
|
|
20
20
|
command = make_curl_command url: "#{@jira_url}#{relative_url}", method: 'POST'
|
|
21
|
-
log_entry = " #{command.gsub(/\s+/, ' ')}"
|
|
22
|
-
log_entry = sanitize_message log_entry
|
|
23
|
-
@file_system.log log_entry
|
|
24
|
-
|
|
25
21
|
stdout, stderr, status = Open3.capture3(command, stdin_data: payload)
|
|
26
|
-
unless
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@file_system.log "Returned (stderr): #{stderr.inspect}"
|
|
30
|
-
raise "Failed call with exit status #{status.exitstatus}. " \
|
|
31
|
-
"See #{@file_system.logfile_name} for details"
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
@file_system.log "Returned (stderr): #{stderr}" unless stderr == ''
|
|
35
|
-
raise 'no response from curl on stdout' if stdout == ''
|
|
22
|
+
@file_system.log "Error: #{stderr}" unless stderr == ''
|
|
23
|
+
raise 'no response' if stdout == ''
|
|
24
|
+
return parse_response(command: command, result: stdout) if status.success?
|
|
36
25
|
|
|
37
|
-
|
|
26
|
+
@file_system.log result
|
|
27
|
+
@file_system.log "Failed call with exit status #{status.exitstatus}."
|
|
28
|
+
raise "Failed call with exit status #{status.exitstatus}. " \
|
|
29
|
+
"See #{@file_system.logfile_name} for details"
|
|
38
30
|
end
|
|
39
31
|
|
|
40
32
|
def call_url relative_url:
|
|
@@ -61,12 +53,12 @@ class JiraGateway
|
|
|
61
53
|
token = @jira_api_token || @jira_personal_access_token
|
|
62
54
|
raise 'Neither Jira API Token or personal access token has been set' unless token
|
|
63
55
|
|
|
64
|
-
message.gsub(
|
|
56
|
+
message.gsub(@jira_api_token, '[API_TOKEN]')
|
|
65
57
|
end
|
|
66
58
|
|
|
67
59
|
def call_command command
|
|
68
60
|
log_entry = " #{command.gsub(/\s+/, ' ')}"
|
|
69
|
-
log_entry = sanitize_message log_entry
|
|
61
|
+
log_entry = sanitize_message log_entry if @jira_api_token
|
|
70
62
|
@file_system.log log_entry
|
|
71
63
|
|
|
72
64
|
result = `#{command}`
|
data/lib/jirametrics.rb
CHANGED
|
@@ -47,9 +47,9 @@ class JiraMetrics < Thor
|
|
|
47
47
|
|
|
48
48
|
option :config
|
|
49
49
|
desc 'info', 'Dump information about one issue'
|
|
50
|
-
def info
|
|
50
|
+
def info keys
|
|
51
51
|
load_config options[:config]
|
|
52
|
-
Exporter.instance.info(
|
|
52
|
+
Exporter.instance.info(keys, name_filter: options[:name] || '*')
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
no_commands do
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jirametrics
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.18pre1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Bowler
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2025-09-26 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: random-word
|
|
@@ -159,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
159
159
|
- !ruby/object:Gem::Version
|
|
160
160
|
version: '0'
|
|
161
161
|
requirements: []
|
|
162
|
-
rubygems_version: 3.
|
|
162
|
+
rubygems_version: 3.6.2
|
|
163
163
|
specification_version: 4
|
|
164
164
|
summary: Extract Jira metrics
|
|
165
165
|
test_files: []
|