From d19d16e065cf35317af76074d8bebe6e24ad9b47 Mon Sep 17 00:00:00 2001 From: Gregor Martynus Date: Sun, 11 Oct 2020 14:07:07 -0700 Subject: [PATCH 1/7] refactor: separate finding package.json from reading content --- lib/get-config.js | 13 +++++++++---- package.json | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/get-config.js b/lib/get-config.js index bd40cecc1d..c65f9db16d 100644 --- a/lib/get-config.js +++ b/lib/get-config.js @@ -1,5 +1,5 @@ const {castArray, pickBy, isNil, isString, isPlainObject} = require('lodash'); -const readPkgUp = require('read-pkg-up'); +const findPkgUp = require('pkg-up'); const {cosmiconfig} = require('cosmiconfig'); const resolveFrom = require('resolve-from'); const debug = require('debug')('semantic-release:config'); @@ -74,7 +74,7 @@ module.exports = async (context, cliOptions) => { {name: 'beta', prerelease: true}, {name: 'alpha', prerelease: true}, ], - repositoryUrl: (await pkgRepoUrl({normalize: false, cwd})) || (await repoUrl({cwd, env})), + repositoryUrl: (await pkgRepoUrl({cwd})) || (await repoUrl({cwd, env})), tagFormat: `v\${version}`, plugins: [ '@semantic-release/commit-analyzer', @@ -93,6 +93,11 @@ module.exports = async (context, cliOptions) => { }; async function pkgRepoUrl(options) { - const {packageJson} = (await readPkgUp(options)) || {}; - return packageJson && (isPlainObject(packageJson.repository) ? packageJson.repository.url : packageJson.repository); + const packageJsonPath = await findPkgUp(options); + if (!packageJsonPath) return; + + const {repository} = require(packageJsonPath); + if (!repository) return; + + return isPlainObject(repository) ? repository.url : repository; } diff --git a/package.json b/package.json index fdbf3b90f0..b7c64bde4e 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "micromatch": "^4.0.2", "p-each-series": "^2.1.0", "p-reduce": "^2.0.0", - "read-pkg-up": "^7.0.0", + "pkg-up": "^3.1.0", "resolve-from": "^5.0.0", "semver": "^7.3.2", "semver-diff": "^3.1.1", From 9efed6ee390c535552353525ccd9d2bb7a683aad Mon Sep 17 00:00:00 2001 From: Gregor Martynus Date: Sun, 11 Oct 2020 14:07:24 -0700 Subject: [PATCH 2/7] test: Throw an Error if package.json has duplicate "repository" key --- test/get-config.test.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/get-config.test.js b/test/get-config.test.js index 4e5b456708..14f9e31c3b 100644 --- a/test/get-config.test.js +++ b/test/get-config.test.js @@ -516,3 +516,21 @@ test('Throw an Error if one of the shareable config cannot be found', async (t) code: 'MODULE_NOT_FOUND', }); }); + +test('Throw an Error if package.json has duplicate "repository" key', async (t) => { + // Create a git repository, set the current working directory at the root of the repo + const {cwd} = await gitRepo(); + + // Create package.json with duplicate "repository" key + await writeFile( + path.resolve(cwd, 'package.json'), + `{ + "repository": "https://github.com/octocat/repository", + "repository": "https://github.com/octocat/repository" + }` + ); + + const error = await t.throwsAsync(t.context.getConfig({cwd})); + t.deepEqual(error.code, 'EDUPLICATEREPOSITORYKEY') + t.deepEqual(error.message, 'Duplicate `"repository"` key in package.json.') +}); From 25b7ea579ede358826b70248e5c05319be2cc767 Mon Sep 17 00:00:00 2001 From: Gregor Martynus Date: Sun, 11 Oct 2020 14:30:28 -0700 Subject: [PATCH 3/7] build(deps): find-duplicated-property-keys --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index b7c64bde4e..bc1f9b0a2e 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "env-ci": "^5.0.0", "execa": "^4.0.0", "figures": "^3.0.0", + "find-duplicated-property-keys": "^1.2.2", "find-versions": "^3.0.0", "get-stream": "^5.0.0", "git-log-parser": "^1.2.0", From d6a6f3e65127f72a903cfaaf13def1f438f3e8ec Mon Sep 17 00:00:00 2001 From: Gregor Martynus Date: Sun, 11 Oct 2020 14:32:06 -0700 Subject: [PATCH 4/7] docs(CONTRIBUTING): add note about default git branch when running tests --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a3c40c5851..0e9c655b6a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -229,7 +229,7 @@ Before pushing your code changes make sure there are no linting errors with `npm ### Tests -Running the integration test requires you to install [Docker](https://docs.docker.com/engine/installation) on your machine. +Running the integration test requires you to install [Docker](https://docs.docker.com/engine/installation) on your machine. Note: the test assume that running `git init` will create a `master` branch by default. If your local `git` is configured differently (see `init.defaultBranch`), change it temporarily when running the tests. All the [semantic-release](https://github.com/semantic-release) repositories use [AVA](https://github.com/avajs/ava) for writing and running tests. From 194a2c83262931500d7b604a43885eaa9f9c62a1 Mon Sep 17 00:00:00 2001 From: Gregor Martynus Date: Sun, 11 Oct 2020 14:32:25 -0700 Subject: [PATCH 5/7] feat: Throw an Error if package.json has duplicate "repository" key --- lib/definitions/errors.js | 4 ++++ lib/get-config.js | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/definitions/errors.js b/lib/definitions/errors.js index a602983803..75546d282a 100644 --- a/lib/definitions/errors.js +++ b/lib/definitions/errors.js @@ -29,6 +29,10 @@ Please make sure to add the \`repositoryUrl\` to the [semantic-release configura 'docs/usage/configuration.md' )}).`, }), + EDUPLICATEREPOSITORYKEY: ({ packageJsonPath }) => ({ + message: 'Duplicate `"repository"` key in package.json.', + details: `Your package.json file at ${packageJsonPath} has more than one "repository" keys.`, + }), EGITNOPERMISSION: ({options: {repositoryUrl}, branch: {name}}) => ({ message: 'Cannot push to the Git repository.', details: `**semantic-release** cannot push the version tag to the branch \`${name}\` on the remote Git repository with URL \`${repositoryUrl}\`. diff --git a/lib/get-config.js b/lib/get-config.js index c65f9db16d..73d390a8de 100644 --- a/lib/get-config.js +++ b/lib/get-config.js @@ -1,12 +1,16 @@ +const { readFile } = require('fs').promises const {castArray, pickBy, isNil, isString, isPlainObject} = require('lodash'); const findPkgUp = require('pkg-up'); const {cosmiconfig} = require('cosmiconfig'); const resolveFrom = require('resolve-from'); +const findDuplicatedPropertyKeys = require('find-duplicated-property-keys') const debug = require('debug')('semantic-release:config'); const {repoUrl} = require('./git'); const PLUGINS_DEFINITIONS = require('./definitions/plugins'); const plugins = require('./plugins'); const {validatePlugin, parseConfig} = require('./plugins/utils'); +const getError = require('./get-error'); + const CONFIG_NAME = 'release'; const CONFIG_FILES = [ @@ -96,6 +100,13 @@ async function pkgRepoUrl(options) { const packageJsonPath = await findPkgUp(options); if (!packageJsonPath) return; + const packageJsonString = await readFile(packageJsonPath, 'utf-8') + const result = findDuplicatedPropertyKeys(packageJsonString) + + if (result.length) { + throw getError('EDUPLICATEREPOSITORYKEY', {packageJsonPath}); + } + const {repository} = require(packageJsonPath); if (!repository) return; From aa32cabdda58f4b4e51df67c20f6fc650a50c25a Mon Sep 17 00:00:00 2001 From: Gregor Martynus Date: Sun, 11 Oct 2020 14:35:34 -0700 Subject: [PATCH 6/7] style: xo --- lib/definitions/errors.js | 2 +- lib/get-config.js | 13 ++++++------- package.json | 3 ++- test/get-config.test.js | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/definitions/errors.js b/lib/definitions/errors.js index 75546d282a..b125b778d8 100644 --- a/lib/definitions/errors.js +++ b/lib/definitions/errors.js @@ -29,7 +29,7 @@ Please make sure to add the \`repositoryUrl\` to the [semantic-release configura 'docs/usage/configuration.md' )}).`, }), - EDUPLICATEREPOSITORYKEY: ({ packageJsonPath }) => ({ + EDUPLICATEREPOSITORYKEY: ({packageJsonPath}) => ({ message: 'Duplicate `"repository"` key in package.json.', details: `Your package.json file at ${packageJsonPath} has more than one "repository" keys.`, }), diff --git a/lib/get-config.js b/lib/get-config.js index 73d390a8de..e7bf683284 100644 --- a/lib/get-config.js +++ b/lib/get-config.js @@ -1,9 +1,9 @@ -const { readFile } = require('fs').promises +const {readFile} = require('fs').promises; const {castArray, pickBy, isNil, isString, isPlainObject} = require('lodash'); const findPkgUp = require('pkg-up'); const {cosmiconfig} = require('cosmiconfig'); const resolveFrom = require('resolve-from'); -const findDuplicatedPropertyKeys = require('find-duplicated-property-keys') +const findDuplicatedPropertyKeys = require('find-duplicated-property-keys'); const debug = require('debug')('semantic-release:config'); const {repoUrl} = require('./git'); const PLUGINS_DEFINITIONS = require('./definitions/plugins'); @@ -11,7 +11,6 @@ const plugins = require('./plugins'); const {validatePlugin, parseConfig} = require('./plugins/utils'); const getError = require('./get-error'); - const CONFIG_NAME = 'release'; const CONFIG_FILES = [ 'package.json', @@ -100,11 +99,11 @@ async function pkgRepoUrl(options) { const packageJsonPath = await findPkgUp(options); if (!packageJsonPath) return; - const packageJsonString = await readFile(packageJsonPath, 'utf-8') - const result = findDuplicatedPropertyKeys(packageJsonString) + const packageJsonString = await readFile(packageJsonPath, 'utf-8'); + const result = findDuplicatedPropertyKeys(packageJsonString); - if (result.length) { - throw getError('EDUPLICATEREPOSITORYKEY', {packageJsonPath}); + if (result.length > 0) { + throw getError('EDUPLICATEREPOSITORYKEY', {packageJsonPath}); } const {repository} = require(packageJsonPath); diff --git a/package.json b/package.json index bc1f9b0a2e..12146b8893 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,8 @@ "prettier": true, "space": true, "rules": { - "unicorn/string-content": "off" + "unicorn/string-content": "off", + "node/no-unsupported-features/node-builtins": "off" } } } diff --git a/test/get-config.test.js b/test/get-config.test.js index 14f9e31c3b..f44a90b9d0 100644 --- a/test/get-config.test.js +++ b/test/get-config.test.js @@ -531,6 +531,6 @@ test('Throw an Error if package.json has duplicate "repository" key', async (t) ); const error = await t.throwsAsync(t.context.getConfig({cwd})); - t.deepEqual(error.code, 'EDUPLICATEREPOSITORYKEY') - t.deepEqual(error.message, 'Duplicate `"repository"` key in package.json.') + t.is(error.code, 'EDUPLICATEREPOSITORYKEY'); + t.is(error.message, 'Duplicate `"repository"` key in package.json.'); }); From 86282711a4a8b127e0c85ade979f0383d5826f2d Mon Sep 17 00:00:00 2001 From: Gregor Martynus Date: Sun, 11 Oct 2020 14:44:48 -0700 Subject: [PATCH 7/7] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e9c655b6a..1f466461cd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -229,7 +229,7 @@ Before pushing your code changes make sure there are no linting errors with `npm ### Tests -Running the integration test requires you to install [Docker](https://docs.docker.com/engine/installation) on your machine. Note: the test assume that running `git init` will create a `master` branch by default. If your local `git` is configured differently (see `init.defaultBranch`), change it temporarily when running the tests. +Running the integration test requires you to install [Docker](https://docs.docker.com/engine/installation) on your machine. Note: the tests assume that running `git init` will create a `master` branch by default. If your local `git` is configured differently (see [`init.defaultBranch`](https://github.blog/2020-07-27-highlights-from-git-2-28/#introducing-init-defaultbranch)), change it temporarily when running the tests. All the [semantic-release](https://github.com/semantic-release) repositories use [AVA](https://github.com/avajs/ava) for writing and running tests.