diff --git a/lib/committer/commit_generator.rb b/lib/committer/commit_generator.rb
index d0878b3..0e8d4a6 100644
--- a/lib/committer/commit_generator.rb
+++ b/lib/committer/commit_generator.rb
@@ -16,9 +16,8 @@ def initialize(diff, commit_context = nil)
end
def build_commit_prompt
- format(template,
- diff: @diff,
- commit_context: @commit_context)
+ scopes = Committer::Config::Accessor.instance[:scopes] || []
+ Committer::PromptTemplates.build_prompt(diff, scopes, commit_context)
end
def template
diff --git a/lib/committer/config/accessor.rb b/lib/committer/config/accessor.rb
index b1120c7..3e6ee8a 100644
--- a/lib/committer/config/accessor.rb
+++ b/lib/committer/config/accessor.rb
@@ -52,10 +52,6 @@ def read_file_from_path(path)
File.read(path)
end
- def load_formatting_rules
- read_path_prioritized_file(Committer::Config::Constants::FORMATTING_RULES_FILE_NAME)
- end
-
def read_file_from_git_root(file_name)
read_file_from_path(File.join(Committer::GitHelper.repo_root, '.committer', file_name))
end
diff --git a/lib/committer/config/constants.rb b/lib/committer/config/constants.rb
index ca638f9..53dbbbd 100644
--- a/lib/committer/config/constants.rb
+++ b/lib/committer/config/constants.rb
@@ -6,7 +6,8 @@ module Constants
CONFIG_DIR = File.join(Dir.home, '.committer')
DEFAULTS_PATH = File.join(File.dirname(__FILE__), './defaults')
- FORMATTING_RULES_FILE_NAME = 'formatting_rules.txt'
+ COMMIT_MESSAGE_ONLY_PROMPT_FILE_NAME = 'commit_message_only.prompt'
+ COMMIT_MESSAGE_AND_BODY_PROMPT_FILE_NAME = 'commit_message_and_body.prompt'
CONFIG_FILE_NAME = 'config.yml'
DEFAULT_CONFIG = {
diff --git a/lib/committer/config/defaults/commit_message_and_body.prompt b/lib/committer/config/defaults/commit_message_and_body.prompt
new file mode 100644
index 0000000..c27b52e
--- /dev/null
+++ b/lib/committer/config/defaults/commit_message_and_body.prompt
@@ -0,0 +1,52 @@
+You are an experienced software developer tasked with creating a commit message based on a git diff. Your goal is to produce a clear, concise, and informative commit message.
+
+First, carefully analyze the following git diff:
+
+
+{{DIFF}}
+
+
+Here are the available scopes (if any):
+
+
+{{SCOPES}}
+
+
+
+{{CONTEXT}}
+
+
+Please follow these instructions to generate the commit message:
+
+1. Analyze the git diff and determine the most appropriate commit type from the following options:
+ - feat: A new feature
+ - fix: A bug fix
+ - docs: Documentation only changes
+ - style: Changes that do not affect the meaning of the code
+ - refactor: A code change that neither fixes a bug nor adds a feature
+ - perf: A code change that improves performance
+ - test: Adding missing tests or correcting existing tests
+ - chore: Changes to the build process or auxiliary tools and libraries
+
+
+2. Adhere to these message guidelines:
+ - Keep the summary under 70 characters
+ - Use imperative, present tense (e.g., "add" not "added" or "adds")
+ - Do not end the summary with a period
+ - Be concise but descriptive
+
+3. Format the commit message as follows:
+ - If a scope is available: ():
+ - If no scope is available: :
+
+4 Body Guidelines:
+ - Add a blank line between summary and body
+ - Use the body to explain why the change was made, incorporating the user's context, defined in
+ - Wrap each line in the body at 80 characters maximum
+ - Break the body into multiple paragraphs if needed
+
+ [Your concise commit message in the specified format]
+ [blank line]
+ [Your detailed commit message body]
+
+Respond ONLY with the commit message text (message and body), nothing else.
\ No newline at end of file
diff --git a/lib/committer/config/defaults/commit_message_only.prompt b/lib/committer/config/defaults/commit_message_only.prompt
new file mode 100644
index 0000000..d28bc8c
--- /dev/null
+++ b/lib/committer/config/defaults/commit_message_only.prompt
@@ -0,0 +1,38 @@
+You are an experienced software developer tasked with creating a commit message based on a git diff. Your goal is to produce a clear, concise, and informative commit message.
+
+First, carefully analyze the following git diff:
+
+
+{{DIFF}}
+
+
+Here are the available scopes (if any):
+
+
+{{SCOPES}}
+
+
+Please follow these instructions to generate the commit message:
+
+1. Analyze the git diff and determine the most appropriate commit type from the following options:
+ - feat: A new feature
+ - fix: A bug fix
+ - docs: Documentation only changes
+ - style: Changes that do not affect the meaning of the code
+ - refactor: A code change that neither fixes a bug nor adds a feature
+ - perf: A code change that improves performance
+ - test: Adding missing tests or correcting existing tests
+ - chore: Changes to the build process or auxiliary tools and libraries
+
+
+2. Adhere to these message guidelines:
+ - Keep the summary under 70 characters
+ - Use imperative, present tense (e.g., "add" not "added" or "adds")
+ - Do not end the summary with a period
+ - Be concise but descriptive
+
+3. Format the commit message as follows:
+ - If a scope is available: ():
+ - If no scope is available: :
+
+Respond ONLY with the commit message line, nothing else.
\ No newline at end of file
diff --git a/lib/committer/config/writer.rb b/lib/committer/config/writer.rb
index da9b4ac..c3888dc 100644
--- a/lib/committer/config/writer.rb
+++ b/lib/committer/config/writer.rb
@@ -20,7 +20,6 @@ def config_file
def setup
create_default_config
- create_sample_formatting_rules
end
def write_config_file(file_path, contents)
@@ -34,15 +33,6 @@ def write_config_file(file_path, contents)
end
end
- def create_sample_formatting_rules
- default_formatting_rules = File.read(File.join(Committer::Config::Constants::DEFAULTS_PATH,
- Committer::Config::Constants::FORMATTING_RULES_FILE_NAME))
- formatting_rules_file = File.join(@config_dir,
- "#{Committer::Config::Constants::FORMATTING_RULES_FILE_NAME}.sample")
- wrote_file = write_config_file(formatting_rules_file, default_formatting_rules)
- nil unless wrote_file
- end
-
def create_default_config
wrote_file = write_config_file(config_file, Committer::Config::Constants::DEFAULT_CONFIG.to_yaml)
return unless wrote_file
diff --git a/lib/committer/prompt_templates.rb b/lib/committer/prompt_templates.rb
index 501817c..16dbbf8 100644
--- a/lib/committer/prompt_templates.rb
+++ b/lib/committer/prompt_templates.rb
@@ -2,12 +2,19 @@
module Committer
module PromptTemplates
- def self.load_formatting_rules
- Committer::Config::Accessor.instance.load_formatting_rules
+ def self.build_prompt(diff, scopes, commit_context)
+ prompt_template = if commit_context.nil? || commit_context.empty?
+ Committer::PromptTemplates.build_prompt_summary_only
+ else
+ Committer::PromptTemplates.build_prompt_summary_and_body
+ end
+ prompt_template
+ .gsub('{{DIFF}}', diff)
+ .gsub('{{SCOPES}}', build_scopes_list(scopes))
+ .gsub('{{CONTEXT}}', commit_context || '')
end
- def self.load_scopes
- scopes = Committer::Config::Accessor.instance[:scopes] || []
+ def self.build_scopes_list(scopes)
return 'DO NOT include a scope in your commit message' if scopes.empty?
scope_list = "\nScopes:\n#{scopes.map { |s| "- #{s}" }.join("\n")}"
@@ -15,56 +22,16 @@ def self.load_scopes
"- Choose an appropriate scope from the list above if relevant to the change \n#{scope_list}"
end
- def self.commit_message_guidelines
- <<~PROMPT
- #{load_formatting_rules}
-
- # Formatting rules with body:
-
-
-
-
-
- #{load_scopes}
-
- # Message Guidelines:
- - Keep the summary under 70 characters
- - Use imperative, present tense (e.g., "add" not "added" or "adds")
- - Do not end the summary with a period
- - Be concise but descriptive in the summary
-
- # Body Guidelines:
- - Add a blank line between summary and body
- - Use the body to explain why the change was made, incorporating the user's context
- - Wrap each line in the body at 80 characters maximum
- - Break the body into multiple paragraphs if needed
-
- Git Diff:
- ```
- %s
- ```
- PROMPT
- end
-
def self.build_prompt_summary_only
- <<~PROMPT
- 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):
-
- #{commit_message_guidelines}
-
- Respond ONLY with the commit message line, nothing else.
- PROMPT
+ load_prompt(Committer::Config::Constants::COMMIT_MESSAGE_ONLY_PROMPT_FILE_NAME)
end
def self.build_prompt_summary_and_body
- <<~PROMPT
- 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:
-
- #{commit_message_guidelines}
- User's context for this change: %s
+ load_prompt(Committer::Config::Constants::COMMIT_MESSAGE_AND_BODY_PROMPT_FILE_NAME)
+ end
- Respond ONLY with the commit message text (message and body), nothing else.
- PROMPT
+ def self.load_prompt(file_name)
+ Committer::Config::Accessor.instance.read_path_prioritized_file(file_name)
end
end
end
diff --git a/spec/committer/commit_generator_spec.rb b/spec/committer/commit_generator_spec.rb
index 8c838de..ad02827 100644
--- a/spec/committer/commit_generator_spec.rb
+++ b/spec/committer/commit_generator_spec.rb
@@ -62,7 +62,6 @@
let(:generator) { described_class.new(diff, commit_context) }
it 'uses the template with body' do
- expect(generator).to receive(:template).and_call_original
prompt = generator.build_commit_prompt
expect(prompt).to include(commit_context)
expect(prompt).to include('Respond ONLY with the commit message text (message and body), nothing else.')
@@ -74,7 +73,6 @@
let(:generator) { described_class.new(diff, commit_context) }
it 'uses summary-only template when commit context is nil' do
- expect(generator).to receive(:template).and_call_original
prompt = generator.build_commit_prompt
expect(prompt).to include('Respond ONLY with the commit message line, nothing else.')
end
diff --git a/spec/committer/config/writer_spec.rb b/spec/committer/config/writer_spec.rb
index 1c96bf6..9cfe40b 100644
--- a/spec/committer/config/writer_spec.rb
+++ b/spec/committer/config/writer_spec.rb
@@ -43,14 +43,6 @@
config = YAML.load_file(config_file)
expect(config).to eq(Committer::Config::Constants::DEFAULT_CONFIG)
end
-
- it 'writes config sample config rules' do
- expect(File.exist?(sample_formatting_rules_file)).to be false
- writer.setup
- expect(File.exist?(sample_formatting_rules_file)).to be true
- contents = File.read(sample_formatting_rules_file)
- expect(contents).to include('# Formatting rules for message')
- end
end
describe '#create_default_config' do