From 7ef777bb2bb2316d76246f05105d438e492ce3cd Mon Sep 17 00:00:00 2001 From: Olivers Vitins Date: Sat, 19 Aug 2023 22:33:29 +0300 Subject: [PATCH] feat!: use commander for command management from this commit npm package commander will be used for command management, making sub-commands possible, due to what commiting from now and on is called through rcz commit --- package.json | 5 +- pnpm-lock.yaml | 8 ++ src/index.ts | 300 +++++++++++++++++++++++++------------------------ 3 files changed, 167 insertions(+), 146 deletions(-) diff --git a/package.json b/package.json index a7dd55c..6e10d53 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@resultium/rcz", - "version": "1.0.0-alpha.1", - "description": "Resultium commit standardization library, based on commitizen", + "version": "1.0.0", + "description": "Resultium commit standardization library, based on conventional commits", "main": "./dist/index.js", "bin": { "rcz": "./dist/index.js" @@ -27,6 +27,7 @@ }, "dependencies": { "@clack/prompts": "^0.7.0", + "commander": "^11.0.0", "simple-git": "^3.19.1" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ddee204..a822a20 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ dependencies: '@clack/prompts': specifier: ^0.7.0 version: 0.7.0 + commander: + specifier: ^11.0.0 + version: 11.0.0 simple-git: specifier: ^3.19.1 version: 3.19.1 @@ -55,6 +58,11 @@ packages: resolution: {integrity: sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==} dev: true + /commander@11.0.0: + resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==} + engines: {node: '>=16'} + dev: false + /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} diff --git a/src/index.ts b/src/index.ts index e528b9c..c28288e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,7 @@ import fs from "fs"; import path from "path"; import { Config } from "./types"; import simpleGit from "simple-git"; +import { Command } from "commander"; const GetConfig = async () => { if (fs.existsSync(path.join(process.cwd(), ".rczrc"))) { @@ -26,153 +27,164 @@ const GetConfig = async () => { return null; } }; +const program = new Command(); -(async () => { - const config = await GetConfig(); +program + .name("rcz") + .description("Resultium commit standardization command-line interface") + .version("1.0.0"); - intro("Creating a conventional commit"); +program + .command("commit") + .description("Create a conventional commit") + .action(async () => { + const config = await GetConfig(); - if (!fs.existsSync(path.join(process.cwd(), ".git"))) { - cancel("Git repository has not been initialized"); - process.exit(0); - } + intro("Creating a conventional commit"); - const stageAll = await confirm({ - message: "Stage all changes?", - initialValue: true, + if (!fs.existsSync(path.join(process.cwd(), ".git"))) { + cancel("Git repository has not been initialized"); + process.exit(0); + } + + const stageAll = await confirm({ + message: "Stage all changes?", + initialValue: true, + }); + + if (isCancel(stageAll)) { + cancel("Commit creation cancelled"); + process.exit(0); + } + + const type: string | symbol = await select({ + message: "Choose a commit type", + options: config?.types || [ + { + label: "feat", + value: "feat", + hint: "new feature", + }, + { + label: "fix", + value: "fix", + hint: "bug fix", + }, + { + label: "build", + value: "build", + hint: "changes that affect the build system, configs or external dependencies (e.g. npm, .prettierrc)", + }, + { + label: "ci", + value: "ci", + hint: "change to CI/CD configurations and scripts (e.g. CircleCI, GitHub workflows)", + }, + { + label: "docs", + value: "docs", + hint: "documentation changes (e.g. README, CHANGELOG)", + }, + { + label: "perf", + value: "perf", + hint: "code change, that improves performance", + }, + { + label: "refactor", + value: "refactor", + hint: "code change that neither fixes a bug nor adds a feature", + }, + ], + }); + + if (isCancel(type)) { + cancel("Commit creation cancelled"); + process.exit(0); + } + + const scope: string | symbol = await text({ + message: "Input a scope (e.g. router, forms, core) or leave empty", + validate: (value) => { + if (config?.scopes && value) { + if (!config?.scopes.includes(value)) + return "This scope is not allowed by local configuration"; + } + }, + }); + + if (isCancel(scope)) { + cancel("Commit creation cancelled"); + process.exit(0); + } + + const message = await text({ + message: `Briefly describe made changes in imperative tense, maximum length 50`, + validate: (value) => { + if (value.length > 50) { + return "Your message is too long"; + } + }, + }); + + if (isCancel(message)) { + cancel("Commit creation cancelled"); + process.exit(0); + } + + const body = await text({ + message: `Insert a commit body, recommended length 100, can be left empty`, + }); + + if (isCancel(body)) { + cancel("Commit creation cancelled"); + process.exit(0); + } + + const isBreaking = await confirm({ + message: "Does this commit have breaking changes?", + initialValue: false, + }); + + if (isCancel(isBreaking)) { + cancel("Commit creation cancelled"); + process.exit(0); + } + + const resolvesIssue = await confirm({ + message: "Does this commit resolve an existing issue?", + initialValue: false, + }); + + if (isCancel(resolvesIssue)) { + cancel("Commit creation cancelled"); + process.exit(0); + } + + const issue = resolvesIssue + ? await text({ message: "Enter an issue identifier, e.g. #274" }) + : null; + + if (isCancel(issue)) { + cancel("Commit creation cancelled"); + process.exit(0); + } + + const commitMessage = `${type.toString()}${ + scope ? `(${scope.toString()})` : `` + }${isBreaking ? "!" : ""}: ${message.toString()}${ + resolvesIssue ? ` (${issue?.toString()})` : `` + }${body ? `\n\n${body}` : ``}`; + + if (stageAll) { + await simpleGit().add(".").commit(commitMessage); + } else { + await simpleGit().commit(commitMessage); + } + + note(commitMessage); + + outro("Finished creating a conventional commit, feel free to push"); }); - if (isCancel(stageAll)) { - cancel("Commit creation cancelled"); - process.exit(0); - } - - const type: string | symbol = await select({ - message: "Choose a commit type", - options: config?.types || [ - { - label: "feat", - value: "feat", - hint: "new feature", - }, - { - label: "fix", - value: "fix", - hint: "bug fix", - }, - { - label: "build", - value: "build", - hint: "changes that affect the build system, configs or external dependencies (e.g. npm, .prettierrc)", - }, - { - label: "ci", - value: "ci", - hint: "change to CI/CD configurations and scripts (e.g. CircleCI, GitHub workflows)", - }, - { - label: "docs", - value: "docs", - hint: "documentation changes (e.g. README, CHANGELOG)", - }, - { - label: "perf", - value: "perf", - hint: "code change, that improves performance", - }, - { - label: "refactor", - value: "refactor", - hint: "code change that neither fixes a bug nor adds a feature", - }, - ], - }); - - if (isCancel(type)) { - cancel("Commit creation cancelled"); - process.exit(0); - } - - const scope: string | symbol = await text({ - message: "Input a scope (e.g. router, forms, core) or leave empty", - validate: (value) => { - if (config?.scopes && value) { - if (!config?.scopes.includes(value)) - return "This scope is not allowed by local configuration"; - } - }, - }); - - if (isCancel(scope)) { - cancel("Commit creation cancelled"); - process.exit(0); - } - - const message = await text({ - message: `Briefly describe made changes in imperative tense, maximum length 50`, - validate: (value) => { - if (value.length > 50) { - return "Your message is too long"; - } - }, - }); - - if (isCancel(message)) { - cancel("Commit creation cancelled"); - process.exit(0); - } - - const body = await text({ - message: `Insert a commit body, recommended length 100, can be left empty`, - }); - - if (isCancel(body)) { - cancel("Commit creation cancelled"); - process.exit(0); - } - - const isBreaking = await confirm({ - message: "Does this commit have breaking changes?", - initialValue: false, - }); - - if (isCancel(isBreaking)) { - cancel("Commit creation cancelled"); - process.exit(0); - } - - const resolvesIssue = await confirm({ - message: "Does this commit resolve an existing issue?", - initialValue: false, - }); - - if (isCancel(resolvesIssue)) { - cancel("Commit creation cancelled"); - process.exit(0); - } - - const issue = resolvesIssue - ? await text({ message: "Enter an issue identifier, e.g. #274" }) - : null; - - if (isCancel(issue)) { - cancel("Commit creation cancelled"); - process.exit(0); - } - - const commitMessage = `${type.toString()}${ - scope ? `(${scope.toString()})` : `` - }${isBreaking ? "!" : ""}: ${message.toString()}${ - resolvesIssue ? ` (${issue?.toString()})` : `` - }${body ? `\n\n${body}` : ``}`; - - if (stageAll) { - await simpleGit().add(".").commit(commitMessage); - } else { - await simpleGit().commit(commitMessage); - } - - note(commitMessage); - - outro("Finished creating a conventional commit, feel free to push"); -})(); +program.parse();