Skip to content

Commit

Permalink
Fix npm tag for pre-release
Browse files Browse the repository at this point in the history
  • Loading branch information
webpro committed Dec 13, 2018
1 parent 3607e70 commit ec3e010
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 30 deletions.
9 changes: 5 additions & 4 deletions lib/config.js
Expand Up @@ -88,10 +88,11 @@ class Config {
parsePreReleaseArgument(cli) {
const { preRelease } = cli;
if (preRelease) {
cli.preReleaseId = preRelease === true ? undefined : preRelease;
const preReleaseId = preRelease === true ? undefined : preRelease;
cli.preReleaseId = preReleaseId;
cli.preRelease = !!preRelease;
cli.npm = cli.npm || {};
cli.npm.tag = cli.npm.tag || preRelease;
cli.npm.tag = cli.npm.tag || preReleaseId || null;
cli.github = cli.github || {};
cli.github.preRelease = true;
}
Expand Down Expand Up @@ -134,11 +135,11 @@ class Config {
}

setOption(key, value) {
this.options[key] = value;
_.set(this.options, key, value);
}

getOption(key) {
return this.options[key];
return _.get(this.options, key);
}

get isDryRun() {
Expand Down
39 changes: 39 additions & 0 deletions lib/npm.js
@@ -0,0 +1,39 @@
const semver = require('semver');
const _ = require('lodash');
const { run } = require('./shell');
const { warn } = require('./log');
const { config } = require('./config');

const getTag = () => {
const tag = config.getOption('npm.tag');
if (tag) return tag;
const preReleaseComponents = semver.prerelease(config.getOption('version'));
return _.get(preReleaseComponents, 0, config.defaultOptions.npm.tag);
};

const publish = (options, pkgName, otpPrompt) => {
const { publishPath, tag, access, otp } = options;
const isScopedPkg = pkgName.startsWith('@');
const accessArg = isScopedPkg && access ? `--access ${access}` : '';
const otpArg = otp ? `--otp ${otp}` : '';
const dryRunArg = config.isDryRun ? '--dry-run' : '';
return run(`npm publish ${publishPath} --tag ${tag} ${accessArg} ${otpArg} ${dryRunArg}`, {
isReadOnly: true,
verbose: config.isVerbose || config.isDryRun
}).catch(err => {
if (/one-time pass/.test(err)) {
if (otp != null) {
warn('The provided OTP is incorrect or has expired.');
}
if (otpPrompt) {
return otpPrompt(otp => publish(Object.assign(options, { otp }), pkgName, otpPrompt));
}
}
throw err;
});
};

module.exports = {
getTag,
publish
};
2 changes: 1 addition & 1 deletion lib/prompt.js
Expand Up @@ -66,7 +66,7 @@ const prompts = {
},
publish: {
type: 'confirm',
message: () => `Publish ${options.name} to npm?`
message: context => `Publish ${options.name}${context.npm.tag === 'latest' ? '' : `@${context.npm.tag}`} to npm?`
},
otp: {
type: 'input',
Expand Down
25 changes: 1 addition & 24 deletions lib/shell.js
Expand Up @@ -2,7 +2,7 @@ const cpy = require('cpy');
const shell = require('shelljs');
const _ = require('lodash');
const bumpFile = require('bump-file');
const { logExec, logDry, warn } = require('./log');
const { logExec, logDry } = require('./log');
const { debugShell } = require('./debug');
const { config } = require('./config');
const { format } = require('./util');
Expand Down Expand Up @@ -54,28 +54,6 @@ const pushd = path => run(`!pushd ${path}`, { isReadOnly: true });

const popd = () => run('!popd', { isReadOnly: true });

const npmPublish = (options, pkgName, otpPrompt) => {
const { publishPath, tag, access, otp } = options;
const isScopedPkg = pkgName.startsWith('@');
const accessArg = isScopedPkg && access ? `--access ${access}` : '';
const otpArg = otp ? `--otp ${otp}` : '';
const dryRunArg = config.isDryRun ? '--dry-run' : '';
return run(`npm publish ${publishPath} --tag ${tag} ${accessArg} ${otpArg} ${dryRunArg}`, {
isReadOnly: true,
verbose: config.isVerbose || config.isDryRun
}).catch(err => {
if (/one-time pass/.test(err)) {
if (otp != null) {
warn('The provided OTP is incorrect or has expired.');
}
if (otpPrompt) {
return otpPrompt(otp => npmPublish(Object.assign(options, { otp }), pkgName, otpPrompt));
}
}
throw err;
});
};

const copy = (files, options, target) => {
const opts = Object.assign(
{
Expand Down Expand Up @@ -106,7 +84,6 @@ module.exports = {
runTemplateCommand,
pushd,
popd,
npmPublish,
copy,
bump
};
4 changes: 3 additions & 1 deletion lib/tasks.js
@@ -1,7 +1,8 @@
const { EOL } = require('os');
const repoPathParse = require('parse-repo');
const _ = require('lodash');
const { bump, runTemplateCommand: run, pushd, copy, npmPublish, popd } = require('./shell');
const { bump, runTemplateCommand: run, pushd, copy, popd } = require('./shell');
const { getTag, publish: npmPublish } = require('./npm');
const Git = require('./git');
const githubClient = require('./github-client');
const semver = require('semver');
Expand Down Expand Up @@ -115,6 +116,7 @@ module.exports = async options => {

const version = provisionalVersion;
config.setOption('version', version);
config.setOption('npm.tag', getTag());

if (!version) {
throw new InvalidVersionError();
Expand Down
18 changes: 18 additions & 0 deletions test/config.js
Expand Up @@ -92,6 +92,24 @@ test('config.preRelease (shorthand)', t => {
t.end();
});

test('config.preRelease (shorthand w/o npm.tag)', t => {
const config = new Config({}, '--preRelease');
const { options } = config;
t.equal(options.preRelease, true);
t.equal(options.preReleaseId, null);
t.equal(options.npm.tag, null);
t.end();
});

test('config.preRelease (shorthand w/ npm.tag)', t => {
const config = new Config({}, '--preRelease --npm.tag=alpha');
const { options } = config;
t.equal(options.preRelease, true);
t.equal(options.preReleaseId, null);
t.equal(options.npm.tag, 'alpha');
t.end();
});

test('config.preRelease (shorthand w/o increment)', t => {
const config = new Config({}, '--preRelease=alpha');
const { options } = config;
Expand Down
26 changes: 26 additions & 0 deletions test/npm.js
@@ -0,0 +1,26 @@
const test = require('tape');
const proxyquire = require('proxyquire');
const { Config } = require('../lib/config');
const { getTag } = require('../lib/npm');

const getMock = config =>
proxyquire('../lib/npm', {
'./config': { config }
});

test('getTag', t => {
t.equal(getTag(), 'latest');
t.end();
});

test('getTag (pre-release)', t => {
const npm = getMock(new Config({}, '--preRelease=beta'));
t.equal(npm.getTag(), 'beta');
t.end();
});

test('getTag (pre-release continuation)', t => {
const npm = getMock(new Config({ version: '1.0.2-alpha.3' }, '--preRelease'));
t.equal(npm.getTag(), 'alpha');
t.end();
});

0 comments on commit ec3e010

Please sign in to comment.