Files
reader-star/packages/scripts/src/commands/git-commit.ts
2026-01-16 13:06:44 +08:00

86 lines
2.1 KiB
TypeScript

import type { Lang } from '../locales'
import { readFileSync } from 'node:fs'
import path from 'node:path'
import { prompt } from 'enquirer'
import { locales } from '../locales'
import { execCommand } from '../shared'
interface PromptObject {
types: string
scopes: string
description: string
}
/**
* Git commit with Conventional Commits standard
*
* @param lang
*/
export async function gitCommit(lang: Lang = 'en-us') {
const { gitCommitMessages, gitCommitTypes, gitCommitScopes } = locales[lang]
const typesChoices = gitCommitTypes.map(([value, msg]) => {
const nameWithSuffix = `${value}:`
const message = `${nameWithSuffix.padEnd(12)}${msg}`
return {
name: value,
message,
}
})
const scopesChoices = gitCommitScopes.map(([value, msg]) => ({
name: value,
message: `${value.padEnd(30)} (${msg})`,
}))
const result = await prompt<PromptObject>([
{
name: 'types',
type: 'select',
message: gitCommitMessages.types,
choices: typesChoices,
},
{
name: 'scopes',
type: 'select',
message: gitCommitMessages.scopes,
choices: scopesChoices,
},
{
name: 'description',
type: 'text',
message: gitCommitMessages.description,
},
])
const breaking = result.description.startsWith('!') ? '!' : ''
const description = result.description.replace(/^!/, '').trim()
const commitMsg = `${result.types}(${result.scopes})${breaking}: ${description}`
await execCommand('git', ['commit', '-m', commitMsg], { stdio: 'inherit' })
}
/** Git commit message verify */
export async function gitCommitVerify(lang: Lang = 'en-us', ignores: RegExp[] = []) {
const gitPath = await execCommand('git', ['rev-parse', '--show-toplevel'])
const gitMsgPath = path.join(gitPath, '.git', 'COMMIT_EDITMSG')
const commitMsg = readFileSync(gitMsgPath, 'utf8').trim()
if (ignores.some(regExp => regExp.test(commitMsg)))
return
const REG_EXP = /(?<type>[a-z]+)(?:\((?<scope>.+)\))?(?<breaking>!)?: (?<description>.+)/i
if (!REG_EXP.test(commitMsg)) {
const errorMsg = locales[lang].gitCommitVerify
throw new Error(errorMsg)
}
}