Skip to content

Commit

Permalink
feat: Read package.json file instead using the one passed by semantic…
Browse files Browse the repository at this point in the history
…-release
  • Loading branch information
pvdlg committed Nov 25, 2017
1 parent 2058e9e commit 8565d9d
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 42 deletions.
12 changes: 9 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
const getPkg = require('./lib/get-pkg');
const verifyNpm = require('./lib/verify');
const publishNpm = require('./lib/publish');
const getLastReleaseNpm = require('./lib/get-last-release');

let verified;

async function verifyConditions(pluginConfig, {pkg, logger}) {
async function verifyConditions(pluginConfig, {logger}) {
const pkg = await getPkg();
await verifyNpm(pkg, logger);
verified = true;
}

async function getLastRelease(pluginConfig, {pkg, logger}) {
async function getLastRelease(pluginConfig, {logger}) {
// Reload package.json in case a previous external step updated it
const pkg = await getPkg();
if (!verified) {
await verifyNpm(pkg, logger);

This comment has been minimized.

Copy link
@felixfbecker

felixfbecker Nov 25, 2017

Shouldn't this be pkg.pkg?

This comment has been minimized.

Copy link
@pvdlg

pvdlg Nov 25, 2017

Author Member

Why would it be pkg.pkg?

This comment has been minimized.

Copy link
@felixfbecker

felixfbecker Nov 25, 2017

In all the other files, you call const {pkg} = await getPkg() because read-pkg-up returns an {pkg, path} object. But not here?

This comment has been minimized.

Copy link
@pvdlg

pvdlg Nov 25, 2017

Author Member

read-pkg-up is called like this const {pkg} = await readPkgUp(); so the pkg is already extracted.

I don't see any const {pkg} = await getPkg() in the code. Only const pkg = await getPkg(); 3 times.

This comment has been minimized.

Copy link
@felixfbecker

felixfbecker Nov 25, 2017

Oh, I was confused by getPkg vs readPkgUp

This comment has been minimized.

Copy link
@gr2m

gr2m Nov 25, 2017

Member

thanks for having a look at the PRs @felixfbecker 👍

verified = true;
}
return getLastReleaseNpm(pkg, logger);
}

async function publish(pluginConfig, {pkg, nextRelease: {version}, logger}) {
async function publish(pluginConfig, {nextRelease: {version}, logger}) {
// Reload package.json in case a previous external step updated it
const pkg = await getPkg();
if (!verified) {
await verifyNpm(pkg, logger);
verified = true;
Expand Down
16 changes: 16 additions & 0 deletions lib/get-pkg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const readPkgUp = require('read-pkg-up');
const SemanticReleaseError = require('@semantic-release/error');

module.exports = async () => {
const {pkg} = await readPkgUp();

if (!pkg) {
throw new SemanticReleaseError('A package.json file is required to release on npm.', 'ENOPKG');
}

if (!pkg.name) {
throw new SemanticReleaseError('No "name" found in package.json.', 'ENOPKGNAME');
}

return pkg;
};
7 changes: 0 additions & 7 deletions lib/verify-pkg.js

This file was deleted.

2 changes: 0 additions & 2 deletions lib/verify.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
const execa = require('execa');
const SemanticReleaseError = require('@semantic-release/error');
const verifyPkg = require('./verify-pkg');
const setNpmrcAuth = require('./set-npmrc-auth');

module.exports = async (pkg, logger) => {
verifyPkg(pkg);
await setNpmrcAuth(pkg, logger);
try {
await execa('npm', ['whoami']);
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"nerf-dart": "^1.0.0",
"npm-conf": "^1.1.3",
"npm-registry-client": "^8.5.0",
"read-pkg-up": "^3.0.0",
"registry-auth-token": "^3.3.1"
},
"devDependencies": {
Expand All @@ -39,7 +40,7 @@
"nock": "^9.1.0",
"nyc": "^11.2.1",
"prettier": "~1.8.2",
"semantic-release": "^9.1.1",
"semantic-release": "^10.0.0",
"sinon": "^4.1.2",
"tempy": "^0.2.1",
"xo": "^0.18.2"
Expand Down
49 changes: 49 additions & 0 deletions test/get-pkg.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import test from 'ava';
import {writeJson, writeFile} from 'fs-extra';
import tempy from 'tempy';
import getPkg from '../lib/get-pkg';

test.beforeEach(t => {
// Save the current working diretory
t.context.cwd = process.cwd();
// Change current working directory to a temp directory
process.chdir(tempy.directory());
});

test.afterEach.always(t => {
// Restore the current working directory
process.chdir(t.context.cwd);
});

test.serial('Verify name and return parsed package.json', async t => {
const pkg = {name: 'package', version: '0.0.0'};
await writeJson('./package.json', pkg);

const result = await getPkg();
t.is(pkg.name, result.name);
t.is(pkg.version, result.version);
});

test.serial('Throw error if missing package.json', async t => {
const error = await t.throws(getPkg());

t.is(error.name, 'SemanticReleaseError');
t.is(error.code, 'ENOPKG');
});

test.serial('Throw error if missing package name', async t => {
await writeJson('./package.json', {version: '0.0.0'});

const error = await t.throws(getPkg());

t.is(error.name, 'SemanticReleaseError');
t.is(error.code, 'ENOPKGNAME');
});

test.serial('Throw error if package.json is malformed', async t => {
await writeFile('./package.json', "{name: 'package',}");

const error = await t.throws(getPkg());

t.is(error.name, 'JSONError');
});
28 changes: 15 additions & 13 deletions test/integration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ test.after.always(async () => {

test.serial('Throws error if NPM token is invalid', async t => {
process.env.NPM_TOKEN = 'wrong_token';
const error = await t.throws(
t.context.m.verifyConditions({}, {pkg: {name: 'invalid-token'}, logger: t.context.logger})
);
const pkg = {name: 'published', version: '1.0.0', publishConfig: {registry: npmRegistry.url}};
await writeJson('./package.json', pkg);
const error = await t.throws(t.context.m.verifyConditions({}, {logger: t.context.logger}));

t.true(error instanceof SemanticReleaseError);
t.is(error.code, 'EINVALIDNPMTOKEN');
Expand All @@ -81,7 +81,8 @@ test.serial('Throws error if NPM token is invalid', async t => {
test.serial('Verify npm auth and package', async t => {
Object.assign(process.env, npmRegistry.authEnv);
const pkg = {name: 'valid-token', publishConfig: {registry: npmRegistry.url}};
await t.notThrows(t.context.m.verifyConditions({}, {pkg, logger: t.context.logger}));
await writeJson('./package.json', pkg);
await t.notThrows(t.context.m.verifyConditions({}, {logger: t.context.logger}));

const npmrc = (await readFile('.npmrc')).toString();
t.regex(npmrc, /_auth =/);
Expand All @@ -91,7 +92,8 @@ test.serial('Verify npm auth and package', async t => {
test.serial('Return nothing if no version if published', async t => {
Object.assign(process.env, npmRegistry.authEnv);
const pkg = {name: 'not-published', publishConfig: {registry: npmRegistry.url}};
const nextRelease = await t.context.m.getLastRelease({}, {pkg, logger: t.context.logger});
await writeJson('./package.json', pkg);
const nextRelease = await t.context.m.getLastRelease({}, {logger: t.context.logger});

t.deepEqual(nextRelease, {});
});
Expand All @@ -110,7 +112,7 @@ test.serial('Return last version published', async t => {

await execa('npm', ['publish']);

const nextRelease = await t.context.m.getLastRelease({}, {pkg, logger: t.context.logger});
const nextRelease = await t.context.m.getLastRelease({}, {logger: t.context.logger});
t.is(nextRelease.version, '1.0.0');
});

Expand All @@ -133,7 +135,7 @@ test.serial('Return last version published on a dist-tag', async t => {
// Publish version 1.1.0 on next
await execa('npm', ['publish', '--tag=next']);

const nextRelease = await t.context.m.getLastRelease({}, {pkg, logger: t.context.logger});
const nextRelease = await t.context.m.getLastRelease({}, {logger: t.context.logger});
t.is(nextRelease.version, '1.1.0');
});

Expand All @@ -152,7 +154,7 @@ test.serial('Return nothing for an unpublished package', async t => {
await execa('npm', ['publish']);
await execa('npm', ['unpublish', 'unpublished', '--force']);

const nextRelease = await t.context.m.getLastRelease({}, {pkg, logger: t.context.logger});
const nextRelease = await t.context.m.getLastRelease({}, {logger: t.context.logger});
t.deepEqual(nextRelease, {});
});

Expand All @@ -161,7 +163,7 @@ test.serial('Publish a package', async t => {
const pkg = {name: 'publish', version: '1.0.0', publishConfig: {registry: npmRegistry.url}};
await writeJson('./package.json', pkg);

await t.context.m.publish({}, {pkg, logger: t.context.logger, nextRelease: {version: '1.0.0'}});
await t.context.m.publish({}, {logger: t.context.logger, nextRelease: {version: '1.0.0'}});

t.is((await execa('npm', ['view', 'publish', 'version'])).stdout, '1.0.0');
});
Expand All @@ -171,13 +173,13 @@ test.serial('Verify token and set up auth only on the fist call', async t => {
const pkg = {name: 'test-module', version: '0.0.0-dev', publishConfig: {registry: npmRegistry.url}};
await writeJson('./package.json', pkg);

await t.notThrows(t.context.m.verifyConditions({}, {pkg, logger: t.context.logger}));
await t.notThrows(t.context.m.verifyConditions({}, {logger: t.context.logger}));

let nextRelease = await t.context.m.getLastRelease({}, {pkg, logger: t.context.logger});
let nextRelease = await t.context.m.getLastRelease({}, {logger: t.context.logger});
t.deepEqual(nextRelease, {});

await t.context.m.publish({}, {pkg, logger: t.context.logger, nextRelease: {version: '1.0.0'}});
await t.context.m.publish({}, {logger: t.context.logger, nextRelease: {version: '1.0.0'}});

nextRelease = await t.context.m.getLastRelease({}, {pkg, logger: t.context.logger});
nextRelease = await t.context.m.getLastRelease({}, {logger: t.context.logger});
t.is(nextRelease.version, '1.0.0');
});
2 changes: 1 addition & 1 deletion test/set-npmrc-auth.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test.beforeEach(t => {
});

test.afterEach.always(t => {
// Clear `rc` from the npm cache as it cache the relative path of .npmrc files, preventing to load a new file after changing current working directory
// Clear `rc` from the npm cache as it cache the relative path of .npmrc files, preventing to load a new file after changing current working directory. See https://github.com/dominictarr/rc/issues/101
clearModule('rc');
// Restore process.env
process.env = Object.assign({}, t.context.env);
Expand Down
2 changes: 1 addition & 1 deletion test/update-package-version.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {writeJson, readJson} from 'fs-extra';
import test from 'ava';
import {writeJson, readJson} from 'fs-extra';
import tempy from 'tempy';
import execa from 'execa';
import {stub} from 'sinon';
Expand Down
14 changes: 0 additions & 14 deletions test/verify-pkg.test.js

This file was deleted.

0 comments on commit 8565d9d

Please sign in to comment.