From ebe83a493e31508632ac467f2b902ce6f1577556 Mon Sep 17 00:00:00 2001 From: Rocktim Date: Sat, 1 Apr 2023 15:49:34 +0530 Subject: [PATCH] feat: `--all` flag (#182) Co-authored-by: Hiroki Osame --- README.md | 9 +++++++-- src/cli.ts | 7 +++++++ src/commands/aicommits.ts | 8 +++++++- tests/specs/cli/commits.ts | 34 +++++++++++++++++++++++++++++++++- tests/specs/cli/error-cases.ts | 2 +- 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 416e90f5..6287b8da 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,11 @@ git add aicommits ``` -`aicommits` passes down unknown flags to `git commit`, so you can pass in [`commit` flags](https://git-scm.com/docs/git-commit) (with some exceptions (e.g. `--all`): +`aicommits` passes down unknown flags to `git commit`, so you can pass in [`commit` flags](https://git-scm.com/docs/git-commit). +For example, you can stage all changes in tracked files with as you commit: ```sh -aicommits --dry-run +aicommits --all # or -a ``` > 👉 **Tip:** Use the `aic` alias if `aicommits` is too long for you. @@ -73,6 +74,10 @@ aicommits --generate # or -g > Warning: this uses more tokens, meaning it costs more. +```sh +aicommits --all +``` + ### Git hook You can also integrate _aicommits_ with Git via the [`prepare-commit-msg`](https://git-scm.com/docs/githooks#_prepare_commit_msg) hook. This lets you use Git like you normally would, and edit the commit message before committing. diff --git a/src/cli.ts b/src/cli.ts index 54f35155..01b30c60 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -29,6 +29,12 @@ cli( description: 'Files to exclude from AI analysis', alias: 'x', }, + all: { + type: Boolean, + description: 'Automatically stage changes in tracked files for the commit', + alias: 'a', + default: false, + }, }, commands: [ @@ -49,6 +55,7 @@ cli( aicommits( argv.flags.generate, argv.flags.exclude, + argv.flags.all, rawArgv, ); } diff --git a/src/commands/aicommits.ts b/src/commands/aicommits.ts index bb51adf9..eb457a7b 100644 --- a/src/commands/aicommits.ts +++ b/src/commands/aicommits.ts @@ -17,18 +17,24 @@ import { KnownError, handleCliError } from '../utils/error.js'; export default async ( generate: number | undefined, excludeFiles: string[], + stageAll: boolean, rawArgv: string[], ) => (async () => { intro(bgCyan(black(' aicommits '))); await assertGitRepo(); const detectingFiles = spinner(); + + if (stageAll) { + await execa('git', ['add', '--all']); + } + detectingFiles.start('Detecting staged files'); const staged = await getStagedDiff(excludeFiles); if (!staged) { detectingFiles.stop('Detecting staged files'); - throw new KnownError('No staged changes found. Make sure to stage your changes with `git add`.'); + throw new KnownError('No staged changes found. Stage your changes manually, or automatically stage all changes with the `--all` flag.'); } detectingFiles.stop(`${getDetectedMessage(staged.files)}:\n${ diff --git a/tests/specs/cli/commits.ts b/tests/specs/cli/commits.ts index 7b7b3a41..98d473f4 100644 --- a/tests/specs/cli/commits.ts +++ b/tests/specs/cli/commits.ts @@ -31,7 +31,7 @@ export default testSuite(({ describe }) => { 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`.'); + expect(stdout).toMatch('No staged changes found.'); await fixture.rm(); }); @@ -61,6 +61,38 @@ export default testSuite(({ describe }) => { await fixture.rm(); }); + test('Accepts --all flag, staging all changes before commit', async () => { + const { fixture, aicommits } = await createFixture(files); + const git = await createGit(fixture.path); + + await git('add', ['data.json']); + await git('commit', ['-m', 'wip']); + + await fixture.writeFile('data.json', 'Test'); + + const statusBefore = await git('status', ['--short', '--untracked-files=no']); + expect(statusBefore.stdout).toBe(' M data.json'); + + const committing = aicommits(['--all']); + committing.stdout!.on('data', (buffer: Buffer) => { + const stdout = buffer.toString(); + if (stdout.match('└')) { + committing.stdin!.write('y'); + committing.stdin!.end(); + } + }); + + await committing; + + const statusAfter = await git('status', ['--short', '--untracked-files=no']); + expect(statusAfter.stdout).toBe(''); + + const { stdout: commitMessage } = await git('log', ['-n1', '--oneline']); + console.log('Committed with:', commitMessage); + + await fixture.rm(); + }); + test('Accepts --generate flag, overriding config', async ({ onTestFail }) => { const { fixture, aicommits } = await createFixture({ ...files, diff --git a/tests/specs/cli/error-cases.ts b/tests/specs/cli/error-cases.ts index e99602cf..6695e080 100644 --- a/tests/specs/cli/error-cases.ts +++ b/tests/specs/cli/error-cases.ts @@ -17,7 +17,7 @@ export default testSuite(({ describe }) => { const { stdout, exitCode } = await aicommits([], { reject: false }); expect(exitCode).toBe(1); - expect(stdout).toMatch('No staged changes found. Make sure to stage your changes with `git add`.'); + expect(stdout).toMatch('No staged changes found. Stage your changes manually, or automatically stage all changes with the `--all` flag.'); await fixture.rm(); }); });