From 6c500c8fce778baa997a0a9665973c75a304e4a0 Mon Sep 17 00:00:00 2001 From: Flosch Date: Sun, 12 Apr 2020 14:31:09 +0200 Subject: [PATCH 1/8] build(microbundle): rewrite codebase to ESM compile to ESM and CommonJS BREAKING CHANGE: internal file structure has been changed and root index.js has been removed --- .gitignore | 4 +++ .../get-contributors-from-commits.js | 11 ++++++++ lib/contributors/merge-contributors.js | 11 ++++++++ lib/contributors/save-contributors.js | 25 +++++++++++++++++++ lib/get-contributors-from-commits.js | 10 -------- lib/index.js | 3 +++ lib/merge-contributors.js | 12 --------- lib/save-contributors.js | 23 ----------------- index.js => lib/steps/prepare.js | 16 ++++++------ package.json | 24 +++++++++++++----- .../get-contributors-from-commits.test.js | 8 +++--- .../merge-contributors.test.js | 2 +- .../save-contributors.test.js | 2 +- test/integration.test.js | 2 +- 14 files changed, 86 insertions(+), 67 deletions(-) create mode 100644 lib/contributors/get-contributors-from-commits.js create mode 100644 lib/contributors/merge-contributors.js create mode 100644 lib/contributors/save-contributors.js delete mode 100644 lib/get-contributors-from-commits.js create mode 100644 lib/index.js delete mode 100644 lib/merge-contributors.js delete mode 100644 lib/save-contributors.js rename index.js => lib/steps/prepare.js (60%) rename test/{ => contributors}/get-contributors-from-commits.test.js (87%) rename test/{ => contributors}/merge-contributors.test.js (96%) rename test/{ => contributors}/save-contributors.test.js (97%) diff --git a/.gitignore b/.gitignore index fa6f8ca..e712e92 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,7 @@ $RECYCLE.BIN/ package-lock.json yarn.lock + +# Dist subfolder + +dist diff --git a/lib/contributors/get-contributors-from-commits.js b/lib/contributors/get-contributors-from-commits.js new file mode 100644 index 0000000..2cc7eb0 --- /dev/null +++ b/lib/contributors/get-contributors-from-commits.js @@ -0,0 +1,11 @@ +import {chain} from 'lodash'; + +const getContributorsFromCommits = (commits = []) => + chain(commits) + .map((commit) => commit.author) + .sortBy('date') + .map(({email, name}) => ({email, name})) + .uniqBy('email') + .value(); + +export default getContributorsFromCommits; diff --git a/lib/contributors/merge-contributors.js b/lib/contributors/merge-contributors.js new file mode 100644 index 0000000..e2a3889 --- /dev/null +++ b/lib/contributors/merge-contributors.js @@ -0,0 +1,11 @@ +import parseAuthor from 'parse-author'; +import {chain, concat} from 'lodash'; + +const parseContributor = (contributor) => (typeof contributor === 'string' ? parseAuthor(contributor) : contributor); + +const mergeContributors = (packageContributors = [], commitsContributors = []) => + chain(concat(packageContributors.map(parseContributor), commitsContributors.map(parseContributor))) + .uniqBy('email') + .value(); + +export default mergeContributors; diff --git a/lib/contributors/save-contributors.js b/lib/contributors/save-contributors.js new file mode 100644 index 0000000..d2e98dd --- /dev/null +++ b/lib/contributors/save-contributors.js @@ -0,0 +1,25 @@ +import {readJson, writeJson} from 'fs-extra'; +import stringifyAuthor from 'stringify-author'; +import mergeContributors from './merge-contributors'; + +const saveContributors = async (packageFilePath, contributors = [], format = 'string', logger = undefined) => { + const pkg = await readJson(packageFilePath); + + let allContributors = mergeContributors(pkg.contributors, contributors); + + if (format === 'string') { + allContributors = allContributors.map(stringifyAuthor); + } + + if (logger) { + logger.info('Updated contributors list', allContributors); + } + + pkg.contributors = allContributors; + + await writeJson(packageFilePath, pkg, { + spaces: 2, + }); +}; + +export default saveContributors; diff --git a/lib/get-contributors-from-commits.js b/lib/get-contributors-from-commits.js deleted file mode 100644 index 57ac249..0000000 --- a/lib/get-contributors-from-commits.js +++ /dev/null @@ -1,10 +0,0 @@ -const {chain} = require('lodash'); - -module.exports = function (commits = []) { - return chain(commits) - .map((commit) => commit.author) - .sortBy('date') - .map(({email, name}) => ({email, name})) - .uniqBy('email') - .value(); -}; diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..7300fca --- /dev/null +++ b/lib/index.js @@ -0,0 +1,3 @@ +import prepare from './steps/prepare'; + +export {prepare}; diff --git a/lib/merge-contributors.js b/lib/merge-contributors.js deleted file mode 100644 index 162d56a..0000000 --- a/lib/merge-contributors.js +++ /dev/null @@ -1,12 +0,0 @@ -const {chain, concat} = require('lodash'); -const parseAuthor = require('parse-author'); - -const parseContributor = function (contributor) { - return typeof contributor === 'string' ? parseAuthor(contributor) : contributor; -}; - -module.exports = function (packageContributors = [], commitsContributors = []) { - return chain(concat(packageContributors.map(parseContributor), commitsContributors.map(parseContributor))) - .uniqBy('email') - .value(); -}; diff --git a/lib/save-contributors.js b/lib/save-contributors.js deleted file mode 100644 index ab6e363..0000000 --- a/lib/save-contributors.js +++ /dev/null @@ -1,23 +0,0 @@ -const fs = require('fs-extra'); -const stringifyAuthor = require('stringify-author'); -const mergeContributors = require('./merge-contributors'); - -module.exports = async function (packageFilePath, contributors = [], format = 'string', logger = undefined) { - const pkg = await fs.readJson(packageFilePath); - - let allContributors = mergeContributors(pkg.contributors, contributors); - - if (format === 'string') { - allContributors = allContributors.map(stringifyAuthor); - } - - if (logger) { - logger.info('Updated contributors list', allContributors); - } - - pkg.contributors = allContributors; - - await fs.writeJson(packageFilePath, pkg, { - spaces: 2, - }); -}; diff --git a/index.js b/lib/steps/prepare.js similarity index 60% rename from index.js rename to lib/steps/prepare.js index 2f1c545..aba5bb9 100644 --- a/index.js +++ b/lib/steps/prepare.js @@ -1,9 +1,9 @@ -const path = require('path'); -const AggregateError = require('aggregate-error'); -const getContributors = require('./lib/get-contributors-from-commits'); -const saveContributors = require('./lib/save-contributors'); +import path from 'path'; +import AggregateError from 'aggregate-error'; +import getContributors from '../contributors/get-contributors-from-commits'; +import saveContributors from '../contributors/save-contributors'; -async function prepare(pluginConfig, context) { +const prepare = async (pluginConfig, context) => { const errors = []; const {cwd, commits, logger} = context; @@ -19,8 +19,6 @@ async function prepare(pluginConfig, context) { if (errors.length > 0) { throw new AggregateError(errors); } -} - -module.exports = { - prepare, }; + +export default prepare; diff --git a/package.json b/package.json index 09e3d43..5cb9b48 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "node": ">=10.18" }, "files": [ - "lib", - "index.js" + "dist", + "lib" ], "keywords": [ "author", @@ -39,14 +39,21 @@ "version" ], "license": "MIT", - "main": "index.js", + "module": "dist/index.esm.js", + "main": "dist/index.js", + "source": "lib/index.js", "scripts": { + "build": "microbundle -f cjs,es --target node", "codecov": "codecov -f coverage/coverage-final.json", "commit": "git-cz", "lint": "xo", + "postinstall": "npm run build", + "prebuild": "rimraf dist/*", + "presemantic-release": "npm run build", "pretest": "npm run lint", "semantic-release": "semantic-release", - "test": "nyc ava -v" + "test": "nyc ava -v", + "watch": "microbundle watch" }, "dependencies": { "aggregate-error": "^3.0.0", @@ -69,10 +76,13 @@ "codecov": "^3.5.0", "commitizen": "^4.0.3", "cz-conventional-changelog": "^3.0.2", + "esm": "^3.2.25", "husky": "^4.2.3", "lint-staged": "^10.0.3", + "microbundle": "^0.12.0-next.8", "nyc": "^15.0.1", "prettier": "^2.0.4", + "rimraf": "^3.0.2", "semantic-release": "^17.0.4", "sinon": "^9.0.2", "tempy": "^0.5.0", @@ -89,12 +99,14 @@ "babel": true, "files": [ "test/**/*.test.js" + ], + "require": [ + "esm" ] }, "nyc": { "include": [ - "lib/**/*.js", - "index.js" + "lib/**/*.js" ], "reporter": [ "json", diff --git a/test/get-contributors-from-commits.test.js b/test/contributors/get-contributors-from-commits.test.js similarity index 87% rename from test/get-contributors-from-commits.test.js rename to test/contributors/get-contributors-from-commits.test.js index 0c34f5d..97cbf16 100644 --- a/test/get-contributors-from-commits.test.js +++ b/test/contributors/get-contributors-from-commits.test.js @@ -1,6 +1,6 @@ import test from 'ava'; import {stub} from 'sinon'; -import getContributors from '../lib/get-contributors-from-commits'; +import getContributorsFromCommits from '../../lib/contributors/get-contributors-from-commits'; test.beforeEach((t) => { // Stub the logger functions @@ -17,7 +17,7 @@ test.beforeEach((t) => { }); test('Extract an empty list if the commit list is empty', (t) => { - const contributors = getContributors(); + const contributors = getContributorsFromCommits(); t.is(contributors.length, 0); }); @@ -26,7 +26,7 @@ test('Extract a list of contributors from a commits list', (t) => { const firstCommiterName = 'John Doe'; const secondCommiterEmail = 'john.smith@domain.tld'; - const contributors = getContributors([ + const contributors = getContributorsFromCommits([ { message: 'feat(something): add something', author: { @@ -52,7 +52,7 @@ test('Removes duplicates email from the commiters list', (t) => { const name = 'John Doe'; const email = 'john.doe@domain.tld'; - const contributors = getContributors([ + const contributors = getContributorsFromCommits([ { message: 'feat(something): add something', author: { diff --git a/test/merge-contributors.test.js b/test/contributors/merge-contributors.test.js similarity index 96% rename from test/merge-contributors.test.js rename to test/contributors/merge-contributors.test.js index 22a9ca6..878e190 100644 --- a/test/merge-contributors.test.js +++ b/test/contributors/merge-contributors.test.js @@ -1,6 +1,6 @@ import test from 'ava'; import {stub} from 'sinon'; -import mergeContributors from '../lib/merge-contributors'; +import mergeContributors from '../../lib/contributors/merge-contributors'; test.beforeEach((t) => { // Stub the logger functions diff --git a/test/save-contributors.test.js b/test/contributors/save-contributors.test.js similarity index 97% rename from test/save-contributors.test.js rename to test/contributors/save-contributors.test.js index 73ce601..71506f2 100644 --- a/test/save-contributors.test.js +++ b/test/contributors/save-contributors.test.js @@ -3,7 +3,7 @@ import test from 'ava'; import {stub} from 'sinon'; import tempy from 'tempy'; import {outputJson, readJson} from 'fs-extra'; -import saveContributors from '../lib/save-contributors'; +import saveContributors from '../../lib/contributors/save-contributors'; test.beforeEach((t) => { // Stub the logger functions diff --git a/test/integration.test.js b/test/integration.test.js index a4cd300..537aea0 100644 --- a/test/integration.test.js +++ b/test/integration.test.js @@ -5,7 +5,7 @@ import {spy} from 'sinon'; import tempy from 'tempy'; test.beforeEach((t) => { - t.context.m = require('..'); + t.context.m = require('../lib'); const log = spy(); t.context.log = log; From 88d171c27feff6a1ade79a3bcc1a05c7947e79a4 Mon Sep 17 00:00:00 2001 From: Flosch Date: Sun, 12 Apr 2020 14:47:27 +0200 Subject: [PATCH 2/8] perf(dependencies): remove lodash and fs-extra use jsonfile straight and internal array helpers instead --- .../get-contributors-from-commits.js | 21 ++++-- lib/contributors/merge-contributors.js | 21 ++++-- lib/contributors/save-contributors.js | 14 +++- lib/helpers/sort-by.js | 22 +++++++ lib/helpers/uniq-by.js | 26 ++++++++ package.json | 4 +- test/contributors/save-contributors.test.js | 7 +- test/helpers/sort-by.test.js | 60 +++++++++++++++++ test/helpers/uniq-by.test.js | 66 +++++++++++++++++++ 9 files changed, 222 insertions(+), 19 deletions(-) create mode 100644 lib/helpers/sort-by.js create mode 100644 lib/helpers/uniq-by.js create mode 100644 test/helpers/sort-by.test.js create mode 100644 test/helpers/uniq-by.test.js diff --git a/lib/contributors/get-contributors-from-commits.js b/lib/contributors/get-contributors-from-commits.js index 2cc7eb0..e54688f 100644 --- a/lib/contributors/get-contributors-from-commits.js +++ b/lib/contributors/get-contributors-from-commits.js @@ -1,11 +1,18 @@ -import {chain} from 'lodash'; +import uniqBy from '../helpers/uniq-by'; +import sortBy from '../helpers/sort-by'; +/** + * Extract an array of contributors from an array of commits, removing duplicates on email + * + * @param array commits + */ const getContributorsFromCommits = (commits = []) => - chain(commits) - .map((commit) => commit.author) - .sortBy('date') - .map(({email, name}) => ({email, name})) - .uniqBy('email') - .value(); + uniqBy( + sortBy(commits, 'date').map((commit) => ({ + email: commit.author.email, + name: commit.author.name, + })), + 'email' + ); export default getContributorsFromCommits; diff --git a/lib/contributors/merge-contributors.js b/lib/contributors/merge-contributors.js index e2a3889..c99276f 100644 --- a/lib/contributors/merge-contributors.js +++ b/lib/contributors/merge-contributors.js @@ -1,11 +1,24 @@ import parseAuthor from 'parse-author'; -import {chain, concat} from 'lodash'; +import uniqBy from '../helpers/uniq-by'; +/** + * Parse a contributor string with parse-author + * + * @param mixed contributor + * + * @return object + */ const parseContributor = (contributor) => (typeof contributor === 'string' ? parseAuthor(contributor) : contributor); +/** + * Merge array of contributors, parsing them and removing duplicates on email + * + * @param array packageContributors + * @param array commitsContributors + * + * @return array + */ const mergeContributors = (packageContributors = [], commitsContributors = []) => - chain(concat(packageContributors.map(parseContributor), commitsContributors.map(parseContributor))) - .uniqBy('email') - .value(); + uniqBy(packageContributors.concat(commitsContributors).map(parseContributor), 'email'); export default mergeContributors; diff --git a/lib/contributors/save-contributors.js b/lib/contributors/save-contributors.js index d2e98dd..f5a48e0 100644 --- a/lib/contributors/save-contributors.js +++ b/lib/contributors/save-contributors.js @@ -1,9 +1,17 @@ -import {readJson, writeJson} from 'fs-extra'; +import {readFile, writeFile} from 'jsonfile'; import stringifyAuthor from 'stringify-author'; import mergeContributors from './merge-contributors'; +/** + * Save an array of contributors to a package.json file + * + * @param string packageFilePath + * @param array contributors + * @param string format + * @param mixed logger + */ const saveContributors = async (packageFilePath, contributors = [], format = 'string', logger = undefined) => { - const pkg = await readJson(packageFilePath); + const pkg = await readFile(packageFilePath); let allContributors = mergeContributors(pkg.contributors, contributors); @@ -17,7 +25,7 @@ const saveContributors = async (packageFilePath, contributors = [], format = 'st pkg.contributors = allContributors; - await writeJson(packageFilePath, pkg, { + await writeFile(packageFilePath, pkg, { spaces: 2, }); }; diff --git a/lib/helpers/sort-by.js b/lib/helpers/sort-by.js new file mode 100644 index 0000000..dcdfc3d --- /dev/null +++ b/lib/helpers/sort-by.js @@ -0,0 +1,22 @@ +/** + * Sort an array of objects by a given property + * + * @param array items + * @param string property + * + * @return array + */ +const sortBy = (items, property) => + items.sort((itemA, itemB) => { + if (itemA[property] > itemB[property]) { + return -1; + } + + if (itemA[property] < itemB[property]) { + return 1; + } + + return 0; + }); + +export default sortBy; diff --git a/lib/helpers/uniq-by.js b/lib/helpers/uniq-by.js new file mode 100644 index 0000000..b3fe80a --- /dev/null +++ b/lib/helpers/uniq-by.js @@ -0,0 +1,26 @@ +/** + * Remove duplicates from an array of objects by a given property + * + * @param array items + * @param string property + * + * @return array + */ +const uniqBy = (items, property) => + items.reduce((uniqItems, item) => { + const value = item[property]; + + if (typeof value === 'undefined') { + uniqItems.push(item); + } else { + const uniqKeys = uniqItems.map((i) => i[property]); + + if (!uniqKeys.includes(item[property])) { + uniqItems.push(item); + } + } + + return uniqItems; + }, []); + +export default uniqBy; diff --git a/package.json b/package.json index 5cb9b48..ff6a2ae 100644 --- a/package.json +++ b/package.json @@ -57,8 +57,7 @@ }, "dependencies": { "aggregate-error": "^3.0.0", - "fs-extra": "^9.0.0", - "lodash": "^4.17.15", + "jsonfile": "^6.0.1", "parse-author": "^2.0.0", "stringify-author": "^0.1.3" }, @@ -77,6 +76,7 @@ "commitizen": "^4.0.3", "cz-conventional-changelog": "^3.0.2", "esm": "^3.2.25", + "fs-extra": "^9.0.0", "husky": "^4.2.3", "lint-staged": "^10.0.3", "microbundle": "^0.12.0-next.8", diff --git a/test/contributors/save-contributors.test.js b/test/contributors/save-contributors.test.js index 71506f2..b67db2c 100644 --- a/test/contributors/save-contributors.test.js +++ b/test/contributors/save-contributors.test.js @@ -2,7 +2,8 @@ import path from 'path'; import test from 'ava'; import {stub} from 'sinon'; import tempy from 'tempy'; -import {outputJson, readJson} from 'fs-extra'; +import {readFile} from 'jsonfile'; +import {outputJson} from 'fs-extra'; import saveContributors from '../../lib/contributors/save-contributors'; test.beforeEach((t) => { @@ -62,7 +63,7 @@ test('Save an updated list of contributors in "string" format', async (t) => { ); }); - pkg = await readJson(filepath); + pkg = await readFile(filepath); t.is(pkg.contributors.length, 2); t.is(typeof pkg.contributors[0], 'string'); @@ -97,7 +98,7 @@ test('Save an updated list of contributors in "object" format', async (t) => { ); }); - pkg = await readJson(filepath); + pkg = await readFile(filepath); t.is(pkg.contributors.length, 2); t.is(typeof pkg.contributors[0], 'object'); diff --git a/test/helpers/sort-by.test.js b/test/helpers/sort-by.test.js new file mode 100644 index 0000000..999c12e --- /dev/null +++ b/test/helpers/sort-by.test.js @@ -0,0 +1,60 @@ +import test from 'ava'; +import sortBy from '../../lib/helpers/sort-by'; + +test('Sort by a given property', (t) => { + const value1 = 'foo'; + const value2 = 'bar'; + const value3 = 'baz'; + + const sortedItems = sortBy( + [ + { + id: 1, + value: value1, + }, + { + id: 3, + value: value3, + }, + { + id: 2, + value: value2, + }, + ], + 'id' + ); + + t.is(sortedItems.length, 3); + t.is(sortedItems[0].value, value3); + t.is(sortedItems[1].value, value2); + t.is(sortedItems[2].value, value1); +}); + +test('Return the array as such when the property does not exists', (t) => { + const value1 = 'foo'; + const value2 = 'bar'; + const value3 = 'baz'; + + const sortedItems = sortBy( + [ + { + id: 1, + value: value1, + }, + { + id: 3, + value: value3, + }, + { + id: 2, + value: value2, + }, + ], + 'unexisting-property' + ); + + t.is(sortedItems.length, 3); + t.is(sortedItems[0].value, value1); + t.is(sortedItems[1].value, value3); + t.is(sortedItems[2].value, value2); +}); diff --git a/test/helpers/uniq-by.test.js b/test/helpers/uniq-by.test.js new file mode 100644 index 0000000..46f3f2d --- /dev/null +++ b/test/helpers/uniq-by.test.js @@ -0,0 +1,66 @@ +import test from 'ava'; +import uniqBy from '../../lib/helpers/uniq-by'; + +test('Removes duplicate by a given property', (t) => { + const value = 'foo'; + const uniqItems = uniqBy( + [ + { + id: 1, + value, + }, + { + id: 1, + value: 'bar', + }, + ], + 'id' + ); + + t.is(uniqItems.length, 1); + t.is(uniqItems[0].value, value); +}); + +test('Returns the array without change if there is no duplicate', (t) => { + const value1 = 'foo'; + const value2 = 'bar'; + const uniqItems = uniqBy( + [ + { + id: 1, + value: value1, + }, + { + id: 2, + value: value2, + }, + ], + 'id' + ); + + t.is(uniqItems.length, 2); + t.is(uniqItems[0].value, value1); + t.is(uniqItems[1].value, value2); +}); + +test('Returns the array as such if the property does not exist', (t) => { + const value1 = 'foo'; + const value2 = 'bar'; + const uniqItems = uniqBy( + [ + { + id: 1, + value: value1, + }, + { + id: 2, + value: value2, + }, + ], + 'unexisting-property' + ); + + t.is(uniqItems.length, 2); + t.is(uniqItems[0].value, value1); + t.is(uniqItems[1].value, value2); +}); From 73c50f13d09eb9655fe0f8826bbb53e946cb26ee Mon Sep 17 00:00:00 2001 From: Flosch Date: Sun, 12 Apr 2020 14:56:37 +0200 Subject: [PATCH 3/8] docs(badges): add bundlephobia and license badges to README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c0a3cfb..27aaccf 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ [![Maintainability](https://api.codeclimate.com/v1/badges/0c542e19db095ddb9947/maintainability)](https://codeclimate.com/github/flo-sch/semantic-release-contributors/maintainability) [![npm latest version](https://img.shields.io/npm/v/semantic-release-contributors/latest.svg)](https://www.npmjs.com/package/semantic-release-contributors) +![npm bundle size](https://img.shields.io/bundlephobia/min/semantic-release-contributors) +![npm bundle size](https://img.shields.io/bundlephobia/minzip/semantic-release-contributors) +![NPM](https://img.shields.io/npm/l/semantic-release-contributors) | Step | Description | |----------------|------------------------------------------------------------------------------------------------------------| From 4573bd30bfde8890a70b01a1928f83e2f4b157fc Mon Sep 17 00:00:00 2001 From: Flosch Date: Sun, 12 Apr 2020 18:29:32 +0200 Subject: [PATCH 4/8] docs(readme): improve markdown syntax --- README.md | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 27aaccf..b7f3cdb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # **contributors** -[**semantic-release**](https://github.com/semantic-release/semantic-release) plugin to automatically update contributors list from git history +[**semantic-release**](https://github.com/semantic-release/semantic-release) +plugin to automatically update contributors list based on commits history [![Travis](https://img.shields.io/travis/flo-sch/semantic-release-contributors.svg)](https://travis-ci.org/flo-sch/semantic-release-contributors) [![Codecov](https://img.shields.io/codecov/c/github/flo-sch/semantic-release-contributors.svg)](https://codecov.io/gh/flo-sch/semantic-release-contributors) @@ -12,19 +13,20 @@ ![npm bundle size](https://img.shields.io/bundlephobia/minzip/semantic-release-contributors) ![NPM](https://img.shields.io/npm/l/semantic-release-contributors) -| Step | Description | -|----------------|------------------------------------------------------------------------------------------------------------| -| `prepare` | Determine the contributors list by analyzing git history. | +| Step | Description | +|----------------|------------------------------------------------------------------| +| `prepare` | Determine the contributors list by analyzing commits history. | ## Install ```bash -$ npm install semantic-release-contributors -D +npm install semantic-release-contributors -D ``` -## How does it work? +## How does it work -Whenener someone commit to the project, his/her name will be appended to the [contributors list of your package.json](https://docs.npmjs.com/files/package.json#people-fields-author-contributors) file. +Whenener someone commit to the project, his/her name will be appended +to the [contributors list of your package.json](https://docs.npmjs.com/files/package.json#people-fields-author-contributors) file. If `Paul Smith` commits to a project with the following set-up: @@ -51,7 +53,10 @@ The `package.json` file would then be updated to: } ``` -**NOTE**: this package internally deserialize the contributors to objects (name, email, url) and make sure duplicated emails are removed. Contributors objects are then potentially re-serialized before being written to the package file (unless you opt for a different format) +**NOTE**: this package internally deserialize the contributors to +objects (name, email, url) and make sure duplicated emails are removed. +Contributors objects are then potentially re-serialized before being written +to the package file (unless you opt for a different format) ## Usage @@ -69,8 +74,10 @@ The plugin can be configured in the [**semantic-release** configuration file](ht ``` With this example: -- the contributors will be stringified to `name ` -- the package file containing the contributors will be read then updated in the current directory + +* the contributors will be stringified to `name ` +* the package file containing the contributors will be read +then updated in the current directory ## Configuration @@ -83,8 +90,8 @@ With this example: ## Similar or related projects -- [parse-author](https://www.npmjs.com/package/parse-author) -- [stringify-author](https://www.npmjs.com/package/stringify-author) +* [parse-author](https://www.npmjs.com/package/parse-author) +* [stringify-author](https://www.npmjs.com/package/stringify-author)

Kill all humans From 0f3aa81ff1616246db66f668de7d75466233ca8f Mon Sep 17 00:00:00 2001 From: Flosch Date: Sun, 12 Apr 2020 18:30:57 +0200 Subject: [PATCH 5/8] refactor(uniq-by): attempt to reduce Cognitive Complexity --- lib/helpers/uniq-by.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/helpers/uniq-by.js b/lib/helpers/uniq-by.js index b3fe80a..7db07c3 100644 --- a/lib/helpers/uniq-by.js +++ b/lib/helpers/uniq-by.js @@ -9,15 +9,10 @@ const uniqBy = (items, property) => items.reduce((uniqItems, item) => { const value = item[property]; + const uniqKeys = uniqItems.map((i) => i[property]); - if (typeof value === 'undefined') { + if (typeof value === 'undefined' || !uniqKeys.includes(value)) { uniqItems.push(item); - } else { - const uniqKeys = uniqItems.map((i) => i[property]); - - if (!uniqKeys.includes(item[property])) { - uniqItems.push(item); - } } return uniqItems; From 4b14f0f4c11c1f23a83e0928f9a33cc19f1c3adf Mon Sep 17 00:00:00 2001 From: Flosch Date: Sun, 12 Apr 2020 19:12:15 +0200 Subject: [PATCH 6/8] refactor(prepare): streamline function name --- lib/steps/prepare.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/steps/prepare.js b/lib/steps/prepare.js index aba5bb9..54edd5f 100644 --- a/lib/steps/prepare.js +++ b/lib/steps/prepare.js @@ -1,6 +1,6 @@ import path from 'path'; import AggregateError from 'aggregate-error'; -import getContributors from '../contributors/get-contributors-from-commits'; +import getContributorsFromCommits from '../contributors/get-contributors-from-commits'; import saveContributors from '../contributors/save-contributors'; const prepare = async (pluginConfig, context) => { @@ -11,7 +11,12 @@ const prepare = async (pluginConfig, context) => { const pkgRoot = pluginConfig.pkgRoot || '.'; try { - await saveContributors(path.resolve(cwd, pkgRoot, 'package.json'), getContributors(commits), format, logger); + await saveContributors( + path.resolve(cwd, pkgRoot, 'package.json'), + getContributorsFromCommits(commits), + format, + logger + ); } catch (error) { errors.push(error); } From 23cff6c8735ed641536c912e9ea3cde3d38e601d Mon Sep 17 00:00:00 2001 From: Flosch Date: Sun, 12 Apr 2020 19:13:24 +0200 Subject: [PATCH 7/8] docs(config): add note regarding plugins order --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b7f3cdb..f941c8d 100644 --- a/README.md +++ b/README.md @@ -62,13 +62,21 @@ to the package file (unless you opt for a different format) The plugin can be configured in the [**semantic-release** configuration file](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#configuration): +**IMPORTANT**: since this plugin acts on semantic-release's "prepare" step +and do not commit the updated package.json file itself, +it *requires* to be placed *before* "@semantic-release/git". + ```json { "plugins": [ + // important: insert it before @semantic-release/git ["semantic-release-contributors", { "format": "string", "pkgRoot": "." - }] + }], + // ... + "@semantic-release/git" + // ... ] } ``` From e45714726e9a20250af27657bc753b3fa4dde3ec Mon Sep 17 00:00:00 2001 From: Flosch Date: Sun, 12 Apr 2020 19:37:33 +0200 Subject: [PATCH 8/8] docs(badges): center badges as semantic-release does --- README.md | 61 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index f941c8d..64a00b9 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,50 @@ -# **contributors** - -[**semantic-release**](https://github.com/semantic-release/semantic-release) -plugin to automatically update contributors list based on commits history - -[![Travis](https://img.shields.io/travis/flo-sch/semantic-release-contributors.svg)](https://travis-ci.org/flo-sch/semantic-release-contributors) -[![Codecov](https://img.shields.io/codecov/c/github/flo-sch/semantic-release-contributors.svg)](https://codecov.io/gh/flo-sch/semantic-release-contributors) -[![Known Vulnerabilities](https://snyk.io/test/github/flo-sch/semantic-release-contributors/badge.svg?targetFile=package.json)](https://snyk.io/test/github/flo-sch/semantic-release-contributors?targetFile=package.json) -[![Maintainability](https://api.codeclimate.com/v1/badges/0c542e19db095ddb9947/maintainability)](https://codeclimate.com/github/flo-sch/semantic-release-contributors/maintainability) +

📦🤖 semantic-release-contributors

+

+ semantic-release + plugin to automatically update contributors list based on commits history +

+

+ + Semantic Release + + + Commitizen friendly + +

+

+ + Travis + + + Codecov + + + Known Vulnerabilities + + + Maintainability + +

+

+ + npm latest version + + + npm bundle size + + + npm bundle size + + + LICENSE + +

-[![npm latest version](https://img.shields.io/npm/v/semantic-release-contributors/latest.svg)](https://www.npmjs.com/package/semantic-release-contributors) -![npm bundle size](https://img.shields.io/bundlephobia/min/semantic-release-contributors) -![npm bundle size](https://img.shields.io/bundlephobia/minzip/semantic-release-contributors) -![NPM](https://img.shields.io/npm/l/semantic-release-contributors) +------------------ -| Step | Description | -|----------------|------------------------------------------------------------------| -| `prepare` | Determine the contributors list by analyzing commits history. | +| Step | Description | +|----------------|-----------------------------------------------------------------------------------------------------| +| `prepare` | Determine the contributors list by analyzing commits history. | ## Install