committer 0.3.2 → 0.4.1
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/bin/committer +1 -1
- data/lib/clients/claude_client.rb +19 -15
- data/lib/committer/commands/default.rb +3 -5
- data/lib/committer/commands/setup.rb +6 -1
- data/lib/committer/commands/setup_git_hook.rb +3 -1
- data/lib/committer/commit_generator.rb +8 -22
- data/lib/committer/committer_errors.rb +15 -0
- data/lib/committer/config/accessor.rb +98 -0
- data/lib/committer/config/constants.rb +18 -0
- data/lib/committer/config/writer.rb +64 -0
- data/lib/committer/formatting_rules.txt +19 -0
- data/lib/committer/git_helper.rb +29 -0
- data/lib/committer/prompt_templates.rb +66 -77
- data/lib/committer/version.rb +1 -1
- metadata +9 -18
- data/lib/committer/config.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ca6ac927c9239d879501e10d0330d199aaa79b765f1e2defbc277e8e81afe58
|
4
|
+
data.tar.gz: d64d8b037073bedc7ff95d84ea9c120ddae09ce65efe205fab5a051c08498811
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89663d836e0f90f46136755392251629853e7ec05eccba8d447c200c87f1e0697513b93a9f91d0f115e6c438d2cdbb9fc3b58303fcbdea5df21179762fd54c32
|
7
|
+
data.tar.gz: cde4fc03c29556a8b21b39d22bdddbe27f1d795fb02b5111fce79a97512f9ba32a1da71620b4bd700b232c1db2261187912df9dd4a2b6ada21ab00a496a37982
|
data/bin/committer
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'json'
|
4
|
-
require '
|
5
|
-
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
6
|
+
require_relative '../committer/config/accessor'
|
6
7
|
|
7
8
|
module Clients
|
8
9
|
# Claude API client for communicating with Anthropic's Claude model
|
@@ -11,8 +12,10 @@ module Clients
|
|
11
12
|
class UnknownError < StandardError; end
|
12
13
|
class ConfigError < StandardError; end
|
13
14
|
|
15
|
+
API_ENDPOINT = 'https://api.anthropic.com/v1/messages'
|
16
|
+
|
14
17
|
def initialize
|
15
|
-
@config = Committer::Config.
|
18
|
+
@config = Committer::Config::Accessor.instance
|
16
19
|
|
17
20
|
return unless @config['api_key'].nil? || @config['api_key'].empty?
|
18
21
|
|
@@ -38,19 +41,20 @@ module Clients
|
|
38
41
|
private
|
39
42
|
|
40
43
|
def send_request(body)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
uri = URI.parse(API_ENDPOINT)
|
45
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
46
|
+
http.use_ssl = true
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
49
|
+
request['anthropic-version'] = '2023-06-01'
|
50
|
+
request['content-type'] = 'application/json'
|
51
|
+
request['x-api-key'] = @config['api_key']
|
52
|
+
request.body = body.to_json
|
53
|
+
|
54
|
+
response = http.request(request)
|
55
|
+
JSON.parse(response.body)
|
56
|
+
rescue JSON::ParserError
|
57
|
+
{ 'type' => 'error', 'error' => { 'type' => 'unknown_error' } }
|
54
58
|
end
|
55
59
|
|
56
60
|
def handle_error_response(response)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../git_helper'
|
4
|
+
|
3
5
|
module Committer
|
4
6
|
module Commands
|
5
7
|
class Default
|
@@ -10,11 +12,7 @@ module Committer
|
|
10
12
|
summary = commit_message[:summary]
|
11
13
|
body = commit_message[:body]
|
12
14
|
# Create git commit with the suggested message and open in editor
|
13
|
-
|
14
|
-
system('git', 'commit', '-m', summary, '-m', body, '-e')
|
15
|
-
else
|
16
|
-
system('git', 'commit', '-m', summary, '-e')
|
17
|
-
end
|
15
|
+
Committer::GitHelper.commit(summary, body)
|
18
16
|
end
|
19
17
|
|
20
18
|
def self.execute(_args)
|
@@ -1,10 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../config/writer'
|
4
|
+
require_relative '../config/constants'
|
5
|
+
|
3
6
|
module Committer
|
4
7
|
module Commands
|
5
8
|
class Setup
|
6
9
|
def self.execute(_args)
|
7
|
-
Committer::Config
|
10
|
+
config_dir = Committer::Config::Constants::CONFIG_DIR
|
11
|
+
writer = Committer::Config::Writer.new(config_dir)
|
12
|
+
writer.setup
|
8
13
|
exit 0
|
9
14
|
end
|
10
15
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../git_helper'
|
4
|
+
|
3
5
|
module Committer
|
4
6
|
module Commands
|
5
7
|
class SetupGitHook
|
@@ -29,7 +31,7 @@ module Committer
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def self.validate_git_root
|
32
|
-
git_toplevel =
|
34
|
+
git_toplevel = Committer::GitHelper.repo_root
|
33
35
|
current_dir = Dir.pwd
|
34
36
|
return if git_toplevel == current_dir
|
35
37
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'open3'
|
4
3
|
require 'httparty'
|
5
4
|
require 'yaml'
|
6
|
-
require_relative 'config'
|
5
|
+
require_relative 'config/accessor'
|
7
6
|
require_relative 'prompt_templates'
|
8
7
|
require_relative '../clients/claude_client'
|
8
|
+
require_relative 'git_helper'
|
9
9
|
|
10
10
|
module Committer
|
11
11
|
class CommitGenerator
|
@@ -17,38 +17,24 @@ module Committer
|
|
17
17
|
end
|
18
18
|
|
19
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
20
|
format(template,
|
28
21
|
diff: @diff,
|
29
|
-
scopes_section: scope_section,
|
30
|
-
scope_instruction: scope_instruction,
|
31
22
|
commit_context: @commit_context)
|
32
23
|
end
|
33
24
|
|
34
25
|
def template
|
35
26
|
if @commit_context.nil? || @commit_context.empty?
|
36
|
-
Committer::PromptTemplates
|
27
|
+
Committer::PromptTemplates.build_prompt_summary_only
|
37
28
|
else
|
38
|
-
Committer::PromptTemplates
|
29
|
+
Committer::PromptTemplates.build_prompt_summary_and_body
|
39
30
|
end
|
40
31
|
end
|
41
32
|
|
42
33
|
def self.check_git_status
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
puts stderr
|
48
|
-
exit 1
|
49
|
-
end
|
50
|
-
|
51
|
-
stdout
|
34
|
+
Committer::GitHelper.staged_diff
|
35
|
+
rescue Committer::Error => e
|
36
|
+
puts e.message
|
37
|
+
exit 1
|
52
38
|
end
|
53
39
|
|
54
40
|
def parse_response(response)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Committer
|
4
|
+
# Base error class for all Committer errors
|
5
|
+
class Error < StandardError; end
|
6
|
+
|
7
|
+
# Configuration management for the Committer gem
|
8
|
+
class ConfigErrors
|
9
|
+
class BaseError < StandardError; end
|
10
|
+
|
11
|
+
# Request Processing Errors
|
12
|
+
class FormatError < BaseError; end
|
13
|
+
class NotSetup < BaseError; end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'singleton'
|
5
|
+
require_relative '../committer_errors'
|
6
|
+
require_relative 'constants'
|
7
|
+
require_relative '../git_helper'
|
8
|
+
|
9
|
+
module Committer
|
10
|
+
# Configuration management for the Committer gem
|
11
|
+
module Config
|
12
|
+
class Accessor
|
13
|
+
include Singleton
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@config = load_config
|
17
|
+
end
|
18
|
+
|
19
|
+
# Accessor for the loaded config
|
20
|
+
def [](key)
|
21
|
+
@config[key.to_sym] || @config[key.to_s]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get the entire config hash
|
25
|
+
def to_h
|
26
|
+
@config.dup
|
27
|
+
end
|
28
|
+
|
29
|
+
def load_config
|
30
|
+
# Load configs from both locations and merge them
|
31
|
+
home_config = load_config_from_path(Committer::Config::Constants::CONFIG_FILE)
|
32
|
+
git_root_config = load_config_from_git_root
|
33
|
+
raise Committer::ConfigErrors::NotSetup if home_config.empty? && git_root_config.empty?
|
34
|
+
|
35
|
+
# Merge configs with git root taking precedence
|
36
|
+
home_config.merge(git_root_config)
|
37
|
+
end
|
38
|
+
|
39
|
+
def load_config_from_path(path)
|
40
|
+
return {} unless File.exist?(path)
|
41
|
+
|
42
|
+
result = YAML.load_file(path)
|
43
|
+
raise Committer::ConfigErrors::FormatError, 'Config file must be a YAML hash' unless result.is_a?(Hash)
|
44
|
+
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
def load_file_from_path(path)
|
49
|
+
return '' unless File.exist?(path)
|
50
|
+
|
51
|
+
File.read(path)
|
52
|
+
end
|
53
|
+
|
54
|
+
def load_formatting_rules
|
55
|
+
git_root = Committer::GitHelper.repo_root
|
56
|
+
unless git_root.empty?
|
57
|
+
formatting_rules_git_path = File.join(git_root, '.committer',
|
58
|
+
Committer::Config::Constants::FORMATTING_RULES_FILE_NAME)
|
59
|
+
end
|
60
|
+
|
61
|
+
git_path_contents = load_file_from_path(formatting_rules_git_path) if formatting_rules_git_path
|
62
|
+
|
63
|
+
return git_path_contents unless git_path_contents.empty?
|
64
|
+
|
65
|
+
home_path = File.join(Committer::Config::Constants::CONFIG_DIR,
|
66
|
+
Committer::Config::Constants::FORMATTING_RULES_FILE_NAME)
|
67
|
+
|
68
|
+
home_path_contents = load_file_from_path(home_path)
|
69
|
+
|
70
|
+
return home_path_contents unless home_path_contents.empty?
|
71
|
+
|
72
|
+
default_path = File.join(Committer::Config::Constants::DEFAULT_PROMPT_PATH,
|
73
|
+
Committer::Config::Constants::FORMATTING_RULES_FILE_NAME)
|
74
|
+
load_file_from_path(default_path)
|
75
|
+
end
|
76
|
+
|
77
|
+
def load_config_from_git_root
|
78
|
+
git_root = Committer::GitHelper.repo_root
|
79
|
+
return {} if git_root.empty?
|
80
|
+
|
81
|
+
git_config_file = File.join(git_root, '.committer', 'config.yml')
|
82
|
+
load_config_from_path(git_config_file)
|
83
|
+
rescue StandardError
|
84
|
+
{}
|
85
|
+
end
|
86
|
+
|
87
|
+
# Force reload configuration (useful for testing)
|
88
|
+
def reload
|
89
|
+
@config = load_config
|
90
|
+
end
|
91
|
+
|
92
|
+
# Class method for reload
|
93
|
+
def self.reload
|
94
|
+
instance.reload
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Committer
|
4
|
+
module Config
|
5
|
+
module Constants
|
6
|
+
CONFIG_DIR = File.join(Dir.home, '.committer')
|
7
|
+
CONFIG_FILE = File.join(CONFIG_DIR, 'config.yml')
|
8
|
+
FORMATTING_RULES_FILE_NAME = 'formatting_rules.txt'
|
9
|
+
DEFAULT_PROMPT_PATH = File.join(File.dirname(__FILE__), '..')
|
10
|
+
CONFIG_FILE_NAME = 'config.yml'
|
11
|
+
DEFAULT_CONFIG = {
|
12
|
+
'api_key' => nil,
|
13
|
+
'model' => 'claude-3-7-sonnet-20250219',
|
14
|
+
'scopes' => nil
|
15
|
+
}.freeze
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'fileutils'
|
5
|
+
require_relative '../committer_errors'
|
6
|
+
require_relative 'constants'
|
7
|
+
|
8
|
+
module Committer
|
9
|
+
module Config
|
10
|
+
class Writer
|
11
|
+
attr_reader :config_dir
|
12
|
+
|
13
|
+
def initialize(config_dir)
|
14
|
+
@config_dir = config_dir
|
15
|
+
end
|
16
|
+
|
17
|
+
def config_file
|
18
|
+
File.join(@config_dir, Committer::Config::Constants::CONFIG_FILE_NAME)
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup
|
22
|
+
create_default_config
|
23
|
+
create_sample_formatting_rules
|
24
|
+
end
|
25
|
+
|
26
|
+
def write_config_file(file_path, contents)
|
27
|
+
FileUtils.mkdir_p(@config_dir)
|
28
|
+
if File.exist?(file_path)
|
29
|
+
puts "Config file already exists at #{config_file}, skipping write"
|
30
|
+
false
|
31
|
+
else
|
32
|
+
File.write(file_path, contents)
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_sample_formatting_rules
|
38
|
+
default_formatting_rules = File.read(File.join(Committer::Config::Constants::DEFAULT_PROMPT_PATH,
|
39
|
+
Committer::Config::Constants::FORMATTING_RULES_FILE_NAME))
|
40
|
+
formatting_rules_file = File.join(@config_dir,
|
41
|
+
"#{Committer::Config::Constants::FORMATTING_RULES_FILE_NAME}.sample")
|
42
|
+
wrote_file = write_config_file(formatting_rules_file, default_formatting_rules)
|
43
|
+
nil unless wrote_file
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_default_config
|
47
|
+
wrote_file = write_config_file(config_file, Committer::Config::Constants::DEFAULT_CONFIG.to_yaml)
|
48
|
+
return unless wrote_file
|
49
|
+
|
50
|
+
puts 'Created config file at:'
|
51
|
+
puts config_file
|
52
|
+
puts "\nPlease edit this file to add your Anthropic API key."
|
53
|
+
puts 'Example config format:'
|
54
|
+
puts '---'
|
55
|
+
puts 'api_key: your_api_key_here'
|
56
|
+
puts 'model: claude-3-7-sonnet-20250219'
|
57
|
+
puts 'scopes:'
|
58
|
+
puts ' - feature'
|
59
|
+
puts ' - api'
|
60
|
+
puts ' - ui'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Formatting rules for message
|
2
|
+
Message should be formatted according to conventional commits
|
3
|
+
|
4
|
+
## When scopes are available:
|
5
|
+
<type>(<scope>): <description>
|
6
|
+
|
7
|
+
# Formatting Rules
|
8
|
+
## When scopes are not available:
|
9
|
+
<type>: <description>
|
10
|
+
|
11
|
+
# Types:
|
12
|
+
- feat: A new feature
|
13
|
+
- fix: A bug fix
|
14
|
+
- docs: Documentation only changes
|
15
|
+
- style: Changes that do not affect the meaning of the code
|
16
|
+
- refactor: A code change that neither fixes a bug nor adds a feature
|
17
|
+
- perf: A code change that improves performance
|
18
|
+
- test: Adding missing tests or correcting existing tests
|
19
|
+
- chore: Changes to the build process or auxiliary tools
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'open3'
|
4
|
+
|
5
|
+
module Committer
|
6
|
+
# Helper class for git operations
|
7
|
+
class GitHelper
|
8
|
+
class << self
|
9
|
+
def commit(summary, body = nil)
|
10
|
+
if body
|
11
|
+
system('git', 'commit', '-m', summary, '-m', body, '-e')
|
12
|
+
else
|
13
|
+
system('git', 'commit', '-m', summary, '-e')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def repo_root
|
18
|
+
`git rev-parse --show-toplevel`.strip
|
19
|
+
end
|
20
|
+
|
21
|
+
def staged_diff
|
22
|
+
stdout, stderr, status = Open3.capture3('git diff --staged')
|
23
|
+
raise Committer::Error, "Failed to get git diff: #{stderr}" unless status.success?
|
24
|
+
|
25
|
+
stdout
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -2,82 +2,71 @@
|
|
2
2
|
|
3
3
|
module Committer
|
4
4
|
module PromptTemplates
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
%<scope_instruction>s
|
72
|
-
|
73
|
-
User's context for this change: %<commit_context>s
|
74
|
-
|
75
|
-
Git Diff:
|
76
|
-
```
|
77
|
-
%<diff>s
|
78
|
-
```
|
79
|
-
|
80
|
-
Respond ONLY with the commit message text (summary and body), nothing else.
|
81
|
-
PROMPT
|
5
|
+
FORMATTING_RULES_PATH = File.join(File.dirname(__FILE__), 'formatting_rules.txt')
|
6
|
+
|
7
|
+
def self.load_formatting_rules
|
8
|
+
File.read(FORMATTING_RULES_PATH)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.load_scopes
|
12
|
+
scopes = Committer::Config::Accessor.instance[:scopes] || []
|
13
|
+
return 'DO NOT include a scope in your commit message' if scopes.empty?
|
14
|
+
|
15
|
+
scope_list = "\nScopes:\n#{scopes.map { |s| "- #{s}" }.join("\n")}"
|
16
|
+
|
17
|
+
"- Choose an appropriate scope from the list above if relevant to the change \n#{scope_list}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.commit_message_guidelines
|
21
|
+
<<~PROMPT
|
22
|
+
#{load_formatting_rules}
|
23
|
+
|
24
|
+
# Formatting rules with body:
|
25
|
+
<message>
|
26
|
+
|
27
|
+
<blank line>
|
28
|
+
<body with more detailed explanation>
|
29
|
+
|
30
|
+
#{load_scopes}
|
31
|
+
|
32
|
+
# Message Guidelines:
|
33
|
+
- Keep the summary under 70 characters
|
34
|
+
- Use imperative, present tense (e.g., "add" not "added" or "adds")
|
35
|
+
- Do not end the summary with a period
|
36
|
+
- Be concise but descriptive in the summary
|
37
|
+
|
38
|
+
# Body Guidelines:
|
39
|
+
- Add a blank line between summary and body
|
40
|
+
- Use the body to explain why the change was made, incorporating the user's context
|
41
|
+
- Wrap each line in the body at 80 characters maximum
|
42
|
+
- Break the body into multiple paragraphs if needed
|
43
|
+
|
44
|
+
Git Diff:
|
45
|
+
```
|
46
|
+
%<diff>s
|
47
|
+
```
|
48
|
+
PROMPT
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.build_prompt_summary_only
|
52
|
+
<<~PROMPT
|
53
|
+
Below is a git diff of staged changes. Please analyze it and create a commit message following the formatting rules format with ONLY a message line (NO body):
|
54
|
+
|
55
|
+
#{commit_message_guidelines}
|
56
|
+
|
57
|
+
Respond ONLY with the commit message line, nothing else.
|
58
|
+
PROMPT
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.build_prompt_summary_and_body
|
62
|
+
<<~PROMPT
|
63
|
+
Below is a git diff of staged changes. Please analyze it and create a commit message following the formatting rules format with a summary line and a detailed body:
|
64
|
+
|
65
|
+
#{commit_message_guidelines}
|
66
|
+
User's context for this change: %<commit_context>s
|
67
|
+
|
68
|
+
Respond ONLY with the commit message text (message and body), nothing else.
|
69
|
+
PROMPT
|
70
|
+
end
|
82
71
|
end
|
83
72
|
end
|
data/lib/committer/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: committer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
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-
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: httparty
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.20'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0.20'
|
11
|
+
date: 2025-03-08 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
27
13
|
description: A tool that uses Claude API to generate conventional commit messages
|
28
14
|
based on staged changes
|
29
15
|
email:
|
@@ -43,7 +29,12 @@ files:
|
|
43
29
|
- lib/committer/commands/setup.rb
|
44
30
|
- lib/committer/commands/setup_git_hook.rb
|
45
31
|
- lib/committer/commit_generator.rb
|
46
|
-
- lib/committer/
|
32
|
+
- lib/committer/committer_errors.rb
|
33
|
+
- lib/committer/config/accessor.rb
|
34
|
+
- lib/committer/config/constants.rb
|
35
|
+
- lib/committer/config/writer.rb
|
36
|
+
- lib/committer/formatting_rules.txt
|
37
|
+
- lib/committer/git_helper.rb
|
47
38
|
- lib/committer/prepare-commit-msg
|
48
39
|
- lib/committer/prompt_templates.rb
|
49
40
|
- lib/committer/version.rb
|
data/lib/committer/config.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'yaml'
|
4
|
-
require 'fileutils'
|
5
|
-
|
6
|
-
module Committer
|
7
|
-
# Configuration management for the Committer gem
|
8
|
-
class Config
|
9
|
-
CONFIG_DIR = File.join(Dir.home, '.committer')
|
10
|
-
CONFIG_FILE = File.join(CONFIG_DIR, 'config.yml')
|
11
|
-
DEFAULT_CONFIG = {
|
12
|
-
'api_key' => nil,
|
13
|
-
'model' => 'claude-3-7-sonnet-20250219',
|
14
|
-
'scopes' => nil
|
15
|
-
}.freeze
|
16
|
-
|
17
|
-
def self.load
|
18
|
-
create_default_config unless File.exist?(CONFIG_FILE)
|
19
|
-
begin
|
20
|
-
YAML.load_file(CONFIG_FILE) || DEFAULT_CONFIG
|
21
|
-
rescue StandardError => e
|
22
|
-
# Use $stdout directly for better test capture
|
23
|
-
$stdout.puts "Error loading config: #{e.message}"
|
24
|
-
DEFAULT_CONFIG
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.create_default_config
|
29
|
-
FileUtils.mkdir_p(CONFIG_DIR)
|
30
|
-
File.write(CONFIG_FILE, DEFAULT_CONFIG.to_yaml)
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.setup
|
34
|
-
create_default_config
|
35
|
-
puts 'Created config file at:'
|
36
|
-
puts CONFIG_FILE
|
37
|
-
puts "\nPlease edit this file to add your Anthropic API key."
|
38
|
-
puts 'Example config format:'
|
39
|
-
puts '---'
|
40
|
-
puts 'api_key: your_api_key_here'
|
41
|
-
puts 'model: claude-3-7-sonnet-20250219'
|
42
|
-
puts 'scopes:'
|
43
|
-
puts ' - feature'
|
44
|
-
puts ' - api'
|
45
|
-
puts ' - ui'
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|