feat: git hook (#95)
This commit is contained in:
65
src/prepare-commit-msg-hook.ts
Normal file
65
src/prepare-commit-msg-hook.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import fs from 'fs/promises';
|
||||
import {
|
||||
intro, outro, spinner,
|
||||
} from '@clack/prompts';
|
||||
import {
|
||||
black, green, red, bgCyan,
|
||||
} from 'kolorist';
|
||||
import { getStagedDiff } from './utils/git.js';
|
||||
import { getConfig } from './utils/config.js';
|
||||
import { generateCommitMessage } from './utils/openai.js';
|
||||
|
||||
const [messageFilePath, commitSource] = process.argv.slice(2);
|
||||
|
||||
(async () => {
|
||||
if (!messageFilePath) {
|
||||
throw new Error('Commit message file path is missing. This file should be called from the "prepare-commit-msg" git hook');
|
||||
}
|
||||
|
||||
// If a commit message is passed in, ignore
|
||||
if (commitSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
// All staged files can be ignored by our filter
|
||||
const staged = await getStagedDiff();
|
||||
if (!staged) {
|
||||
return;
|
||||
}
|
||||
|
||||
intro(bgCyan(black(' aicommits ')));
|
||||
|
||||
const { OPENAI_KEY, generate } = await getConfig();
|
||||
if (!OPENAI_KEY) {
|
||||
throw new Error('Please set your OpenAI API key in ~/.aicommits');
|
||||
}
|
||||
|
||||
const s = spinner();
|
||||
s.start('The AI is analyzing your changes');
|
||||
const messages = await generateCommitMessage(
|
||||
OPENAI_KEY,
|
||||
staged!.diff,
|
||||
generate || 1,
|
||||
);
|
||||
s.stop('Changes analyzed');
|
||||
|
||||
const hasMultipleMessages = messages.length > 1;
|
||||
let instructions = `# 🤖 AI generated commit${hasMultipleMessages ? 's' : ''}\n`;
|
||||
|
||||
if (hasMultipleMessages) {
|
||||
instructions += '# Select one of the following messages by uncommeting:\n';
|
||||
instructions += `\n${messages.map(message => `# ${message}`).join('\n')}`;
|
||||
} else {
|
||||
instructions += '# Edit the message below and commit:\n';
|
||||
instructions += `\n${messages[0]}\n`;
|
||||
}
|
||||
|
||||
await fs.appendFile(
|
||||
messageFilePath,
|
||||
instructions,
|
||||
);
|
||||
outro(`${green('✔')} Saved commit message!`);
|
||||
})().catch((error) => {
|
||||
outro(`${red('✖')} ${error.message}`);
|
||||
process.exit(1); // eslint-disable-line unicorn/no-process-exit
|
||||
});
|
||||
Reference in New Issue
Block a user