pull_request_templates 0.2.0 โ†’ 0.3.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: e611a2cbdb56bda1b85bc97bcd1e9ba850944a956aca3772e2479e2080780ed0
4
- data.tar.gz: f22afc24c2cab63778da2174ffdbde15a375a0f6d96b8643ffe7e5ec9a10dfd5
3
+ metadata.gz: 95ddd43a03464906a1436dab7a0167817113bf43fe5d8c59c53fb7b8658da2f1
4
+ data.tar.gz: 7f385ff70f9be681072eaa3c5b52e6290a8edc6c902dc2ae41ecaae7201fdcce
5
5
  SHA512:
6
- metadata.gz: e285e78b50d6a53f31a3bf8c1c8162816e6310175a1ddda470d01490e82ff1744d6663a392870992adead8bd2856a609024e62e93218629aa3b2bfe925a9beee
7
- data.tar.gz: a0c10b8ee580963bd2a109f4d262a311681d76558e486ae0ecfa2f08c007134a6ef99b9762deff4ab0fb3edb7398843e7e0a3f2c98b6dc88d60e18a57db593b8
6
+ metadata.gz: 6b914f1efe7ee44d378c53a2468de2283914d7e4a125f4079bb7408963a633e2dc8284544bff47a6b9b26921b9b5f951f0b64b4ba8ebd89182a17a2c60445228
7
+ data.tar.gz: d60ea637488d20978570ecefaee4c4da01ea6fcdc7e91c3b2b6ca2a1088d0715617e3deb9d96fdef6a35177b811f1dbacba78ea5c5a2e74e43f8cbd6ff0dc844
@@ -0,0 +1,59 @@
1
+ ---
2
+ description:
3
+ globs: *_spec.rb
4
+ alwaysApply: false
5
+ ---
6
+ # TDD Workflow Rule
7
+
8
+ ## Core Priorities
9
+ 1. Always write a failing test before implementing behavior
10
+ 2. Automatically implement changes when test failures match expectations
11
+
12
+ ## Workflow Steps
13
+
14
+ 1. **Write Test**
15
+ - Write a minimal test to demonstrate missing behavior
16
+ - Include specific error message expectations
17
+ - Follow RSpec best practices
18
+
19
+ 2. **Verify Test Failure**
20
+ - Run the specific failing test
21
+ - If the failure matches expectations, proceed to implementation
22
+ - If the failure is unexpected, revise the test
23
+
24
+ 3. **Commit the Failing Test**
25
+ - Commit the failing test separately from the implementation
26
+ - Use conventional commits with gitmoji
27
+ - Format: `๐Ÿงช test(scope): description` for tests
28
+ - Include a `Co-authored-by:` trailer if AI contributed
29
+
30
+ 4. **Implement Behavior**
31
+ - Write minimal code to pass the test
32
+ - Follow Ruby best practices
33
+ - Maintain existing code style
34
+
35
+ 5. **Commit the Implementation**
36
+ - Commit the implementation separately from the test
37
+ - Use conventional commits with gitmoji
38
+ - Format: `โœจ feat(scope): description` for implementation
39
+ - Include a `Co-authored-by:` trailer if AI contributed
40
+
41
+ 6. **Review Confidence**
42
+ - The goal is to build confidence in the process so that you can review the changes in a PR rather than accepting every change in the agent session
43
+ - If you get stuck, you are encouraged to ask for help, but strict adherence to the process is required
44
+
45
+ ## Gitmoji Reference
46
+ - ๐Ÿงช for failing test commits
47
+ - โœจ for feature implementations
48
+ - โ™ป๏ธ for refactoring
49
+ - ๐Ÿ› for bug fixes
50
+ - ๐Ÿ”ง for configuration changes
51
+ - ๐Ÿšš for renaming or moving
52
+ - ๐Ÿ—๏ธ for architectural changes
53
+
54
+ ## Notes
55
+ - Keep tests focused and atomic
56
+ - One behavior per test
57
+ - Maintain test isolation
58
+ - Follow red-green-refactor cycle strictly
59
+ - Always attribute AI contributions in commit messages
@@ -52,30 +52,63 @@ module PullRequestTemplates
52
52
  changes.split("\n").reject(&:empty?)
53
53
  end
54
54
 
55
- def select_template(templates, changes)
56
- mapping_file = ".github/PULL_REQUEST_TEMPLATE/.mapping.yml"
55
+ def select_template(template_files, changes)
56
+ mapping_file = ".github/PULL_REQUEST_TEMPLATE/config.yml"
57
57
  candidates = []
58
58
  if File.exist?(mapping_file)
59
- mapping = YAML.load_file(mapping_file)
59
+ templates = YAML.load_file(mapping_file).fetch("templates")
60
60
  matches = Hash.new { |h, k| h[k] = [] }
61
61
  changes.each do |file|
62
- mapping.each do |template, patterns|
62
+ templates.each do |template|
63
+ patterns = template.fetch("pattern")
63
64
  Array(patterns).each do |pattern|
64
- matches[template] << file if File.fnmatch(pattern, file, File::FNM_PATHNAME | File::FNM_EXTGLOB)
65
+ matches[template] << file if File.fnmatch(pattern, file, File::FNM_PATHNAME | File::FNM_EXTGLOB | File::Constants::FNM_DOTMATCH)
65
66
  end
66
67
  end
67
68
  end
68
69
  selected = matches.select { |_, files| files.sort == changes.sort }
69
70
  candidates = selected.keys if selected.any?
70
71
  end
71
- candidates = templates if candidates.empty?
72
+ candidates = template_files.map { {"file" => _1} } if candidates.empty?
73
+
74
+ # If we have a template with fallback: true, use it when multiple templates match
75
+ if candidates.length > 1
76
+ fallback = candidates.find { _1.fetch("fallback", false) }
77
+ return fallback.fetch("file") if fallback
78
+ end
79
+
72
80
  if candidates.length == 1
73
- return candidates.first
81
+ return candidates.first.fetch("file")
82
+ end
83
+
84
+ if File.exist?(mapping_file)
85
+ raise AmbiguousTemplateSelection, <<~MESSAGE
86
+ Unable to pick one template from #{candidates.map { _1.fetch("file") }} for the changes to #{changes.count} files:
87
+ * #{changes.join("\n* ")}
88
+
89
+ To resolve this, add a fallback template to your config.yml:
90
+ - file: default.md
91
+ pattern: "**/*"
92
+ fallback: true
93
+ MESSAGE
94
+ else
95
+ raise AmbiguousTemplateSelection, <<~MESSAGE
96
+ Unable to pick one template from #{candidates.map { _1.fetch("file") }} for the changes to #{changes.count} files:
97
+ * #{changes.join("\n* ")}
98
+
99
+ To resolve this, add a fallback template to your config.yml:
100
+ - file: default.md
101
+ pattern: "**/*"
102
+ fallback: true
103
+
104
+ Run this command to create the fallback template:
105
+ echo 'templates:
106
+ - file: default.md
107
+ pattern: "**/*"
108
+ fallback: true
109
+ ' >> .github/PULL_REQUEST_TEMPLATE/config.yml
110
+ MESSAGE
74
111
  end
75
- raise AmbiguousTemplateSelection, <<~MESSAGE
76
- Unable to pick one template from #{candidates} for the changes to #{changes.count} files:
77
- * #{changes.join("\n* ")}
78
- MESSAGE
79
112
  end
80
113
 
81
114
  def generate_pr_url(branch, template)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PullRequestTemplates
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -3,7 +3,10 @@
3
3
  require_relative "pull_request_templates/version"
4
4
  require_relative "pull_request_templates/cli"
5
5
 
6
+ require "thor/error"
7
+
6
8
  module PullRequestTemplates
7
9
  Error = Class.new(StandardError)
8
- AmbiguousTemplateSelection = Class.new(Error)
10
+ CliError = Class.new(Thor::Error)
11
+ AmbiguousTemplateSelection = Class.new(CliError)
9
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pull_request_templates
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Caleb Buxton
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-05-11 00:00:00.000000000 Z
11
+ date: 2025-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -33,6 +33,7 @@ executables:
33
33
  extensions: []
34
34
  extra_rdoc_files: []
35
35
  files:
36
+ - ".cursor/rules/test-driven-developer.mdc"
36
37
  - ".rspec"
37
38
  - ".standard.yml"
38
39
  - CHANGELOG.md