conventional_commits 0.2.23 → 0.4.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/.pre-commit-hooks.yaml +20 -1
- data/Gemfile.lock +3 -1
- data/README.md +22 -1
- data/exe/conventional_commits +1 -0
- data/lib/branch/branch_name_generator.rb +24 -3
- data/lib/cli/branch_name_cli.rb +38 -9
- data/lib/commit/commit_message_validator.rb +12 -2
- data/lib/configuration.rb +6 -0
- data/lib/conventional_commits/version.rb +1 -1
- data/lib/git/git.rb +10 -0
- data/lib/models/release_rule.rb +3 -2
- data/lib/release/next_version_calculator.rb +85 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8ef389be49918b12a03941a89178003c8b6ba9962583516728948bb1c61d5557
|
|
4
|
+
data.tar.gz: e4e5c3dd45bb0e3c140b9519dcd76f432fc7812012402dde8a4a643da8318c9a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d8435aa0ae03a4ab74880debbec1f7a925b39a972337a17432234f64907e97388b82d48692f58ac16f2d7566dd0f0d96e365ef2ef86940e5ea6372fd59eb5ad8
|
|
7
|
+
data.tar.gz: 5cc8f961cc6ce9296f0348fe6d200c53edbfb10996320065d3b3ae045125177204aa3a01a1be062b861c95561dc828e0c19236a1400bd0015f8d15f353df2971
|
data/.pre-commit-hooks.yaml
CHANGED
|
@@ -5,4 +5,23 @@
|
|
|
5
5
|
language: ruby
|
|
6
6
|
language_version: 3.2.2
|
|
7
7
|
always_run: true
|
|
8
|
-
pass_filenames: false
|
|
8
|
+
pass_filenames: false
|
|
9
|
+
|
|
10
|
+
- id: validate_message
|
|
11
|
+
name: Message Validation
|
|
12
|
+
description: "Validate commit message"
|
|
13
|
+
entry: "conventional_commits validate_commit_msg"
|
|
14
|
+
language: ruby
|
|
15
|
+
language_version: 3.2.2
|
|
16
|
+
pass_filenames: false
|
|
17
|
+
always_run: true
|
|
18
|
+
|
|
19
|
+
- id: prepare_message
|
|
20
|
+
name: Prepare Commit Message
|
|
21
|
+
description: "Preparing commit message"
|
|
22
|
+
entry: "conventional_commits prepare_commit_msg"
|
|
23
|
+
language: ruby
|
|
24
|
+
language_version: 3.2.2
|
|
25
|
+
pass_filenames: false
|
|
26
|
+
args: [--source=$PRE_COMMIT_COMMIT_MSG_SOURCE]
|
|
27
|
+
always_run: true
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
conventional_commits (0.
|
|
4
|
+
conventional_commits (0.3.0)
|
|
5
5
|
open3
|
|
6
6
|
thor
|
|
7
7
|
yaml
|
|
@@ -104,6 +104,8 @@ GEM
|
|
|
104
104
|
PLATFORMS
|
|
105
105
|
arm64-darwin-23
|
|
106
106
|
arm64-darwin-24
|
|
107
|
+
arm64-darwin-25
|
|
108
|
+
x86_64-linux
|
|
107
109
|
|
|
108
110
|
DEPENDENCIES
|
|
109
111
|
aruba
|
data/README.md
CHANGED
|
@@ -55,8 +55,29 @@ to create a new branch
|
|
|
55
55
|
- `pattern` - is used to define the separators between in future it will be used to define the order as well
|
|
56
56
|
- `type` - is used for mapping combination of short names for the type of request. Helps to avoid inconsistency.
|
|
57
57
|
|
|
58
|
+
### Validating in CI
|
|
59
|
+
The hooks validate the current branch and `.git/COMMIT_EDITMSG`. In CI, pass them explicitly:
|
|
60
|
+
|
|
61
|
+
$ conventional_commits validate_branch --branch "$GITHUB_HEAD_REF"
|
|
62
|
+
$ conventional_commits validate_commit_msg --msg "$(git log -1 --format=%B "$SHA")"
|
|
63
|
+
|
|
64
|
+
With a detached `HEAD` and no `--branch`, `validate_branch` falls back to `$GITHUB_HEAD_REF`.
|
|
65
|
+
|
|
58
66
|
### Release
|
|
59
|
-
|
|
67
|
+
`next_version` prints the next version from the commits since the latest version tag
|
|
68
|
+
(`X.Y.Z` or `vX.Y.Z`), following `release.rules`:
|
|
69
|
+
|
|
70
|
+
$ conventional_commits next_version
|
|
71
|
+
0.3.1
|
|
72
|
+
|
|
73
|
+
- Each commit's type is matched against the rules' types; aliases from `type` count as their
|
|
74
|
+
main type, so a `ref:` commit matches a rule listing `refactor`.
|
|
75
|
+
- A breaking change — `type!:` in the subject or a `BREAKING CHANGE:` footer — uses the rule
|
|
76
|
+
for `breaking`.
|
|
77
|
+
- The biggest bump of all the commits wins (`major` > `minor` > `patch`); `version: none`, or a
|
|
78
|
+
type without a rule, produces no release.
|
|
79
|
+
- It prints nothing when no commit calls for a release, and `--initial` (default `0.1.0`) when
|
|
80
|
+
there is no version tag yet.
|
|
60
81
|
|
|
61
82
|
|
|
62
83
|
## Development
|
data/exe/conventional_commits
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module ConventionalCommits
|
|
4
4
|
class BranchNameGenerator
|
|
5
|
-
attr_reader :reader
|
|
5
|
+
attr_reader :reader, :main_reader
|
|
6
6
|
|
|
7
|
-
def initialize(reader: reader = Configuration::BranchConfigurationReader.new
|
|
7
|
+
def initialize(reader: reader = Configuration::BranchConfigurationReader.new,
|
|
8
|
+
main_reader: Configuration::MainConfigurationReader.new)
|
|
8
9
|
@reader = reader
|
|
10
|
+
@main_reader = main_reader
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
def generate_name_for(_input, path: Configuration::DEFAULT_CONFIGURATION_PATH)
|
|
@@ -34,12 +36,31 @@ module ConventionalCommits
|
|
|
34
36
|
components
|
|
35
37
|
end
|
|
36
38
|
|
|
39
|
+
# A branch is valid when the commit message generator can build a subject from it: the
|
|
40
|
+
# type must be one the configuration allows, and the description must not be empty.
|
|
37
41
|
def is_valid_branch(_input, path: Configuration::DEFAULT_CONFIGURATION_PATH)
|
|
38
|
-
|
|
42
|
+
components = branch_name_components(_input, path:)
|
|
43
|
+
validate_description(components[:description], branch: _input)
|
|
44
|
+
validate_type(components[:type], path:)
|
|
45
|
+
true
|
|
39
46
|
end
|
|
40
47
|
|
|
41
48
|
private
|
|
42
49
|
|
|
50
|
+
def validate_description(description, branch:)
|
|
51
|
+
return unless description.to_s.strip.empty?
|
|
52
|
+
|
|
53
|
+
raise GenericError, "The branch #{branch} has no description"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def validate_type(type, path:)
|
|
57
|
+
type_configuration = main_reader.get_configuration(path:).type
|
|
58
|
+
return if type_configuration.is_allowed(type.to_s.downcase)
|
|
59
|
+
|
|
60
|
+
raise GenericError,
|
|
61
|
+
"The type #{type} is not allowed. Allowed types #{type_configuration.all_types}"
|
|
62
|
+
end
|
|
63
|
+
|
|
43
64
|
def find_delimiters_from_pattern(pattern: string)
|
|
44
65
|
delimiters = pattern.gsub(/<scope>/, "<replace>")
|
|
45
66
|
.gsub(/<type>/, "<replace>")
|
data/lib/cli/branch_name_cli.rb
CHANGED
|
@@ -24,44 +24,60 @@ module ConventionalCommits
|
|
|
24
24
|
option :source, type: :string, required: false
|
|
25
25
|
option :cfg_path, type: :string, required: false
|
|
26
26
|
def prepare_commit_msg
|
|
27
|
-
source = options["source"] || ""
|
|
28
|
-
puts source
|
|
27
|
+
source = options["source"] || ENV["PRE_COMMIT_COMMIT_MSG_SOURCE"] || ""
|
|
29
28
|
msg_path = options["msg_path"] || Configuration::DEFAULT_COMMIT_MSG_PATH
|
|
30
29
|
cfg_path = options["cfg_path"] || Configuration::DEFAULT_CONFIGURATION_PATH
|
|
31
30
|
|
|
31
|
+
return if Configuration.git_generated_message?(msg_path)
|
|
32
|
+
|
|
32
33
|
generator = ConventionalCommits::CommitMessageGenerator.new
|
|
33
34
|
unless generator.should_preserve_original_message(source:)
|
|
34
35
|
puts "Generating message"
|
|
35
36
|
name = generator.prepare_message_template_for_type(type: source, cfg_path:, msg_file_path: msg_path)
|
|
36
37
|
File.write_to_file(msg_path, name)
|
|
37
38
|
end
|
|
38
|
-
|
|
39
39
|
rescue StandardError => e
|
|
40
40
|
raise Thor::Error, e.message
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
desc "validate_branch", "validates if the branch conforms to the rules"
|
|
44
44
|
option :cfg_path, type: :string, required: false
|
|
45
|
+
option :branch, type: :string, required: false,
|
|
46
|
+
desc: "Branch to validate; defaults to the current branch, then $GITHUB_HEAD_REF"
|
|
45
47
|
def validate_branch_name
|
|
46
48
|
cfg_path = options["cfg_path"] || Configuration::DEFAULT_CONFIGURATION_PATH
|
|
47
49
|
generator = ConventionalCommits::BranchNameGenerator.new
|
|
48
|
-
|
|
49
|
-
generator.is_valid_branch(name.strip, path: cfg_path.strip)
|
|
50
|
+
generator.is_valid_branch(branch_name_to_validate, path: cfg_path.strip)
|
|
50
51
|
rescue StandardError => e
|
|
51
52
|
raise Thor::Error, e.message
|
|
52
53
|
end
|
|
53
54
|
|
|
54
|
-
desc "validate_commit_msg", "validates if the
|
|
55
|
+
desc "validate_commit_msg", "validates if the commit message conforms to the rules"
|
|
55
56
|
option :msg_path, type: :string, required: false
|
|
56
|
-
option :msg, type: :string, required: false
|
|
57
|
+
option :msg, type: :string, required: false, desc: "Message text to validate instead of a file"
|
|
57
58
|
option :cfg_path, type: :string, required: false
|
|
58
59
|
def validate_commit_msg
|
|
59
|
-
|
|
60
60
|
msg_path = options["msg_path"] || Configuration::DEFAULT_COMMIT_MSG_PATH
|
|
61
61
|
cfg_path = options["cfg_path"] || Configuration::DEFAULT_CONFIGURATION_PATH
|
|
62
62
|
validator = ConventionalCommits::CommitMessageValidator.new
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
if options["msg"]
|
|
65
|
+
validator.validate_commit_msg(message: options["msg"], cfg_path:)
|
|
66
|
+
else
|
|
67
|
+
validator.validate_commit_msg_from_file(commit_msg_path: msg_path, cfg_path:)
|
|
68
|
+
end
|
|
69
|
+
rescue StandardError => e
|
|
70
|
+
raise Thor::Error, e.message
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
desc "next_version", "prints the next release version from the commits since the latest version tag"
|
|
74
|
+
option :cfg_path, type: :string, required: false
|
|
75
|
+
option :initial, type: :string, required: false, desc: "Version to print when there is no version tag yet (default 0.1.0)"
|
|
76
|
+
def next_version
|
|
77
|
+
cfg_path = options["cfg_path"] || Configuration::DEFAULT_CONFIGURATION_PATH
|
|
78
|
+
version = ConventionalCommits::NextVersionCalculator.new
|
|
79
|
+
.next_version(cfg_path:, initial: options["initial"] || "0.1.0")
|
|
80
|
+
puts version if version
|
|
65
81
|
rescue StandardError => e
|
|
66
82
|
raise Thor::Error, e.message
|
|
67
83
|
end
|
|
@@ -73,5 +89,18 @@ module ConventionalCommits
|
|
|
73
89
|
rescue StandardError => e
|
|
74
90
|
raise Thor::Error, e.message
|
|
75
91
|
end
|
|
92
|
+
|
|
93
|
+
no_commands do
|
|
94
|
+
# A detached HEAD (e.g. a CI checkout of a pull request) has no current branch, so fall
|
|
95
|
+
# back to the pull request's head branch that GitHub Actions provides.
|
|
96
|
+
def branch_name_to_validate
|
|
97
|
+
name = [options["branch"], ConventionalCommits::Git.new.current_branch_name, ENV["GITHUB_HEAD_REF"]]
|
|
98
|
+
.map { |candidate| candidate.to_s.strip }
|
|
99
|
+
.find { |candidate| !candidate.empty? }
|
|
100
|
+
raise GenericError, "Cannot determine the branch name (HEAD is detached); pass --branch" if name.nil?
|
|
101
|
+
|
|
102
|
+
name
|
|
103
|
+
end
|
|
104
|
+
end
|
|
76
105
|
end
|
|
77
106
|
end
|
|
@@ -4,10 +4,20 @@ module ConventionalCommits
|
|
|
4
4
|
class CommitMessageValidator
|
|
5
5
|
def validate_commit_msg_from_file(commit_msg_path: Configuration::DEFAULT_COMMIT_MSG_PATH,
|
|
6
6
|
cfg_path: Configuration::DEFAULT_CONFIGURATION_PATH)
|
|
7
|
-
return if commit_msg_path
|
|
7
|
+
return if Configuration.git_generated_message?(commit_msg_path)
|
|
8
|
+
|
|
9
|
+
parser = CommitMessageParser.new
|
|
10
|
+
validate(parser.message_components(commit_msg_path:, cfg_path:))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def validate_commit_msg(message:, cfg_path: Configuration::DEFAULT_CONFIGURATION_PATH)
|
|
8
14
|
parser = CommitMessageParser.new
|
|
9
|
-
|
|
15
|
+
validate(parser.message_components_from_string(commit_msg: message, cfg_path:))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
10
19
|
|
|
20
|
+
def validate(components)
|
|
11
21
|
raise GenericError, "The Message is Invalid" if components.empty?
|
|
12
22
|
|
|
13
23
|
if components[:body].include?(Configuration::DEFAULT_COMMIT_BODY_TEMPLATE)
|
data/lib/configuration.rb
CHANGED
|
@@ -6,5 +6,11 @@ module ConventionalCommits
|
|
|
6
6
|
DEFAULT_COMMIT_MSG_PATH = ".git/COMMIT_EDITMSG"
|
|
7
7
|
DEFAULT_COMMIT_BODY_TEMPLATE = "[Describe your work, and put an empty string after]"
|
|
8
8
|
MAX_ELEMENTS_IN_PATTERN = 4
|
|
9
|
+
# Messages git writes itself for merges and squashes; hooks receive them and leave them as is.
|
|
10
|
+
GIT_GENERATED_MESSAGE_FILES = %w[MERGE_MSG SQUASH_MSG].freeze
|
|
11
|
+
|
|
12
|
+
def self.git_generated_message?(path)
|
|
13
|
+
GIT_GENERATED_MESSAGE_FILES.include?(File.basename(path.to_s))
|
|
14
|
+
end
|
|
9
15
|
end
|
|
10
16
|
end
|
data/lib/git/git.rb
CHANGED
|
@@ -10,6 +10,16 @@ module ConventionalCommits
|
|
|
10
10
|
run_system_command "git symbolic-ref --short HEAD"
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
+
def tags
|
|
14
|
+
run_system_command("git tag --list").split("\n").map(&:strip).reject(&:empty?)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Full messages of the commits reachable from HEAD but not from `ref`, newest first.
|
|
18
|
+
def commit_messages_since(ref)
|
|
19
|
+
run_system_command("git log --format=%B%x00 #{ref}..HEAD")
|
|
20
|
+
.split("\x00").map(&:strip).reject(&:empty?)
|
|
21
|
+
end
|
|
22
|
+
|
|
13
23
|
def run_system_command(_cmd)
|
|
14
24
|
Open3.popen3(_cmd) { |_stdin, stdout, _stderr, _wait_thr| stdout.read }
|
|
15
25
|
end
|
data/lib/models/release_rule.rb
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
module ConventionalCommits
|
|
4
4
|
module Configuration
|
|
5
|
-
#
|
|
5
|
+
# A release rule: which commit types produce which version bump
|
|
6
6
|
class ReleaseRule
|
|
7
7
|
attr_reader :types, :version
|
|
8
8
|
|
|
9
|
+
# Accepts both `types: [..]` and the singular `type: ..` used for the breaking rule.
|
|
9
10
|
def initialize(options = {})
|
|
10
|
-
@types = options["types"] || []
|
|
11
|
+
@types = Array(options["types"] || options["type"])
|
|
11
12
|
@version = options["version"] || "none"
|
|
12
13
|
end
|
|
13
14
|
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConventionalCommits
|
|
4
|
+
# Works out the next release version from the commits since the latest version tag, using the
|
|
5
|
+
# `release.rules` of the configuration: each commit's type (aliases included) maps to a bump,
|
|
6
|
+
# and the biggest bump wins. A breaking change (`type!:` or a `BREAKING CHANGE:` footer) uses
|
|
7
|
+
# the rule for the `breaking` type.
|
|
8
|
+
class NextVersionCalculator
|
|
9
|
+
VERSION_TAG = /\Av?\d+\.\d+\.\d+\z/
|
|
10
|
+
SUBJECT = /\A(?<type>[A-Za-z]+)(?:\([^)]*\))?(?<breaking>!)?:/
|
|
11
|
+
BREAKING_FOOTER = /^BREAKING[ -]CHANGE:/
|
|
12
|
+
BREAKING_TYPE = "breaking"
|
|
13
|
+
BUMPS = %w[none patch minor major].freeze
|
|
14
|
+
|
|
15
|
+
attr_reader :git, :reader
|
|
16
|
+
|
|
17
|
+
def initialize(git: Git.new, reader: Configuration::MainConfigurationReader.new)
|
|
18
|
+
@git = git
|
|
19
|
+
@reader = reader
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# The next version as "X.Y.Z", `initial` when there is no version tag yet, or nil when no
|
|
23
|
+
# commit since the latest tag calls for a release.
|
|
24
|
+
def next_version(cfg_path: Configuration::DEFAULT_CONFIGURATION_PATH, initial: "0.1.0")
|
|
25
|
+
tag = latest_version_tag
|
|
26
|
+
return initial if tag.nil?
|
|
27
|
+
|
|
28
|
+
config = reader.get_configuration(path: cfg_path)
|
|
29
|
+
bumps = git.commit_messages_since(tag).map { |message| bump_for(message, config) }
|
|
30
|
+
bumped(tag, bumps.max_by { |bump| BUMPS.index(bump) } || "none")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def latest_version_tag
|
|
36
|
+
git.tags.grep(VERSION_TAG).max_by { |tag| Gem::Version.new(tag.delete_prefix("v")) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def bump_for(message, config)
|
|
40
|
+
subject = SUBJECT.match(message.lines.first.to_s.strip)
|
|
41
|
+
return "none" if subject.nil?
|
|
42
|
+
|
|
43
|
+
if subject[:breaking] || message.match?(BREAKING_FOOTER)
|
|
44
|
+
rule_bump(BREAKING_TYPE, config) || type_bump(subject[:type], config)
|
|
45
|
+
else
|
|
46
|
+
type_bump(subject[:type], config)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def type_bump(type, config)
|
|
51
|
+
rule_bump(main_type(type.downcase, config), config) || "none"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def rule_bump(type, config)
|
|
55
|
+
rule = config.release.rules.find do |candidate|
|
|
56
|
+
candidate.types.map { |rule_type| main_type(rule_type.to_s, config) }.include?(type)
|
|
57
|
+
end
|
|
58
|
+
rule && validated(rule.version)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Rule types and commit types may be aliases ("feature", "ref"); both sides compare as the
|
|
62
|
+
# configured main type. `breaking` and unknown types stay as they are.
|
|
63
|
+
def main_type(type, config)
|
|
64
|
+
main = config.type.main_type(type)
|
|
65
|
+
main.to_s.empty? ? type : main
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def validated(bump)
|
|
69
|
+
raise GenericError, "Unknown release version '#{bump}', expected one of #{BUMPS}" unless BUMPS.include?(bump)
|
|
70
|
+
|
|
71
|
+
bump
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def bumped(tag, bump)
|
|
75
|
+
return nil if bump == "none"
|
|
76
|
+
|
|
77
|
+
major, minor, patch = tag.delete_prefix("v").split(".").map(&:to_i)
|
|
78
|
+
case bump
|
|
79
|
+
when "major" then "#{major + 1}.0.0"
|
|
80
|
+
when "minor" then "#{major}.#{minor + 1}.0"
|
|
81
|
+
else "#{major}.#{minor}.#{patch + 1}"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: conventional_commits
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Swift-Gurus
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-10-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: open3
|
|
@@ -129,6 +129,7 @@ files:
|
|
|
129
129
|
- lib/models/release_configuration.rb
|
|
130
130
|
- lib/models/release_rule.rb
|
|
131
131
|
- lib/models/type_configuration.rb
|
|
132
|
+
- lib/release/next_version_calculator.rb
|
|
132
133
|
- sig/conventional_commit/branch_name_generator.rbs
|
|
133
134
|
- sig/conventional_commits.rbs
|
|
134
135
|
- sig/conventional_commits/branch_name_cli.rbs
|