diff --git a/packages/semver/src/generators/install/index.spec.ts b/packages/semver/src/generators/install/index.spec.ts index 97c801f63..d847e2b2e 100644 --- a/packages/semver/src/generators/install/index.spec.ts +++ b/packages/semver/src/generators/install/index.spec.ts @@ -3,6 +3,7 @@ import { readJson, writeJson, type Tree, + logger, } from '@nx/devkit'; import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import * as inquirer from 'inquirer'; @@ -17,6 +18,9 @@ const defaultOptions: SchemaOptions = { syncVersions: false, enforceConventionalCommits: true, projects: [], + skipInstall: false, + baseBranch: 'main', + preset: 'conventionalcommits', }; describe('@jscutlery/semver:install', () => { @@ -73,7 +77,7 @@ describe('@jscutlery/semver:install', () => { const lib1 = findJson(tree, projectName1, 'project.json'); const lib2 = findJson(tree, projectName2, 'project.json'); - expect(inquirer.prompt).toBeCalledWith( + expect(inquirer.prompt).toHaveBeenCalledWith( expect.objectContaining({ name: 'projects', type: 'checkbox', @@ -87,6 +91,7 @@ describe('@jscutlery/semver:install', () => { expect.objectContaining({ version: { executor: '@jscutlery/semver:version', + options: expect.toBeObject(), }, }), ); @@ -100,12 +105,13 @@ describe('@jscutlery/semver:install', () => { const lib1 = findJson(tree, projectName1, 'project.json'); const lib2 = findJson(tree, projectName2, 'project.json'); - expect(inquirer.prompt).not.toBeCalled(); + expect(inquirer.prompt).not.toHaveBeenCalled(); expect(lib1.targets.version).toBeUndefined(); expect(lib2.targets).toEqual( expect.objectContaining({ version: { executor: '@jscutlery/semver:version', + options: expect.toBeObject(), }, }), ); @@ -154,7 +160,10 @@ describe('@jscutlery/semver:install', () => { describe('--preset option', () => { it('should install conventional config', async () => { - await install(tree, { ...defaultOptions, preset: 'conventional' }); + await install(tree, { + ...defaultOptions, + preset: 'conventionalcommits', + }); const packageJson = readJson(tree, 'package.json'); const lib1 = findJson(tree, projectName1, 'project.json'); @@ -167,7 +176,9 @@ describe('@jscutlery/semver:install', () => { expect.objectContaining({ version: { executor: '@jscutlery/semver:version', - options: expect.objectContaining({ preset: 'conventional' }), + options: expect.objectContaining({ + preset: 'conventionalcommits', + }), }, }), ); @@ -194,7 +205,10 @@ describe('@jscutlery/semver:install', () => { }); it('should install angular config', async () => { - await install(tree, { ...defaultOptions, preset: 'conventional' }); + await install(tree, { + ...defaultOptions, + preset: 'conventionalcommits', + }); const lib1 = findJson(tree, projectName1, 'project.json'); @@ -202,14 +216,16 @@ describe('@jscutlery/semver:install', () => { expect.objectContaining({ version: { executor: '@jscutlery/semver:version', - options: expect.objectContaining({ preset: 'conventional' }), + options: expect.objectContaining({ + preset: 'conventionalcommits', + }), }, }), ); }); it('extends conventional commitlint config', async () => { - await install(tree, { ...options, preset: 'conventional' }); + await install(tree, { ...options, preset: 'conventionalcommits' }); const commitlintConfig = readJson(tree, '.commitlintrc.json'); @@ -237,6 +253,21 @@ describe('@jscutlery/semver:install', () => { preset: 'angular', }; + it('skip if config not found', async () => { + const warnSpy = jest.spyOn(logger, 'warn').mockImplementation(); + + await install(tree, { ...options, preset: 'atom' }); + + const packageJson = readJson(tree, 'package.json'); + expect(packageJson.devDependencies).not.toContainKeys([ + '@commitlint/cli', + 'husky', + ]); + expect(tree.exists('.commitlintrc.json')).toBeFalse(); + expect(tree.exists('.husky')).toBeFalse(); + expect(warnSpy).toHaveBeenCalled(); + }); + it('add commitlint to package.json devDepencencies', async () => { await install(tree, options); diff --git a/packages/semver/src/generators/install/schema.ts b/packages/semver/src/generators/install/schema.ts index aba029876..88e808489 100644 --- a/packages/semver/src/generators/install/schema.ts +++ b/packages/semver/src/generators/install/schema.ts @@ -2,10 +2,10 @@ import type { Preset } from '../../executors/common/preset'; export interface SchemaOptions { syncVersions: boolean; - baseBranch?: string; + baseBranch: string; projects?: string[]; - enforceConventionalCommits?: boolean; - skipInstall?: boolean; + enforceConventionalCommits: boolean; + skipInstall: boolean; commitMessageFormat?: string; - preset?: Preset; + preset: Preset; } diff --git a/packages/semver/src/generators/install/utils/dependencies.ts b/packages/semver/src/generators/install/utils/dependencies.ts index a7f26d294..2227f0c10 100644 --- a/packages/semver/src/generators/install/utils/dependencies.ts +++ b/packages/semver/src/generators/install/utils/dependencies.ts @@ -3,6 +3,7 @@ import { readJson, updateJson, type Tree, + logger, } from '@nx/devkit'; import { constants } from 'fs'; import type { SchemaOptions } from '../schema'; @@ -21,6 +22,15 @@ export interface PackageJsonPart { export function addDependencies(tree: Tree, options: SchemaOptions) { if (options.enforceConventionalCommits) { + const preset = _getCommitlintConfig(options); + + if (preset === null) { + logger.warn( + `No commitlint config found for ${options.preset} preset, --enforceConventionalCommits option ignored.`, + ); + return tree; + } + _addCommitlintConfig(tree, options); _addHuskyConfig(tree); _addHuskyConfigMsg(tree); @@ -35,7 +45,8 @@ function _addDevDependencies(tree: Tree, options: SchemaOptions) { {}, { '@commitlint/cli': '^17.0.0', - [_getCommitlintConfig(options)]: '^17.0.0', + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + [_getCommitlintConfig(options)!]: '^17.0.0', husky: '^8.0.0', }, ); @@ -58,7 +69,8 @@ function _addCommitlintConfig(tree: Tree, options: SchemaOptions) { '.commitlintrc.json', JSON.stringify( { - extends: [_getCommitlintConfig(options)], + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + extends: [_getCommitlintConfig(options)!], rules: {}, }, null, @@ -98,8 +110,13 @@ function _addHuskyConfigMsg(tree: Tree) { } } -function _getCommitlintConfig(options: SchemaOptions) { - return options.preset === 'angular' - ? '@commitlint/config-angular' - : '@commitlint/config-conventional'; +function _getCommitlintConfig(options: SchemaOptions): string | null { + switch (options.preset) { + case 'angular': + return '@commitlint/config-angular'; + case 'conventionalcommits': + return '@commitlint/config-conventional'; + default: + return null; + } }