Skip to content

Commit

Permalink
fix: local dependencies correct bump from release to prerelease (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
davikawasaki committed Jan 5, 2021
1 parent 3bfed38 commit 6481a59
Show file tree
Hide file tree
Showing 9 changed files with 415 additions and 10,829 deletions.
1 change: 1 addition & 0 deletions lib/createInlinePluginCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ function createInlinePluginCreator(packages, multiContext, synchronizer, flags)
const analyzeCommits = async (pluginOptions, context) => {
const firstParentBranch = flags.firstParent ? context.branch.name : undefined;
pkg._preRelease = context.branch.prerelease || null;
pkg._branch = context.branch.name;

// Filter commits by directory.
commits = await getCommitsFiltered(cwd, dir, context.lastRelease.gitHead, firstParentBranch);
Expand Down
30 changes: 30 additions & 0 deletions lib/git.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const execa = require("execa");

/**
* Get all the tags for a given branch.
*
* @param {String} branch The branch for which to retrieve the tags.
* @param {Object} [execaOptions] Options to pass to `execa`.
* @param {Array<String>} filters List of prefixes/sufixes to be checked inside tags.
*
* @return {Array<String>} List of git tags.
* @throws {Error} If the `git` command fails.
* @internal
*/
function getTags(branch, execaOptions, filters) {
let tags = execa.sync("git", ["tag", "--merged", branch], execaOptions).stdout;
tags = tags
.split("\n")
.map((tag) => tag.trim())
.filter(Boolean);

if (!filters || !filters.length) return tags;

const validateSubstr = (t, f) => !!f.find((v) => t.includes(v));

return tags.filter((tag) => validateSubstr(tag, filters));
}

module.exports = {
getTags,
};
51 changes: 49 additions & 2 deletions lib/updateDeps.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const semver = require("semver");
const { isObject, isEqual, transform } = require("lodash");
const recognizeFormat = require("./recognizeFormat");
const getManifest = require("./getManifest");
const { getHighestVersion, getLatestVersion } = require("./utils");
const { getTags } = require("./git");
const debug = require("debug")("msr:updateDeps");

/**
Expand All @@ -24,13 +26,58 @@ const getNextVersion = (pkg) => {
* Resolve next package version on prereleases.
*
* @param {Package} pkg Package object.
* @param {Array<string>} tags Override list of tags from specific pkg and branch.
* @returns {string|undefined} Next pkg version.
* @internal
*/
const getNextPreVersion = (pkg) => {
const getNextPreVersion = (pkg, tags) => {
const tagFilters = [pkg._preRelease];
const lastVersion = pkg._lastRelease && pkg._lastRelease.version;
const version = `1.0.0-${pkg._preRelease}.1`;

return lastVersion ? semver.inc(lastVersion, "prerelease", pkg._preRelease) : `1.0.0-${pkg._preRelease}.1`;
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;

// 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 version;
};

/**
* Resolve next prerelease 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.
* @param {string} pkgNextType Next type evaluated for the next package type.
* @param {string} pkgPreRelease Package prerelease suffix.
* @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 { 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`;
}
};

/**
Expand Down
60 changes: 60 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Lifted and tweaked from semantic-release because we follow how they bump their packages/dependencies.
* https://github.com/semantic-release/semantic-release/blob/master/lib/utils.js
*/

const { gt, lt, prerelease, rcompare } = require("semver");

/**
* Get tag objects and convert them to a list of stringified versions.
* @param {array} tags Tags as object list.
* @returns {array} Tags as string list.
* @internal
*/
function tagsToVersions(tags) {
if (!tags) return [];
return tags.map(({ version }) => version);
}

/**
* HOC that applies highest/lowest semver function.
* @param {Function} predicate High order function to be called.
* @param {string|undefined} version1 Version 1 to be compared with.
* @param {string|undefined} version2 Version 2 to be compared with.
* @returns {string|undefined} Highest or lowest version.
* @internal
*/
const _selectVersionBy = (predicate, version1, version2) => {
if (predicate && version1 && version2) {
return predicate(version1, version2) ? version1 : version2;
}
return version1 || version2;
};

/**
* Gets highest semver function binding gt to the HOC selectVersionBy.
*/
const getHighestVersion = _selectVersionBy.bind(null, gt);

/**
* Gets lowest semver function binding gt to the HOC selectVersionBy.
*/
const getLowestVersion = _selectVersionBy.bind(null, lt);

/**
* Retrieve the latest version from a list of versions.
* @param {array} versions Versions as string list.
* @param {bool|undefined} withPrerelease Prerelease flag.
* @returns {string|undefined} Latest version.
* @internal
*/
function getLatestVersion(versions, withPrerelease) {
return versions.filter((version) => withPrerelease || !prerelease(version)).sort(rcompare)[0];
}

module.exports = {
tagsToVersions,
getHighestVersion,
getLowestVersion,
getLatestVersion,
};
Loading

0 comments on commit 6481a59

Please sign in to comment.