Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: refactor nextPreVersion to reduce cognitive complexity #35

Merged
merged 22 commits into from
Jan 5, 2021
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
fd8fcad
feat(helpers/file): added file creation on list of folders
davikawasaki Dec 23, 2020
da7b781
feat(helpers/git): added release branch creation on git init origin e…
davikawasaki Dec 23, 2020
4850de3
feat(prerelease): enabled correct prerelease updates on dependencies
davikawasaki Dec 23, 2020
de5265e
chore(update-deps): reducing cognitive complexity
davikawasaki Dec 23, 2020
fa57c5a
test(update-deps): setting nextVersion as last param on test cases
davikawasaki Dec 23, 2020
eedf2f2
Merge branch 'master' of https://github.com/qiwi/multi-semantic-relea…
davikawasaki Dec 30, 2020
fc378b4
test: added fixture for 2 packages only
davikawasaki Dec 30, 2020
a8e40c8
chore: updated package lock
davikawasaki Dec 30, 2020
cadc3a8
fix: avoid local dep bump when it's not updated
davikawasaki Dec 30, 2020
d6b4ed2
chore: package update + changelog merge
davikawasaki Jan 4, 2021
54c7af8
feat: branch name available at pkg level
davikawasaki Jan 4, 2021
ac4962b
feat: git module to get filtered tags from a branch
davikawasaki Jan 4, 2021
7d299d8
feat: tweak utils from semantic-release
davikawasaki Jan 4, 2021
a654af5
fix: getNextPreVersion updated to cover edge cases
davikawasaki Jan 4, 2021
a1fedc7
test: covers semantic release on a release-prerelease branch change
davikawasaki Jan 4, 2021
2632492
chore: reducing code complexity
davikawasaki Jan 4, 2021
97c21aa
fix: refactor validateSubstr fn
davikawasaki Jan 5, 2021
5533a08
fix: refactor highest/lowest fn, fail fast on tagsToVersions
davikawasaki Jan 5, 2021
4f55c95
fix: reducing code cognitive complexity on getNextPreVersion
davikawasaki Jan 5, 2021
ef4a351
fix: refactor nextPreVersion to reduce code complexity
davikawasaki Jan 5, 2021
1f6bc2b
chore: merging from upstream
davikawasaki Jan 5, 2021
ed6c89b
chore: todo to replace cwd on getNextPreVersion
davikawasaki Jan 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 45 additions & 24 deletions lib/updateDeps.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,35 @@ const getNextPreVersion = (pkg, tags) => {
const lastVersion = pkg._lastRelease && pkg._lastRelease.version;
const version = `1.0.0-${pkg._preRelease}.1`;

// Extract tags:
// 1. Set filter to extract only package tags
// 2. Get tags from a branch considering the filters established
davikawasaki marked this conversation as resolved.
Show resolved Hide resolved
if (pkg.name) tagFilters.push(pkg.name);
if (!tags || !tags.length) tags = getTags(pkg._branch, { cwd: "." }, tagFilters);

if (lastVersion) {
const { prerelease } = semver.parse(lastVersion);
const lastPreRelTag = prerelease[0] || null;
const lastPreRelTag = getPreReleaseTag(lastVersion);
const isNewPreRelTag = lastPreRelTag && lastPreRelTag !== pkg._preRelease;

// If there was a change in the prerelease tag (e.g. dev to rc), start semver from scratch with the new prerelease tag
if (lastPreRelTag && lastPreRelTag !== pkg._preRelease) {
return version;
}

return _nextPreHighestVersion(tags, lastVersion, pkg._nextType, pkg._preRelease);
}
return isNewPreRelTag || !lastVersion
? `1.0.0-${pkg._preRelease}.1`
: _nextPreVersionCases(tags, lastVersion, pkg._nextType, pkg._preRelease);
};

return version;
/**
* Parse the prerelease tag from a semver version.
*
* @param {string} version Semver version in a string format.
* @returns {string|null} preReleaseTag Version prerelease tag or null.
* @internal
*/
const getPreReleaseTag = (version) => {
const parsed = semver.parse(version);
if (!parsed) return null;
return parsed.prerelease[0] || null;
};

/**
* Resolve next prerelease highest version from tags or major/minor/patch.
* Resolve next prerelease special cases: highest version from tags or major/minor/patch.
*
* @param {Array} tags List of all released tags from package.
* @param {string} lastVersion Last package version released.
Expand All @@ -63,21 +72,32 @@ const getNextPreVersion = (pkg, tags) => {
* @returns {string|undefined} Next pkg version.
* @internal
*/
const _nextPreHighestVersion = (tags, lastVersion, pkgNextType, pkgPreRelease) => {
if (semver.prerelease(lastVersion)) {
const latestVerTags = getLatestVersion(tags, { withPrerelease: true });
// Bump the latest version from tags if:
// 1. There is a tag list and a latest version result from the list
// 2. The last prerelease tag exists and is the same
const bumpLatestVerTags = latestVerTags ? semver.inc(latestVerTags, "prerelease", pkgPreRelease) : null;
const bumpLastVer = semver.inc(lastVersion, "prerelease", pkgPreRelease);

return bumpLatestVerTags ? getHighestVersion(bumpLastVer, bumpLatestVerTags) : bumpLastVer;
} else {
const _nextPreVersionCases = (tags, lastVersion, pkgNextType, pkgPreRelease) => {
// Case 1: Normal release on last version and is now converted to a prerelease
if (!semver.prerelease(lastVersion)) {
const { major, minor, patch } = semver.parse(lastVersion);
// Case when last version was a normal release and now it needs to be a prerelease
return `${semver.inc(`${major}.${minor}.${patch}`, pkgNextType || "patch")}-${pkgPreRelease}.1`;
}

// Case 2: Validates version with tags
const latestTag = getLatestVersion(tags, { withPrerelease: true });
return _nextPreHighestVersion(latestTag, lastVersion, pkgPreRelease);
};

/**
* Resolve next prerelease comparing bumped tags versions with last version.
*
* @param {string|null} latestTag Last released tag from branch or null if non-existent.
* @param {string} lastVersion Last version released.
* @param {string} pkgPreRelease Prerelease tag from package to-be-released.
* @returns {string} Next pkg version.
* @internal
*/
const _nextPreHighestVersion = (latestTag, lastVersion, pkgPreRelease) => {
const bumpFromTags = latestTag ? semver.inc(latestTag, "prerelease", pkgPreRelease) : null;
const bumpFromLast = semver.inc(lastVersion, "prerelease", pkgPreRelease);

return bumpFromTags ? getHighestVersion(bumpFromLast, bumpFromTags) : bumpFromLast;
};

/**
Expand Down Expand Up @@ -283,6 +303,7 @@ const auditManifestChanges = (actualManifest, path) => {
module.exports = {
getNextVersion,
getNextPreVersion,
getPreReleaseTag,
updateManifestDeps,
resolveReleaseType,
resolveNextVersion,
Expand Down
30 changes: 29 additions & 1 deletion test/lib/updateDeps.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
const { resolveReleaseType, resolveNextVersion, getNextVersion, getNextPreVersion } = require("../../lib/updateDeps");
const {
resolveReleaseType,
resolveNextVersion,
getNextVersion,
getNextPreVersion,
getPreReleaseTag,
} = require("../../lib/updateDeps");

describe("resolveNextVersion()", () => {
// prettier-ignore
Expand Down Expand Up @@ -197,3 +203,25 @@ describe("getNextPreVersion()", () => {
});
});
});

describe("getPreReleaseTag()", () => {
// prettier-ignore
const cases = [
[undefined, null],
[null, null],
["1.0.0-rc.0", "rc"],
["1.0.0-dev.0", "dev"],
["1.0.0-dev.2", "dev"],
["1.1.0-beta.0", "beta"],
["11.0.0", null],
["11.1.0", null],
["11.0.1", null],
]

cases.forEach(([version, preReleaseTag]) => {
it(`${version} gives ${preReleaseTag}`, () => {
// prettier-ignore
expect(getPreReleaseTag(version)).toBe(preReleaseTag);
});
});
});