committer 0.2.2 → 0.3.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 +4 -4
- data/README.md +52 -24
- data/bin/committer +4 -114
- data/lib/committer/commands/default.rb +38 -0
- data/lib/committer/commands/help.rb +19 -0
- data/lib/committer/commands/output_message.rb +30 -0
- data/lib/committer/commands/setup.rb +12 -0
- data/lib/committer/commands/setup_git_hook.rb +61 -0
- data/lib/committer/commands.rb +26 -0
- data/lib/committer/commit_generator.rb +81 -0
- data/lib/committer/config.rb +2 -1
- data/lib/committer/prepare-commit-msg +35 -0
- data/lib/committer/version.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9dce742b36edfa9cef8ad7811bccfef3ca049a91a92cd05264b4004423a1afb9
|
4
|
+
data.tar.gz: 50c8ff360e6905279969af7537e2b6e4cd4f918fec61a65ec1b9333e943906e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9b64954d73434cb9c095b32426f673fe544d23d1d1b0bf74da1ab29b700f77e1a7b3b2d5cd9d571d4e005b706d0369f08666317b521996d18145c6fd2224f6a
|
7
|
+
data.tar.gz: e453d6be97c3ab39aa2fc19c13236477d3b6aed625841e2e2d6035d435adda196ab83353e4763788858e0e4ee328a6f01fd8423412b86679a373648f1b776f45
|
data/README.md
CHANGED
@@ -6,11 +6,12 @@ An AI-powered git commit message generator using Claude.
|
|
6
6
|
|
7
7
|
The goal of committer is to make it easier to write beautiful commits.
|
8
8
|
|
9
|
-
Committer uses Claude AI to analyze your staged git changes and generate conventional commit messages for you. It detects the type of changes (feature, fix, refactor, etc.) and creates a well-formatted commit message that follows best practices.
|
9
|
+
Committer uses Claude AI to analyze your staged git changes and generate [conventional commit](https://www.conventionalcommits.org/en/v1.0.0/) messages for you. It detects the type of changes (feature, fix, refactor, etc.) and creates a well-formatted commit message that follows best practices.
|
10
10
|
|
11
11
|
## What Makes a Good Commit
|
12
12
|
|
13
13
|
A good commit should:
|
14
|
+
|
14
15
|
- Have a summary that clearly describes the change
|
15
16
|
- Explain WHY the change was made, not just what changed
|
16
17
|
|
@@ -19,9 +20,10 @@ When a future developer uses git blame to understand a line of code, they should
|
|
19
20
|
## How Committer Helps
|
20
21
|
|
21
22
|
Committer analyzes your code changes and generates commit messages that:
|
23
|
+
|
22
24
|
1. Provide a clean, descriptive summary of the change
|
23
25
|
2. Include context about why the change was necessary
|
24
|
-
3. Follow conventional commit format for consistency
|
26
|
+
3. Follow [conventional commit](https://www.conventionalcommits.org/en/v1.0.0/) format for consistency
|
25
27
|
|
26
28
|
## Installation
|
27
29
|
|
@@ -31,26 +33,6 @@ Committer analyzes your code changes and generates commit messages that:
|
|
31
33
|
gem install committer
|
32
34
|
```
|
33
35
|
|
34
|
-
### Manual Installation
|
35
|
-
|
36
|
-
1. Install Bundler if you haven't already:
|
37
|
-
|
38
|
-
```sh
|
39
|
-
gem install bundler
|
40
|
-
```
|
41
|
-
|
42
|
-
2. Install the project dependencies:
|
43
|
-
|
44
|
-
```sh
|
45
|
-
bundle install
|
46
|
-
```
|
47
|
-
|
48
|
-
3. Link the executable:
|
49
|
-
```bash
|
50
|
-
gem build committer.gemspec
|
51
|
-
gem install committer-0.1.0.gem
|
52
|
-
```
|
53
|
-
|
54
36
|
## Configuration
|
55
37
|
|
56
38
|
Before using Committer, you need to set up your configuration file:
|
@@ -72,7 +54,7 @@ scopes:
|
|
72
54
|
- ui
|
73
55
|
```
|
74
56
|
|
75
|
-
The `scopes` configuration is optional. When provided, Committer will generate conventional commit messages with scopes (like `feat(api): add new endpoint`). If left as `null` or omitted, commit messages will be generated without scopes (like `feat: add new endpoint`).
|
57
|
+
The `scopes` configuration is optional. When provided, Committer will generate [conventional commit](https://www.conventionalcommits.org/en/v1.0.0/) messages with scopes (like `feat(api): add new endpoint`). If left as `null` or omitted, commit messages will be generated without scopes (like `feat: add new endpoint`).
|
76
58
|
|
77
59
|
You only need to do this setup once.
|
78
60
|
|
@@ -89,7 +71,7 @@ This will:
|
|
89
71
|
1. Get the diff of your staged changes
|
90
72
|
2. Ask you for optional context about why you're making the change
|
91
73
|
3. Send the diff and context to Claude for analysis
|
92
|
-
4. Generate a commit message in conventional format (with scope if configured)
|
74
|
+
4. Generate a commit message in [conventional commit](https://www.conventionalcommits.org/en/v1.0.0/) format (with scope if configured)
|
93
75
|
5. Open your default git editor with the suggested message
|
94
76
|
6. Allow you to edit the message if needed or simply save to confirm
|
95
77
|
|
@@ -98,6 +80,52 @@ This will:
|
|
98
80
|
- `committer` - Generate commit message for staged changes
|
99
81
|
- `committer setup` - Create the config file template
|
100
82
|
- `committer help` - Display help information
|
83
|
+
- `committer setup-git-hook` - Install the git hook for automatic commit message generation
|
84
|
+
- `committer output-message` - Generate a commit message (used by the git hook)
|
85
|
+
|
86
|
+
## Git Hook Integration
|
87
|
+
|
88
|
+
Committer can be integrated directly with Git using a prepare-commit-msg hook, which automatically generates commit messages whenever you commit.
|
89
|
+
|
90
|
+
### Installing the Git Hook
|
91
|
+
|
92
|
+
To install the git hook, navigate to the root of your git repository and run:
|
93
|
+
|
94
|
+
```bash
|
95
|
+
committer setup-git-hook
|
96
|
+
```
|
97
|
+
|
98
|
+
This command will:
|
99
|
+
1. Verify you're in the root of a git repository
|
100
|
+
2. Install the prepare-commit-msg hook in your `.git/hooks` directory
|
101
|
+
3. Make the hook executable
|
102
|
+
|
103
|
+
### How the Git Hook Works
|
104
|
+
|
105
|
+
Once installed, the git hook will:
|
106
|
+
1. Automatically run whenever you execute `git commit`
|
107
|
+
2. Generate an AI-powered commit message based on your staged changes
|
108
|
+
3. Pre-fill your commit message editor with the generated message
|
109
|
+
4. Allow you to edit the message before finalizing the commit
|
110
|
+
|
111
|
+
Since git hooks run in non-interactive mode, you can provide context for your commit by using the REASON environment variable:
|
112
|
+
|
113
|
+
```bash
|
114
|
+
REASON="Improve performance by optimizing database queries" git commit
|
115
|
+
```
|
116
|
+
|
117
|
+
If you don't provide a REASON, the commit message will still be generated, but without the additional context that would be used to generate a more detailed body.
|
118
|
+
|
119
|
+
## Development
|
120
|
+
|
121
|
+
### Running Tests
|
122
|
+
|
123
|
+
Committer uses RSpec for testing. To run the tests:
|
124
|
+
|
125
|
+
```bash
|
126
|
+
bundle install
|
127
|
+
bundle exec rake spec
|
128
|
+
```
|
101
129
|
|
102
130
|
## License
|
103
131
|
|
data/bin/committer
CHANGED
@@ -2,122 +2,12 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'bundler/setup'
|
5
|
-
require 'open3'
|
6
|
-
require 'httparty'
|
7
|
-
require 'yaml'
|
8
5
|
require_relative '../lib/committer/config'
|
9
|
-
require_relative '../lib/committer/
|
10
|
-
require_relative '../lib/
|
6
|
+
require_relative '../lib/committer/commit_generator'
|
7
|
+
require_relative '../lib/committer/commands'
|
11
8
|
|
12
9
|
# Handle command line arguments
|
13
10
|
command = ARGV[0]
|
11
|
+
args = ARGV[1..]
|
14
12
|
|
15
|
-
|
16
|
-
when 'setup'
|
17
|
-
Committer::Config.setup
|
18
|
-
exit 0
|
19
|
-
|
20
|
-
when 'help', '--help', '-h'
|
21
|
-
puts 'Committer - AI-powered git commit message generator'
|
22
|
-
puts
|
23
|
-
puts 'Commands:'
|
24
|
-
puts ' committer setup - Create the config file template at ~/.committer/config.yml'
|
25
|
-
puts ' committer - Generate commit message for staged changes'
|
26
|
-
puts
|
27
|
-
exit 0
|
28
|
-
end
|
29
|
-
|
30
|
-
# Default behavior: generate commit message
|
31
|
-
def build_commit_prompt(diff, commit_context = nil)
|
32
|
-
scopes = Committer::Config.load
|
33
|
-
scope_section = scopes.empty? ? '' : "\nScopes:\n#{scopes.map { |s| "- #{s}" }.join("\n")}"
|
34
|
-
scope_instruction = if scopes.empty?
|
35
|
-
'- DO NOT include a scope in your commit message'
|
36
|
-
else
|
37
|
-
'- Choose an appropriate scope from the list above if relevant to the change'
|
38
|
-
end
|
39
|
-
format(template(commit_context),
|
40
|
-
diff: diff,
|
41
|
-
scopes_section: scope_section,
|
42
|
-
scope_instruction: scope_instruction,
|
43
|
-
commit_context: commit_context)
|
44
|
-
end
|
45
|
-
|
46
|
-
def template(commit_context)
|
47
|
-
if commit_context.nil? || commit_context.empty?
|
48
|
-
Committer::PromptTemplates::SUMMARY_ONLY
|
49
|
-
else
|
50
|
-
Committer::PromptTemplates::SUMMARY_AND_BODY
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def check_git_status
|
55
|
-
stdout, stderr, status = Open3.capture3('git diff --staged')
|
56
|
-
|
57
|
-
unless status.success?
|
58
|
-
puts 'Error executing git diff --staged:'
|
59
|
-
puts stderr
|
60
|
-
exit 1
|
61
|
-
end
|
62
|
-
|
63
|
-
if stdout.empty?
|
64
|
-
puts 'No changes are staged for commit.'
|
65
|
-
exit 0
|
66
|
-
end
|
67
|
-
|
68
|
-
stdout
|
69
|
-
end
|
70
|
-
|
71
|
-
def parse_response(response, commit_context)
|
72
|
-
text = response.dig('content', 0, 'text')
|
73
|
-
|
74
|
-
# If user didn't provide context, response should only be a summary line
|
75
|
-
if commit_context.nil? || commit_context.empty?
|
76
|
-
{ summary: text.strip, body: nil }
|
77
|
-
else
|
78
|
-
# Split the response into summary and body
|
79
|
-
message_parts = text.split("\n\n", 2)
|
80
|
-
summary = message_parts[0].strip
|
81
|
-
body = message_parts[1]&.strip
|
82
|
-
|
83
|
-
# Wrap body text at 80 characters
|
84
|
-
body = body.gsub(/(.{1,80})(\s+|$)/, "\\1\n").strip if body
|
85
|
-
|
86
|
-
{ summary: summary, body: body }
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def prepare_commit_message(diff, commit_context = nil)
|
91
|
-
client = Clients::ClaudeClient.new
|
92
|
-
puts 'Sending diff to Claude...'
|
93
|
-
|
94
|
-
prompt = build_commit_prompt(diff, commit_context)
|
95
|
-
response = client.post(prompt)
|
96
|
-
parse_response(response, commit_context)
|
97
|
-
end
|
98
|
-
|
99
|
-
def execute_git_diff_staged
|
100
|
-
diff = check_git_status
|
101
|
-
|
102
|
-
# Prompt user for commit context
|
103
|
-
puts 'Why are you making this change? (Press Enter to skip)'
|
104
|
-
commit_context = gets.chomp
|
105
|
-
|
106
|
-
commit_message = prepare_commit_message(diff, commit_context)
|
107
|
-
|
108
|
-
summary = commit_message[:summary]
|
109
|
-
body = commit_message[:body]
|
110
|
-
|
111
|
-
# Create git commit with the suggested message and open in editor
|
112
|
-
if body
|
113
|
-
system('git', 'commit', '-m', summary, '-m', body, '-e')
|
114
|
-
else
|
115
|
-
system('git', 'commit', '-m', summary, '-e')
|
116
|
-
end
|
117
|
-
rescue Clients::ClaudeClient::ConfigError, StandardError => e
|
118
|
-
puts "Error: #{e.message}"
|
119
|
-
exit 1
|
120
|
-
end
|
121
|
-
|
122
|
-
# Execute the function if no specific command was given
|
123
|
-
execute_git_diff_staged
|
13
|
+
Committer::Commands.run(command, args)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Committer
|
4
|
+
module Commands
|
5
|
+
class Default
|
6
|
+
def self.execute_commit(diff, commit_context)
|
7
|
+
commit_generator = Committer::CommitGenerator.new(diff, commit_context)
|
8
|
+
commit_message = commit_generator.prepare_commit_message
|
9
|
+
|
10
|
+
summary = commit_message[:summary]
|
11
|
+
body = commit_message[:body]
|
12
|
+
# Create git commit with the suggested message and open in editor
|
13
|
+
if body
|
14
|
+
system('git', 'commit', '-m', summary, '-m', body, '-e')
|
15
|
+
else
|
16
|
+
system('git', 'commit', '-m', summary, '-e')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.execute(_args)
|
21
|
+
diff = Committer::CommitGenerator.check_git_status
|
22
|
+
|
23
|
+
if diff.empty?
|
24
|
+
puts 'No changes are staged for commit.'
|
25
|
+
exit 0
|
26
|
+
end
|
27
|
+
|
28
|
+
# Prompt user for commit context
|
29
|
+
puts 'Why are you making this change? (Press Enter to skip)'
|
30
|
+
commit_context = gets.chomp
|
31
|
+
execute_commit(diff, commit_context)
|
32
|
+
rescue Clients::ClaudeClient::ConfigError, StandardError => e
|
33
|
+
puts "Error: #{e.message}"
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Committer
|
4
|
+
module Commands
|
5
|
+
class Help
|
6
|
+
def self.execute(_args)
|
7
|
+
puts 'Committer - AI-powered git commit message generator'
|
8
|
+
puts
|
9
|
+
puts 'Commands:'
|
10
|
+
puts ' committer setup - Create the config file template at ~/.committer/config.yml'
|
11
|
+
puts ' committer - Generate commit message for staged changes'
|
12
|
+
puts ' committer output-message - Generate commit message without creating a commit'
|
13
|
+
puts ' committer setup-git-hook - Install the prepare-commit-msg git hook'
|
14
|
+
puts
|
15
|
+
exit 0
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Committer
|
4
|
+
module Commands
|
5
|
+
class OutputMessage
|
6
|
+
def self.execute(args)
|
7
|
+
commit_context = args[0]
|
8
|
+
diff = Committer::CommitGenerator.check_git_status
|
9
|
+
|
10
|
+
commit_generator = Committer::CommitGenerator.new(diff, commit_context)
|
11
|
+
commit_message = commit_generator.prepare_commit_message
|
12
|
+
|
13
|
+
summary = commit_message[:summary]
|
14
|
+
body = commit_message[:body]
|
15
|
+
|
16
|
+
puts <<~OUTPUT
|
17
|
+
#{summary}
|
18
|
+
|
19
|
+
#{body}
|
20
|
+
OUTPUT
|
21
|
+
exit 0
|
22
|
+
rescue Clients::ClaudeClient::ConfigError => e
|
23
|
+
puts "Error: #{e.message}"
|
24
|
+
exit 1
|
25
|
+
rescue StandardError
|
26
|
+
exit 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Committer
|
4
|
+
module Commands
|
5
|
+
class SetupGitHook
|
6
|
+
HOOK_PATH = '.git/hooks/prepare-commit-msg'
|
7
|
+
|
8
|
+
def self.execute(_args)
|
9
|
+
validate_git_repository
|
10
|
+
install_git_hook
|
11
|
+
display_success_message
|
12
|
+
exit 0
|
13
|
+
rescue StandardError => e
|
14
|
+
puts "Error: #{e.message}"
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.validate_git_repository
|
19
|
+
validate_git_root
|
20
|
+
validate_git_directory_exists
|
21
|
+
validate_hook_doesnt_exist
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.validate_git_directory_exists
|
25
|
+
return if Dir.exist?('.git')
|
26
|
+
|
27
|
+
puts 'Error: Current directory is not a git repository.'
|
28
|
+
exit 1
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.validate_git_root
|
32
|
+
git_toplevel = `git rev-parse --show-toplevel`.strip
|
33
|
+
current_dir = Dir.pwd
|
34
|
+
return if git_toplevel == current_dir
|
35
|
+
|
36
|
+
puts 'Error: Please run this command from the root of your git repository.'
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.validate_hook_doesnt_exist
|
41
|
+
return unless File.exist?(HOOK_PATH)
|
42
|
+
|
43
|
+
puts 'Error: prepare-commit-msg hook already exists.'
|
44
|
+
puts 'Please remove or rename the existing hook and try again.'
|
45
|
+
exit 1
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.install_git_hook
|
49
|
+
template_path = File.expand_path('../prepare-commit-msg', __dir__)
|
50
|
+
hook_content = File.read(template_path)
|
51
|
+
File.write(HOOK_PATH, hook_content)
|
52
|
+
File.chmod(0o755, HOOK_PATH)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.display_success_message
|
56
|
+
puts 'Git hook successfully installed!'
|
57
|
+
puts 'Now your commit messages will be automatically generated.'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'commands/setup'
|
4
|
+
require_relative 'commands/help'
|
5
|
+
require_relative 'commands/output_message'
|
6
|
+
require_relative 'commands/setup_git_hook'
|
7
|
+
require_relative 'commands/default'
|
8
|
+
|
9
|
+
module Committer
|
10
|
+
module Commands
|
11
|
+
def self.run(command, args)
|
12
|
+
case command
|
13
|
+
when 'setup'
|
14
|
+
Setup.execute(args)
|
15
|
+
when 'help', '--help', '-h'
|
16
|
+
Help.execute(args)
|
17
|
+
when 'output-message'
|
18
|
+
OutputMessage.execute(args)
|
19
|
+
when 'setup-git-hook'
|
20
|
+
SetupGitHook.execute(args)
|
21
|
+
else
|
22
|
+
Default.execute(args)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'open3'
|
4
|
+
require 'httparty'
|
5
|
+
require 'yaml'
|
6
|
+
require_relative 'config'
|
7
|
+
require_relative 'prompt_templates'
|
8
|
+
require_relative '../clients/claude_client'
|
9
|
+
|
10
|
+
module Committer
|
11
|
+
class CommitGenerator
|
12
|
+
attr_reader :diff, :commit_context
|
13
|
+
|
14
|
+
def initialize(diff, commit_context = nil)
|
15
|
+
@diff = diff
|
16
|
+
@commit_context = commit_context
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_commit_prompt
|
20
|
+
scopes = Committer::Config.load
|
21
|
+
scope_section = scopes.empty? ? '' : "\nScopes:\n#{scopes.map { |s| "- #{s}" }.join("\n")}"
|
22
|
+
scope_instruction = if scopes.empty?
|
23
|
+
'- DO NOT include a scope in your commit message'
|
24
|
+
else
|
25
|
+
'- Choose an appropriate scope from the list above if relevant to the change'
|
26
|
+
end
|
27
|
+
format(template,
|
28
|
+
diff: @diff,
|
29
|
+
scopes_section: scope_section,
|
30
|
+
scope_instruction: scope_instruction,
|
31
|
+
commit_context: @commit_context)
|
32
|
+
end
|
33
|
+
|
34
|
+
def template
|
35
|
+
if @commit_context.nil? || @commit_context.empty?
|
36
|
+
Committer::PromptTemplates::SUMMARY_ONLY
|
37
|
+
else
|
38
|
+
Committer::PromptTemplates::SUMMARY_AND_BODY
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.check_git_status
|
43
|
+
stdout, stderr, status = Open3.capture3('git diff --staged')
|
44
|
+
|
45
|
+
unless status.success?
|
46
|
+
puts 'Error executing git diff --staged:'
|
47
|
+
puts stderr
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
|
51
|
+
stdout
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_response(response)
|
55
|
+
text = response.dig('content', 0, 'text')
|
56
|
+
|
57
|
+
# If user didn't provide context, response should only be a summary line
|
58
|
+
if @commit_context.nil? || @commit_context.empty?
|
59
|
+
{ summary: text.strip, body: nil }
|
60
|
+
else
|
61
|
+
# Split the response into summary and body
|
62
|
+
message_parts = text.split("\n\n", 2)
|
63
|
+
summary = message_parts[0].strip
|
64
|
+
body = message_parts[1]&.strip
|
65
|
+
|
66
|
+
# Wrap body text at 80 characters
|
67
|
+
body = body.gsub(/(.{1,80})(\s+|$)/, "\\1\n").strip if body
|
68
|
+
|
69
|
+
{ summary: summary, body: body }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def prepare_commit_message
|
74
|
+
client = Clients::ClaudeClient.new
|
75
|
+
|
76
|
+
prompt = build_commit_prompt
|
77
|
+
response = client.post(prompt)
|
78
|
+
parse_response(response)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/committer/config.rb
CHANGED
@@ -19,7 +19,8 @@ module Committer
|
|
19
19
|
begin
|
20
20
|
YAML.load_file(CONFIG_FILE) || DEFAULT_CONFIG
|
21
21
|
rescue StandardError => e
|
22
|
-
|
22
|
+
# Use $stdout directly for better test capture
|
23
|
+
$stdout.puts "Error loading config: #{e.message}"
|
23
24
|
DEFAULT_CONFIG
|
24
25
|
end
|
25
26
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# Check if parameters 2 and 3 are null
|
4
|
+
if [ -z "$2" ] && [ -z "$3" ]; then
|
5
|
+
# Check if parameter 1 is provided and is a valid file
|
6
|
+
if [ -z "$1" ]; then
|
7
|
+
echo "Error: No target file specified in parameter 1"
|
8
|
+
exit 1
|
9
|
+
fi
|
10
|
+
|
11
|
+
if [ ! -f "$1" ]; then
|
12
|
+
echo "Error: File '$1' does not exist"
|
13
|
+
exit 1
|
14
|
+
fi
|
15
|
+
|
16
|
+
# Check if committer command exists
|
17
|
+
if command -v committer &> /dev/null; then
|
18
|
+
# Execute committer command and capture its output
|
19
|
+
COMMITTER_OUTPUT=$(committer output-message "$REASON")
|
20
|
+
|
21
|
+
# Create a temporary file with the committer output at the top
|
22
|
+
# followed by the original content of the file
|
23
|
+
{
|
24
|
+
echo "$COMMITTER_OUTPUT"
|
25
|
+
cat "$1"
|
26
|
+
} > "$1.tmp"
|
27
|
+
|
28
|
+
# Replace the original file with the temporary file
|
29
|
+
mv "$1.tmp" "$1"
|
30
|
+
|
31
|
+
echo "Successfully added committer output to the top of $1"
|
32
|
+
else
|
33
|
+
echo "Committer command not found - no action taken"
|
34
|
+
fi
|
35
|
+
fi
|
data/lib/committer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: committer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastien Stettler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -36,7 +36,15 @@ files:
|
|
36
36
|
- README.md
|
37
37
|
- bin/committer
|
38
38
|
- lib/clients/claude_client.rb
|
39
|
+
- lib/committer/commands.rb
|
40
|
+
- lib/committer/commands/default.rb
|
41
|
+
- lib/committer/commands/help.rb
|
42
|
+
- lib/committer/commands/output_message.rb
|
43
|
+
- lib/committer/commands/setup.rb
|
44
|
+
- lib/committer/commands/setup_git_hook.rb
|
45
|
+
- lib/committer/commit_generator.rb
|
39
46
|
- lib/committer/config.rb
|
47
|
+
- lib/committer/prepare-commit-msg
|
40
48
|
- lib/committer/prompt_templates.rb
|
41
49
|
- lib/committer/version.rb
|
42
50
|
homepage: https://github.com/Hyper-Unearthing/committer
|