feat: throw an Error if package.json has duplicate "repository" key (#1656)
This commit is contained in:
		
							parent
							
								
									18e35b28ad
								
							
						
					
					
						commit
						b8fb35c7e1
					
				| @ -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 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. | ||||
| 
 | ||||
|  | ||||
| @ -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}\`.
 | ||||
|  | ||||
| @ -1,12 +1,15 @@ | ||||
| const {readFile} = require('fs').promises; | ||||
| 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 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 = [ | ||||
| @ -74,7 +77,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 +96,18 @@ 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 packageJsonString = await readFile(packageJsonPath, 'utf-8'); | ||||
|   const result = findDuplicatedPropertyKeys(packageJsonString); | ||||
| 
 | ||||
|   if (result.length > 0) { | ||||
|     throw getError('EDUPLICATEREPOSITORYKEY', {packageJsonPath}); | ||||
|   } | ||||
| 
 | ||||
|   const {repository} = require(packageJsonPath); | ||||
|   if (!repository) return; | ||||
| 
 | ||||
|   return isPlainObject(repository) ? repository.url : repository; | ||||
| } | ||||
|  | ||||
| @ -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", | ||||
| @ -42,7 +43,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", | ||||
| @ -128,7 +129,8 @@ | ||||
|     "prettier": true, | ||||
|     "space": true, | ||||
|     "rules": { | ||||
|       "unicorn/string-content": "off" | ||||
|       "unicorn/string-content": "off", | ||||
|       "node/no-unsupported-features/node-builtins": "off" | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -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.is(error.code, 'EDUPLICATEREPOSITORYKEY'); | ||||
|   t.is(error.message, 'Duplicate `"repository"` key in package.json.'); | ||||
| }); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user