diff --git a/__tests__/commands/version.js b/__tests__/commands/version.js new file mode 100644 index 0000000000..1c3e0ec1d7 --- /dev/null +++ b/__tests__/commands/version.js @@ -0,0 +1,70 @@ +/* @flow */ + +jest.mock('../../src/util/execute-lifecycle-script'); +jest.mock('../../src/util/child'); + +import {run as buildRun} from './_helpers.js'; +import {BufferReporter} from '../../src/reporters/index.js'; +import {run} from '../../src/cli/commands/version.js'; +import * as fs from '../../src/util/fs.js'; +import * as reporters from '../../src/reporters/index.js'; + +jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000; + +const execCommand: $FlowFixMe = require('../../src/util/execute-lifecycle-script').execCommand; + +const path = require('path'); + +beforeEach(() => execCommand.mockClear()); + +const fixturesLoc = path.join(__dirname, '..', 'fixtures', 'version'); +const runRun = buildRun.bind(null, BufferReporter, fixturesLoc, (args, flags, config, reporter): Promise => { + return run(config, reporter, flags, args); +}); + +const oldVersion = '1.0.0'; +const newVersion = '2.0.0'; + +const gitTagVersion = true; + +test('run version with no arguments and --new-version flag', (): Promise => { + return runRun([], {newVersion, gitTagVersion}, 'no-args', (config, reporter): ?Promise => { + const rprtr = new reporters.BufferReporter({stdout: null, stdin: null}); + + // Emulate run output + rprtr.info(`${rprtr.lang('currentVersion')}: ${oldVersion}`); + rprtr.info(`${rprtr.lang('newVersion')}: ${newVersion}`); + + expect(reporter.getBuffer()).toEqual(rprtr.getBuffer()); + }); +}); + +test('run version and make sure all lifecycle steps are executed', (): Promise => { + return runRun([], {newVersion, gitTagVersion}, 'no-args', async(config): ?Promise => { + const pkg = await fs.readJson(path.join(config.cwd, 'package.json')); + + const preversionLifecycle = ['preversion', config, pkg.scripts.preversion, config.cwd]; + const versionLifecycle = ['version', config, pkg.scripts.version, config.cwd]; + const postversionLifecycle = ['postversion', config, pkg.scripts.postversion, config.cwd]; + + expect(execCommand.mock.calls.length).toBe(3); + + expect(execCommand.mock.calls[0]).toEqual(preversionLifecycle); + expect(execCommand.mock.calls[1]).toEqual(versionLifecycle); + expect(execCommand.mock.calls[2]).toEqual(postversionLifecycle); + }); +}); + +test('run version and make sure only the defined lifecycle steps are executed', (): Promise => { + return runRun([], {newVersion, gitTagVersion}, 'pre-post', async(config): ?Promise => { + const pkg = await fs.readJson(path.join(config.cwd, 'package.json')); + + const preversionLifecycle = ['preversion', config, pkg.scripts.preversion, config.cwd]; + const postversionLifecycle = ['postversion', config, pkg.scripts.postversion, config.cwd]; + + expect(execCommand.mock.calls.length).toBe(2); + + expect(execCommand.mock.calls[0]).toEqual(preversionLifecycle); + expect(execCommand.mock.calls[1]).toEqual(postversionLifecycle); + }); +}); diff --git a/__tests__/fixtures/version/no-args/package.json b/__tests__/fixtures/version/no-args/package.json new file mode 100644 index 0000000000..c8c699e438 --- /dev/null +++ b/__tests__/fixtures/version/no-args/package.json @@ -0,0 +1,9 @@ +{ + "version": "1.0.0", + "license": "BSD-2-Clause", + "scripts": { + "preversion": "echo preversion", + "version": "echo version", + "postversion": "echo postversion" + } +} diff --git a/__tests__/fixtures/version/pre-post/package.json b/__tests__/fixtures/version/pre-post/package.json new file mode 100644 index 0000000000..66dcf9c40f --- /dev/null +++ b/__tests__/fixtures/version/pre-post/package.json @@ -0,0 +1,8 @@ +{ + "version": "1.0.0", + "license": "BSD-2-Clause", + "scripts": { + "preversion": "echo preversion", + "postversion": "echo postversion" + } +} diff --git a/src/cli/commands/version.js b/src/cli/commands/version.js index 6eb834d797..ad3d25cc54 100644 --- a/src/cli/commands/version.js +++ b/src/cli/commands/version.js @@ -3,9 +3,11 @@ import type {Reporter} from '../../reporters/index.js'; import type Config from '../../config.js'; import {registryNames} from '../../registries/index.js'; +import {execCommand} from '../../util/execute-lifecycle-script.js'; import {MessageError} from '../../errors.js'; import {spawn} from '../../util/child.js'; import * as fs from '../../util/fs.js'; +import map from '../../util/map.js'; const invariant = require('invariant'); const semver = require('semver'); @@ -31,6 +33,7 @@ export async function setVersion( ): Promise<() => Promise> { const pkg = await config.readRootManifest(); const pkgLoc = pkg._loc; + const scripts = map(); let newVersion = flags.newVersion; invariant(pkgLoc, 'expected package location'); @@ -38,6 +41,19 @@ export async function setVersion( throw new MessageError(reporter.lang('invalidVersionArgument', NEW_VERSION_FLAG)); } + async function runLifecycle(lifecycle: string): Promise { + if (scripts[lifecycle]) { + return await execCommand(lifecycle, config, scripts[lifecycle], config.cwd); + } + + return Promise.resolve(); + } + + if (pkg.scripts) { + // inherit `scripts` from manifest + Object.assign(scripts, pkg.scripts); + } + // get old version let oldVersion = pkg.version; if (oldVersion) { @@ -77,7 +93,7 @@ export async function setVersion( throw new MessageError(reporter.lang('publishSame')); } - await config.executeLifecycleScript('preversion'); + await runLifecycle('preversion'); // update version reporter.info(`${reporter.lang('newVersion')}: ${newVersion}`); @@ -115,6 +131,9 @@ export async function setVersion( parts.pop(); } } + + await runLifecycle('version'); + if (isGit) { const message = (flags.message || String(config.getOption('version-git-message'))).replace(/%s/g, newVersion); const sign: boolean = Boolean(config.getOption('version-sign-git-tag')); @@ -131,7 +150,7 @@ export async function setVersion( await spawn('git', ['tag', `${prefix}${newVersion}`, flag, message]); } - await config.executeLifecycleScript('postversion'); + await runLifecycle('postversion'); }; }