feat(cli): --exclude flag for ignoring files (#162)

Co-authored-by: Hiroki Osame <hiroki.osame@gmail.com>
This commit is contained in:
tomaskudlicka
2023-03-27 03:24:48 +02:00
committed by GitHub
parent 7f6bdd93b5
commit 52b62d5a50
4 changed files with 41 additions and 16 deletions

View File

@@ -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,
); );
} }

View File

@@ -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');

View File

@@ -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 {

View File

@@ -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();