feat: config file at ~/.aicommits (#51)

Co-authored-by: Yu Le <is.yuler@gmail.com>
This commit is contained in:
hiroki osame
2023-02-16 00:15:07 -05:00
committed by GitHub
parent a282874b7a
commit de38c891f5
5 changed files with 58 additions and 10 deletions

View File

@@ -14,20 +14,28 @@
## Installation and Usage
Install the CLI then grab your [OpenAI key](https://openai.com/api/) and add it as an env variable with the two commands below.
1. Install the CLI:
1. `npm install -g aicommits`
2. `export OPENAI_KEY=sk-xxxxxxxxxxxxxxxx`
```sh
npm install -g aicommits
```
It's recommended to add the line in #2 to your `.zshrc` or `.bashrc` so it persists instead of having to define it in each terminal session.
2. Retrieve your API key from [OpenAI](https://platform.openai.com/account/api-keys)
> Note: If you haven't already, you'll have to create an account and set up billing.
After doing the two steps above, generate your commit by running `aicommits`.
3. Set the key so aicommits can use it:
> Note: If you get a EACCESS error on mac/linux when running the first command, try running it with `sudo npm install -g aicommits`.
```sh
echo "OPENAI_KEY=<your token>" >> ~/.aicommits
```
4. You're ready to go!
Run `aicommits` in any Git repo and it will generate a commit message for you.
## How it works
This CLI tool runs a `git diff` command to grab all the latest changes, sends this to OpenAI's GPT-3, then returns the AI generated commit message. I also want to note that it does cost money since GPT-3 generations aren't free. However, OpenAI gives folks $18 of free credits and commit message generations are cheap so it should be free for a long time.
This CLI tool runs `git diff` to grab all the latest changes, sends them to OpenAI's GPT-3, then returns the AI generated commit message.
Video coming soon where I rebuild it from scratch to show you how to easily build your own CLI tools powered by AI.

View File

@@ -20,11 +20,13 @@
},
"dependencies": {
"chalk": "^4.1.2",
"ini": "^3.0.1",
"inquirer": "^8.0.0",
"openai": "^3.1.0"
},
"devDependencies": {
"@pvtnbr/eslint-config": "^0.33.0",
"@types/ini": "^1.3.31",
"@types/node": "^18.13.0",
"eslint": "^8.34.0",
"typescript": "^4.9.5"

13
pnpm-lock.yaml generated
View File

@@ -2,20 +2,24 @@ lockfileVersion: 5.4
specifiers:
'@pvtnbr/eslint-config': ^0.33.0
'@types/ini': ^1.3.31
'@types/node': ^18.13.0
chalk: ^4.1.2
eslint: ^8.34.0
ini: ^3.0.1
inquirer: ^8.0.0
openai: ^3.1.0
typescript: ^4.9.5
dependencies:
chalk: 4.1.2
ini: 3.0.1
inquirer: 8.2.5
openai: 3.1.0
devDependencies:
'@pvtnbr/eslint-config': 0.33.0_7kw3g6rralp5ps6mg3uyzz6azm
'@types/ini': 1.3.31
'@types/node': 18.13.0
eslint: 8.34.0
typescript: 4.9.5
@@ -141,6 +145,10 @@ packages:
- typescript
dev: true
/@types/ini/1.3.31:
resolution: {integrity: sha512-8ecxxaG4AlVEM1k9+BsziMw8UsX0qy3jYI1ad/71RrDZ+rdL6aZB0wLfAuflQiDhkD5o4yJ0uPK3OSUic3fG0w==}
dev: true
/@types/json-schema/7.0.11:
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
dev: true
@@ -1487,6 +1495,11 @@ packages:
/inherits/2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
/ini/3.0.1:
resolution: {integrity: sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
dev: false
/inquirer/8.2.5:
resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==}
engines: {node: '>=12.0.0'}

View File

@@ -3,11 +3,15 @@
import { execSync } from 'child_process';
import chalk from 'chalk';
import inquirer from 'inquirer';
import { generateCommitMessage } from './utils';
const OPENAI_KEY = process.env.OPENAI_KEY ?? process.env.OPENAI_API_KEY;
import {
getConfig,
generateCommitMessage,
} from './utils';
(async () => {
const config = await getConfig();
const OPENAI_KEY = process.env.OPENAI_KEY ?? process.env.OPENAI_API_KEY ?? config.OPENAI_KEY;
console.log(chalk.white('▲ ') + chalk.green('Welcome to AICommits!'));
if (!OPENAI_KEY) {

View File

@@ -1,5 +1,26 @@
import fs from 'fs/promises';
import path from 'path';
import os from 'os';
import ini from 'ini';
import { Configuration, OpenAIApi } from 'openai';
const fileExists = (filePath: string) => fs.access(filePath).then(() => true, () => false);
type ConfigType = {
OPENAI_KEY?: string;
};
export const getConfig = async (): Promise<ConfigType> => {
const configPath = path.join(os.homedir(), '.aicommits');
const configExists = await fileExists(configPath);
if (!configExists) {
return {};
}
const configString = await fs.readFile(configPath, 'utf8');
return ini.parse(configString);
};
export const generateCommitMessage = async (
apiKey: string,
prompt: string,