feat(cli): --exclude flag for ignoring files (#162)
Co-authored-by: Hiroki Osame <hiroki.osame@gmail.com>
This commit is contained in:
@@ -21,9 +21,14 @@ cli(
|
|||||||
flags: {
|
flags: {
|
||||||
generate: {
|
generate: {
|
||||||
type: Number,
|
type: Number,
|
||||||
description: 'Number of messages to generate. (Warning: generating multiple costs more) (default: 1)',
|
description: 'Number of messages to generate (Warning: generating multiple costs more) (default: 1)',
|
||||||
alias: 'g',
|
alias: 'g',
|
||||||
},
|
},
|
||||||
|
exclude: {
|
||||||
|
type: [String],
|
||||||
|
description: 'Files to exclude from AI analysis',
|
||||||
|
alias: 'x',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
commands: [
|
commands: [
|
||||||
@@ -43,6 +48,7 @@ cli(
|
|||||||
} else {
|
} else {
|
||||||
aicommits(
|
aicommits(
|
||||||
argv.flags.generate,
|
argv.flags.generate,
|
||||||
|
argv.flags.exclude,
|
||||||
rawArgv,
|
rawArgv,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,15 +16,15 @@ import { KnownError, handleCliError } from '../utils/error.js';
|
|||||||
|
|
||||||
export default async (
|
export default async (
|
||||||
generate: number | undefined,
|
generate: number | undefined,
|
||||||
|
excludeFiles: string[],
|
||||||
rawArgv: string[],
|
rawArgv: string[],
|
||||||
) => (async () => {
|
) => (async () => {
|
||||||
intro(bgCyan(black(' aicommits ')));
|
intro(bgCyan(black(' aicommits ')));
|
||||||
|
|
||||||
await assertGitRepo();
|
await assertGitRepo();
|
||||||
|
|
||||||
const detectingFiles = spinner();
|
const detectingFiles = spinner();
|
||||||
detectingFiles.start('Detecting staged files');
|
detectingFiles.start('Detecting staged files');
|
||||||
const staged = await getStagedDiff();
|
const staged = await getStagedDiff(excludeFiles);
|
||||||
|
|
||||||
if (!staged) {
|
if (!staged) {
|
||||||
detectingFiles.stop('Detecting staged files');
|
detectingFiles.stop('Detecting staged files');
|
||||||
|
|||||||
@@ -9,19 +9,30 @@ export const assertGitRepo = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const excludeFromDiff = [
|
const excludeFromDiff = (path: string) => `:(exclude)${path}`;
|
||||||
|
|
||||||
|
const filesToExclude = [
|
||||||
'package-lock.json',
|
'package-lock.json',
|
||||||
'pnpm-lock.yaml',
|
'pnpm-lock.yaml',
|
||||||
|
|
||||||
// yarn.lock, Cargo.lock, Gemfile.lock, Pipfile.lock, etc.
|
// yarn.lock, Cargo.lock, Gemfile.lock, Pipfile.lock, etc.
|
||||||
'*.lock',
|
'*.lock',
|
||||||
].map(file => `:(exclude)${file}`);
|
].map(excludeFromDiff);
|
||||||
|
|
||||||
export const getStagedDiff = async () => {
|
export const getStagedDiff = async (excludeFiles?: string[]) => {
|
||||||
const diffCached = ['diff', '--cached'];
|
const diffCached = ['diff', '--cached'];
|
||||||
const { stdout: files } = await execa(
|
const { stdout: files } = await execa(
|
||||||
'git',
|
'git',
|
||||||
[...diffCached, '--name-only', ...excludeFromDiff],
|
[
|
||||||
|
...diffCached,
|
||||||
|
'--name-only',
|
||||||
|
...filesToExclude,
|
||||||
|
...(
|
||||||
|
excludeFiles
|
||||||
|
? excludeFiles.map(excludeFromDiff)
|
||||||
|
: []
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!files) {
|
if (!files) {
|
||||||
@@ -30,7 +41,10 @@ export const getStagedDiff = async () => {
|
|||||||
|
|
||||||
const { stdout: diff } = await execa(
|
const { stdout: diff } = await execa(
|
||||||
'git',
|
'git',
|
||||||
[...diffCached, ...excludeFromDiff],
|
[
|
||||||
|
...diffCached,
|
||||||
|
...filesToExclude,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -43,18 +43,23 @@ export default testSuite(({ describe }) => {
|
|||||||
expect(stdout).toMatch('No staged changes found. Make sure to stage your changes with `git add`.');
|
expect(stdout).toMatch('No staged changes found. Make sure to stage your changes with `git add`.');
|
||||||
});
|
});
|
||||||
|
|
||||||
await test('Generates commit message', async () => {
|
|
||||||
await git('add', ['data.json']);
|
|
||||||
|
|
||||||
await aicommits([
|
await aicommits([
|
||||||
'config',
|
'config',
|
||||||
'set',
|
'set',
|
||||||
`OPENAI_KEY=${OPENAI_KEY}`,
|
`OPENAI_KEY=${OPENAI_KEY}`,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
await test('Excludes files', async () => {
|
||||||
|
await git('add', ['data.json']);
|
||||||
const statusBefore = await git('status', ['--porcelain', '--untracked-files=no']);
|
const statusBefore = await git('status', ['--porcelain', '--untracked-files=no']);
|
||||||
expect(statusBefore.stdout).toBe('A data.json');
|
expect(statusBefore.stdout).toBe('A data.json');
|
||||||
|
|
||||||
|
const { stdout, exitCode } = await aicommits(['--exclude', 'data.json'], { reject: false });
|
||||||
|
expect(exitCode).toBe(1);
|
||||||
|
expect(stdout).toMatch('No staged changes found. Make sure to stage your changes with `git add`.');
|
||||||
|
});
|
||||||
|
|
||||||
|
await test('Generates commit message', async () => {
|
||||||
const committing = aicommits();
|
const committing = aicommits();
|
||||||
committing.stdout!.on('data', (buffer: Buffer) => {
|
committing.stdout!.on('data', (buffer: Buffer) => {
|
||||||
const stdout = buffer.toString();
|
const stdout = buffer.toString();
|
||||||
|
|||||||
Reference in New Issue
Block a user