Compare commits

..

25 Commits

Author SHA1 Message Date
di-sukharev
2ae35749a5 1.0.15 2023-03-11 00:28:58 +08:00
di-sukharev
8836c57fa4 * chore(commit.ts): add TODO comment to show proper error messages 2023-03-11 00:24:52 +08:00
di-sukharev
4b523e5782 1.0.14 2023-03-11 00:23:55 +08:00
di-sukharev
33491486bb * feat(CommandsEnum.ts): add COMMANDS enum
* refactor(api.ts): use CONFIG_MODES enum from config.ts
* refactor(config.ts): use COMMANDS and CONFIG_MODES enums, extract validateConfig function
* feat(config.ts): add CONFIG_MODES enum and refactor configCommand function to use it

* refactor(githook.ts): import COMMANDS enum from CommandsEnum.js file
2023-03-11 00:23:30 +08:00
di-sukharev
e76db8276b 1.0.13 2023-03-11 00:20:09 +08:00
di-sukharev
c2ae98170c * refactor(api.ts): move apiKey initialization to the top of the file
* feat(api.ts): add check for process arguments to avoid intro message if 'config set' command is used
2023-03-11 00:19:29 +08:00
di-sukharev
91987030f0 1.0.12 2023-03-11 00:15:34 +08:00
di-sukharev
2a55b08b51 * refactor(api.ts): remove redundant code block and process.exit(1) call 2023-03-11 00:15:17 +08:00
di-sukharev
ed4d6e0109 1.0.11 2023-03-10 22:49:43 +08:00
di-sukharev
6712e798c5 * feat(cli.ts): add check for new opencommit version after commit is made
* chore(cli.ts): import execa and outro from their respective packages
2023-03-10 22:49:27 +08:00
di-sukharev
1347962a93 1.0.10 2023-03-10 22:42:33 +08:00
di-sukharev
3ca9b9752f * fix(api.ts): add process.exit(1) to terminate the process if apiKey is not provided 2023-03-10 22:41:53 +08:00
di-sukharev
50e2f67a9b 1.0.9 2023-03-10 17:56:21 +08:00
di-sukharev
c1a4c3daf2 * chore: update package description and keywords
* chore: update README with new package description and title
2023-03-10 17:55:51 +08:00
di-sukharev
e4de6d8186 * feat(README.md): add OpenCommit example image to README
* chore(README.md): update OPENAI_API_KEY config key to use 'your_api_key' instead of 'your token'
* chore(README.md): update description of where the api key is stored
2023-03-10 15:59:57 +08:00
di-sukharev
5abe5d715d * refactor(commit.ts): remove unnecessary blank lines
* feat(commit.ts): add spinner to show progress of `git push` command
* feat(commit.ts): show success message after successful `git push` command execution
2023-03-10 15:24:49 +08:00
di-sukharev
32c34abd22 1.0.8 2023-03-09 21:32:24 +08:00
di-sukharev
1050cad95d * refactor(commit.ts): extract stdout from git push command into a variable 2023-03-09 21:32:07 +08:00
di-sukharev
7bbc97980e * refactor(commit.ts): remove unused stdout variable and simplify pushSpinner.stop() call 2023-03-09 21:31:31 +08:00
di-sukharev
2a9a3d5818 * chore(README.md): add emoji to the project description 2023-03-09 21:30:44 +08:00
di-sukharev
22935f38ba 1.0.7 2023-03-09 21:29:52 +08:00
di-sukharev
4ae6361ad8 * chore(package.json): update description with emojis. 2023-03-09 21:29:28 +08:00
di-sukharev
5a0a384cbe 1.0.6 2023-03-09 21:25:49 +08:00
di-sukharev
a8839353f7 * chore(commit.ts): add spinner to indicate git push process
* refactor(commit.ts): change success message to include spinner in `git push` process
2023-03-09 21:25:38 +08:00
di-sukharev
88006b8693 * fix(commit.ts): add check for cancelation of git push confirmation prompt 2023-03-09 21:23:58 +08:00
10 changed files with 55 additions and 20 deletions

BIN
.github/opencommit-example.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

View File

@@ -5,13 +5,16 @@
<h4 align="center">Author <a href="https://github.com/di-sukharev">@di-sukharev</a> <a href="https://twitter.com/io_Y_oi"><img src="https://img.shields.io/twitter/follow/io_Y_oi?style=flat&label=io_Y_oi&logo=twitter&color=0bf&logoColor=fff" align="center"></a>
</h4>
</div>
<p>AI generates conventional commits with mind-blowing accuracy</p>
<h2>GPT CLI to auto-generate impressive commits in 1 second</h2>
<p>Killing lame commits with AI 🤯🔫</p>
<a href="https://www.npmjs.com/package/opencommit"><img src="https://img.shields.io/npm/v/opencommit" alt="Current version"></a>
</div>
---
## Examples
<div align="center">
<img src=".github/opencommit-example.png" alt="OpenCommit example"/>
</div>
All the commits in this repo are done with OpenCommit — look into [the commits](https://github.com/di-sukharev/opencommit/commit/eae7618d575ee8d2e9fff5de56da79d40c4bc5fc) to see how OpenCommit works. Emoji and long commit description text is configurable.
@@ -30,10 +33,10 @@ All the commits in this repo are done with OpenCommit — look into [the commits
3. Set the key to opencommit config:
```sh
opencommit config set OPENAI_API_KEY=<your token>
opencommit config set OPENAI_API_KEY=<your_api_key>
```
Your token isn't sent to anyone, it's saved in `~/.opencommit` config file.
Your api key is stored locally in `~/.opencommit` config file.
## Usage

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "open-commit",
"version": "1.0.5",
"version": "1.0.15",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "open-commit",
"version": "1.0.5",
"version": "1.0.15",
"license": "ISC",
"dependencies": {
"@clack/prompts": "^0.6.1",

View File

@@ -1,13 +1,17 @@
{
"name": "opencommit",
"version": "1.0.5",
"description": "AI generates conventional commits with mind-blowing accuracy.",
"version": "1.0.15",
"description": "GPT CLI to auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫",
"keywords": [
"git",
"chatgpt",
"gpt",
"ai",
"openai",
"opencommit",
"aicommit",
"aicommits",
"gptcommit",
"commit"
],
"main": "cli.js",

4
src/CommandsEnum.ts Normal file
View File

@@ -0,0 +1,4 @@
export enum COMMANDS {
config = 'config',
hook = 'hook'
}

View File

@@ -5,13 +5,15 @@ import {
OpenAIApi
} from 'openai';
import { getConfig } from './commands/config';
import { CONFIG_MODES, getConfig } from './commands/config';
const config = getConfig();
let apiKey = config?.OPENAI_API_KEY;
if (!apiKey) {
const [command, mode] = process.argv.slice(2);
if (!apiKey && command !== 'config' && mode !== CONFIG_MODES.set) {
intro('opencommit');
outro(
@@ -20,6 +22,8 @@ if (!apiKey) {
outro(
'For help Look into README https://github.com/di-sukharev/opencommit#setup'
);
process.exit(1);
}
// if (!apiKey) {

View File

@@ -7,6 +7,8 @@ import { configCommand } from './commands/config';
import { hookCommand, isHookCalled } from './commands/githook.js';
import { prepareCommitMessageHook } from './commands/prepare-commit-msg-hook';
import { commit } from './commands/commit';
import { execa } from 'execa';
import { outro } from '@clack/prompts';
const rawArgv = process.argv.slice(2);
@@ -19,11 +21,17 @@ cli(
ignoreArgv: (type) => type === 'unknown-flag' || type === 'argument',
help: { description: packageJSON.description }
},
() => {
async () => {
if (isHookCalled) {
prepareCommitMessageHook();
await prepareCommitMessageHook();
} else {
commit();
await commit();
const { stdout } = await execa('npm', ['view', 'opencommit', 'version']);
if (stdout !== packageJSON.version)
outro(
'new opencommit version is available, update with `npm i -g opencommit`'
);
}
},
rawArgv

View File

@@ -16,6 +16,7 @@ const generateCommitMessageFromGitDiff = async (
commitSpinner.start('Generating the commit message');
const commitMessage = await generateCommitMessageWithChatCompletion(diff);
// TODO: show proper error messages
if (typeof commitMessage !== 'string') {
const errorMessages = {
[GenerateCommitMessageErrorEnum.emptyMessage]:
@@ -51,10 +52,14 @@ ${chalk.grey('——————————————————')}`
message: 'Do you want to run `git push`?'
});
if (isPushConfirmedByUser) {
if (isPushConfirmedByUser && !isCancel(isPushConfirmedByUser)) {
const pushSpinner = spinner();
pushSpinner.start('Running `git push`');
const { stdout } = await execa('git', ['push']);
outro(`${chalk.green('✔')} successfully pushed all commits`);
outro(stdout);
pushSpinner.stop(`${chalk.green('✔')} successfully pushed all commits`);
if (stdout) outro(stdout);
}
} else outro(`${chalk.gray('✖')} process cancelled`);
};

View File

@@ -5,6 +5,7 @@ import { existsSync, writeFileSync, readFileSync } from 'fs';
import { homedir } from 'os';
import { intro, outro } from '@clack/prompts';
import chalk from 'chalk';
import { COMMANDS } from '../CommandsEnum';
export enum CONFIG_KEYS {
OPENAI_API_KEY = 'OPENAI_API_KEY',
@@ -12,6 +13,11 @@ export enum CONFIG_KEYS {
emoji = 'emoji'
}
export enum CONFIG_MODES {
get = 'get',
set = 'set'
}
const validateConfig = (
key: string,
condition: any,
@@ -110,7 +116,7 @@ export const setConfig = (keyValues: [key: string, value: string][]) => {
export const configCommand = command(
{
name: 'config',
name: COMMANDS.config,
parameters: ['<mode>', '<key=values...>']
},
async (argv) => {
@@ -118,12 +124,12 @@ export const configCommand = command(
try {
const { mode, keyValues } = argv._;
if (mode === 'get') {
if (mode === CONFIG_MODES.get) {
const config = getConfig() || {};
for (const key of keyValues) {
outro(`${key}=${config[key as keyof typeof config]}`);
}
} else if (mode === 'set') {
} else if (mode === CONFIG_MODES.set) {
await setConfig(
keyValues.map((keyValue) => keyValue.split('=') as [string, string])
);

View File

@@ -5,6 +5,7 @@ import { assertGitRepo } from '../utils/git.js';
import { existsSync } from 'fs';
import chalk from 'chalk';
import { intro, outro } from '@clack/prompts';
import { COMMANDS } from '../CommandsEnum.js';
const HOOK_NAME = 'prepare-commit-msg';
const SYMLINK_URL = `.git/hooks/${HOOK_NAME}`;
@@ -15,7 +16,7 @@ const isHookExists = existsSync(SYMLINK_URL);
export const hookCommand = command(
{
name: 'hook',
name: COMMANDS.hook,
parameters: ['<set/unset>']
},
async (argv) => {