pull_request_templates 0.2.0 โ 0.3.0.pre.2
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9038ada19f6b753fe0c7bdde625a38ddf76aa4b91a64dd0761b55223e0d04c6e
|
4
|
+
data.tar.gz: 7ed0febfb2172bb9b65f79a205f3d2685c3846e876a91cdb1f59233b7e00758c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a6526cd5bfb2dbb0d5f9f46c3d7baf9ac3f1b5b5d0448f2c757077caaa8d3ada57348d3249a288d0be088c77213a3d0532b30e947c5b33603ad1a44191e8bad
|
7
|
+
data.tar.gz: ed7973df8bc2125fd0b29600a102378c52b94d2f7bb66a6e9d321f64a4cb3b50db93603a36e950ba6cd853cd9d4a2f4627aa706462058e61fbcaab2131b3b34d
|
@@ -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,14 +52,15 @@ module PullRequestTemplates
|
|
52
52
|
changes.split("\n").reject(&:empty?)
|
53
53
|
end
|
54
54
|
|
55
|
-
def select_template(
|
56
|
-
mapping_file = ".github/PULL_REQUEST_TEMPLATE
|
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
|
-
|
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
|
-
|
62
|
+
templates.each do |template|
|
63
|
+
patterns = template.fetch("pattern")
|
63
64
|
Array(patterns).each do |pattern|
|
64
65
|
matches[template] << file if File.fnmatch(pattern, file, File::FNM_PATHNAME | File::FNM_EXTGLOB)
|
65
66
|
end
|
@@ -68,14 +69,46 @@ module PullRequestTemplates
|
|
68
69
|
selected = matches.select { |_, files| files.sort == changes.sort }
|
69
70
|
candidates = selected.keys if selected.any?
|
70
71
|
end
|
71
|
-
candidates =
|
72
|
+
candidates = template_files.map { {"file" => _1} } if candidates.empty?
|
73
|
+
|
74
|
+
# If we have a default template with catch-all pattern, 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)
|
@@ -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
|
-
|
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.
|
4
|
+
version: 0.3.0.pre.2
|
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-
|
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
|