Skip to content

Commit

Permalink
refactor(cli): global options
Browse files Browse the repository at this point in the history
* testing, lint, mock objects
* cli, set options
* cmds, files, parse, global options
* index, global options, settings
  • Loading branch information
cdcabrera committed Dec 23, 2022
1 parent 64b13ab commit 6379124
Show file tree
Hide file tree
Showing 14 changed files with 251 additions and 154 deletions.
12 changes: 6 additions & 6 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@
"plugins": ["jest"],
"extends": [
"plugin:jest/recommended"
],
"globals": {
"_COMMIT_CHANGELOG_CONTEXT_ROOT": "readonly",
"generateFixture": "readonly",
"setMockResourceFunctions": "readonly"
}
]
}
],
"parserOptions": {
"ecmaVersion": 2022
},
"globals": {
"generateFixture": "readonly",
"mockObjectProperty": "readonly",
"setMockResourceFunctions": "readonly"
},
"rules": {
"arrow-parens": ["error", "as-needed"],
"comma-dangle": 0,
Expand Down
52 changes: 27 additions & 25 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const yargs = require('yargs');
const packageJson = require('../package');
const { commitChangelog } = require('../src');
const { commitChangelog, OPTIONS } = require('../src');

/**
* Setup yargs
Expand Down Expand Up @@ -77,30 +77,32 @@ const {
type: 'string'
}).argv;

/**
* Set global OPTIONS
*
* @type {{comparePath: string, date: string, commitPath: string, isOverrideVersion: boolean,
* isAllowNonConventionalCommits: boolean, isDryRun: boolean,
* remoteUrl: string, prPath: string, isCommit: boolean, overrideVersion: string|*}}
* @private
*/
OPTIONS._set = {
commitPath,
comparePath,
date,
isAllowNonConventionalCommits,
isDryRun,
isCommit,
isOverrideVersion: overrideVersion !== undefined,
overrideVersion,
prPath,
remoteUrl
};

/**
* If testing stop here, otherwise continue.
*/
if (process.env.NODE_ENV === 'test') {
process.stdout.write(
JSON.stringify({
commitPath,
comparePath,
date,
isAllowNonConventionalCommits,
isDryRun,
isCommit,
overrideVersion,
prPath,
remoteUrl
})
);
process.stdout.write(JSON.stringify(OPTIONS));
} else {
commitChangelog({
commitPath,
comparePath,
date,
isAllowNonConventionalCommits,
isDryRun,
isCommit,
overrideVersion,
prPath,
remoteUrl
});
commitChangelog();
}
28 changes: 26 additions & 2 deletions jest.setupTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ const { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } = require('
const crypto = require('crypto');
const { extname, join, resolve } = require('path');

global._COMMIT_CHANGELOG_CONTEXT_PATH = join('..', 'src', '__fixtures__');

jest.mock('child_process', () => ({
...jest.requireActual('child_process'),
execSync: (...args) => `<execSync>${JSON.stringify(args)}</execSync>`
Expand Down Expand Up @@ -84,3 +82,29 @@ const setMockResourceFunctions = mockFunctions => {
};

global.setMockResourceFunctions = setMockResourceFunctions;

/**
* Mock object properties, restore with callback, mockClear.
* A consistent object property mock for scenarios where the property is not a function/Jest fails.
*
* @param {object} object
* @param {object} propertiesValues
* @returns {{mockClear: Function}}
*/
const mockObjectProperty = (object = {}, propertiesValues) => {
const updatedObject = object;
const originalPropertiesValues = {};

Object.entries(propertiesValues).forEach(([key, value]) => {
originalPropertiesValues[key] = updatedObject[key];
updatedObject[key] = value;
});

return {
mockClear: () => {
Object.assign(updatedObject, originalPropertiesValues);
}
};
};

global.mockObjectProperty = mockObjectProperty;
14 changes: 14 additions & 0 deletions src/__tests__/__snapshots__/global.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

exports[`Global should return specific properties: specific properties 1`] = `
{
"OPTIONS": {
"_set": undefined,
"contextPath": "../src/__fixtures__",
},
"color": {
"BLACK": "",
"BLUE": "",
Expand Down Expand Up @@ -81,3 +85,13 @@ exports[`Global should return specific properties: specific properties 1`] = `
},
}
`;

exports[`Global should set a one-time mutable OPTIONS object: immutable 1`] = `
{
"OPTIONS": {
"contextPath": "../src/__fixtures__",
"lorem": "ipsum",
},
"isFrozen": true,
}
`;
32 changes: 22 additions & 10 deletions src/__tests__/files.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,17 @@ describe('Files', () => {
});

expect(
updateChangelog(commitObj, '1.0.0', {
date: '2022-10-01',
getComparisonCommitHashes: () => comparisonObjNoReleaseCommit,
getRemoteUrls: () => urlObj
})
updateChangelog(
commitObj,
'1.0.0',
{
date: '2022-10-01'
},
{
getComparisonCommitHashes: () => comparisonObjNoReleaseCommit,
getRemoteUrls: () => urlObj
}
)
).toMatchSnapshot('urls and paths, no release commit');

const comparisonObjReleaseCommit = getComparisonCommitHashes({
Expand All @@ -49,11 +55,17 @@ describe('Files', () => {
});

expect(
updateChangelog(commitObj, '1.0.0', {
date: '2022-10-01',
getComparisonCommitHashes: () => comparisonObjReleaseCommit,
getRemoteUrls: () => urlObj
})
updateChangelog(
commitObj,
'1.0.0',
{
date: '2022-10-01'
},
{
getComparisonCommitHashes: () => comparisonObjReleaseCommit,
getRemoteUrls: () => urlObj
}
)
).toMatchSnapshot('urls and paths, release commit');
});

Expand Down
9 changes: 9 additions & 0 deletions src/__tests__/global.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,13 @@ describe('Global', () => {
it('should return specific properties', () => {
expect(global).toMatchSnapshot('specific properties');
});

it('should set a one-time mutable OPTIONS object', () => {
const { OPTIONS } = global;
OPTIONS._set = { lorem: 'ipsum' };
OPTIONS.lorem = 'hello world';
OPTIONS.dolor = 'sit';

expect({ isFrozen: Object.isFrozen(OPTIONS), OPTIONS }).toMatchSnapshot('immutable');
});
});
19 changes: 15 additions & 4 deletions src/__tests__/index.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
const { commitChangelog } = require('../index');
const { OPTIONS } = require('../global');

describe('Commit Changelog', () => {
it('should parse commits to produce a CHANGELOG.md', () => {
expect(commitChangelog({ date: new Date('2022-10-01').toISOString() })).toMatchSnapshot('Commit Changelog');
const { mockClear } = mockObjectProperty(OPTIONS, { date: new Date('2022-10-01').toISOString() });

expect(commitChangelog()).toMatchSnapshot('Commit Changelog');

mockClear();
});

it('should parse commits to produce a CHANGELOG.md with an override version', () => {
expect(commitChangelog({ overrideVersion: '15.0.0', date: new Date('2022-10-01').toISOString() })).toMatchSnapshot(
'override'
);
const { mockClear } = mockObjectProperty(OPTIONS, {
date: new Date('2022-10-01').toISOString(),
isOverrideVersion: true,
overrideVersion: '15.0.0'
});

expect(commitChangelog()).toMatchSnapshot('override');

mockClear();
});
});
20 changes: 12 additions & 8 deletions src/__tests__/parse.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,16 @@ describe('Parse', () => {
const commitMessageNonCC = '1f12345b597123453031234555b6d25574ccacee Initial commit';

expect({
refactor: formatChangelogMessage(parseCommitMessage(commitMessageRefactor), {
getRemoteUrls: () => ({
commitUrl: 'https://localhost/lorem/ipsum/commitsmock/',
prUrl: 'https://localhost/lorem/ipsum/prmock/'
})
}),
refactor: formatChangelogMessage(
parseCommitMessage(commitMessageRefactor),
{},
{
getRemoteUrls: () => ({
commitUrl: 'https://localhost/lorem/ipsum/commitsmock/',
prUrl: 'https://localhost/lorem/ipsum/prmock/'
})
}
),
feat: formatChangelogMessage(parseCommitMessage(commitMessageFeature)),
general: formatChangelogMessage(parseCommitMessage(commitMessageNonCC))
}).toMatchSnapshot('formatChangelogMessages');
Expand Down Expand Up @@ -87,8 +91,8 @@ describe('Parse', () => {
{ getGit: () => commitLog }
);
const generalCommitsObj = parseCommits(
{ remoteUrl: 'https://localhost/lorem/ipsum' },
{ getGit: () => commitLog, isAllowNonConventionalCommits: true }
{ isAllowNonConventionalCommits: true, remoteUrl: 'https://localhost/lorem/ipsum' },
{ getGit: () => commitLog }
);

expect({
Expand Down
40 changes: 20 additions & 20 deletions src/cmds.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ const { execSync } = require('child_process');
const { join } = require('path');
const semverClean = require('semver/functions/clean');
const semverInc = require('semver/functions/inc');
const { color } = require('./global');
const { _COMMIT_CHANGELOG_CONTEXT_PATH: CONTEXT_PATH } = global;
const { color, OPTIONS } = require('./global');
/**
* Execute a command
*
* @param {string} cmd
* @param {object} options
* @param {string} options.errorMessage
* @param {object} settings
* @param {string} settings.errorMessage
* @returns {string}
*/
const runCmd = (cmd, { errorMessage = 'Skipping... {0}' } = {}) => {
Expand All @@ -33,7 +32,7 @@ const runCmd = (cmd, { errorMessage = 'Skipping... {0}' } = {}) => {
* @param {string} options.releaseTypeScope
* @returns {string}
*/
const commitFiles = (version, { contextPath = CONTEXT_PATH, releaseTypeScope = 'chore(release)' } = {}) =>
const commitFiles = (version, { contextPath, releaseTypeScope = 'chore(release)' } = OPTIONS) =>
runCmd(
`git add ${join(contextPath, 'package.json')} ${join(contextPath, 'CHANGELOG.md')} && git commit ${join(
contextPath,
Expand All @@ -49,7 +48,7 @@ const commitFiles = (version, { contextPath = CONTEXT_PATH, releaseTypeScope = '
* @param {string} options.contextPath
* @returns {*}
*/
const getCurrentVersion = ({ contextPath = CONTEXT_PATH } = {}) => {
const getCurrentVersion = ({ contextPath } = OPTIONS) => {
const { version } = require(join(contextPath, 'package.json'));
return version;
};
Expand All @@ -58,23 +57,23 @@ const getCurrentVersion = ({ contextPath = CONTEXT_PATH } = {}) => {
* Get last release commit hash
*
* @param {object} options
* @param {string} releaseTypeScope
* @param {string} options.releaseTypeScope
* @returns {string}
*/
const getReleaseCommit = ({ releaseTypeScope = 'chore(release)' } = {}) =>
const getReleaseCommit = ({ releaseTypeScope = 'chore(release)' } = OPTIONS) =>
runCmd(`git log --grep="${releaseTypeScope}" --pretty=oneline -1`, 'Skipping release commit check... {0}');

/**
* Get the repositories remote
*
* @param {object} params
* @param {string} params.commitPath
* @param {string} params.comparePath
* @param {string} params.prPath
* @param {string} params.remoteUrl
* @param {object} options
* @param {string} options.commitPath
* @param {string} options.comparePath
* @param {string} options.prPath
* @param {string} options.remoteUrl
* @returns {{baseUrl: string, prUrl, commitUrl}}
*/
const getRemoteUrls = ({ commitPath, comparePath, prPath, remoteUrl } = {}) => {
const getRemoteUrls = ({ commitPath, comparePath, prPath, remoteUrl } = OPTIONS) => {
const setUrl = remoteUrl || runCmd('git remote get-url origin', 'Skipping remote path check... {0}');
let updatedUrl;
let commitUrl;
Expand Down Expand Up @@ -108,8 +107,8 @@ const getRemoteUrls = ({ commitPath, comparePath, prPath, remoteUrl } = {}) => {
/**
* Return output for a range of commits from a hash
*
* @param {object} options
* @param {Function} options.getReleaseCommit
* @param {object} settings
* @param {Function} settings.getReleaseCommit
* @returns {string}
*/
const getGit = ({ getReleaseCommit: getAliasReleaseCommit = getReleaseCommit } = {}) => {
Expand All @@ -125,10 +124,11 @@ const getGit = ({ getReleaseCommit: getAliasReleaseCommit = getReleaseCommit } =
/**
* Determine if override version is valid semver and return
*
* @param {string|*} version
* @param {object} options
* @param {string|*} options.overrideVersion
* @return {{clean: string, version: string}}
*/
const getOverrideVersion = version => {
const getOverrideVersion = ({ overrideVersion: version } = OPTIONS) => {
let updatedVersion;
let clean;

Expand All @@ -152,8 +152,8 @@ const getOverrideVersion = version => {
* Set package.json version using npm version
*
* @param {'major'|'minor'|'patch'|*} versionBump
* @param {object} options
* @param {Function} options.getCurrentVersion
* @param {object} settings
* @param {Function} settings.getCurrentVersion
* @returns {string}
*/
const getVersion = (versionBump, { getCurrentVersion: getAliasCurrentVersion = getCurrentVersion } = {}) => {
Expand Down
Loading

0 comments on commit 6379124

Please sign in to comment.