mirror of
https://github.com/di-sukharev/opencommit.git
synced 2026-01-12 23:28:16 -05:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d50a67ece | ||
|
|
a2d03e054c | ||
|
|
1c113c2901 | ||
|
|
18dcb8e8c2 | ||
|
|
8b17b5e906 | ||
|
|
284604f6a4 | ||
|
|
bdce94f2ac | ||
|
|
a3fade4d42 | ||
|
|
83906fc704 | ||
|
|
e7f7bfc2bd | ||
|
|
3885ae5893 | ||
|
|
b8e05a5852 | ||
|
|
677b7ecad9 | ||
|
|
6ab06f9db3 | ||
|
|
38ac20612b | ||
|
|
54b8ba7419 | ||
|
|
ff81d7e1ca | ||
|
|
a6ccdb5f77 | ||
|
|
fef8027959 | ||
|
|
0f48cc616e | ||
|
|
b54ff02930 | ||
|
|
7fb46de105 | ||
|
|
2f6e98dc30 | ||
|
|
2aa6582c52 | ||
|
|
2acf833cd0 | ||
|
|
3f7025d50a | ||
|
|
d793bf1340 | ||
|
|
0092e92061 |
8
.github/CONTRIBUTING.md
vendored
8
.github/CONTRIBUTING.md
vendored
@@ -1,6 +1,6 @@
|
||||
# Contribution Guidelines
|
||||
|
||||
Thank you for considering contributing to the project. Let's shake it baby.
|
||||
Thanks for considering contributing to the project.
|
||||
|
||||
## How to contribute
|
||||
|
||||
@@ -9,7 +9,7 @@ Thank you for considering contributing to the project. Let's shake it baby.
|
||||
3. Create a new branch for your changes.
|
||||
4. Make your changes and commit them with descriptive commit messages.
|
||||
5. Push your changes to your forked repository.
|
||||
6. Create a pull request from your branch to the `master` branch.
|
||||
6. Create a pull request from your branch to the `dev` branch.
|
||||
|
||||
## Getting started
|
||||
|
||||
@@ -28,9 +28,9 @@ Use the library to generate commits, stage the files and run `npm run dev` :)
|
||||
|
||||
If you encounter any issues while using the project, please report them on the GitHub issue tracker. When reporting issues, please include as much information as possible, such as steps to reproduce the issue, expected behavior, and actual behavior.
|
||||
|
||||
## Contact us
|
||||
## Contacts
|
||||
|
||||
If you have any questions about contributing to the project, please contact us by [creating an issue](https://github.com/di-sukharev/open-commit/issues) on the GitHub issue tracker.
|
||||
If you have any questions about contributing to the project, please contact by [creating an issue](https://github.com/di-sukharev/open-commit/issues) on the GitHub issue tracker.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,4 +10,5 @@ application.log
|
||||
logfile.log
|
||||
uncaughtExceptions.log
|
||||
.vscode
|
||||
src/*.json
|
||||
src/*.json
|
||||
.idea
|
||||
44
README.md
44
README.md
@@ -84,6 +84,50 @@ To remove description:
|
||||
oc config set description=false
|
||||
```
|
||||
|
||||
### Internationalization support
|
||||
|
||||
To specify the language used to generate commit messages:
|
||||
|
||||
```sh
|
||||
# de, German ,Deutsch
|
||||
oc config set language=de
|
||||
oc config set language=German
|
||||
oc config set language=Deutsch
|
||||
|
||||
# fr, French, française
|
||||
oc config set language=fr
|
||||
oc config set language=French
|
||||
oc config set language=française
|
||||
```
|
||||
The default language set is **English**
|
||||
All available languages are currently listed in the [i18n](https://github.com/di-sukharev/opencommit/tree/master/src/i18n) folder
|
||||
|
||||
### Git flags
|
||||
|
||||
The `opencommit` or `oc` commands can be used in place of the `git commit -m "${generatedMessage}"` command. This means that any regular flags that are used with the `git commit` command will also be applied when using `opencommit` or `oc`.
|
||||
|
||||
```sh
|
||||
oc --no-verify
|
||||
```
|
||||
|
||||
is translated to :
|
||||
|
||||
```sh
|
||||
git commit -m "${generatedMessage}" --no-verify
|
||||
```
|
||||
|
||||
### Ignore files
|
||||
You can ignore files from submission to OpenAI by creating a `.opencommitignore` file. For example:
|
||||
|
||||
```ignorelang
|
||||
path/to/large-asset.zip
|
||||
**/*.jpg
|
||||
```
|
||||
|
||||
This is useful for preventing opencommit from uploading artifacts and large files.
|
||||
|
||||
By default, opencommit ignores files matching: `*-lock.*` and `*.lock`
|
||||
|
||||
## Git hook
|
||||
|
||||
You can set OpenCommit as Git [`prepare-commit-msg`](https://git-scm.com/docs/githooks#_prepare_commit_msg) hook. Hook integrates with you IDE Source Control and allows you edit the message before commit.
|
||||
|
||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -1,19 +1,20 @@
|
||||
{
|
||||
"name": "opencommit",
|
||||
"version": "1.1.15",
|
||||
"version": "1.1.23",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "opencommit",
|
||||
"version": "1.1.15",
|
||||
"license": "ISC",
|
||||
"version": "1.1.23",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^0.6.1",
|
||||
"axios": "^1.3.4",
|
||||
"chalk": "^5.2.0",
|
||||
"cleye": "^1.3.2",
|
||||
"execa": "^7.0.0",
|
||||
"ignore": "^5.2.4",
|
||||
"ini": "^3.0.1",
|
||||
"inquirer": "^9.1.4",
|
||||
"openai": "^3.2.1"
|
||||
@@ -1880,7 +1881,6 @@
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
|
||||
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "opencommit",
|
||||
"version": "1.1.15",
|
||||
"version": "1.1.23",
|
||||
"description": "GPT CLI to auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫",
|
||||
"keywords": [
|
||||
"git",
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"type": "module",
|
||||
"author": "https://github.com/di-sukharev",
|
||||
"license": "ISC",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"out/**/*"
|
||||
],
|
||||
@@ -64,6 +64,7 @@
|
||||
"chalk": "^5.2.0",
|
||||
"cleye": "^1.3.2",
|
||||
"execa": "^7.0.0",
|
||||
"ignore": "^5.2.4",
|
||||
"ini": "^3.0.1",
|
||||
"inquirer": "^9.1.4",
|
||||
"openai": "^3.2.1"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export enum COMMANDS {
|
||||
config = 'config',
|
||||
hook = 'hook'
|
||||
hook = 'hook',
|
||||
config = 'config'
|
||||
}
|
||||
|
||||
19
src/api.ts
19
src/api.ts
@@ -53,7 +53,10 @@ class OpenAi {
|
||||
} catch (error: unknown) {
|
||||
outro(`${chalk.red('✖')} ${error}`);
|
||||
|
||||
if (axios.isAxiosError<{ error?: { message: string } }>(error) && error.response?.status === 401) {
|
||||
if (
|
||||
axios.isAxiosError<{ error?: { message: string } }>(error) &&
|
||||
error.response?.status === 401
|
||||
) {
|
||||
const openAiError = error.response.data.error;
|
||||
|
||||
if (openAiError?.message) outro(openAiError.message);
|
||||
@@ -67,4 +70,18 @@ class OpenAi {
|
||||
};
|
||||
}
|
||||
|
||||
export const getOpenCommitLatestVersion = async (): Promise<
|
||||
string | undefined
|
||||
> => {
|
||||
try {
|
||||
const { data } = await axios.get(
|
||||
'https://unpkg.com/opencommit/package.json'
|
||||
);
|
||||
return data.version;
|
||||
} catch (_) {
|
||||
outro('Error while getting the latest version of opencommit');
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export const api = new OpenAi();
|
||||
|
||||
10
src/cli.ts
10
src/cli.ts
@@ -7,8 +7,9 @@ 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 { checkIsLatestVersion } from './utils/checkIsLatestVersion';
|
||||
|
||||
const rawArgv = process.argv.slice(2);
|
||||
const extraArgs = process.argv.slice(2);
|
||||
|
||||
cli(
|
||||
{
|
||||
@@ -19,12 +20,13 @@ cli(
|
||||
ignoreArgv: (type) => type === 'unknown-flag' || type === 'argument',
|
||||
help: { description: packageJSON.description }
|
||||
},
|
||||
() => {
|
||||
async () => {
|
||||
// await checkIsLatestVersion();
|
||||
if (isHookCalled) {
|
||||
prepareCommitMessageHook();
|
||||
} else {
|
||||
commit();
|
||||
commit(extraArgs);
|
||||
}
|
||||
},
|
||||
rawArgv
|
||||
extraArgs
|
||||
);
|
||||
|
||||
@@ -16,13 +16,21 @@ import {
|
||||
outro,
|
||||
isCancel,
|
||||
intro,
|
||||
multiselect
|
||||
multiselect,
|
||||
select
|
||||
} from '@clack/prompts';
|
||||
import chalk from 'chalk';
|
||||
import { trytm } from '../utils/trytm';
|
||||
|
||||
// Adding a function to get the list of remotes
|
||||
const getGitRemotes = async () => {
|
||||
const { stdout } = await execa('git', ['remote']);
|
||||
return stdout.split('\n').filter((remote) => remote.trim() !== '');
|
||||
};
|
||||
|
||||
const generateCommitMessageFromGitDiff = async (
|
||||
diff: string
|
||||
diff: string,
|
||||
extraArgs: string[]
|
||||
): Promise<void> => {
|
||||
await assertGitRepo();
|
||||
|
||||
@@ -55,35 +63,76 @@ ${chalk.grey('——————————————————')}`
|
||||
);
|
||||
|
||||
const isCommitConfirmedByUser = await confirm({
|
||||
message: 'Confirm the commit message'
|
||||
message: 'Confirm the commit message?'
|
||||
});
|
||||
|
||||
if (isCommitConfirmedByUser && !isCancel(isCommitConfirmedByUser)) {
|
||||
const { stdout } = await execa('git', ['commit', '-m', commitMessage]);
|
||||
const { stdout } = await execa('git', [
|
||||
'commit',
|
||||
'-m',
|
||||
commitMessage,
|
||||
...extraArgs
|
||||
]);
|
||||
|
||||
outro(`${chalk.green('✔')} successfully committed`);
|
||||
|
||||
outro(stdout);
|
||||
const remotes = await getGitRemotes();
|
||||
|
||||
const isPushConfirmedByUser = await confirm({
|
||||
message: 'Do you want to run `git push`?'
|
||||
});
|
||||
if (remotes.length === 1) {
|
||||
const isPushConfirmedByUser = await confirm({
|
||||
message: 'Do you want to run `git push`?'
|
||||
});
|
||||
|
||||
if (isPushConfirmedByUser && !isCancel(isPushConfirmedByUser)) {
|
||||
const pushSpinner = spinner();
|
||||
if (isPushConfirmedByUser && !isCancel(isPushConfirmedByUser)) {
|
||||
const pushSpinner = spinner();
|
||||
|
||||
pushSpinner.start('Running `git push`');
|
||||
const { stdout } = await execa('git', ['push']);
|
||||
pushSpinner.stop(`${chalk.green('✔')} successfully pushed all commits`);
|
||||
pushSpinner.start(`Running \`git push ${remotes[0]}\``);
|
||||
|
||||
if (stdout) outro(stdout);
|
||||
const { stdout } = await execa('git', [
|
||||
'push',
|
||||
'--verbose',
|
||||
remotes[0]
|
||||
]);
|
||||
|
||||
pushSpinner.stop(
|
||||
`${chalk.green('✔')} successfully pushed all commits to ${remotes[0]}`
|
||||
);
|
||||
|
||||
if (stdout) outro(stdout);
|
||||
}
|
||||
} else {
|
||||
const selectedRemote = (await select({
|
||||
message: 'Choose a remote to push to',
|
||||
options: remotes.map((remote) => ({ value: remote, label: remote }))
|
||||
})) as string;
|
||||
|
||||
if (!isCancel(selectedRemote)) {
|
||||
const pushSpinner = spinner();
|
||||
|
||||
pushSpinner.start(`Running \`git push ${selectedRemote}\``);
|
||||
|
||||
const { stdout } = await execa('git', ['push', selectedRemote]);
|
||||
|
||||
pushSpinner.stop(
|
||||
`${chalk.green(
|
||||
'✔'
|
||||
)} successfully pushed all commits to ${selectedRemote}`
|
||||
);
|
||||
|
||||
if (stdout) outro(stdout);
|
||||
} else outro(`${chalk.gray('✖')} process cancelled`);
|
||||
}
|
||||
} else outro(`${chalk.gray('✖')} process cancelled`);
|
||||
}
|
||||
};
|
||||
|
||||
export async function commit(isStageAllFlag = false) {
|
||||
export async function commit(
|
||||
extraArgs: string[] = [],
|
||||
isStageAllFlag: Boolean = false
|
||||
) {
|
||||
if (isStageAllFlag) {
|
||||
const changedFiles = await getChangedFiles();
|
||||
|
||||
if (changedFiles) await gitAdd({ files: changedFiles });
|
||||
else {
|
||||
outro('No changes detected, write some code and run `oc` again');
|
||||
@@ -106,6 +155,7 @@ export async function commit(isStageAllFlag = false) {
|
||||
}
|
||||
|
||||
const stagedFilesSpinner = spinner();
|
||||
|
||||
stagedFilesSpinner.start('Counting staged files');
|
||||
|
||||
if (!stagedFiles.length) {
|
||||
@@ -118,7 +168,7 @@ export async function commit(isStageAllFlag = false) {
|
||||
isStageAllAndCommitConfirmedByUser &&
|
||||
!isCancel(isStageAllAndCommitConfirmedByUser)
|
||||
) {
|
||||
await commit(true);
|
||||
await commit(extraArgs, true);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -136,7 +186,7 @@ export async function commit(isStageAllFlag = false) {
|
||||
await gitAdd({ files });
|
||||
}
|
||||
|
||||
await commit(false);
|
||||
await commit(extraArgs, false);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -147,13 +197,15 @@ export async function commit(isStageAllFlag = false) {
|
||||
);
|
||||
|
||||
const [, generateCommitError] = await trytm(
|
||||
generateCommitMessageFromGitDiff(await getDiff({ files: stagedFiles }))
|
||||
generateCommitMessageFromGitDiff(
|
||||
await getDiff({ files: stagedFiles }),
|
||||
extraArgs
|
||||
)
|
||||
);
|
||||
|
||||
if (generateCommitError) {
|
||||
outro(`${chalk.red('✖')} ${generateCommitError}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ const validateConfig = (
|
||||
outro(
|
||||
`${chalk.red('✖')} Unsupported config key ${key}: ${validationMessage}`
|
||||
);
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
@@ -49,6 +50,7 @@ export const configValidators = {
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
[CONFIG_KEYS.description](value: any) {
|
||||
validateConfig(
|
||||
CONFIG_KEYS.description,
|
||||
@@ -58,6 +60,7 @@ export const configValidators = {
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
[CONFIG_KEYS.emoji](value: any) {
|
||||
validateConfig(
|
||||
CONFIG_KEYS.emoji,
|
||||
@@ -67,6 +70,7 @@ export const configValidators = {
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
[CONFIG_KEYS.language](value: any) {
|
||||
validateConfig(
|
||||
CONFIG_KEYS.language,
|
||||
|
||||
@@ -55,18 +55,18 @@ export const hookCommand = command(
|
||||
}
|
||||
|
||||
if (mode === 'unset') {
|
||||
intro(`unsetting opencommit as '${HOOK_NAME}' hook`);
|
||||
intro(`unsetting OpenCommit as '${HOOK_NAME}' hook`);
|
||||
|
||||
if (!isHookExists) {
|
||||
return outro(
|
||||
`opencommit wasn't previously set as '${HOOK_NAME}' hook, nothing to remove`
|
||||
`OpenCommit wasn't previously set as '${HOOK_NAME}' hook, nothing to remove`
|
||||
);
|
||||
}
|
||||
|
||||
const realpath = await fs.realpath(SYMLINK_URL);
|
||||
if (realpath !== HOOK_URL) {
|
||||
return outro(
|
||||
`opencommit wasn't previously set as '${HOOK_NAME}' hook, but different hook was, if you want to remove it — do it manually`
|
||||
`OpenCommit wasn't previously set as '${HOOK_NAME}' hook, but different hook was, if you want to remove it — do it manually`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { mergeStrings } from './utils/mergeStrings';
|
||||
import { i18n, I18nLocals } from './i18n';
|
||||
|
||||
const config = getConfig();
|
||||
const translation = i18n[config?.language as I18nLocals || 'en']
|
||||
const translation = i18n[(config?.language as I18nLocals) || 'en'];
|
||||
|
||||
const INIT_MESSAGES_PROMPT: Array<ChatCompletionRequestMessage> = [
|
||||
{
|
||||
@@ -20,8 +20,8 @@ const INIT_MESSAGES_PROMPT: Array<ChatCompletionRequestMessage> = [
|
||||
}, use the present tense. ${
|
||||
config?.description
|
||||
? 'Add a short description of what commit is about after the commit message. Don\'t start it with "This commit", just describe the changes.'
|
||||
: 'Don\'t add any descriptions to the commit, only commit message.'
|
||||
} Use ${translation.localLanguage} to answer.}`
|
||||
: "Don't add any descriptions to the commit, only commit message."
|
||||
} Use ${translation.localLanguage} to answer.`
|
||||
},
|
||||
{
|
||||
role: ChatCompletionRequestMessageRoleEnum.User,
|
||||
|
||||
7
src/i18n/es_ES.json
Normal file
7
src/i18n/es_ES.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"localLanguage": "spanish",
|
||||
"commitFix": "fix(server.ts): cambiar la variable port de minúsculas a mayúsculas PORT",
|
||||
"commitFeat": "feat(server.ts): añadir soporte para la variable de entorno process.env.PORT",
|
||||
"commitDescription": "La variable port ahora se llama PORT, lo que mejora la coherencia con las convenciones de nomenclatura, ya que PORT es una constante. El soporte para una variable de entorno permite que la aplicación sea más flexible, ya que ahora puede ejecutarse en cualquier puerto disponible especificado a través de la variable de entorno process.env.PORT."
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ import ko from '../i18n/ko.json' assert { type: 'json' };
|
||||
import zh_CN from '../i18n/zh_CN.json' assert { type: 'json' };
|
||||
import zh_TW from '../i18n/zh_TW.json' assert { type: 'json' };
|
||||
import ja from '../i18n/ja.json' assert { type: 'json' };
|
||||
import pt_br from '../i18n/pt_br.json' assert { type: 'json' };
|
||||
import vi_VN from '../i18n/vi_VN.json' assert { type: 'json' };
|
||||
import es_ES from '../i18n/es_ES.json' assert { type: 'json' };
|
||||
|
||||
export enum I18nLocals {
|
||||
'en' = 'en',
|
||||
@@ -15,7 +18,9 @@ export enum I18nLocals {
|
||||
'de' = 'de',
|
||||
'fr' = 'fr',
|
||||
'it' = 'it',
|
||||
'ko' = 'ko'
|
||||
'ko' = 'ko',
|
||||
'pt_br' = 'pt_br',
|
||||
'es_ES' = 'es_ES'
|
||||
};
|
||||
|
||||
export const i18n = {
|
||||
@@ -27,6 +32,9 @@ export const i18n = {
|
||||
fr,
|
||||
it,
|
||||
ko,
|
||||
pt_br,
|
||||
vi_VN,
|
||||
es_ES
|
||||
};
|
||||
|
||||
export const I18N_CONFIG_ALIAS: { [key: string]: string[] } = {
|
||||
@@ -37,6 +45,10 @@ export const I18N_CONFIG_ALIAS: { [key: string]: string[] } = {
|
||||
de: ['de', 'German' ,'Deutsch'],
|
||||
fr: ['fr', 'French', 'française'],
|
||||
it: ['it', 'Italian', 'italiano'],
|
||||
pt_br: ['pt_br', 'Portuguese', 'português'],
|
||||
vi_VN: ['vi_VN', 'Vietnamese', 'tiếng Việt'],
|
||||
en: ['en', 'English', 'english'],
|
||||
es_ES: ['es_ES', 'Spanish', 'español'],
|
||||
};
|
||||
|
||||
export function getI18nLocal(value: string): string | boolean {
|
||||
|
||||
7
src/i18n/pt_br.json
Normal file
7
src/i18n/pt_br.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"localLanguage": "português",
|
||||
"commitFix": "fix(server.ts): altera o caso da variável de porta de port minúscula para PORT maiúscula",
|
||||
"commitFeat": "feat(server.ts): adiciona suporte para a variável de ambiente process.env.PORT",
|
||||
"commitDescription": "A variável de porta agora é denominada PORT, o que melhora a consistência com as convenções de nomenclatura, pois PORT é uma constante. O suporte para uma variável de ambiente permite que o aplicativo seja mais flexível, pois agora pode ser executado em qualquer porta disponível especificada por meio da variável de ambiente process.env.PORT."
|
||||
}
|
||||
|
||||
6
src/i18n/vi_VN.json
Normal file
6
src/i18n/vi_VN.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"localLanguage": "vietnamese",
|
||||
"commitFix": "fix(server.ts): thay đổi chữ viết thường của biến port thành chữ viết hoa PORT",
|
||||
"commitFeat": "feat(server.ts): thêm hỗ trợ cho biến môi trường process.env.PORT",
|
||||
"commitDescription": "Biến port đã được đổi tên thành PORT, giúp cải thiện tính nhất quán trong việc đặt tên theo quy ước vì PORT là một hằng số. Hỗ trợ cho biến môi trường cho phép ứng dụng linh hoạt hơn khi có thể chạy trên bất kỳ cổng nào được chỉ định thông qua biến môi trường process.env.PORT."
|
||||
}
|
||||
23
src/utils/checkIsLatestVersion.ts
Normal file
23
src/utils/checkIsLatestVersion.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { getOpenCommitLatestVersion } from '../api';
|
||||
import currentPackage from '../../package.json' assert { type: 'json' };
|
||||
import chalk from 'chalk';
|
||||
|
||||
export const checkIsLatestVersion = async () => {
|
||||
const latestVersion = await getOpenCommitLatestVersion();
|
||||
|
||||
if (latestVersion) {
|
||||
const currentVersion = currentPackage.version;
|
||||
|
||||
if (currentVersion !== latestVersion) {
|
||||
console.warn(
|
||||
chalk.yellow(
|
||||
`
|
||||
You are not using the latest stable version of OpenCommit with new features and bug fixes.
|
||||
Current version: ${currentVersion}. Latest version: ${latestVersion}.
|
||||
🚀 To update run: npm i -g opencommit@latest.
|
||||
`
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,7 @@
|
||||
import { execa } from 'execa';
|
||||
import { outro, spinner } from '@clack/prompts';
|
||||
import { readFileSync } from 'fs';
|
||||
import ignore, { Ignore } from 'ignore';
|
||||
|
||||
export const assertGitRepo = async () => {
|
||||
try {
|
||||
@@ -13,16 +15,40 @@ export const assertGitRepo = async () => {
|
||||
// (file) => `:(exclude)${file}`
|
||||
// );
|
||||
|
||||
export const getOpenCommitIgnore = (): Ignore => {
|
||||
const ig = ignore();
|
||||
|
||||
try {
|
||||
ig.add(readFileSync('.opencommitignore').toString().split('\n'));
|
||||
} catch (e) {}
|
||||
|
||||
return ig;
|
||||
};
|
||||
|
||||
export const getStagedFiles = async (): Promise<string[]> => {
|
||||
const { stdout: files } = await execa('git', [
|
||||
'diff',
|
||||
'--name-only',
|
||||
'--cached'
|
||||
const { stdout: gitDir } = await execa("git", [
|
||||
"rev-parse",
|
||||
"--show-toplevel"
|
||||
]);
|
||||
|
||||
const { stdout: files } = await execa("git", [
|
||||
"diff",
|
||||
"--name-only",
|
||||
"--cached",
|
||||
"--relative",
|
||||
gitDir
|
||||
]);
|
||||
|
||||
if (!files) return [];
|
||||
|
||||
return files.split('\n').sort();
|
||||
const filesList = files.split('\n');
|
||||
|
||||
const ig = getOpenCommitIgnore();
|
||||
const allowedFiles = filesList.filter((file) => !ig.ignores(file));
|
||||
|
||||
if (!allowedFiles) return [];
|
||||
|
||||
return allowedFiles.sort();
|
||||
};
|
||||
|
||||
export const getChangedFiles = async (): Promise<string[]> => {
|
||||
@@ -67,6 +93,7 @@ export const getDiff = async ({ files }: { files: string[] }) => {
|
||||
const { stdout: diff } = await execa('git', [
|
||||
'diff',
|
||||
'--staged',
|
||||
'--',
|
||||
...filesWithoutLocks
|
||||
]);
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ export function mergeStrings(arr: string[], maxStringLength: number): string[] {
|
||||
currentItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
mergedArr.push(currentItem);
|
||||
|
||||
return mergedArr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user