plan_my_stuff 0.19.0 → 0.20.0

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: 15988155f3d1798b5b0f43cbb1597f7e8b7ed881feb3db2504da7ecd74ab9c59
4
- data.tar.gz: 35f298dce675a86ca15153a354411c23806e8420374fe5eb4fd7d2c392e0ed9d
3
+ metadata.gz: 06744d7c7bc63206522ce6d7c9176eeb8e93fabb4de903d7df32b17cfae6948d
4
+ data.tar.gz: 2338f2f85989b2ee3b29a48c114a82d36c8105c13e4caf19b2601ff02cbf063c
5
5
  SHA512:
6
- metadata.gz: 838ebf5cb77a3467fb291d76acd9b2ded4cc40d88e65673ca41374324736c6cdc11e5bbc0ed7e04eaf0c0bb5ac4f799c3052379cdc87edcd7343dc30be370059
7
- data.tar.gz: b30d829c2255b61485c72d639992f1095f9726b7e6d8952114eef2e44c91f1016c0f05bd3abd238faf0be83a37c8b75ef492208351d33cbbe1f2f689270e7614
6
+ metadata.gz: dd143db048f77a46fe7875b1592b9ff1dc26e6ddac13af60c177ae977f799606d172a23ca861222a1a133d53fb91d16be19dd40d8f7027b680316276d99088f0
7
+ data.tar.gz: 607957cf66e887c31bb6ab3f9a93726da0cf853cb3d43e8d34857b0dd789981788de4f0c8c6e076ad5236141732867ed9641971dcc683df5e4683e6b726542f3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.20.0
4
+
5
+ ### Breaking
6
+
7
+ - `priority_list` and `priority_list_priority` keys removed from `IssueMetadata` serialization. Existing issues
8
+ migrate to the GitHub Issue Field equivalents (`Priority List`, `Priority List Priority`) on their next save.
9
+
10
+ ### Added
11
+
12
+ - `Issue#priority_list?` and `Issue#priority_list_priority` read the corresponding issue field values directly.
13
+ - `Issue.priority_list(repo:, state:, labels:, page:, per_page:)` convenience method delegates to
14
+ `Issue.list(priority_list: true, ...)`.
15
+ - `Issue.list` and `Issue.count` accept `priority_list:` for server-side filtering via the GitHub issue fields
16
+ API (passes `priority_list: false` raises `ArgumentError` -- the API has no negation qualifier).
17
+
18
+ ### Deprecated
19
+
20
+ - `IssueMetadata#priority_list`, `#priority_list=`, `#priority_list?`, `#priority_list_priority`, and
21
+ `#priority_list_priority=` emit deprecation warnings on each read/write. Legacy writes forward to the issue
22
+ field on `Issue#save!` / `#update!` / `Issue.create!`. The accessors will be removed in 1.0.0.
23
+
3
24
  ## 0.19.0
4
25
 
5
26
  ### Added
@@ -296,26 +296,46 @@ module PlanMyStuff
296
296
 
297
297
  # Lists GitHub issues with optional filters and pagination.
298
298
  #
299
+ # @raise [ArgumentError] when +priority_list: false+ is passed
300
+ #
299
301
  # @param repo [Symbol, String, nil] defaults to config.default_repo
300
302
  # @param state [Symbol] :open, :closed, or :all
301
303
  # @param labels [Array<String>]
304
+ # @param priority_list [Boolean, nil] when +true+, restricts to issues whose +Priority List+ issue field is
305
+ # +Yes+ (server-side filter via the +issue_field_values+ query param). +false+ raises +ArgumentError+ -- GitHub
306
+ # has no negation qualifier. Silently dropped when +config.issue_fields_enabled+ is +false+.
302
307
  # @param page [Integer]
303
308
  # @param per_page [Integer]
304
309
  #
305
310
  # @return [Array<PlanMyStuff::Issue>]
306
311
  #
307
- def list(repo: nil, state: :open, labels: [], page: 1, per_page: 25)
312
+ def list(repo: nil, state: :open, labels: [], priority_list: nil, page: 1, per_page: 25)
313
+ if priority_list == false
314
+ raise(ArgumentError, 'priority_list: false is not supported (no GitHub negation qualifier)')
315
+ end
316
+
308
317
  client = PlanMyStuff.client
309
318
  resolved_repo = client.resolve_repo!(repo)
310
319
 
311
320
  params = { state: state.to_s, page: page, per_page: per_page }
312
321
  params[:labels] = labels.sort.join(',') if labels.present?
322
+ if priority_list && PlanMyStuff.configuration.issue_fields_enabled
323
+ params[:issue_field_values] = 'priority-list:Yes'
324
+ end
313
325
 
314
326
  github_issues = client.rest(:list_issues, resolved_repo, **params)
315
327
  filtered = github_issues.reject { |gi| gi.respond_to?(:pull_request) && gi.pull_request }
316
328
  filtered.map { |gi| build(gi, repo: resolved_repo) }
317
329
  end
318
330
 
331
+ # Convenience shortcut for +list(priority_list: true, ...)+. See +.list+ for parameter semantics.
332
+ #
333
+ # @return [Array<PlanMyStuff::Issue>]
334
+ #
335
+ def priority_list(**)
336
+ list(**, priority_list: true)
337
+ end
338
+
319
339
  # Counts GitHub issues matching the given filters without paginating full payloads.
320
340
  #
321
341
  # Uses GitHub's Search API (+search/issues+), which returns +total_count+ in a single
@@ -327,13 +347,23 @@ module PlanMyStuff
327
347
  # - The Search API has its own rate limit (30 req/min authenticated) separate from
328
348
  # the core REST API.
329
349
  #
350
+ # @raise [ArgumentError] when +priority_list: false+ is passed
351
+ #
330
352
  # @param repo [Symbol, String, nil] defaults to config.default_repo
331
353
  # @param state [Symbol] :open, :closed, or :all
332
354
  # @param labels [Array<String>]
355
+ # @param priority_list [Boolean, nil] when +true+, restricts to issues whose +Priority List+ issue field is
356
+ # +Yes+ (server-side filter via the +field.priority-list:Yes+ Search qualifier). +false+ raises
357
+ # +ArgumentError+ -- GitHub has no negation qualifier. Silently dropped when
358
+ # +config.issue_fields_enabled+ is +false+.
333
359
  #
334
360
  # @return [Integer]
335
361
  #
336
- def count(repo: nil, state: :open, labels: [])
362
+ def count(repo: nil, state: :open, labels: [], priority_list: nil)
363
+ if priority_list == false
364
+ raise(ArgumentError, 'priority_list: false is not supported (no GitHub negation qualifier)')
365
+ end
366
+
337
367
  client = PlanMyStuff.client
338
368
  resolved_repo = client.resolve_repo!(repo)
339
369
 
@@ -344,7 +374,12 @@ module PlanMyStuff
344
374
  qualifiers += labels_to_use.map do |label|
345
375
  "label:\"#{label}\""
346
376
  end
347
- client.rest(:search_issues, qualifiers.join(' '), per_page: 1).total_count
377
+ search_options = { per_page: 1 }
378
+ if priority_list && PlanMyStuff.configuration.issue_fields_enabled
379
+ qualifiers << 'field.priority-list:Yes'
380
+ search_options[:advanced_search] = true
381
+ end
382
+ client.rest(:search_issues, qualifiers.join(' '), **search_options).total_count
348
383
  end
349
384
 
350
385
  # Submits one or more pre-built payloads to GitHub's "Import Issues" preview endpoint
@@ -663,6 +698,8 @@ module PlanMyStuff
663
698
  # @return [self]
664
699
  #
665
700
  def save!(user: nil, skip_notification: false)
701
+ forward_legacy_priority_list_metadata!
702
+
666
703
  if new_record?
667
704
  created = self.class.create!(
668
705
  title: title,
@@ -795,6 +832,16 @@ module PlanMyStuff
795
832
  @issue_fields ||= load_issue_fields!
796
833
  end
797
834
 
835
+ # @return [Boolean]
836
+ def priority_list?
837
+ issue_fields['Priority List'] == 'Yes'
838
+ end
839
+
840
+ # @return [Integer, nil]
841
+ def priority_list_priority
842
+ issue_fields['Priority List Priority']
843
+ end
844
+
798
845
  # Bulk-updates GitHub Issue Field values in a single +setIssueFieldValue+ mutation. Each key is the field display
799
846
  # name; values are coerced to the right input fragment based on the field's type. Passing +nil+ as a value clears
800
847
  # that field.
@@ -934,6 +981,28 @@ module PlanMyStuff
934
981
  reload
935
982
  end
936
983
 
984
+ # Forwards a pending legacy +metadata.priority_list+ /
985
+ # +#priority_list_priority+ write into +@pending_issue_fields+ so the next
986
+ # +save!+ persists the values into the +Priority List+ /
987
+ # +Priority List Priority+ GitHub Issue Fields. Caller-supplied
988
+ # +issue_fields:+ entries win on key collision. Silently skipped when
989
+ # +config.issue_fields_enabled+ is +false+.
990
+ #
991
+ # @return [void]
992
+ #
993
+ def forward_legacy_priority_list_metadata!
994
+ return unless PlanMyStuff.configuration.issue_fields_enabled
995
+ return unless metadata.instance_variable_get(:@legacy_priority_list_pending)
996
+
997
+ legacy_pl = metadata.instance_variable_get(:@priority_list)
998
+ legacy_plp = metadata.instance_variable_get(:@priority_list_priority)
999
+
1000
+ legacy_fields = { 'Priority List' => legacy_pl ? 'Yes' : nil }
1001
+ legacy_fields['Priority List Priority'] = legacy_plp unless legacy_plp == -1
1002
+
1003
+ @pending_issue_fields = legacy_fields.merge(@pending_issue_fields || {})
1004
+ end
1005
+
937
1006
  # Applies in-memory updates from an +update!+ kwargs hash. Top-level scalars go through their setters so
938
1007
  # +@body_dirty+ and friends stay in sync; +metadata:+ is merged into +@metadata+ (top-level attrs assigned
939
1008
  # directly, custom_fields merged key-by-key).
@@ -2,14 +2,16 @@
2
2
 
3
3
  module PlanMyStuff
4
4
  class IssueMetadata < PlanMyStuff::BaseMetadata
5
+ PRIORITY_LIST_METADATA_DEPRECATION =
6
+ 'PlanMyStuff: IssueMetadata#priority_list / #priority_list_priority are deprecated. priority_list moved to ' \
7
+ "GitHub Issue Fields ('Priority List' single_select, 'Priority List Priority' number) in 0.20.0. Reads " \
8
+ 'now come from issue_fields; legacy writes forward to set_issue_fields! on save. The metadata accessors ' \
9
+ 'will be removed in 1.0.0.'
10
+
5
11
  # @return [Time, nil] first support action timestamp, nil until set
6
12
  attr_accessor :responded_at
7
13
  # @return [String, nil] user-facing URL in the consuming app
8
14
  attr_accessor :issues_url
9
- # @return [Boolean] whether this issue appears on the priority dashboard
10
- attr_accessor :priority_list
11
- # @return [Integer] sort order on priority dashboard (-1 = unranked)
12
- attr_accessor :priority_list_priority
13
15
  # @return [Array<Integer>] user IDs of non-support users allowed to view internal comments
14
16
  attr_accessor :visibility_allowlist
15
17
  # @return [String, nil] merged PR commit SHA for release tracking
@@ -50,8 +52,14 @@ module PlanMyStuff
50
52
 
51
53
  metadata.responded_at = parse_time(hash[:responded_at])
52
54
  metadata.issues_url = hash[:issues_url]
53
- metadata.priority_list = hash.fetch(:priority_list, false)
54
- metadata.priority_list_priority = hash.fetch(:priority_list_priority, -1)
55
+ if hash.key?(:priority_list) || hash.key?(:priority_list_priority)
56
+ PlanMyStuff.deprecator.warn(PRIORITY_LIST_METADATA_DEPRECATION)
57
+ metadata.instance_variable_set(:@priority_list, hash[:priority_list]) if hash.key?(:priority_list)
58
+ if hash.key?(:priority_list_priority)
59
+ metadata.instance_variable_set(:@priority_list_priority, hash[:priority_list_priority])
60
+ end
61
+ metadata.instance_variable_set(:@legacy_priority_list_pending, true)
62
+ end
55
63
  metadata.visibility_allowlist = Array.wrap(hash[:visibility_allowlist])
56
64
  metadata.commit_sha = hash[:commit_sha]
57
65
  metadata.auto_complete = hash.fetch(:auto_complete, true)
@@ -86,8 +94,6 @@ module PlanMyStuff
86
94
 
87
95
  metadata.responded_at = nil
88
96
  metadata.issues_url = build_issues_url(PlanMyStuff.configuration)
89
- metadata.priority_list = false
90
- metadata.priority_list_priority = -1
91
97
  metadata.visibility_allowlist = []
92
98
  metadata.commit_sha = nil
93
99
  metadata.auto_complete = true
@@ -169,8 +175,6 @@ module PlanMyStuff
169
175
 
170
176
  def initialize
171
177
  super
172
- @priority_list = false
173
- @priority_list_priority = -1
174
178
  @visibility_allowlist = []
175
179
  @auto_complete = true
176
180
  @links = []
@@ -188,9 +192,55 @@ module PlanMyStuff
188
192
  !!auto_complete
189
193
  end
190
194
 
195
+ # @deprecated Use +Issue#priority_list?+. Removed in 1.0.0.
196
+ #
197
+ # @return [Object, nil]
198
+ #
199
+ def priority_list
200
+ PlanMyStuff.deprecator.warn(PRIORITY_LIST_METADATA_DEPRECATION)
201
+ @priority_list
202
+ end
203
+
204
+ # @deprecated Use +Issue#update!(issue_fields: { 'Priority List' => 'Yes' })+. Removed in 1.0.0.
205
+ #
206
+ # @param value [Object]
207
+ #
208
+ # @return [Object]
209
+ #
210
+ def priority_list=(value)
211
+ PlanMyStuff.deprecator.warn(PRIORITY_LIST_METADATA_DEPRECATION)
212
+ @legacy_priority_list_pending = true
213
+ @priority_list = value
214
+ end
215
+
216
+ # @deprecated Use +Issue#priority_list?+. Removed in 1.0.0.
217
+ #
191
218
  # @return [Boolean]
219
+ #
192
220
  def priority_list?
193
- !!priority_list
221
+ PlanMyStuff.deprecator.warn(PRIORITY_LIST_METADATA_DEPRECATION)
222
+ !!@priority_list
223
+ end
224
+
225
+ # @deprecated Use +Issue#priority_list_priority+. Removed in 1.0.0.
226
+ #
227
+ # @return [Object, nil]
228
+ #
229
+ def priority_list_priority
230
+ PlanMyStuff.deprecator.warn(PRIORITY_LIST_METADATA_DEPRECATION)
231
+ @priority_list_priority
232
+ end
233
+
234
+ # @deprecated Use +Issue#update!(issue_fields: { 'Priority List Priority' => N })+. Removed in 1.0.0.
235
+ #
236
+ # @param value [Object]
237
+ #
238
+ # @return [Object]
239
+ #
240
+ def priority_list_priority=(value)
241
+ PlanMyStuff.deprecator.warn(PRIORITY_LIST_METADATA_DEPRECATION)
242
+ @legacy_priority_list_pending = true
243
+ @priority_list_priority = value
194
244
  end
195
245
 
196
246
  # @return [Boolean]
@@ -220,8 +270,6 @@ module PlanMyStuff
220
270
  super.merge(
221
271
  responded_at: PlanMyStuff.format_time(responded_at),
222
272
  issues_url: issues_url,
223
- priority_list: priority_list,
224
- priority_list_priority: priority_list_priority,
225
273
  visibility_allowlist: visibility_allowlist,
226
274
  commit_sha: commit_sha,
227
275
  auto_complete: auto_complete,
@@ -3,7 +3,7 @@
3
3
  module PlanMyStuff
4
4
  module VERSION
5
5
  MAJOR = 0
6
- MINOR = 19
6
+ MINOR = 20
7
7
  TINY = 0
8
8
 
9
9
  # Set PRE to nil unless it's a pre-release (beta, rc, etc.)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plan_my_stuff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brands Insurance