198 lines
7.3 KiB
Plaintext
198 lines
7.3 KiB
Plaintext
![]() |
# Git commit message generator for Claude Code
|
||
|
# Generates a commit message file based on current changes without creating a commit
|
||
|
# No signatures or automated text added
|
||
|
|
||
|
# Generate commit message file based on staged and unstaged changes
|
||
|
export def "commit-msg" [
|
||
|
--file (-f): string = "COMMIT_MSG.txt" # Output file for commit message
|
||
|
--staged (-s): bool = false # Only consider staged changes
|
||
|
--unstaged (-u): bool = false # Only consider unstaged changes
|
||
|
--show: bool = false # Show changes without generating message
|
||
|
] -> nothing {
|
||
|
|
||
|
if $show {
|
||
|
show-git-changes
|
||
|
return
|
||
|
}
|
||
|
|
||
|
# Determine what changes to analyze
|
||
|
let analyze_staged = if $staged or (not $unstaged) { true } else { false }
|
||
|
let analyze_unstaged = if $unstaged or (not $staged) { true } else { false }
|
||
|
|
||
|
# Get git status
|
||
|
let git_status = (git status --porcelain | lines | where { $in | str length > 0 })
|
||
|
|
||
|
if ($git_status | is-empty) {
|
||
|
print "No changes to commit"
|
||
|
return
|
||
|
}
|
||
|
|
||
|
# Analyze changes
|
||
|
mut files_modified = []
|
||
|
mut files_added = []
|
||
|
mut files_deleted = []
|
||
|
|
||
|
for line in $git_status {
|
||
|
let status_code = ($line | str substring 0..2)
|
||
|
let file_path = ($line | str substring 3..)
|
||
|
|
||
|
# Parse git status codes
|
||
|
match $status_code {
|
||
|
" M" => { if $analyze_unstaged { $files_modified = ($files_modified | append $file_path) } }
|
||
|
"M " => { if $analyze_staged { $files_modified = ($files_modified | append $file_path) } }
|
||
|
"MM" => { $files_modified = ($files_modified | append $file_path) }
|
||
|
"A " => { if $analyze_staged { $files_added = ($files_added | append $file_path) } }
|
||
|
"??" => { if $analyze_unstaged { $files_added = ($files_added | append $file_path) } }
|
||
|
" D" => { if $analyze_unstaged { $files_deleted = ($files_deleted | append $file_path) } }
|
||
|
"D " => { if $analyze_staged { $files_deleted = ($files_deleted | append $file_path) } }
|
||
|
_ => {}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Analyze file types and changes
|
||
|
let config_files = ($files_modified | where { $in | str ends-with ".toml" or $in | str ends-with ".nu" or $in | str ends-with ".yaml" })
|
||
|
let core_files = ($files_modified | where { $in | str contains "core/" })
|
||
|
let provider_files = ($files_modified | where { $in | str contains "provider" })
|
||
|
let migration_files = ($files_modified | where { $in | str contains "migration" })
|
||
|
|
||
|
# Generate commit message based on changes
|
||
|
mut commit_type = "chore"
|
||
|
mut commit_scope = ""
|
||
|
mut commit_description = ""
|
||
|
|
||
|
# Determine commit type and scope based on project patterns
|
||
|
if (not ($files_added | is-empty)) {
|
||
|
$commit_type = "feat"
|
||
|
if ($files_added | any { $in | str contains "taskserv" }) {
|
||
|
$commit_scope = "taskserv"
|
||
|
$commit_description = "add new task service"
|
||
|
} else if ($files_added | any { $in | str contains "provider" }) {
|
||
|
$commit_scope = "provider"
|
||
|
$commit_description = "add new provider"
|
||
|
} else {
|
||
|
$commit_description = "add new functionality"
|
||
|
}
|
||
|
} else if (not ($files_deleted | is-empty)) {
|
||
|
$commit_type = "refactor"
|
||
|
$commit_description = "remove unused components"
|
||
|
} else if (not ($migration_files | is-empty)) {
|
||
|
$commit_type = "refactor"
|
||
|
$commit_scope = "config"
|
||
|
$commit_description = "continue config-driven architecture migration"
|
||
|
} else if (not ($config_files | is-empty)) {
|
||
|
if ($config_files | any { $in | str contains "config.defaults.toml" }) {
|
||
|
$commit_type = "feat"
|
||
|
$commit_scope = "config"
|
||
|
$commit_description = "enhance configuration system"
|
||
|
} else {
|
||
|
$commit_type = "config"
|
||
|
$commit_description = "update configuration settings"
|
||
|
}
|
||
|
} else if (not ($core_files | is-empty)) {
|
||
|
if ($core_files | any { $in | str contains "env.nu" }) {
|
||
|
$commit_type = "refactor"
|
||
|
$commit_scope = "env"
|
||
|
$commit_description = "migrate from ENV to config-driven approach"
|
||
|
} else {
|
||
|
$commit_type = "refactor"
|
||
|
$commit_scope = "core"
|
||
|
$commit_description = "improve core functionality"
|
||
|
}
|
||
|
} else if (not ($provider_files | is-empty)) {
|
||
|
$commit_type = "feat"
|
||
|
$commit_scope = "providers"
|
||
|
$commit_description = "enhance provider capabilities"
|
||
|
} else {
|
||
|
$commit_type = "chore"
|
||
|
$commit_description = "update project files"
|
||
|
}
|
||
|
|
||
|
# Build commit message
|
||
|
let commit_message = if ($commit_scope | is-empty) {
|
||
|
$"($commit_type): ($commit_description)"
|
||
|
} else {
|
||
|
$"($commit_type)\(($commit_scope)\): ($commit_description)"
|
||
|
}
|
||
|
|
||
|
# Add details section for complex changes
|
||
|
mut details = []
|
||
|
|
||
|
if ($files_modified | length) > 5 {
|
||
|
$details = ($details | append $"- Update ($files_modified | length) files across multiple modules")
|
||
|
} else if (not ($files_modified | is-empty)) {
|
||
|
$details = ($details | append $"- Update: ($files_modified | str join ', ')")
|
||
|
}
|
||
|
|
||
|
if (not ($files_added | is-empty)) {
|
||
|
$details = ($details | append $"- Add: ($files_added | str join ', ')")
|
||
|
}
|
||
|
|
||
|
if (not ($files_deleted | is-empty)) {
|
||
|
$details = ($details | append $"- Remove: ($files_deleted | str join ', ')")
|
||
|
}
|
||
|
|
||
|
# Create full commit message
|
||
|
let full_message = if ($details | is-empty) {
|
||
|
$commit_message
|
||
|
} else {
|
||
|
$"($commit_message)\n\n($details | str join '\n')"
|
||
|
}
|
||
|
|
||
|
# Write to file
|
||
|
$full_message | save $file
|
||
|
|
||
|
print $"Commit message saved to: ($file)"
|
||
|
print "\nGenerated message:"
|
||
|
print "=================="
|
||
|
print $full_message
|
||
|
}
|
||
|
|
||
|
# Show current git changes that would be included in commit message
|
||
|
export def "show-git-changes" [] -> table {
|
||
|
let status_output = (git status --porcelain | lines | where { $in | str length > 0 })
|
||
|
|
||
|
if ($status_output | is-empty) {
|
||
|
print "No changes found"
|
||
|
return []
|
||
|
}
|
||
|
|
||
|
$status_output | each { |line|
|
||
|
let status_code = ($line | str substring 0..2)
|
||
|
let file_path = ($line | str substring 3..)
|
||
|
|
||
|
let change_type = match $status_code {
|
||
|
" M" => "Modified (unstaged)"
|
||
|
"M " => "Modified (staged)"
|
||
|
"MM" => "Modified (both)"
|
||
|
"A " => "Added (staged)"
|
||
|
"??" => "Untracked"
|
||
|
" D" => "Deleted (unstaged)"
|
||
|
"D " => "Deleted (staged)"
|
||
|
_ => $status_code
|
||
|
}
|
||
|
|
||
|
{
|
||
|
file: $file_path,
|
||
|
status: $change_type,
|
||
|
code: $status_code
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Quick commit message for common patterns
|
||
|
export def "quick-commit" [
|
||
|
pattern: string # Pattern: config, fix, feat, refactor, docs, test
|
||
|
] -> nothing {
|
||
|
let message = match $pattern {
|
||
|
"config" => "config: update configuration settings"
|
||
|
"fix" => "fix: resolve issue in functionality"
|
||
|
"feat" => "feat: add new functionality"
|
||
|
"refactor" => "refactor: improve code structure"
|
||
|
"docs" => "docs: update documentation"
|
||
|
"test" => "test: add or update tests"
|
||
|
_ => $"chore: ($pattern)"
|
||
|
}
|
||
|
|
||
|
$message | save "COMMIT_MSG.txt"
|
||
|
print $"Quick commit message saved: ($message)"
|
||
|
}
|