jirametrics 2.13 → 2.14pre2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f219c386b574f433dbaf649b9b7cccc42114401b45ff703a7c8f228c52d815c4
4
- data.tar.gz: 68af46ec7256e3b4004c4fd8016d52b17b0fa2bb717e9265b164dc5fa59fca56
3
+ metadata.gz: ddc2265d15bc52422942f009082fd92fea0b296860297b6a6fa5fd0aee1788f4
4
+ data.tar.gz: e76799a3576b4e1e667268b823c99d6be8068ee196a76766e07fb646a44b17ee
5
5
  SHA512:
6
- metadata.gz: 71d289169562b3e4029549ab0db5ef1c4d25bc933d860f6f2a834f6caa39bbb5de93db2932996b7a5d75b4b6fb16f021ac5666cad3d57092dea6b4db4f8b7e97
7
- data.tar.gz: 425c213d81982d99f9d933d7ad8dbeb4f87f92ec97188d763b51edcb2f7b85a1072da80c0a5df8566a6325223e9b35d98b180e18fd67d1e50cb2d44b1b0e3872
6
+ metadata.gz: 0d60ce44257fcd466d092963ec7a58e86d9cf9252bc83262ac3c3b3621941df44b5c686b71e57be68bef06352d964f369b3cd9281324e3235cdad2c94e2f1869
7
+ data.tar.gz: 217c6e8a37ad3b5ae4e25d454a27b77b023ccd87e73ece9a1d3853f55e9c1330e24e64a7578f99289007925c2310482f200ac4f5d5affae6dd0ccb649978269b
@@ -11,6 +11,7 @@ class BoardConfig
11
11
 
12
12
  def run
13
13
  @board = @project_config.all_boards[id]
14
+ raise "Can't find board #{id.inspect} in #{@project_config.all_boards.keys.inspect}" unless @board
14
15
 
15
16
  instance_eval(&@block)
16
17
  raise "Must specify a cycletime for board #{@id}" if @board.cycletime.nil?
@@ -66,6 +66,8 @@ class ChartBase
66
66
  end
67
67
 
68
68
  def label_days days
69
+ return 'unknown' if days.nil?
70
+
69
71
  "#{days} day#{'s' unless days == 1}"
70
72
  end
71
73
 
@@ -82,7 +82,7 @@ class DailyView < ChartBase
82
82
  blocked_stalled = issue.blocked_stalled_by_date(
83
83
  date_range: today..today, chart_end_time: time_range.end, settings: settings
84
84
  )[today]
85
- return [] unless blocked_stalled
85
+ return [] if blocked_stalled.active?
86
86
 
87
87
  lines = []
88
88
  if blocked_stalled.blocked?
@@ -102,15 +102,18 @@ class DailyView < ChartBase
102
102
  lines
103
103
  end
104
104
 
105
- def make_issue_label issue
106
- "<img src='#{issue.type_icon_url}' title='#{issue.type}' class='icon' /> " \
107
- "<b><a href='#{issue.url}'>#{issue.key}</a></b> &nbsp;<i>#{issue.summary}</i>"
105
+ def make_issue_label issue:, done:
106
+ label = "<img src='#{issue.type_icon_url}' title='#{issue.type}' class='icon' /> "
107
+ label << '<s>' if done
108
+ label << "<b><a href='#{issue.url}'>#{issue.key}</a></b> &nbsp;<i>#{issue.summary}</i>"
109
+ label << '</s>' if done
110
+ label
108
111
  end
109
112
 
110
- def make_title_line issue
113
+ def make_title_line issue:, done:
111
114
  title_line = +''
112
115
  title_line << color_block('--expedited-color', title: 'Expedited') if issue.expedited?
113
- title_line << make_issue_label(issue)
116
+ title_line << make_issue_label(issue: issue, done: done)
114
117
  title_line
115
118
  end
116
119
 
@@ -119,20 +122,25 @@ class DailyView < ChartBase
119
122
  parent_key = issue.parent_key
120
123
  if parent_key
121
124
  parent = issues.find_by_key key: parent_key, include_hidden: true
122
- text = parent ? make_issue_label(parent) : parent_key
125
+ text = parent ? make_issue_label(issue: parent, done: parent.done?) : parent_key
123
126
  lines << ["Parent: #{text}"]
124
127
  end
125
128
  lines
126
129
  end
127
130
 
128
- def make_stats_lines issue
131
+ def make_stats_lines issue:, done:
129
132
  line = []
130
133
 
131
134
  line << "<img src='#{issue.priority_url}' class='icon' /> <b>#{issue.priority_name}</b>"
132
135
 
133
- age = issue.board.cycletime.age(issue, today: date_range.end)
134
- line << "Age: <b>#{age ? label_days(age) : '(Not Started)'}</b>"
136
+ if done
137
+ cycletime = issue.board.cycletime.cycletime(issue)
135
138
 
139
+ line << "Cycletime: <b>#{label_days cycletime}</b>"
140
+ else
141
+ age = issue.board.cycletime.age(issue, today: date_range.end)
142
+ line << "Age: <b>#{age ? label_days(age) : '(Not Started)'}</b>"
143
+ end
136
144
  line << "Status: <b>#{format_status issue.status, board: issue.board}</b>"
137
145
 
138
146
  column = issue.board.visible_columns.find { |c| c.status_ids.include?(issue.status.id) }
@@ -158,13 +166,22 @@ class DailyView < ChartBase
158
166
 
159
167
  def make_child_lines issue
160
168
  lines = []
161
- subtasks = issue.subtasks.reject { |i| i.done? }
169
+ subtasks = issue.subtasks
170
+
171
+ return lines if subtasks.empty?
172
+
173
+ id = next_id
174
+ lines <<
175
+ "<a href=\"javascript:toggle_visibility('open#{id}', 'close#{id}', 'section#{id}');\">" \
176
+ "<span id='open#{id}' style='display: none'>▶ Child issues</span>" \
177
+ "<span id='close#{id}'>▼ Child issues</span></a>"
178
+ lines << "<section id='section#{id}'>"
179
+
180
+ # icon_urls = subtasks.collect(&:type_icon_url).uniq.collect { |url| "<img src='#{url}' class='icon' />" }
181
+ # lines << (icon_urls << 'Child issues')
182
+ lines += subtasks
183
+ lines << '</section>'
162
184
 
163
- unless subtasks.empty?
164
- icon_urls = subtasks.collect(&:type_icon_url).uniq.collect { |url| "<img src='#{url}' class='icon' />" }
165
- lines << (icon_urls << 'Incomplete child issues')
166
- lines += subtasks
167
- end
168
185
  lines
169
186
  end
170
187
 
@@ -242,15 +259,19 @@ class DailyView < ChartBase
242
259
  end
243
260
 
244
261
  def assemble_issue_lines issue, child:
262
+ done = issue.done?
263
+
245
264
  lines = []
246
- lines << [make_title_line(issue)]
265
+ lines << [make_title_line(issue: issue, done: done)]
247
266
  lines += make_parent_lines(issue) unless child
248
- lines += make_stats_lines(issue)
249
- lines += make_description_lines(issue)
250
- lines += make_sprints_lines(issue)
251
- lines += make_blocked_stalled_lines(issue)
252
- lines += make_child_lines(issue)
253
- lines += make_history_lines(issue)
267
+ lines += make_stats_lines(issue: issue, done: done)
268
+ unless done
269
+ lines += make_description_lines(issue)
270
+ lines += make_sprints_lines(issue)
271
+ lines += make_blocked_stalled_lines(issue)
272
+ lines += make_child_lines(issue)
273
+ lines += make_history_lines(issue)
274
+ end
254
275
  lines
255
276
  end
256
277
 
@@ -261,6 +282,8 @@ class DailyView < ChartBase
261
282
  assemble_issue_lines(issue, child: child).each do |row|
262
283
  if row.is_a? Issue
263
284
  result << render_issue(row, child: true)
285
+ elsif row.is_a?(String)
286
+ result << row
264
287
  else
265
288
  result << '<div class="heading">'
266
289
  row.each do |chunk|
@@ -191,6 +191,11 @@ div.daily_issue {
191
191
  padding-right: 0.2em;
192
192
  border-radius: 0.2em;
193
193
  }
194
+ h1 {
195
+ border: none;
196
+ background: none;
197
+ padding-left: 0;
198
+ }
194
199
  margin-bottom: 0.5em;
195
200
  }
196
201
  div.child_issue:hover {
@@ -681,9 +681,8 @@ class Issue
681
681
  def done?
682
682
  if artificial? || board.cycletime.nil?
683
683
  # This was probably loaded as a linked issue, which means we don't know what board it really
684
- # belonged to. The best we can do is look at the status category. This case should be rare but
685
- # it can happen.
686
- status.category.name == 'Done'
684
+ # belonged to. The best we can do is look at the status key
685
+ status.category.done?
687
686
  else
688
687
  board.cycletime.done? self
689
688
  end
@@ -114,10 +114,14 @@ class ProjectConfig
114
114
  def file_prefix prefix
115
115
  # The file_prefix has to be set before almost everything else. It really should have been an attribute
116
116
  # on the project declaration itself. Hindsight is 20/20.
117
+
118
+ # There can only be one of these
117
119
  if @file_prefix
118
- raise "file_prefix should only be set once. Was #{@file_prefix.inspect} and now changed to #{prefix.inspect}."
120
+ raise "file_prefix can only be set once. Was #{@file_prefix.inspect} and now changed to #{prefix.inspect}."
119
121
  end
120
122
 
123
+ raise_if_prefix_already_used(prefix)
124
+
121
125
  @file_prefix = prefix
122
126
 
123
127
  # Yes, this is a wierd place to be initializing this. Unfortunately, it has to happen after the file_prefix
@@ -130,8 +134,21 @@ class ProjectConfig
130
134
  @file_prefix
131
135
  end
132
136
 
133
- def get_file_prefix # rubocop:disable Naming/AccessorMethodName
134
- raise 'file_prefix has not been set yet. Move it to the top of the project declaration.' unless @file_prefix
137
+ def raise_if_prefix_already_used prefix
138
+ @exporter.project_configs.each do |project|
139
+ next unless project.get_file_prefix(raise_if_not_set: false) == prefix && project.target_path == target_path
140
+
141
+ raise "Project #{name.inspect} specifies file prefix #{prefix.inspect}, " \
142
+ "but that is already used by project #{project.name.inspect} in the same target path #{target_path.inspect}. " \
143
+ 'This is almost guaranteed to be too much copy and paste in your configuration. ' \
144
+ 'File prefixes must be unique within a directory.'
145
+ end
146
+ end
147
+
148
+ def get_file_prefix raise_if_not_set: true
149
+ if @file_prefix.nil? && raise_if_not_set
150
+ raise 'file_prefix has not been set yet. Move it to the top of the project declaration.'
151
+ end
135
152
 
136
153
  @file_prefix
137
154
  end
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.13'
4
+ version: 2.14pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Bowler
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-07-25 00:00:00.000000000 Z
10
+ date: 2025-08-11 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: random-word