jirametrics 2.19 → 2.20
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/lib/jirametrics/board_config.rb +2 -1
- data/lib/jirametrics/cycletime_config.rb +22 -3
- data/lib/jirametrics/data_quality_report.rb +6 -3
- data/lib/jirametrics/examples/standard_project.rb +9 -9
- data/lib/jirametrics/html/aging_work_in_progress_chart.erb +1 -1
- data/lib/jirametrics/html/index.erb +1 -1
- data/lib/jirametrics/html_report_config.rb +3 -1
- data/lib/jirametrics/project_config.rb +4 -0
- data/lib/jirametrics/settings.json +3 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ba3c618918a65132645f5c74d55695694bf54514b60c9a3d42b666592c1d1e39
|
|
4
|
+
data.tar.gz: 39436664f71ad5814f90bd3549520f76d8a1f9d44270338ef3642b5825ad9c76
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f777b591e53d721796ef66fd9f107e5853e4f9f5e85178e63b43aa790bc271120596451928b27156694e4d44aee781fa16ac70d80e72e4e0a53f723090e02b70
|
|
7
|
+
data.tar.gz: d9b4392d5b45bdb94bb15530d52ce6dee6caddc8904570ce3d59dfc4dd2ba624344d7c43ed37c7eff433dbe9445f817ecffd4014164e82e4863ebcafeac64c19
|
|
@@ -24,7 +24,8 @@ class BoardConfig
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
@board.cycletime = CycleTimeConfig.new(
|
|
27
|
-
parent_config: self, label: label, block: block, file_system: project_config.file_system
|
|
27
|
+
parent_config: self, label: label, block: block, file_system: project_config.file_system,
|
|
28
|
+
settings: project_config.settings
|
|
28
29
|
)
|
|
29
30
|
end
|
|
30
31
|
|
|
@@ -6,12 +6,15 @@ require 'date'
|
|
|
6
6
|
class CycleTimeConfig
|
|
7
7
|
include SelfOrIssueDispatcher
|
|
8
8
|
|
|
9
|
-
attr_reader :label, :parent_config
|
|
9
|
+
attr_reader :label, :parent_config, :settings, :file_system
|
|
10
|
+
|
|
11
|
+
def initialize parent_config:, label:, block:, settings:, file_system: nil, today: Date.today
|
|
10
12
|
|
|
11
|
-
def initialize parent_config:, label:, block:, file_system: nil, today: Date.today
|
|
12
13
|
@parent_config = parent_config
|
|
13
14
|
@label = label
|
|
14
15
|
@today = today
|
|
16
|
+
@settings = settings
|
|
17
|
+
@cache_cycletime_calculations = settings['cache_cycletime_calculations']
|
|
15
18
|
|
|
16
19
|
# If we hit something deprecated and this is nil then we'll blow up. Although it's ugly, this
|
|
17
20
|
# may make it easier to find problems in the test code ;-)
|
|
@@ -63,6 +66,10 @@ class CycleTimeConfig
|
|
|
63
66
|
end
|
|
64
67
|
|
|
65
68
|
def started_stopped_changes issue
|
|
69
|
+
cache_key = "#{issue.key}:#{issue.board.id}"
|
|
70
|
+
last_result = (@cache ||= {})[cache_key]
|
|
71
|
+
return *last_result if last_result && @cache_cycletime_calculations
|
|
72
|
+
|
|
66
73
|
started = @start_at.call(issue)
|
|
67
74
|
stopped = @stop_at.call(issue)
|
|
68
75
|
|
|
@@ -80,7 +87,15 @@ class CycleTimeConfig
|
|
|
80
87
|
# for the start and not have it conflict.
|
|
81
88
|
started = nil if started&.time == stopped&.time
|
|
82
89
|
|
|
83
|
-
[started, stopped]
|
|
90
|
+
result = [started, stopped]
|
|
91
|
+
if last_result && result != last_result
|
|
92
|
+
@file_system.error(
|
|
93
|
+
"Calculation mismatch; this could break caching. #{issue.inspect} new=#{result.inspect}, " \
|
|
94
|
+
"previous=#{last_result.inspect}"
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
@cache[cache_key] = result
|
|
98
|
+
result
|
|
84
99
|
end
|
|
85
100
|
|
|
86
101
|
def started_stopped_times issue
|
|
@@ -88,6 +103,10 @@ class CycleTimeConfig
|
|
|
88
103
|
[started&.time, stopped&.time]
|
|
89
104
|
end
|
|
90
105
|
|
|
106
|
+
def flush_cache
|
|
107
|
+
@cache = nil
|
|
108
|
+
end
|
|
109
|
+
|
|
91
110
|
def started_stopped_dates issue
|
|
92
111
|
started_time, stopped_time = started_stopped_times(issue)
|
|
93
112
|
[started_time&.to_date, stopped_time&.to_date]
|
|
@@ -410,14 +410,17 @@ class DataQualityReport < ChartBase
|
|
|
410
410
|
def render_status_not_on_board problems
|
|
411
411
|
<<-HTML
|
|
412
412
|
#{label_issues problems.size} were not visible on the board for some period of time. This may impact
|
|
413
|
-
timings as the work was likely to have been forgotten if it wasn't visible.
|
|
413
|
+
timings as the work was likely to have been forgotten if it wasn't visible. What does "not visible"
|
|
414
|
+
mean in this context? The issue was in a status that is not mapped to any visible column on the board.
|
|
415
|
+
Look in "unmapped statuses" on your board.
|
|
414
416
|
HTML
|
|
415
417
|
end
|
|
416
418
|
|
|
417
419
|
def render_created_in_wrong_status problems
|
|
418
420
|
<<-HTML
|
|
419
|
-
#{label_issues problems.size} were created in a status not
|
|
420
|
-
|
|
421
|
+
#{label_issues problems.size} were created in a status that is not considered to be some varient
|
|
422
|
+
of To Do. Most likely this means that the issue was created from one of the columns on the board,
|
|
423
|
+
rather than in the backlog. Why Jira allows this is still a mystery.
|
|
421
424
|
HTML
|
|
422
425
|
end
|
|
423
426
|
|
|
@@ -15,15 +15,6 @@ class Exporter
|
|
|
15
15
|
self.anonymize if anonymize
|
|
16
16
|
self.settings.merge! settings
|
|
17
17
|
|
|
18
|
-
status_category_mappings.each do |status, category|
|
|
19
|
-
status_category_mapping status: status, category: category
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
download do
|
|
23
|
-
self.rolling_date_count(rolling_date_count) if rolling_date_count
|
|
24
|
-
self.no_earlier_than(no_earlier_than) if no_earlier_than
|
|
25
|
-
end
|
|
26
|
-
|
|
27
18
|
boards.each_key do |board_id|
|
|
28
19
|
block = boards[board_id]
|
|
29
20
|
if block == :default
|
|
@@ -37,6 +28,15 @@ class Exporter
|
|
|
37
28
|
end
|
|
38
29
|
end
|
|
39
30
|
|
|
31
|
+
status_category_mappings.each do |status, category|
|
|
32
|
+
status_category_mapping status: status, category: category
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
download do
|
|
36
|
+
self.rolling_date_count(rolling_date_count) if rolling_date_count
|
|
37
|
+
self.no_earlier_than(no_earlier_than) if no_earlier_than
|
|
38
|
+
end
|
|
39
|
+
|
|
40
40
|
issues.reject! do |issue|
|
|
41
41
|
ignore_types.include? issue.type
|
|
42
42
|
end
|
|
@@ -40,7 +40,7 @@ new Chart(document.getElementById(<%= chart_id.inspect %>).getContext('2d'),
|
|
|
40
40
|
color: <%= CssVariable['--grid-line-color'].to_json %>,
|
|
41
41
|
z: 1 // draw the grid lines on top of the bars
|
|
42
42
|
},
|
|
43
|
-
stacked:
|
|
43
|
+
stacked: false,
|
|
44
44
|
max: <%= (@max_age * 1.1).to_i %>
|
|
45
45
|
}
|
|
46
46
|
},
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.js"></script>
|
|
6
6
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
7
7
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@^1"></script>
|
|
8
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/1.
|
|
8
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/3.1.0/chartjs-plugin-annotation.min.js"></script>
|
|
9
9
|
<script type="text/javascript">
|
|
10
10
|
<%= javascript %>
|
|
11
11
|
</script>
|
|
@@ -51,7 +51,9 @@ class HtmlReportConfig
|
|
|
51
51
|
@file_config.project_config.all_boards.each_value do |board|
|
|
52
52
|
raise 'Multiple cycletimes not supported' if board.cycletime
|
|
53
53
|
|
|
54
|
-
board.cycletime = CycleTimeConfig.new(
|
|
54
|
+
board.cycletime = CycleTimeConfig.new(
|
|
55
|
+
parent_config: self, label: label, block: block, file_system: file_system, settings: settings
|
|
56
|
+
)
|
|
55
57
|
end
|
|
56
58
|
end
|
|
57
59
|
|
|
@@ -549,6 +549,7 @@ class ProjectConfig
|
|
|
549
549
|
end
|
|
550
550
|
|
|
551
551
|
def discard_changes_before status_becomes: nil, &block
|
|
552
|
+
cycletimes_touched = Set.new
|
|
552
553
|
if status_becomes
|
|
553
554
|
status_becomes = [status_becomes] unless status_becomes.is_a? Array
|
|
554
555
|
|
|
@@ -581,6 +582,7 @@ class ProjectConfig
|
|
|
581
582
|
next if original_start_time.nil?
|
|
582
583
|
|
|
583
584
|
issue.discard_changes_before cutoff_time
|
|
585
|
+
cycletimes_touched << issue.board.cycletime
|
|
584
586
|
|
|
585
587
|
next unless cutoff_time
|
|
586
588
|
next if original_start_time > cutoff_time # ie the cutoff would have made no difference.
|
|
@@ -591,5 +593,7 @@ class ProjectConfig
|
|
|
591
593
|
issue: issue
|
|
592
594
|
}
|
|
593
595
|
end
|
|
596
|
+
|
|
597
|
+
cycletimes_touched.each { |c| c.flush_cache }
|
|
594
598
|
end
|
|
595
599
|
end
|
|
@@ -7,5 +7,7 @@
|
|
|
7
7
|
"flagged_means_blocked": true,
|
|
8
8
|
|
|
9
9
|
"expedited_priority_names": ["Critical", "Highest"],
|
|
10
|
-
"priority_order": ["Lowest", "Low", "Medium", "High", "Highest"]
|
|
10
|
+
"priority_order": ["Lowest", "Low", "Medium", "High", "Highest"],
|
|
11
|
+
|
|
12
|
+
"cache_cycletime_calculations": true
|
|
11
13
|
}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jirametrics
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '2.
|
|
4
|
+
version: '2.20'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Bowler
|
|
@@ -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.9
|
|
163
163
|
specification_version: 4
|
|
164
164
|
summary: Extract Jira metrics
|
|
165
165
|
test_files: []
|