jirametrics 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/jirametrics +4 -0
- data/lib/jirametrics/aggregate_config.rb +89 -0
- data/lib/jirametrics/aging_work_bar_chart.rb +235 -0
- data/lib/jirametrics/aging_work_in_progress_chart.rb +148 -0
- data/lib/jirametrics/aging_work_table.rb +149 -0
- data/lib/jirametrics/anonymizer.rb +186 -0
- data/lib/jirametrics/blocked_stalled_change.rb +43 -0
- data/lib/jirametrics/board.rb +85 -0
- data/lib/jirametrics/board_column.rb +14 -0
- data/lib/jirametrics/board_config.rb +31 -0
- data/lib/jirametrics/change_item.rb +80 -0
- data/lib/jirametrics/chart_base.rb +239 -0
- data/lib/jirametrics/columns_config.rb +42 -0
- data/lib/jirametrics/cycletime_config.rb +69 -0
- data/lib/jirametrics/cycletime_histogram.rb +74 -0
- data/lib/jirametrics/cycletime_scatterplot.rb +128 -0
- data/lib/jirametrics/daily_wip_by_age_chart.rb +88 -0
- data/lib/jirametrics/daily_wip_by_blocked_stalled_chart.rb +77 -0
- data/lib/jirametrics/daily_wip_chart.rb +123 -0
- data/lib/jirametrics/data_quality_report.rb +278 -0
- data/lib/jirametrics/dependency_chart.rb +217 -0
- data/lib/jirametrics/discard_changes_before.rb +37 -0
- data/lib/jirametrics/download_config.rb +41 -0
- data/lib/jirametrics/downloader.rb +337 -0
- data/lib/jirametrics/examples/aggregated_project.rb +36 -0
- data/lib/jirametrics/examples/standard_project.rb +111 -0
- data/lib/jirametrics/expedited_chart.rb +169 -0
- data/lib/jirametrics/experimental/generator.rb +209 -0
- data/lib/jirametrics/experimental/info.rb +77 -0
- data/lib/jirametrics/exporter.rb +127 -0
- data/lib/jirametrics/file_config.rb +119 -0
- data/lib/jirametrics/fix_version.rb +21 -0
- data/lib/jirametrics/groupable_issue_chart.rb +44 -0
- data/lib/jirametrics/grouping_rules.rb +13 -0
- data/lib/jirametrics/hierarchy_table.rb +31 -0
- data/lib/jirametrics/html/aging_work_bar_chart.erb +72 -0
- data/lib/jirametrics/html/aging_work_in_progress_chart.erb +52 -0
- data/lib/jirametrics/html/aging_work_table.erb +60 -0
- data/lib/jirametrics/html/collapsible_issues_panel.erb +32 -0
- data/lib/jirametrics/html/cycletime_histogram.erb +41 -0
- data/lib/jirametrics/html/cycletime_scatterplot.erb +103 -0
- data/lib/jirametrics/html/daily_wip_chart.erb +63 -0
- data/lib/jirametrics/html/data_quality_report.erb +126 -0
- data/lib/jirametrics/html/expedited_chart.erb +67 -0
- data/lib/jirametrics/html/hierarchy_table.erb +29 -0
- data/lib/jirametrics/html/index.erb +66 -0
- data/lib/jirametrics/html/sprint_burndown.erb +116 -0
- data/lib/jirametrics/html/story_point_accuracy_chart.erb +57 -0
- data/lib/jirametrics/html/throughput_chart.erb +65 -0
- data/lib/jirametrics/html_report_config.rb +217 -0
- data/lib/jirametrics/issue.rb +521 -0
- data/lib/jirametrics/issue_link.rb +60 -0
- data/lib/jirametrics/json_file_loader.rb +9 -0
- data/lib/jirametrics/project_config.rb +442 -0
- data/lib/jirametrics/rules.rb +34 -0
- data/lib/jirametrics/self_or_issue_dispatcher.rb +15 -0
- data/lib/jirametrics/sprint.rb +43 -0
- data/lib/jirametrics/sprint_burndown.rb +335 -0
- data/lib/jirametrics/sprint_issue_change_data.rb +31 -0
- data/lib/jirametrics/status.rb +26 -0
- data/lib/jirametrics/status_collection.rb +67 -0
- data/lib/jirametrics/story_point_accuracy_chart.rb +139 -0
- data/lib/jirametrics/throughput_chart.rb +91 -0
- data/lib/jirametrics/tree_organizer.rb +96 -0
- data/lib/jirametrics/trend_line_calculator.rb +74 -0
- data/lib/jirametrics.rb +85 -0
- metadata +167 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TreeOrganizer
|
4
|
+
attr_reader :cyclical_links
|
5
|
+
|
6
|
+
class Node
|
7
|
+
attr_accessor :parent, :issue
|
8
|
+
attr_reader :children
|
9
|
+
|
10
|
+
def initialize issue: nil
|
11
|
+
@issue = issue
|
12
|
+
@children = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
"Node(#{@issue&.key || 'Root'}, parent: #{@parent&.issue&.key || 'Root'}, children: #{@children.inspect})"
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspect
|
20
|
+
to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def <=> other
|
24
|
+
issue <=> other.issue
|
25
|
+
end
|
26
|
+
|
27
|
+
def children?
|
28
|
+
!@children.empty?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize issues:
|
33
|
+
@issues = issues
|
34
|
+
@root = Node.new
|
35
|
+
@cyclical_links = []
|
36
|
+
@node_hash = {}
|
37
|
+
|
38
|
+
@issues.each do |issue|
|
39
|
+
add issue
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def add issue, bread_crumbs = []
|
44
|
+
parent_node = @root
|
45
|
+
|
46
|
+
issue_node = find_node issue.key
|
47
|
+
return issue_node if issue_node
|
48
|
+
|
49
|
+
parent_issue = issue.parent
|
50
|
+
if parent_issue
|
51
|
+
cyclical = bread_crumbs.include? parent_issue.key
|
52
|
+
bread_crumbs << issue.key
|
53
|
+
if cyclical
|
54
|
+
@cyclical_links << bread_crumbs.reverse
|
55
|
+
else
|
56
|
+
parent_node = find_node parent_issue.key
|
57
|
+
end
|
58
|
+
parent_node = add parent_issue, bread_crumbs if parent_node.nil?
|
59
|
+
end
|
60
|
+
|
61
|
+
issue_node = Node.new(issue: issue)
|
62
|
+
if parent_node
|
63
|
+
parent_node.children << issue_node
|
64
|
+
@node_hash[issue_node.issue.key] = issue_node
|
65
|
+
end
|
66
|
+
issue_node
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_node issue_key
|
70
|
+
@node_hash[issue_key]
|
71
|
+
# @root.children.find { |node| node.issue.key == issue_key }
|
72
|
+
end
|
73
|
+
|
74
|
+
def find_issue issue_key
|
75
|
+
@issues.find { |issue| issue.key == issue_key }
|
76
|
+
end
|
77
|
+
|
78
|
+
def flattened_issue_keys
|
79
|
+
flattened_nodes.collect do |node, depth|
|
80
|
+
[node.issue.key, depth]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def flattened_nodes
|
85
|
+
list = []
|
86
|
+
walk_children parent: @root, list: list, depth: 1
|
87
|
+
list
|
88
|
+
end
|
89
|
+
|
90
|
+
def walk_children parent:, list:, depth:
|
91
|
+
parent.children.sort.each do |node|
|
92
|
+
list << [node, depth]
|
93
|
+
walk_children parent: node, list: list, depth: depth + 1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TrendLineCalculator
|
4
|
+
# Using math from https://math.stackexchange.com/questions/204020/what-is-the-equation-used-to-calculate-a-linear-trendline
|
5
|
+
|
6
|
+
def initialize points
|
7
|
+
# We can't do trend calculations with less than two data points
|
8
|
+
@valid = points.size >= 2
|
9
|
+
return unless valid?
|
10
|
+
|
11
|
+
sum_of_x = points.collect { |x, _y| x }.sum
|
12
|
+
sum_of_y = points.collect { |_x, y| y }.sum
|
13
|
+
sum_of_xy = points.collect { |x, y| x * y }.sum
|
14
|
+
sum_of_x2 = points.collect { |x, _y| x * x }.sum
|
15
|
+
n = points.size.to_f
|
16
|
+
|
17
|
+
@slope = ((n * sum_of_xy) - (sum_of_x * sum_of_y)) / ((n * sum_of_x2) - (sum_of_x * sum_of_x))
|
18
|
+
@offset = (sum_of_y - (@slope * sum_of_x)) / n
|
19
|
+
|
20
|
+
@valid = false if vertical?
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid? = @valid
|
24
|
+
def horizontal? = @slope.zero?
|
25
|
+
def vertical? = @slope.nan? || @slope.infinite?
|
26
|
+
|
27
|
+
def calc_y x: # rubocop:disable Naming/MethodParameterName
|
28
|
+
((x * @slope) + @offset).to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
def line_crosses_at y: # rubocop:disable Naming/MethodParameterName
|
32
|
+
raise "line will never cross #{y}. Trend is perfectly horizontal" if horizontal?
|
33
|
+
|
34
|
+
((y.to_f - @offset) / @slope).to_i
|
35
|
+
end
|
36
|
+
|
37
|
+
# If the trend line can't be calculated then return an empty array. Otherwise, return
|
38
|
+
# an array with two (x,y) points, with which you can draw the trend line.
|
39
|
+
def chart_datapoints range:, max_y:, min_y: 0
|
40
|
+
raise 'max_y is nil' if max_y.nil?
|
41
|
+
return [] unless valid?
|
42
|
+
|
43
|
+
data_points = []
|
44
|
+
x_start = range.begin
|
45
|
+
y_start = calc_y(x: range.begin).to_i
|
46
|
+
x_end = range.end
|
47
|
+
y_end = calc_y(x: range.end).to_i
|
48
|
+
|
49
|
+
if y_start < min_y
|
50
|
+
x_start = line_crosses_at y: 0
|
51
|
+
y_start = 0
|
52
|
+
end
|
53
|
+
|
54
|
+
if y_start > max_y
|
55
|
+
x_start = line_crosses_at y: max_y
|
56
|
+
y_start = max_y
|
57
|
+
end
|
58
|
+
|
59
|
+
if y_end < min_y
|
60
|
+
x_end = line_crosses_at y: 0
|
61
|
+
y_end = 0
|
62
|
+
end
|
63
|
+
|
64
|
+
if y_end > max_y
|
65
|
+
x_end = line_crosses_at y: max_y
|
66
|
+
y_end = max_y
|
67
|
+
end
|
68
|
+
|
69
|
+
data_points << { x: x_start, y: y_start }
|
70
|
+
data_points << { x: x_end, y: y_end }
|
71
|
+
|
72
|
+
data_points
|
73
|
+
end
|
74
|
+
end
|
data/lib/jirametrics.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
class JiraMetrics < Thor
|
6
|
+
option :config
|
7
|
+
desc 'export', "Export data into either reports or CSV's as per the configuration"
|
8
|
+
def export
|
9
|
+
load_config options[:config]
|
10
|
+
Exporter.instance.export
|
11
|
+
end
|
12
|
+
|
13
|
+
option :config
|
14
|
+
desc 'download', 'Download data from Jira'
|
15
|
+
def download
|
16
|
+
load_config options[:config]
|
17
|
+
Exporter.instance.download
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def load_config config_file
|
23
|
+
config_file = './config.rb' if config_file.nil?
|
24
|
+
|
25
|
+
if File.exist? config_file
|
26
|
+
# The fact that File.exist can see the file does not mean that require will be
|
27
|
+
# able to load it. Convert this to an absolute pathname now for require.
|
28
|
+
config_file = File.absolute_path(config_file).to_s
|
29
|
+
else
|
30
|
+
puts "Cannot find configuration file #{config_file.inspect}"
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'jirametrics/chart_base'
|
35
|
+
require 'jirametrics/rules'
|
36
|
+
require 'jirametrics/grouping_rules'
|
37
|
+
require 'jirametrics/daily_wip_chart'
|
38
|
+
require 'jirametrics/groupable_issue_chart'
|
39
|
+
require 'jirametrics/discard_changes_before'
|
40
|
+
|
41
|
+
require 'jirametrics/aggregate_config'
|
42
|
+
require 'jirametrics/expedited_chart'
|
43
|
+
require 'jirametrics/board_config'
|
44
|
+
require 'jirametrics/file_config'
|
45
|
+
require 'jirametrics/trend_line_calculator'
|
46
|
+
require 'jirametrics/status'
|
47
|
+
require 'jirametrics/issue_link'
|
48
|
+
require 'jirametrics/story_point_accuracy_chart'
|
49
|
+
require 'jirametrics/status_collection'
|
50
|
+
require 'jirametrics/sprint'
|
51
|
+
require 'jirametrics/issue'
|
52
|
+
require 'jirametrics/daily_wip_by_age_chart'
|
53
|
+
require 'jirametrics/aging_work_in_progress_chart'
|
54
|
+
require 'jirametrics/cycletime_scatterplot'
|
55
|
+
require 'jirametrics/sprint_issue_change_data'
|
56
|
+
require 'jirametrics/cycletime_histogram'
|
57
|
+
require 'jirametrics/daily_wip_by_blocked_stalled_chart'
|
58
|
+
require 'jirametrics/html_report_config'
|
59
|
+
require 'jirametrics/data_quality_report'
|
60
|
+
require 'jirametrics/aging_work_bar_chart'
|
61
|
+
require 'jirametrics/change_item'
|
62
|
+
require 'jirametrics/project_config'
|
63
|
+
require 'jirametrics/dependency_chart'
|
64
|
+
require 'jirametrics/cycletime_config'
|
65
|
+
require 'jirametrics/tree_organizer'
|
66
|
+
require 'jirametrics/aging_work_table'
|
67
|
+
require 'jirametrics/sprint_burndown'
|
68
|
+
require 'jirametrics/self_or_issue_dispatcher'
|
69
|
+
require 'jirametrics/throughput_chart'
|
70
|
+
require 'jirametrics/exporter'
|
71
|
+
require 'jirametrics/json_file_loader'
|
72
|
+
require 'jirametrics/blocked_stalled_change'
|
73
|
+
require 'jirametrics/board_column'
|
74
|
+
require 'jirametrics/anonymizer'
|
75
|
+
require 'jirametrics/downloader'
|
76
|
+
require 'jirametrics/fix_version'
|
77
|
+
require 'jirametrics/download_config'
|
78
|
+
require 'jirametrics/columns_config'
|
79
|
+
require 'jirametrics/hierarchy_table'
|
80
|
+
require 'jirametrics/board'
|
81
|
+
require config_file
|
82
|
+
end
|
83
|
+
|
84
|
+
# Dir.foreach('lib/jirametrics') {|file| puts "require 'jirametrics/#{$1}'" if file =~ /^(.+)\.rb$/}
|
85
|
+
end
|
metadata
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jirametrics
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Bowler
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-07-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: random-word
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.1.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.1.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: require_all
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.2.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.2.2
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.4'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.4'
|
69
|
+
description: Tool to extract metrics from Jira and export to either a report or to
|
70
|
+
CSV files
|
71
|
+
email: mbowler@gargoylesoftware.com
|
72
|
+
executables:
|
73
|
+
- jirametrics
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- bin/jirametrics
|
78
|
+
- lib/jirametrics.rb
|
79
|
+
- lib/jirametrics/aggregate_config.rb
|
80
|
+
- lib/jirametrics/aging_work_bar_chart.rb
|
81
|
+
- lib/jirametrics/aging_work_in_progress_chart.rb
|
82
|
+
- lib/jirametrics/aging_work_table.rb
|
83
|
+
- lib/jirametrics/anonymizer.rb
|
84
|
+
- lib/jirametrics/blocked_stalled_change.rb
|
85
|
+
- lib/jirametrics/board.rb
|
86
|
+
- lib/jirametrics/board_column.rb
|
87
|
+
- lib/jirametrics/board_config.rb
|
88
|
+
- lib/jirametrics/change_item.rb
|
89
|
+
- lib/jirametrics/chart_base.rb
|
90
|
+
- lib/jirametrics/columns_config.rb
|
91
|
+
- lib/jirametrics/cycletime_config.rb
|
92
|
+
- lib/jirametrics/cycletime_histogram.rb
|
93
|
+
- lib/jirametrics/cycletime_scatterplot.rb
|
94
|
+
- lib/jirametrics/daily_wip_by_age_chart.rb
|
95
|
+
- lib/jirametrics/daily_wip_by_blocked_stalled_chart.rb
|
96
|
+
- lib/jirametrics/daily_wip_chart.rb
|
97
|
+
- lib/jirametrics/data_quality_report.rb
|
98
|
+
- lib/jirametrics/dependency_chart.rb
|
99
|
+
- lib/jirametrics/discard_changes_before.rb
|
100
|
+
- lib/jirametrics/download_config.rb
|
101
|
+
- lib/jirametrics/downloader.rb
|
102
|
+
- lib/jirametrics/examples/aggregated_project.rb
|
103
|
+
- lib/jirametrics/examples/standard_project.rb
|
104
|
+
- lib/jirametrics/expedited_chart.rb
|
105
|
+
- lib/jirametrics/experimental/generator.rb
|
106
|
+
- lib/jirametrics/experimental/info.rb
|
107
|
+
- lib/jirametrics/exporter.rb
|
108
|
+
- lib/jirametrics/file_config.rb
|
109
|
+
- lib/jirametrics/fix_version.rb
|
110
|
+
- lib/jirametrics/groupable_issue_chart.rb
|
111
|
+
- lib/jirametrics/grouping_rules.rb
|
112
|
+
- lib/jirametrics/hierarchy_table.rb
|
113
|
+
- lib/jirametrics/html/aging_work_bar_chart.erb
|
114
|
+
- lib/jirametrics/html/aging_work_in_progress_chart.erb
|
115
|
+
- lib/jirametrics/html/aging_work_table.erb
|
116
|
+
- lib/jirametrics/html/collapsible_issues_panel.erb
|
117
|
+
- lib/jirametrics/html/cycletime_histogram.erb
|
118
|
+
- lib/jirametrics/html/cycletime_scatterplot.erb
|
119
|
+
- lib/jirametrics/html/daily_wip_chart.erb
|
120
|
+
- lib/jirametrics/html/data_quality_report.erb
|
121
|
+
- lib/jirametrics/html/expedited_chart.erb
|
122
|
+
- lib/jirametrics/html/hierarchy_table.erb
|
123
|
+
- lib/jirametrics/html/index.erb
|
124
|
+
- lib/jirametrics/html/sprint_burndown.erb
|
125
|
+
- lib/jirametrics/html/story_point_accuracy_chart.erb
|
126
|
+
- lib/jirametrics/html/throughput_chart.erb
|
127
|
+
- lib/jirametrics/html_report_config.rb
|
128
|
+
- lib/jirametrics/issue.rb
|
129
|
+
- lib/jirametrics/issue_link.rb
|
130
|
+
- lib/jirametrics/json_file_loader.rb
|
131
|
+
- lib/jirametrics/project_config.rb
|
132
|
+
- lib/jirametrics/rules.rb
|
133
|
+
- lib/jirametrics/self_or_issue_dispatcher.rb
|
134
|
+
- lib/jirametrics/sprint.rb
|
135
|
+
- lib/jirametrics/sprint_burndown.rb
|
136
|
+
- lib/jirametrics/sprint_issue_change_data.rb
|
137
|
+
- lib/jirametrics/status.rb
|
138
|
+
- lib/jirametrics/status_collection.rb
|
139
|
+
- lib/jirametrics/story_point_accuracy_chart.rb
|
140
|
+
- lib/jirametrics/throughput_chart.rb
|
141
|
+
- lib/jirametrics/tree_organizer.rb
|
142
|
+
- lib/jirametrics/trend_line_calculator.rb
|
143
|
+
homepage: https://rubygems.org/gems/jirametrics
|
144
|
+
licenses:
|
145
|
+
- Apache-2.0
|
146
|
+
metadata:
|
147
|
+
rubygems_mfa_required: 'true'
|
148
|
+
post_install_message:
|
149
|
+
rdoc_options: []
|
150
|
+
require_paths:
|
151
|
+
- lib
|
152
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: 3.0.0
|
157
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
requirements: []
|
163
|
+
rubygems_version: 3.2.15
|
164
|
+
signing_key:
|
165
|
+
specification_version: 4
|
166
|
+
summary: Extract Jira metrics
|
167
|
+
test_files: []
|