From 253640227a2b71044bc7337e114a78ab56962c43 Mon Sep 17 00:00:00 2001 From: Patrick Sullivan Date: Fri, 10 Jan 2025 18:27:56 +0000 Subject: [PATCH] feat(git-tools): Added custom commit linting logic --- packages/git-tools/package.json | 4 +- packages/git-tools/src/commitlint/config.ts | 17 ++ packages/git-tools/src/commitlint/lint.ts | 187 ++++++++++++++++++++ packages/git-tools/src/commitlint/run.ts | 47 ++--- packages/git-tools/src/types.ts | 40 ++++- packages/git-tools/tsup.bin.ts | 2 +- pnpm-lock.yaml | 99 ++--------- 7 files changed, 277 insertions(+), 119 deletions(-) create mode 100644 packages/git-tools/src/commitlint/lint.ts diff --git a/packages/git-tools/package.json b/packages/git-tools/package.json index 094314b50..076e65af3 100755 --- a/packages/git-tools/package.json +++ b/packages/git-tools/package.json @@ -1,6 +1,7 @@ { "name": "@storm-software/git-tools", "version": "2.79.1", + "type": "module", "description": "Tools for managing Git repositories within a Nx workspace.", "repository": { "type": "github", @@ -244,7 +245,7 @@ "tsconfig-paths": "4.2.0" }, "devDependencies": { - "@commitlint/lint": "^19.6.0", + "@commitlint/rules": "^19.6.0", "@humanfs/core": "^0.19.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/retry": "0.4.1", @@ -272,6 +273,7 @@ "chalk": "catalog:", "chalk-template": "1.1.0", "commander": "catalog:", + "conventional-commits-parser": "^6.0.0", "defu": "catalog:", "htmlparser2": "10.0.0", "jsonc-parser": "3.2.1", diff --git a/packages/git-tools/src/commitlint/config.ts b/packages/git-tools/src/commitlint/config.ts index 74c232398..2284f9111 100644 --- a/packages/git-tools/src/commitlint/config.ts +++ b/packages/git-tools/src/commitlint/config.ts @@ -29,3 +29,20 @@ export const DEFAULT_COMMIT_RULES: DefaultCommitRulesEnum = { "scope-case": [RuleConfigSeverity.Error, "always", ["kebab-case"]], "scope-empty": [RuleConfigSeverity.Error, "never"] }; + +export const DEFAULT_COMMITLINT_CONFIG = { + rules: DEFAULT_COMMIT_RULES, + helpUrl: "https://stormsoftware.com/ops/commitlint", + parserOpts: { + headerPattern: /^(\w*)(?:\((.*)\))?!?: (.*)$/, + breakingHeaderPattern: /^(\w*)(?:\((.*)\))?!: (.*)$/, + headerCorrespondence: ["type", "scope", "subject"], + noteKeywords: ["BREAKING CHANGE", "BREAKING-CHANGE"], + revertPattern: + /^(?:Revert|revert:)\s"?([\s\S]+?)"?\s*This reverts commit (\w*)\./i, + revertCorrespondence: ["header", "hash"], + issuePrefixes: ["#"] + } +}; + +export type CommitLintOptions = typeof DEFAULT_COMMITLINT_CONFIG; diff --git a/packages/git-tools/src/commitlint/lint.ts b/packages/git-tools/src/commitlint/lint.ts new file mode 100644 index 000000000..2b5976a6a --- /dev/null +++ b/packages/git-tools/src/commitlint/lint.ts @@ -0,0 +1,187 @@ +import defaultRules from "@commitlint/rules"; +import { CommitParser } from "conventional-commits-parser"; +import util from "util"; +import { + CommitLintOutcome, + CommitLintRuleOutcome, + DefaultCommitRulesEnum, + RuleConfigSeverity +} from "../types"; +import { CommitLintOptions, DEFAULT_COMMITLINT_CONFIG } from "./config"; + +interface CommitMessageData { + header: string | null; + body?: string | null; + footer?: string | null; +} + +const buildCommitMessage = ({ + header, + body, + footer +}: CommitMessageData): string => { + let message = header; + + message = body ? `${message}\n\n${body}` : message; + message = footer ? `${message}\n\n${footer}` : message; + + return message || ""; +}; + +export default async function lint( + message: string, + rawRulesConfig?: DefaultCommitRulesEnum, + rawOpts?: { + parserOpts?: CommitLintOptions["parserOpts"]; + helpUrl?: CommitLintOptions["helpUrl"]; + } +): Promise { + const rulesConfig = rawRulesConfig || {}; + + const parser = new CommitParser( + rawOpts?.parserOpts ?? DEFAULT_COMMITLINT_CONFIG.parserOpts + ); + const parsed = parser.parse(message); + + if ( + parsed.header === null && + parsed.body === null && + parsed.footer === null + ) { + // Commit is empty, skip + return { + valid: true, + errors: [], + warnings: [], + input: message + }; + } + + const allRules: Map = new Map(Object.entries(defaultRules)); + + // Find invalid rules configs + const missing = Object.keys(rulesConfig).filter( + name => typeof allRules.get(name) !== "function" + ); + + if (missing.length > 0) { + const names = [...allRules.keys()]; + throw new RangeError( + [ + `Found rules without implementation: ${missing.join(", ")}.`, + `Supported rules are: ${names.join(", ")}.` + ].join("\n") + ); + } + + const invalid = Object.entries(rulesConfig) + .map(([name, config]) => { + if (!Array.isArray(config)) { + return new Error( + `config for rule ${name} must be array, received ${util.inspect( + config + )} of type ${typeof config}` + ); + } + + const [level] = config; + + if (level === RuleConfigSeverity.Disabled && config.length === 1) { + return null; + } + + const [, when] = config; + + if (typeof level !== "number" || isNaN(level)) { + return new Error( + `level for rule ${name} must be number, received ${util.inspect( + level + )} of type ${typeof level}` + ); + } + + if (config.length < 2 || config.length > 3) { + return new Error( + `config for rule ${name} must be 2 or 3 items long, received ${util.inspect( + config + )} of length ${config.length}` + ); + } + + if (level < 0 || level > 2) { + return new RangeError( + `level for rule ${name} must be between 0 and 2, received ${util.inspect( + level + )}` + ); + } + + if (typeof when !== "string") { + return new Error( + `condition for rule ${name} must be string, received ${util.inspect( + when + )} of type ${typeof when}` + ); + } + + if (when !== "never" && when !== "always") { + return new Error( + `condition for rule ${name} must be "always" or "never", received ${util.inspect( + when + )}` + ); + } + + return null; + }) + .filter((item): item is Error => item instanceof Error); + + if (invalid.length > 0) { + throw new Error(invalid.map(i => i.message).join("\n")); + } + + // Validate against all rules + const pendingResults = Object.entries(rulesConfig as DefaultCommitRulesEnum) + // Level 0 rules are ignored + .filter(([, config]) => !!config && config.length && config[0] > 0) + .map(async entry => { + const [name, config] = entry; + const [level, when, value] = config!; // + + const rule = allRules.get(name); + + if (!rule) { + throw new Error(`Could not find rule implementation for ${name}`); + } + + const executableRule = rule as any; + const [valid, message] = await executableRule(parsed, when, value); + + return { + level, + valid, + name, + message + }; + }); + + const results = (await Promise.all(pendingResults)).filter( + (result): result is CommitLintRuleOutcome => result !== null + ); + + const errors = results.filter( + result => result.level === RuleConfigSeverity.Error && !result.valid + ); + const warnings = results.filter( + result => result.level === RuleConfigSeverity.Warning && !result.valid + ); + + const valid = errors.length === 0; + + return { + valid, + errors, + warnings, + input: buildCommitMessage(parsed) + }; +} diff --git a/packages/git-tools/src/commitlint/run.ts b/packages/git-tools/src/commitlint/run.ts index 4f5b3c90f..04161984b 100644 --- a/packages/git-tools/src/commitlint/run.ts +++ b/packages/git-tools/src/commitlint/run.ts @@ -6,11 +6,13 @@ import { writeWarning } from "@storm-software/config-tools"; import { StormConfig } from "@storm-software/config/types"; +import defu from "defu"; import { existsSync } from "fs"; import { readFile } from "fs/promises"; import childProcess from "node:child_process"; import { DEFAULT_COMMIT_TYPES } from "../types"; -import { DEFAULT_COMMIT_RULES } from "./config"; +import { DEFAULT_COMMITLINT_CONFIG } from "./config"; +import lint from "./lint"; import { getNxScopes, getRuleFromScopeEnum } from "./scope"; const COMMIT_EDITMSG_PATH = ".git/COMMIT_EDITMSG"; @@ -90,45 +92,46 @@ export const runCommitLint = async ( const allowedTypes = Object.keys(DEFAULT_COMMIT_TYPES).join("|"); const allowedScopes = await getNxScopes(); + // eslint-disable-next-line no-useless-escape const commitMsgRegex = `(${allowedTypes})\\((${allowedScopes})\\)!?:\\s(([a-z0-9:\-\s])+)`; - const matchCommit = new RegExp(commitMsgRegex, "g").test(commitMessage); - const matchRevert = /Revert/gi.test(commitMessage); - const matchRelease = /Release/gi.test(commitMessage); - const lint = (await import("@commitlint/lint")).default; + const commitlintConfig = defu( + params.config ?? {}, + { rules: { "scope-enum": getRuleFromScopeEnum(allowedScopes) } }, + DEFAULT_COMMITLINT_CONFIG + ); - const report = await lint(commitMessage, { - ...DEFAULT_COMMIT_RULES, - "scope-enum": getRuleFromScopeEnum(allowedScopes) - } as any); + const report = await lint(commitMessage, commitlintConfig.rules, { + parserOpts: commitlintConfig.parserOpts, + helpUrl: commitlintConfig.helpUrl + }); - if ( - +!(matchRelease || matchRevert || matchCommit) === 0 || - report.errors.length || - report.warnings.length - ) { + if (!matchCommit || report.errors.length || report.warnings.length) { writeSuccess(`Commit was processing completed successfully!`, config); } else { let errorMessage = - " Oh no! 😦 Your commit message: \n" + + " Oh no! Your commit message: \n" + "-------------------------------------------------------------------\n" + commitMessage + "\n-------------------------------------------------------------------" + - "\n\n 👉️ Does not follow the commit message convention specified in the CONTRIBUTING.MD file."; + "\n\n Does not follow the commit message convention specified by Storm Software."; errorMessage += "\ntype(scope): subject \n BLANK LINE \n body"; errorMessage += "\n"; - errorMessage += `\npossible types: ${allowedTypes}`; - errorMessage += `\npossible scopes: ${allowedScopes} (if unsure use "core")`; + errorMessage += `\nPossible types: ${allowedTypes}`; + errorMessage += `\nPossible scopes: ${allowedScopes} (if unsure use "monorepo")`; errorMessage += - "\nEXAMPLE: \n" + - "feat(nx): add an option to generate lazy-loadable modules\n" + - "fix(core)!: breaking change should have exclamation mark\n"; + "\n\nEXAMPLE: \n" + + "feat(my-lib): add an option to generate lazy-loadable modules\n" + + "fix(monorepo)!: breaking change should have exclamation mark\n"; errorMessage += `\n\nCommitLint Errors: ${report.errors.length ? report.errors.map(error => ` - ${error.message}`).join("\n") : "None"}`; errorMessage += `\nCommitLint Warnings: ${report.warnings.length ? report.warnings.map(warning => ` - ${warning.message}`).join("\n") : "None"}`; - errorMessage += "\n\nPlease fix the commit message and try again."; + errorMessage += "\n\nPlease fix the commit message and rerun storm-commit."; + errorMessage += `\n\nMore details about the Storm Software commit message specification can be found at: ${commitlintConfig.helpUrl}`; throw new Error(errorMessage); } + + return report.input; }; diff --git a/packages/git-tools/src/types.ts b/packages/git-tools/src/types.ts index 644e02f07..e74cd40c9 100644 --- a/packages/git-tools/src/types.ts +++ b/packages/git-tools/src/types.ts @@ -118,11 +118,11 @@ export const DEFAULT_COMMIT_TYPES = { }, revert: { description: "Revert a previously committed change", - title: "Rollback", + title: "Revert", emoji: "🗑️ ", semverBump: "patch", changelog: { - title: "Rollbacks", + title: "Reverts", hidden: false } }, @@ -308,6 +308,13 @@ export type CommitSettingsEnum = Record & { format: string; }; +export type RuleConfigCondition = "always" | "never"; +export enum RuleConfigSeverity { + Disabled = 0, + Warning = 1, + Error = 2 +} + export type CommitRulesEnum = Record< string, | [RuleConfigSeverity, RuleConfigCondition] @@ -353,13 +360,6 @@ export type CommitConfig< questions: TCommitQuestionEnum; }; -export type RuleConfigCondition = "always" | "never"; -export enum RuleConfigSeverity { - Disabled = 0, - Warning = 1, - Error = 2 -} - export type DefaultResolvedCommitRulesEnum = DefaultCommitRulesEnum & { "scope-enum": ( ctx: any @@ -403,6 +403,28 @@ export type CommitState< root: string; }; +export interface CommitLintRuleOutcome { + /** If the commit is considered valid for the rule */ + valid: boolean; + /** The "severity" of the rule (1 = warning, 2 = error) */ + level: RuleConfigSeverity; + /** The name of the rule */ + name: string; + /** The message returned from the rule, if invalid */ + message: string; +} + +export interface CommitLintOutcome { + /** The linted commit, as string */ + input: string; + /** If the linted commit is considered valid */ + valid: boolean; + /** All errors, per rule, for the commit */ + errors: CommitLintRuleOutcome[]; + /** All warnings, per rule, for the commit */ + warnings: CommitLintRuleOutcome[]; +} + export type ReleaseConfig = any & { npm: boolean; github: boolean; diff --git a/packages/git-tools/tsup.bin.ts b/packages/git-tools/tsup.bin.ts index c29adf8d7..74d3d1132 100644 --- a/packages/git-tools/tsup.bin.ts +++ b/packages/git-tools/tsup.bin.ts @@ -16,6 +16,6 @@ export default defineConfig([ tsconfig: "./tsconfig.json", shims: true, skipNodeModulesBundle: false, - noExternal: ["@commitlint/lint", "defu"] + noExternal: ["@commitlint/rules", "conventional-commits-parser", "defu"] } ]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a86d986c..12e9970cf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -640,7 +640,7 @@ importers: specifier: 4.2.0 version: 4.2.0 devDependencies: - '@commitlint/lint': + '@commitlint/rules': specifier: ^19.6.0 version: 19.6.0 '@humanfs/core': @@ -724,6 +724,9 @@ importers: commander: specifier: 'catalog:' version: 12.1.0 + conventional-commits-parser: + specifier: ^6.0.0 + version: 6.0.0 defu: specifier: 'catalog:' version: 6.1.4 @@ -2348,22 +2351,10 @@ packages: resolution: {integrity: sha512-Kv0pYZeMrdg48bHFEU5KKcccRfKmISSm9MvgIgkpI6m+ohFTB55qZlBW6eYqh/XDfRuIO0x4zSmvBjmOwWTwkg==} engines: {node: '>=v18'} - '@commitlint/is-ignored@19.6.0': - resolution: {integrity: sha512-Ov6iBgxJQFR9koOupDPHvcHU9keFupDgtB3lObdEZDroiG4jj1rzky60fbQozFKVYRTUdrBGICHG0YVmRuAJmw==} - engines: {node: '>=v18'} - - '@commitlint/lint@19.6.0': - resolution: {integrity: sha512-LRo7zDkXtcIrpco9RnfhOKeg8PAnE3oDDoalnrVU/EVaKHYBWYL1DlRR7+3AWn0JiBqD8yKOfetVxJGdEtZ0tg==} - engines: {node: '>=v18'} - '@commitlint/message@19.5.0': resolution: {integrity: sha512-R7AM4YnbxN1Joj1tMfCyBryOC5aNJBdxadTZkuqtWi3Xj0kMdutq16XQwuoGbIzL2Pk62TALV1fZDCv36+JhTQ==} engines: {node: '>=v18'} - '@commitlint/parse@19.5.0': - resolution: {integrity: sha512-cZ/IxfAlfWYhAQV0TwcbdR1Oc0/r0Ik1GEessDJ3Lbuma/MRO8FRQX76eurcXtmhJC//rj52ZSZuXUg0oIX0Fw==} - engines: {node: '>=v18'} - '@commitlint/rules@19.6.0': resolution: {integrity: sha512-1f2reW7lbrI0X0ozZMesS/WZxgPa4/wi56vFuJENBmed6mWq5KsheN/nxqnl/C23ioxpPO/PL6tXpiiFy5Bhjw==} engines: {node: '>=v18'} @@ -5637,9 +5628,6 @@ packages: array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - array-ify@1.0.0: - resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - array-includes@3.1.8: resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} engines: {node: '>= 0.4'} @@ -6267,9 +6255,6 @@ packages: commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - compare-func@2.0.0: - resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} @@ -6318,13 +6303,9 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} - conventional-changelog-angular@7.0.0: - resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} - engines: {node: '>=16'} - - conventional-commits-parser@5.0.0: - resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} - engines: {node: '>=16'} + conventional-commits-parser@6.0.0: + resolution: {integrity: sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==} + engines: {node: '>=18'} hasBin: true convert-source-map@2.0.0: @@ -6859,10 +6840,6 @@ packages: domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - dot-prop@5.3.0: - resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} - engines: {node: '>=8'} - dot-prop@6.0.1: resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} engines: {node: '>=10'} @@ -8512,10 +8489,6 @@ packages: resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} engines: {node: '>= 0.4'} - is-text-path@2.0.0: - resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} - engines: {node: '>=8'} - is-typed-array@1.1.15: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} @@ -9433,9 +9406,9 @@ packages: resolution: {integrity: sha512-Cl0yeeIrko6d94KpUo1M+0X1sB14ikoaqlIGuTH1fW4I+E3+YljL54/hb/BWmVfrV9tTV9zU04+xjw08Fh2WkA==} engines: {node: '>=14.16'} - meow@12.1.1: - resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} - engines: {node: '>=16.10'} + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} + engines: {node: '>=18'} merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} @@ -12296,10 +12269,6 @@ packages: text-decoder@1.2.3: resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} - text-extensions@2.4.0: - resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} - engines: {node: '>=8'} - thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -14947,26 +14916,8 @@ snapshots: lodash.startcase: 4.4.0 lodash.upperfirst: 4.3.1 - '@commitlint/is-ignored@19.6.0': - dependencies: - '@commitlint/types': 19.5.0 - semver: 7.6.2 - - '@commitlint/lint@19.6.0': - dependencies: - '@commitlint/is-ignored': 19.6.0 - '@commitlint/parse': 19.5.0 - '@commitlint/rules': 19.6.0 - '@commitlint/types': 19.5.0 - '@commitlint/message@19.5.0': {} - '@commitlint/parse@19.5.0': - dependencies: - '@commitlint/types': 19.5.0 - conventional-changelog-angular: 7.0.0 - conventional-commits-parser: 5.0.0 - '@commitlint/rules@19.6.0': dependencies: '@commitlint/ensure': 19.5.0 @@ -19004,8 +18955,6 @@ snapshots: array-flatten@1.1.1: {} - array-ify@1.0.0: {} - array-includes@3.1.8: dependencies: call-bind: 1.0.8 @@ -19729,11 +19678,6 @@ snapshots: commondir@1.0.1: {} - compare-func@2.0.0: - dependencies: - array-ify: 1.0.0 - dot-prop: 5.3.0 - compressible@2.0.18: dependencies: mime-db: 1.53.0 @@ -19798,16 +19742,9 @@ snapshots: content-type@1.0.5: {} - conventional-changelog-angular@7.0.0: + conventional-commits-parser@6.0.0: dependencies: - compare-func: 2.0.0 - - conventional-commits-parser@5.0.0: - dependencies: - JSONStream: 1.3.5 - is-text-path: 2.0.0 - meow: 12.1.1 - split2: 4.2.0 + meow: 13.2.0 convert-source-map@2.0.0: {} @@ -20430,10 +20367,6 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 - dot-prop@5.3.0: - dependencies: - is-obj: 2.0.0 - dot-prop@6.0.1: dependencies: is-obj: 2.0.0 @@ -22572,10 +22505,6 @@ snapshots: has-symbols: 1.1.0 safe-regex-test: 1.1.0 - is-text-path@2.0.0: - dependencies: - text-extensions: 2.4.0 - is-typed-array@1.1.15: dependencies: which-typed-array: 1.1.18 @@ -23964,7 +23893,7 @@ snapshots: type-fest: 3.13.1 yargs-parser: 21.1.1 - meow@12.1.1: {} + meow@13.2.0: {} merge-descriptors@1.0.1: {} @@ -27595,8 +27524,6 @@ snapshots: dependencies: b4a: 1.6.7 - text-extensions@2.4.0: {} - thenify-all@1.6.0: dependencies: thenify: 3.3.1