plan_my_stuff 0.17.0 → 0.19.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 +4 -4
- data/CHANGELOG.md +30 -0
- data/CONFIGURATION.md +53 -1
- data/README.md +2 -30
- data/app/controllers/plan_my_stuff/comments_controller.rb +21 -10
- data/app/controllers/plan_my_stuff/issues/approvals_controller.rb +13 -4
- data/app/controllers/plan_my_stuff/issues/closures_controller.rb +12 -6
- data/app/controllers/plan_my_stuff/issues/links_controller.rb +14 -8
- data/app/controllers/plan_my_stuff/issues/takes_controller.rb +19 -17
- data/app/controllers/plan_my_stuff/issues/viewers_controller.rb +15 -9
- data/app/controllers/plan_my_stuff/issues/waitings_controller.rb +14 -8
- data/app/controllers/plan_my_stuff/issues_controller.rb +19 -5
- data/app/controllers/plan_my_stuff/labels_controller.rb +14 -8
- data/app/controllers/plan_my_stuff/project_items/assignments_controller.rb +6 -0
- data/app/controllers/plan_my_stuff/project_items/statuses_controller.rb +3 -0
- data/app/controllers/plan_my_stuff/project_items_controller.rb +11 -4
- data/app/controllers/plan_my_stuff/projects_controller.rb +14 -0
- data/app/controllers/plan_my_stuff/testing_project_items/results_controller.rb +3 -0
- data/app/controllers/plan_my_stuff/testing_project_items_controller.rb +5 -0
- data/app/controllers/plan_my_stuff/testing_projects_controller.rb +12 -0
- data/app/views/plan_my_stuff/issues/index.html.erb +1 -1
- data/app/views/plan_my_stuff/issues/partials/_approvals.html.erb +5 -5
- data/app/views/plan_my_stuff/issues/partials/_form.html.erb +1 -1
- data/app/views/plan_my_stuff/issues/partials/_links.html.erb +3 -3
- data/app/views/plan_my_stuff/issues/partials/_viewers.html.erb +2 -2
- data/app/views/plan_my_stuff/issues/show.html.erb +8 -8
- data/app/views/plan_my_stuff/projects/show.html.erb +3 -1
- data/app/views/plan_my_stuff/testing_projects/partials/_item.html.erb +1 -1
- data/lib/generators/plan_my_stuff/install/templates/initializer.rb +6 -0
- data/lib/plan_my_stuff/configuration.rb +61 -5
- data/lib/plan_my_stuff/issue.rb +91 -15
- data/lib/plan_my_stuff/repo.rb +28 -0
- data/lib/plan_my_stuff/version.rb +1 -1
- metadata +2 -2
data/lib/plan_my_stuff/issue.rb
CHANGED
|
@@ -255,16 +255,20 @@ module PlanMyStuff
|
|
|
255
255
|
|
|
256
256
|
# Finds a single GitHub issue by number and parses its PMS metadata.
|
|
257
257
|
#
|
|
258
|
+
# Accepts a numeric id (Integer or all-digit String) plus an optional +repo:+ kwarg, or a nickname-id String
|
|
259
|
+
# (e.g. +"Rawr-1234"+) where the repo is encoded in the prefix and +repo:+ is ignored.
|
|
260
|
+
#
|
|
258
261
|
# @raise [Octokit::NotFound] when the issue number resolves to a pull request
|
|
262
|
+
# @raise [ArgumentError] when a nickname-id String references an unknown repo nickname
|
|
259
263
|
#
|
|
260
|
-
# @param
|
|
261
|
-
# @param repo [Symbol, String, nil] defaults to config.default_repo
|
|
264
|
+
# @param id_or_number [Integer, String]
|
|
265
|
+
# @param repo [Symbol, String, nil] defaults to config.default_repo; ignored when +id_or_number+ is a nickname id
|
|
262
266
|
#
|
|
263
267
|
# @return [PlanMyStuff::Issue]
|
|
264
268
|
#
|
|
265
|
-
def find(
|
|
269
|
+
def find(id_or_number, repo: nil)
|
|
270
|
+
number, resolved_repo = resolve_find_args(id_or_number, repo)
|
|
266
271
|
client = PlanMyStuff.client
|
|
267
|
-
resolved_repo = client.resolve_repo!(repo)
|
|
268
272
|
|
|
269
273
|
github_issue =
|
|
270
274
|
fetch_with_etag_cache(
|
|
@@ -393,8 +397,68 @@ module PlanMyStuff
|
|
|
393
397
|
raise(PlanMyStuff::APIError.new(e.message, status: e.respond_to?(:response_status) ? e.response_status : nil))
|
|
394
398
|
end
|
|
395
399
|
|
|
400
|
+
# @raise [ArgumentError] when +repo+ resolves to a Repo with no configured key (cannot reverse-resolve through
|
|
401
|
+
# +Repo.from_nickname!+, so the resulting token would not round-trip through +Issue.find+ / +from_param+)
|
|
402
|
+
#
|
|
403
|
+
# @param number [Integer]
|
|
404
|
+
# @param repo [String] full repo path, e.g. +"BrandsInsurance/Element"+
|
|
405
|
+
#
|
|
406
|
+
# @return [String]
|
|
407
|
+
#
|
|
408
|
+
def to_param(number, repo)
|
|
409
|
+
return if number.blank?
|
|
410
|
+
return if repo.blank?
|
|
411
|
+
|
|
412
|
+
repo_obj = PlanMyStuff::Repo.resolve!(repo)
|
|
413
|
+
if repo_obj.key.nil?
|
|
414
|
+
raise(
|
|
415
|
+
ArgumentError,
|
|
416
|
+
"Repo #{repo_obj.full_name.inspect} is not configured in config.repos; " \
|
|
417
|
+
'cannot build reversible Issue#to_param token',
|
|
418
|
+
)
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
"#{repo_obj.nickname}-#{number}"
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
# Parses an +Issue#to_param+ string of the form +"Nickname-1234"+ back into +[Repo, Integer]+. The repo is
|
|
425
|
+
# looked up via +PlanMyStuff::Repo.from_nickname!+, which scans +config.repos+ for the key whose
|
|
426
|
+
# +config.repo_nickname_for+ matches.
|
|
427
|
+
#
|
|
428
|
+
# @raise [ArgumentError] when +param+ does not match the +"Prefix-1234"+ shape or the prefix is not a known
|
|
429
|
+
# repo nickname
|
|
430
|
+
#
|
|
431
|
+
# @param param [String]
|
|
432
|
+
#
|
|
433
|
+
# @return [Array(PlanMyStuff::Repo, Integer)]
|
|
434
|
+
#
|
|
435
|
+
def from_param(param)
|
|
436
|
+
match = param.to_s.match(/\A(?<nickname>.+)-(?<number>\d+)\z/)
|
|
437
|
+
raise(ArgumentError, "Invalid issue param: #{param.inspect}") if match.nil?
|
|
438
|
+
|
|
439
|
+
[PlanMyStuff::Repo.from_nickname!(match[:nickname]), match[:number].to_i]
|
|
440
|
+
end
|
|
441
|
+
|
|
396
442
|
private
|
|
397
443
|
|
|
444
|
+
# Splits the +Issue.find+ first arg into +[number, resolved_repo_full_name]+. A nickname-id String like
|
|
445
|
+
# +"Rawr-1234"+ is decoded via +from_param+ (repo derived from the prefix; +repo:+ kwarg ignored). All other
|
|
446
|
+
# inputs (Integer, all-digit String) fall through to the existing +client.resolve_repo!+ path with the kwarg.
|
|
447
|
+
#
|
|
448
|
+
# @param id_or_number [Integer, String]
|
|
449
|
+
# @param repo [Symbol, String, PlanMyStuff::Repo, nil]
|
|
450
|
+
#
|
|
451
|
+
# @return [Array(Integer, String)]
|
|
452
|
+
#
|
|
453
|
+
def resolve_find_args(id_or_number, repo)
|
|
454
|
+
if id_or_number.is_a?(String) && !id_or_number.match?(/\A\d+\z/)
|
|
455
|
+
repo_obj, number = from_param(id_or_number)
|
|
456
|
+
[number, repo_obj.full_name]
|
|
457
|
+
else
|
|
458
|
+
[id_or_number.to_i, PlanMyStuff.client.resolve_repo!(repo)]
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
398
462
|
# Resolves an +issue_type:+ kwarg to the literal display name GitHub expects. Two stages: a Symbol is first
|
|
399
463
|
# looked up in the gem-side +ISSUE_TYPE_NICKNAMES+ to get a canonical name; then the canonical (or
|
|
400
464
|
# directly-provided String) name is passed through +config.issue_types+ for org-specific renames. Missing
|
|
@@ -443,9 +507,8 @@ module PlanMyStuff
|
|
|
443
507
|
end
|
|
444
508
|
|
|
445
509
|
# Builds the visible body string written to GitHub for an issue: a markdown link to the consuming-app
|
|
446
|
-
# per-issue URL (
|
|
447
|
-
#
|
|
448
|
-
# or +number+ is missing.
|
|
510
|
+
# per-issue URL (in +Issue#to_param+ form, e.g. +"/issues/Rawr-1234"+), labelled with the GitHub
|
|
511
|
+
# +Org/Repo#number+. Returns +""+ when either +config.issues_url_prefix+ or +number+ is missing.
|
|
449
512
|
#
|
|
450
513
|
# @param number [Integer]
|
|
451
514
|
# @param repo [String] full repo path, e.g. +"BrandsInsurance/Element"+
|
|
@@ -456,7 +519,8 @@ module PlanMyStuff
|
|
|
456
519
|
prefix = PlanMyStuff.configuration.issues_url_prefix
|
|
457
520
|
return '' if prefix.blank? || number.blank?
|
|
458
521
|
|
|
459
|
-
|
|
522
|
+
to_par = to_param(number, repo)
|
|
523
|
+
url = "#{prefix.to_s.chomp('/')}/#{to_par}"
|
|
460
524
|
"[#{repo}##{number}](#{url})"
|
|
461
525
|
end
|
|
462
526
|
|
|
@@ -526,17 +590,29 @@ module PlanMyStuff
|
|
|
526
590
|
@body_dirty = true
|
|
527
591
|
end
|
|
528
592
|
|
|
529
|
-
#
|
|
530
|
-
#
|
|
531
|
-
#
|
|
593
|
+
# Single-segment URL token combining repo nickname and issue number, used by Rails route helpers
|
|
594
|
+
# (+youtrack_issue_path(@issue)+ -> +"/issues/Rawr-1234"+). Returns +nil+ for new records or when +number+ or
|
|
595
|
+
# +repo+ is unset; +Issue.from_param+ parses the same shape back into +[Repo, Integer]+.
|
|
596
|
+
#
|
|
597
|
+
# @return [String, nil]
|
|
598
|
+
#
|
|
599
|
+
def to_param
|
|
600
|
+
return if new_record?
|
|
601
|
+
|
|
602
|
+
self.class.to_param(number, repo)
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
# @return [String, nil] per-issue URL in the consuming app (+config.issues_url_prefix+ + +"/"+ + +to_param+, or
|
|
606
|
+
# +nil+ when prefix, number, or repo is missing). Also rendered as the destination of the markdown link in
|
|
607
|
+
# the GitHub issue body.
|
|
532
608
|
def user_link
|
|
533
609
|
prefix = PlanMyStuff.configuration.issues_url_prefix
|
|
534
|
-
return if prefix.blank?
|
|
610
|
+
return if prefix.blank?
|
|
535
611
|
|
|
536
|
-
|
|
537
|
-
return
|
|
612
|
+
to_par = to_param
|
|
613
|
+
return if to_par.blank?
|
|
538
614
|
|
|
539
|
-
"#{
|
|
615
|
+
"#{prefix.to_s.chomp('/')}/#{to_par}"
|
|
540
616
|
end
|
|
541
617
|
|
|
542
618
|
# Tags the issue with the configured +archived_label+, removes it from every Projects V2 board it belongs to,
|
data/lib/plan_my_stuff/repo.rb
CHANGED
|
@@ -55,6 +55,23 @@ module PlanMyStuff
|
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
+
# Reverse lookup for the +Issue#to_param+ prefix: finds the configured repo whose nickname (per
|
|
59
|
+
# +config.repo_nickname_for+) matches +nickname+ and returns its +Repo+ instance.
|
|
60
|
+
#
|
|
61
|
+
# @raise [ArgumentError] if no configured repo has the given nickname
|
|
62
|
+
#
|
|
63
|
+
# @param nickname [String]
|
|
64
|
+
#
|
|
65
|
+
# @return [PlanMyStuff::Repo]
|
|
66
|
+
#
|
|
67
|
+
def from_nickname!(nickname)
|
|
68
|
+
config = PlanMyStuff.configuration
|
|
69
|
+
match = config.repos.keys.find { |key| config.repo_nickname_for(key) == nickname }
|
|
70
|
+
raise(ArgumentError, "Unknown repo nickname: #{nickname.inspect}") if match.nil?
|
|
71
|
+
|
|
72
|
+
resolve!(match)
|
|
73
|
+
end
|
|
74
|
+
|
|
58
75
|
private
|
|
59
76
|
|
|
60
77
|
# @raise [ArgumentError] if full_name is not in "Org/Repo" format
|
|
@@ -88,6 +105,17 @@ module PlanMyStuff
|
|
|
88
105
|
"#{organization}/#{name}"
|
|
89
106
|
end
|
|
90
107
|
|
|
108
|
+
# Human-readable repo label used as the +Issue#to_param+ prefix. Resolves through +config.repo_nickname_for+
|
|
109
|
+
# when this repo carries a configured +key+; falls back to the bare repo +name+ for unconfigured repos.
|
|
110
|
+
#
|
|
111
|
+
# @return [String]
|
|
112
|
+
#
|
|
113
|
+
def nickname
|
|
114
|
+
return PlanMyStuff.configuration.repo_nickname_for(key) if key
|
|
115
|
+
|
|
116
|
+
name
|
|
117
|
+
end
|
|
118
|
+
|
|
91
119
|
# @see #full_name
|
|
92
120
|
alias to_s full_name
|
|
93
121
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: plan_my_stuff
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.19.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brands Insurance
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|