From f659c344823bdfa17d3e7e15b517f3026f4084c7 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Sat, 30 Nov 2019 23:04:16 +0100 Subject: [PATCH] fix(prepare): ask commit range when tag is missing (#471) * fix(prepare): ask commit range when tag is missing * fix: update message --- packages/shipjs/src/flow/prepare.js | 4 +- .../__tests__/validateBeforePrepare.spec.js | 20 +--------- .../src/helper/validateBeforePrepare.js | 12 +----- .../step/prepare/__tests__/validate.spec.js | 2 - .../shipjs/src/step/prepare/getCommitRange.js | 38 +++++++++++++++++++ .../shipjs/src/step/prepare/getNextVersion.js | 4 +- packages/shipjs/src/step/prepare/validate.js | 8 +--- 7 files changed, 49 insertions(+), 39 deletions(-) create mode 100644 packages/shipjs/src/step/prepare/getCommitRange.js diff --git a/packages/shipjs/src/flow/prepare.js b/packages/shipjs/src/flow/prepare.js index 36e31669..9ce0a3f9 100644 --- a/packages/shipjs/src/flow/prepare.js +++ b/packages/shipjs/src/flow/prepare.js @@ -3,6 +3,7 @@ import { getAppName, loadConfig, getReleaseType } from 'shipjs-lib'; import printHelp from '../step/prepare/printHelp'; import printDryRunBanner from '../step/printDryRunBanner'; import validate from '../step/prepare/validate'; +import getCommitRange from '../step/prepare/getCommitRange'; import validateMergeStrategy from '../step/prepare/validateMergeStrategy'; import pull from '../step/pull'; import fetchTags from '../step/prepare/fetchTags'; @@ -50,7 +51,8 @@ async function prepare({ pull({ remote, currentBranch: baseBranch, dir, dryRun }); fetchTags({ dir, dryRun }); push({ remote, currentBranch: baseBranch, dir, dryRun }); - let { nextVersion } = getNextVersion({ currentVersion, dir }); + const { commitRange } = getCommitRange({ currentVersion, dir }); + let { nextVersion } = getNextVersion({ commitRange, currentVersion, dir }); nextVersion = await confirmNextVersion({ yes, currentVersion, diff --git a/packages/shipjs/src/helper/__tests__/validateBeforePrepare.spec.js b/packages/shipjs/src/helper/__tests__/validateBeforePrepare.spec.js index ff8e1164..11fae76f 100644 --- a/packages/shipjs/src/helper/__tests__/validateBeforePrepare.spec.js +++ b/packages/shipjs/src/helper/__tests__/validateBeforePrepare.spec.js @@ -1,5 +1,5 @@ import validate from '../validateBeforePrepare'; -import { isWorkingTreeClean, getCurrentBranch, hasTag } from 'shipjs-lib'; +import { isWorkingTreeClean, getCurrentBranch } from 'shipjs-lib'; const defaultOpts = { baseBranches: ['master'], @@ -9,7 +9,6 @@ describe('Validate', () => { beforeEach(() => { isWorkingTreeClean.mockImplementation(() => true); getCurrentBranch.mockImplementation(() => 'master'); - hasTag.mockImplementation(() => true); }); it('returns error if working tree is not clean', () => { @@ -40,26 +39,11 @@ describe('Validate', () => { expect(result).toBe(true); }); - it('returns error if there is no git tag for current version', () => { - hasTag.mockImplementation(() => false); - const result = validate(defaultOpts); - expect(result).not.toBe(true); - expect(result.length).toBe(1); - expect(result[0]).toMatchInlineSnapshot(`"noTagForCurrentVersion"`); - }); - - it('does not return error if there is git tag for current version', () => { - hasTag.mockImplementation(() => true); - const result = validate(defaultOpts); - expect(result).toBe(true); - }); - it('returns more than one error', () => { isWorkingTreeClean.mockImplementation(() => false); getCurrentBranch.mockImplementation(() => 'aaa'); - hasTag.mockImplementation(() => false); const result = validate(defaultOpts); expect(result).not.toBe(true); - expect(result.length).toBe(3); + expect(result.length).toBe(2); }); }); diff --git a/packages/shipjs/src/helper/validateBeforePrepare.js b/packages/shipjs/src/helper/validateBeforePrepare.js index 93207c10..8efe73e9 100644 --- a/packages/shipjs/src/helper/validateBeforePrepare.js +++ b/packages/shipjs/src/helper/validateBeforePrepare.js @@ -1,14 +1,9 @@ -import { isWorkingTreeClean, getCurrentBranch, hasTag } from 'shipjs-lib'; +import { isWorkingTreeClean, getCurrentBranch } from 'shipjs-lib'; const WORKING_TREE_NOT_CLEAN = 'workingTreeNotClean'; const CURRENT_BRANCH_INCORRECT = 'currentBranchIncorrect'; -const NO_TAG_FOR_CURRENT_VERSION = 'noTagForCurrentVersion'; -export default function validateBeforePrepare({ - dir, - currentTagName, - baseBranches, -} = {}) { +export default function validateBeforePrepare({ dir, baseBranches } = {}) { const result = []; if (!isWorkingTreeClean(dir)) { result.push(WORKING_TREE_NOT_CLEAN); @@ -16,8 +11,5 @@ export default function validateBeforePrepare({ if (baseBranches.indexOf(getCurrentBranch(dir)) === -1) { result.push(CURRENT_BRANCH_INCORRECT); } - if (!hasTag(currentTagName, dir)) { - result.push(NO_TAG_FOR_CURRENT_VERSION); - } return result.length === 0 ? true : result; } diff --git a/packages/shipjs/src/step/prepare/__tests__/validate.spec.js b/packages/shipjs/src/step/prepare/__tests__/validate.spec.js index 7e470843..a5a3ab13 100644 --- a/packages/shipjs/src/step/prepare/__tests__/validate.spec.js +++ b/packages/shipjs/src/step/prepare/__tests__/validate.spec.js @@ -32,7 +32,6 @@ describe('validate', () => { validateBeforePrepare.mockImplementation(() => [ 'workingTreeNotClean', 'currentBranchIncorrect', - 'noTagForCurrentVersion', ]); const output = []; mockPrint(print, output); @@ -57,7 +56,6 @@ describe('validate', () => { "Failed to prepare a release for the following reason(s).", " - The working tree is not clean.", " - The current branch must be one of [\\"master\\",\\"legacy\\"]", - " - There is no git tag for the current version (v1.2.3)", ] `); }); diff --git a/packages/shipjs/src/step/prepare/getCommitRange.js b/packages/shipjs/src/step/prepare/getCommitRange.js new file mode 100644 index 00000000..5b31f0c7 --- /dev/null +++ b/packages/shipjs/src/step/prepare/getCommitRange.js @@ -0,0 +1,38 @@ +import inquirer from 'inquirer'; +import { hasTag, silentExec } from 'shipjs-lib'; +import runStep from '../runStep'; +import { print } from '../../util'; +import { info, warning } from '../../color'; + +export default async ({ currentVersion, dir }) => + await runStep( + { title: 'Getting a commit range for this release.' }, + async () => { + let commitRange = `v${currentVersion}..HEAD`; + if (hasTag(`v${currentVersion}`, dir)) { + print(info(`✔ ${commitRange}`)); + return { commitRange }; + } + + print(warning(`Git tag 'v${currentVersion}' doesn't exist.`)); + const commits = silentExec(`git log --pretty=format:"%h%d %s"`, { + dir, + }) + .toString() + .split('\n'); + const { answer } = await inquirer.prompt([ + { + type: 'list', + pageSize: 10, + name: 'answer', + message: 'Since which commit do you want to release?', + choices: commits.map((commit, index) => `${index + 1}) ${commit}`), + }, + ]); + const [, commit] = answer.split(' '); + + commitRange = `${commit}..HEAD`; + print(info(`✔ ${commitRange}`)); + return { commitRange }; + } + ); diff --git a/packages/shipjs/src/step/prepare/getNextVersion.js b/packages/shipjs/src/step/prepare/getNextVersion.js index 24e6a976..0290ad06 100644 --- a/packages/shipjs/src/step/prepare/getNextVersion.js +++ b/packages/shipjs/src/step/prepare/getNextVersion.js @@ -3,10 +3,10 @@ import runStep from '../runStep'; import { print, exitProcess } from '../../util'; import { info, warning } from '../../color'; -export default ({ currentVersion, dir }) => +export default ({ commitRange, currentVersion, dir }) => runStep({ title: 'Calculating the next version.' }, () => { const { version: nextVersion, ignoredMessages = [] } = getNextVersion( - `v${currentVersion}..HEAD`, + commitRange, currentVersion, dir ); diff --git a/packages/shipjs/src/step/prepare/validate.js b/packages/shipjs/src/step/prepare/validate.js index 02bfe299..9761838c 100644 --- a/packages/shipjs/src/step/prepare/validate.js +++ b/packages/shipjs/src/step/prepare/validate.js @@ -4,13 +4,12 @@ import { getBaseBranches, validateBeforePrepare } from '../../helper'; import { print, exitProcess } from '../../util'; import { info, error } from '../../color'; -function printValidationError({ result, currentVersion, baseBranches }) { +function printValidationError({ result, baseBranches }) { const messageMap = { workingTreeNotClean: 'The working tree is not clean.', currentBranchIncorrect: `The current branch must be one of ${JSON.stringify( baseBranches )}`, - noTagForCurrentVersion: `There is no git tag for the current version (v${currentVersion})`, }; print(error('Failed to prepare a release for the following reason(s).')); @@ -25,23 +24,20 @@ export default ({ config, dir }) => title: 'Checking the current status.', }, () => { - const { mergeStrategy, monorepo, getTagName } = config; + const { mergeStrategy, monorepo } = config; const baseBranches = getBaseBranches({ mergeStrategy }); const currentVersion = monorepo && monorepo.mainVersionFile ? getCurrentVersion(dir, monorepo.mainVersionFile) : getCurrentVersion(dir); - const currentTagName = getTagName({ version: currentVersion }); const result = validateBeforePrepare({ dir, - currentTagName, baseBranches, }); const baseBranch = getCurrentBranch(dir); if (result !== true) { printValidationError({ result, - currentVersion, baseBranches, }); exitProcess(1);