From a59e6800dd5f8fad8dd16d2380529c275b482d5b Mon Sep 17 00:00:00 2001 From: Artem Sapegin Date: Mon, 27 Jan 2020 13:54:10 +0100 Subject: [PATCH] chore: Add tasks to the monorepo --- .eslintignore | 6 +- .prettierignore | 2 + Readme.md | 444 ++--------------- __mocks__/fs.js | 2 + docs/Custom_presets.md | 59 +++ docs/FAQ.md | 63 +++ docs/Getting_started.md | 76 +++ docs/Sharing_tasks.md | 42 ++ docs/Writing_tasks.md | 114 +++++ lerna.json | 3 +- package-lock.json | 16 +- package.json | 8 +- packages/mrm-core/Readme.md | 8 +- .../__tests__/__snapshots__/fs.spec.js.snap | 5 - .../__snapshots__/packageJson.spec.js.snap | 1 - .../__tests__/__snapshots__/file.spec.js.snap | 4 - .../__tests__/__snapshots__/ini.spec.js.snap | 5 - .../__tests__/__snapshots__/json.spec.js.snap | 2 - .../__snapshots__/markdown.spec.js.snap | 1 - .../__snapshots__/template.spec.js.snap | 2 - .../__tests__/__snapshots__/yaml.spec.js.snap | 2 - packages/mrm-preset-default/License.md | 9 + packages/mrm-preset-default/Readme.md | 42 ++ packages/mrm-preset-default/codecov/index.js | 1 + packages/mrm-preset-default/config.json | 1 + .../mrm-preset-default/contributing/index.js | 1 + .../mrm-preset-default/editorconfig/index.js | 1 + packages/mrm-preset-default/eslint/index.js | 1 + .../mrm-preset-default/gitignore/index.js | 1 + packages/mrm-preset-default/index.spec.js | 94 ++++ packages/mrm-preset-default/jest/index.js | 1 + packages/mrm-preset-default/license/index.js | 1 + .../mrm-preset-default/lint-staged/index.js | 1 + packages/mrm-preset-default/package-lock.json | 356 ++++++++++++++ packages/mrm-preset-default/package.json | 45 ++ packages/mrm-preset-default/package/index.js | 1 + packages/mrm-preset-default/prettier/index.js | 1 + packages/mrm-preset-default/readme/index.js | 1 + .../semantic-release/index.js | 1 + .../mrm-preset-default/styleguidist/index.js | 1 + .../mrm-preset-default/stylelint/index.js | 1 + packages/mrm-preset-default/travis/index.js | 1 + .../mrm-preset-default/typescript/index.js | 1 + packages/mrm-task-codecov/License.md | 9 + packages/mrm-task-codecov/Readme.md | 36 ++ .../__snapshots__/index.spec.js.snap | 23 + packages/mrm-task-codecov/index.js | 56 +++ packages/mrm-task-codecov/index.spec.js | 74 +++ packages/mrm-task-codecov/package-lock.json | 433 ++++++++++++++++ packages/mrm-task-codecov/package.json | 31 ++ packages/mrm-task-contributing/License.md | 9 + packages/mrm-task-contributing/Readme.md | 44 ++ .../__snapshots__/index.spec.js.snap | 59 +++ packages/mrm-task-contributing/index.js | 37 ++ packages/mrm-task-contributing/index.spec.js | 36 ++ .../mrm-task-contributing/package-lock.json | 433 ++++++++++++++++ packages/mrm-task-contributing/package.json | 30 ++ .../templates/Contributing.md | 49 ++ packages/mrm-task-editorconfig/License.md | 9 + packages/mrm-task-editorconfig/Readme.md | 36 ++ .../__snapshots__/index.spec.js.snap | 54 ++ packages/mrm-task-editorconfig/index.js | 47 ++ packages/mrm-task-editorconfig/index.spec.js | 37 ++ .../mrm-task-editorconfig/package-lock.json | 354 ++++++++++++++ packages/mrm-task-editorconfig/package.json | 28 ++ packages/mrm-task-eslint/License.md | 9 + packages/mrm-task-eslint/Readme.md | 52 ++ .../__snapshots__/index.spec.js.snap | 219 +++++++++ packages/mrm-task-eslint/index.js | 151 ++++++ packages/mrm-task-eslint/index.spec.js | 252 ++++++++++ packages/mrm-task-eslint/package-lock.json | 354 ++++++++++++++ packages/mrm-task-eslint/package.json | 30 ++ packages/mrm-task-gitignore/License.md | 9 + packages/mrm-task-gitignore/Readme.md | 28 ++ .../__snapshots__/index.spec.js.snap | 44 ++ packages/mrm-task-gitignore/index.js | 37 ++ packages/mrm-task-gitignore/index.spec.js | 38 ++ packages/mrm-task-gitignore/package-lock.json | 354 ++++++++++++++ packages/mrm-task-gitignore/package.json | 29 ++ packages/mrm-task-gitter/License.md | 9 + packages/mrm-task-gitter/Readme.md | 32 ++ packages/mrm-task-gitter/index.js | 17 + packages/mrm-task-gitter/package-lock.json | 354 ++++++++++++++ packages/mrm-task-gitter/package.json | 30 ++ packages/mrm-task-jest/License.md | 9 + packages/mrm-task-jest/Readme.md | 34 ++ .../__snapshots__/index.spec.js.snap | 146 ++++++ packages/mrm-task-jest/index.js | 154 ++++++ packages/mrm-task-jest/index.spec.js | 191 ++++++++ packages/mrm-task-jest/package-lock.json | 354 ++++++++++++++ packages/mrm-task-jest/package.json | 31 ++ packages/mrm-task-jest/templates/index.js | 5 + packages/mrm-task-jest/templates/jestsetup.js | 4 + packages/mrm-task-jest/templates/test.js | 6 + packages/mrm-task-license/License.md | 9 + packages/mrm-task-license/Readme.md | 52 ++ .../__snapshots__/index.spec.js.snap | 40 ++ packages/mrm-task-license/index.js | 56 +++ packages/mrm-task-license/index.spec.js | 98 ++++ packages/mrm-task-license/package-lock.json | 388 +++++++++++++++ packages/mrm-task-license/package.json | 32 ++ .../mrm-task-license/templates/Apache-2.0.md | 9 + .../templates/BSD-2-Clause.md | 11 + .../templates/BSD-3-Clause.md | 13 + packages/mrm-task-license/templates/MIT.md | 9 + .../mrm-task-license/templates/Unlicense.md | 9 + packages/mrm-task-lint-staged/License.md | 9 + packages/mrm-task-lint-staged/Readme.md | 93 ++++ .../__snapshots__/index.spec.js.snap | 303 ++++++++++++ packages/mrm-task-lint-staged/index.js | 192 ++++++++ packages/mrm-task-lint-staged/index.spec.js | 343 +++++++++++++ .../mrm-task-lint-staged/package-lock.json | 354 ++++++++++++++ packages/mrm-task-lint-staged/package.json | 30 ++ packages/mrm-task-package/License.md | 9 + packages/mrm-task-package/Readme.md | 52 ++ .../__snapshots__/index.spec.js.snap | 79 +++ packages/mrm-task-package/index.js | 52 ++ packages/mrm-task-package/index.spec.js | 52 ++ packages/mrm-task-package/package-lock.json | 462 ++++++++++++++++++ packages/mrm-task-package/package.json | 32 ++ packages/mrm-task-prettier/License.md | 9 + packages/mrm-task-prettier/Readme.md | 56 +++ .../__snapshots__/index.spec.js.snap | 103 ++++ packages/mrm-task-prettier/index.js | 96 ++++ packages/mrm-task-prettier/index.spec.js | 105 ++++ packages/mrm-task-prettier/package-lock.json | 359 ++++++++++++++ packages/mrm-task-prettier/package.json | 34 ++ packages/mrm-task-readme/License.md | 9 + packages/mrm-task-readme/Readme.md | 56 +++ .../__snapshots__/index.spec.js.snap | 27 + packages/mrm-task-readme/index.js | 37 ++ packages/mrm-task-readme/index.spec.js | 38 ++ packages/mrm-task-readme/package-lock.json | 462 ++++++++++++++++++ packages/mrm-task-readme/package.json | 31 ++ packages/mrm-task-readme/templates/Readme.md | 17 + packages/mrm-task-semantic-release/License.md | 9 + packages/mrm-task-semantic-release/Readme.md | 54 ++ .../__snapshots__/index.spec.js.snap | 111 +++++ packages/mrm-task-semantic-release/index.js | 162 ++++++ .../mrm-task-semantic-release/index.spec.js | 158 ++++++ .../package-lock.json | 433 ++++++++++++++++ .../mrm-task-semantic-release/package.json | 29 ++ packages/mrm-task-styleguidist/License.md | 9 + packages/mrm-task-styleguidist/Readme.md | 29 ++ .../__snapshots__/index.spec.js.snap | 26 + packages/mrm-task-styleguidist/index.js | 49 ++ packages/mrm-task-styleguidist/index.spec.js | 84 ++++ .../mrm-task-styleguidist/package-lock.json | 354 ++++++++++++++ packages/mrm-task-styleguidist/package.json | 30 ++ .../templates/styleguide.config.js | 3 + .../templates/styleguide.config.typescript.js | 4 + packages/mrm-task-stylelint/License.md | 9 + packages/mrm-task-stylelint/Readme.md | 46 ++ .../__snapshots__/index.spec.js.snap | 42 ++ packages/mrm-task-stylelint/index.js | 52 ++ packages/mrm-task-stylelint/index.spec.js | 73 +++ packages/mrm-task-stylelint/package-lock.json | 354 ++++++++++++++ packages/mrm-task-stylelint/package.json | 30 ++ packages/mrm-task-travis/License.md | 9 + packages/mrm-task-travis/Readme.md | 45 ++ .../__snapshots__/index.spec.js.snap | 53 ++ packages/mrm-task-travis/index.js | 60 +++ packages/mrm-task-travis/index.spec.js | 77 +++ packages/mrm-task-travis/package-lock.json | 438 +++++++++++++++++ packages/mrm-task-travis/package.json | 31 ++ packages/mrm-task-typescript/License.md | 9 + packages/mrm-task-typescript/Readme.md | 30 ++ .../__snapshots__/index.spec.js.snap | 28 ++ packages/mrm-task-typescript/index.js | 33 ++ packages/mrm-task-typescript/index.spec.js | 32 ++ .../mrm-task-typescript/package-lock.json | 354 ++++++++++++++ packages/mrm-task-typescript/package.json | 28 ++ packages/mrm/Readme.md | 435 +---------------- 173 files changed, 13493 insertions(+), 880 deletions(-) create mode 100644 .prettierignore create mode 100644 __mocks__/fs.js create mode 100644 docs/Custom_presets.md create mode 100644 docs/FAQ.md create mode 100644 docs/Getting_started.md create mode 100644 docs/Sharing_tasks.md create mode 100644 docs/Writing_tasks.md create mode 100644 packages/mrm-preset-default/License.md create mode 100644 packages/mrm-preset-default/Readme.md create mode 100644 packages/mrm-preset-default/codecov/index.js create mode 100644 packages/mrm-preset-default/config.json create mode 100644 packages/mrm-preset-default/contributing/index.js create mode 100644 packages/mrm-preset-default/editorconfig/index.js create mode 100644 packages/mrm-preset-default/eslint/index.js create mode 100644 packages/mrm-preset-default/gitignore/index.js create mode 100644 packages/mrm-preset-default/index.spec.js create mode 100644 packages/mrm-preset-default/jest/index.js create mode 100644 packages/mrm-preset-default/license/index.js create mode 100644 packages/mrm-preset-default/lint-staged/index.js create mode 100644 packages/mrm-preset-default/package-lock.json create mode 100644 packages/mrm-preset-default/package.json create mode 100644 packages/mrm-preset-default/package/index.js create mode 100644 packages/mrm-preset-default/prettier/index.js create mode 100644 packages/mrm-preset-default/readme/index.js create mode 100644 packages/mrm-preset-default/semantic-release/index.js create mode 100644 packages/mrm-preset-default/styleguidist/index.js create mode 100644 packages/mrm-preset-default/stylelint/index.js create mode 100644 packages/mrm-preset-default/travis/index.js create mode 100644 packages/mrm-preset-default/typescript/index.js create mode 100644 packages/mrm-task-codecov/License.md create mode 100644 packages/mrm-task-codecov/Readme.md create mode 100644 packages/mrm-task-codecov/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-codecov/index.js create mode 100644 packages/mrm-task-codecov/index.spec.js create mode 100644 packages/mrm-task-codecov/package-lock.json create mode 100644 packages/mrm-task-codecov/package.json create mode 100644 packages/mrm-task-contributing/License.md create mode 100644 packages/mrm-task-contributing/Readme.md create mode 100644 packages/mrm-task-contributing/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-contributing/index.js create mode 100644 packages/mrm-task-contributing/index.spec.js create mode 100644 packages/mrm-task-contributing/package-lock.json create mode 100644 packages/mrm-task-contributing/package.json create mode 100644 packages/mrm-task-contributing/templates/Contributing.md create mode 100644 packages/mrm-task-editorconfig/License.md create mode 100644 packages/mrm-task-editorconfig/Readme.md create mode 100644 packages/mrm-task-editorconfig/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-editorconfig/index.js create mode 100644 packages/mrm-task-editorconfig/index.spec.js create mode 100644 packages/mrm-task-editorconfig/package-lock.json create mode 100644 packages/mrm-task-editorconfig/package.json create mode 100644 packages/mrm-task-eslint/License.md create mode 100644 packages/mrm-task-eslint/Readme.md create mode 100644 packages/mrm-task-eslint/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-eslint/index.js create mode 100644 packages/mrm-task-eslint/index.spec.js create mode 100644 packages/mrm-task-eslint/package-lock.json create mode 100644 packages/mrm-task-eslint/package.json create mode 100644 packages/mrm-task-gitignore/License.md create mode 100644 packages/mrm-task-gitignore/Readme.md create mode 100644 packages/mrm-task-gitignore/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-gitignore/index.js create mode 100644 packages/mrm-task-gitignore/index.spec.js create mode 100644 packages/mrm-task-gitignore/package-lock.json create mode 100644 packages/mrm-task-gitignore/package.json create mode 100644 packages/mrm-task-gitter/License.md create mode 100644 packages/mrm-task-gitter/Readme.md create mode 100644 packages/mrm-task-gitter/index.js create mode 100644 packages/mrm-task-gitter/package-lock.json create mode 100644 packages/mrm-task-gitter/package.json create mode 100644 packages/mrm-task-jest/License.md create mode 100644 packages/mrm-task-jest/Readme.md create mode 100644 packages/mrm-task-jest/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-jest/index.js create mode 100644 packages/mrm-task-jest/index.spec.js create mode 100644 packages/mrm-task-jest/package-lock.json create mode 100644 packages/mrm-task-jest/package.json create mode 100644 packages/mrm-task-jest/templates/index.js create mode 100644 packages/mrm-task-jest/templates/jestsetup.js create mode 100644 packages/mrm-task-jest/templates/test.js create mode 100644 packages/mrm-task-license/License.md create mode 100644 packages/mrm-task-license/Readme.md create mode 100644 packages/mrm-task-license/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-license/index.js create mode 100644 packages/mrm-task-license/index.spec.js create mode 100644 packages/mrm-task-license/package-lock.json create mode 100644 packages/mrm-task-license/package.json create mode 100644 packages/mrm-task-license/templates/Apache-2.0.md create mode 100644 packages/mrm-task-license/templates/BSD-2-Clause.md create mode 100644 packages/mrm-task-license/templates/BSD-3-Clause.md create mode 100644 packages/mrm-task-license/templates/MIT.md create mode 100644 packages/mrm-task-license/templates/Unlicense.md create mode 100644 packages/mrm-task-lint-staged/License.md create mode 100644 packages/mrm-task-lint-staged/Readme.md create mode 100644 packages/mrm-task-lint-staged/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-lint-staged/index.js create mode 100644 packages/mrm-task-lint-staged/index.spec.js create mode 100644 packages/mrm-task-lint-staged/package-lock.json create mode 100644 packages/mrm-task-lint-staged/package.json create mode 100644 packages/mrm-task-package/License.md create mode 100644 packages/mrm-task-package/Readme.md create mode 100644 packages/mrm-task-package/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-package/index.js create mode 100644 packages/mrm-task-package/index.spec.js create mode 100644 packages/mrm-task-package/package-lock.json create mode 100644 packages/mrm-task-package/package.json create mode 100644 packages/mrm-task-prettier/License.md create mode 100644 packages/mrm-task-prettier/Readme.md create mode 100644 packages/mrm-task-prettier/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-prettier/index.js create mode 100644 packages/mrm-task-prettier/index.spec.js create mode 100644 packages/mrm-task-prettier/package-lock.json create mode 100644 packages/mrm-task-prettier/package.json create mode 100644 packages/mrm-task-readme/License.md create mode 100644 packages/mrm-task-readme/Readme.md create mode 100644 packages/mrm-task-readme/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-readme/index.js create mode 100644 packages/mrm-task-readme/index.spec.js create mode 100644 packages/mrm-task-readme/package-lock.json create mode 100644 packages/mrm-task-readme/package.json create mode 100644 packages/mrm-task-readme/templates/Readme.md create mode 100644 packages/mrm-task-semantic-release/License.md create mode 100644 packages/mrm-task-semantic-release/Readme.md create mode 100644 packages/mrm-task-semantic-release/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-semantic-release/index.js create mode 100644 packages/mrm-task-semantic-release/index.spec.js create mode 100644 packages/mrm-task-semantic-release/package-lock.json create mode 100644 packages/mrm-task-semantic-release/package.json create mode 100644 packages/mrm-task-styleguidist/License.md create mode 100644 packages/mrm-task-styleguidist/Readme.md create mode 100644 packages/mrm-task-styleguidist/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-styleguidist/index.js create mode 100644 packages/mrm-task-styleguidist/index.spec.js create mode 100644 packages/mrm-task-styleguidist/package-lock.json create mode 100644 packages/mrm-task-styleguidist/package.json create mode 100644 packages/mrm-task-styleguidist/templates/styleguide.config.js create mode 100644 packages/mrm-task-styleguidist/templates/styleguide.config.typescript.js create mode 100644 packages/mrm-task-stylelint/License.md create mode 100644 packages/mrm-task-stylelint/Readme.md create mode 100644 packages/mrm-task-stylelint/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-stylelint/index.js create mode 100644 packages/mrm-task-stylelint/index.spec.js create mode 100644 packages/mrm-task-stylelint/package-lock.json create mode 100644 packages/mrm-task-stylelint/package.json create mode 100644 packages/mrm-task-travis/License.md create mode 100644 packages/mrm-task-travis/Readme.md create mode 100644 packages/mrm-task-travis/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-travis/index.js create mode 100644 packages/mrm-task-travis/index.spec.js create mode 100644 packages/mrm-task-travis/package-lock.json create mode 100644 packages/mrm-task-travis/package.json create mode 100644 packages/mrm-task-typescript/License.md create mode 100644 packages/mrm-task-typescript/Readme.md create mode 100644 packages/mrm-task-typescript/__snapshots__/index.spec.js.snap create mode 100644 packages/mrm-task-typescript/index.js create mode 100644 packages/mrm-task-typescript/index.spec.js create mode 100644 packages/mrm-task-typescript/package-lock.json create mode 100644 packages/mrm-task-typescript/package.json diff --git a/.eslintignore b/.eslintignore index 1a4be94d..08aabaa1 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,3 @@ -node_modules -coverage/* -src/tasks/jest/test.js -src/tasks/styleguidist/templates/ node_modules/ +coverage/* +packages/*/templates/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..c79fef2c --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +packages/mrm-task-jest/templates/test.js +packages/mrm-task-readme/templates/Readme.md diff --git a/Readme.md b/Readme.md index e07660ea..cd2190a7 100644 --- a/Readme.md +++ b/Readme.md @@ -1,128 +1,34 @@ # Mrm -[![Build Status](https://travis-ci.org/sapegin/mrm.svg)](https://travis-ci.org/sapegin/mrm) [![npm](https://img.shields.io/npm/v/mrm.svg)](https://www.npmjs.com/package/mrm) +[![Build Status](https://travis-ci.org/sapegin/mrm.svg)](https://travis-ci.org/sapegin/mrm) [![npm](https://img.shields.io/npm/v/mrm.svg)](https://www.npmjs.com/package/mrm) [![Codecov](https://codecov.io/gh/sapegin/mrm/branch/master/graph/badge.svg)](https://codecov.io/gh/sapegin/mrm) Command line tool to help you keep configuration (`package.json`, `.gitignore`, `.eslintrc`, etc.) of your open source projects in sync. ## Features -- Will not overwrite your data if you don’t want it to -- Minimal changes: will keep the original file formatting or read the style from EditorConfig -- Minimal configuration: will try to infer configuration from the project itself or from the environment -- Bunch of [customizable tasks](#tasks) included -- Tools to work with JSON, YAML, INI, Markdown and new line separated text files -- Easy to write [your own tasks](#writing-your-own-tasks) -- Share tasks via npm and group them into [presets](#custom-presets) +- Doesn’t overwrite your data unless you want to +- Minimal changes: keeps the original file formatting or read the style from EditorConfig +- Minimal configuration: tries to infer configuration from the project itself or from the environment +- [Customizable tasks](#tasks) for popular tools like ESLint, Prettier, lint-staged, etc. included +- [Custom tasks](docs/Writing_tasks.md) and [tools](packages/mrm-core/Readme.md) to work with JSON, YAML, INI, Markdown and new line separated text files +- Sharing tasks via npm and grouping them into [presets](#custom-presets) ![](https://d3vv6lp55qjaqc.cloudfront.net/items/1g0e2M3m2Y3j0m3B3n1t/Image%202017-06-20%20at%209.00.39%20PM.png) -## Table of contents - - - - - -- [Motivation](#motivation) -- [Installation](#installation) -- [Usage](#usage) -- [Usage via npx](#usage-via-npx) -- [Configuration](#configuration) -- [Tasks](#tasks) -- [Writing your own tasks](#writing-your-own-tasks) -- [Sharing tasks via npm](#sharing-tasks-via-npm) -- [Custom presets](#custom-presets) -- [Config resolution rules](#config-resolution-rules) -- [Task resolution rules](#task-resolution-rules) -- [FAQ](#faq) - - [How to use Mrm with Lerna?](#how-to-use-mrm-with-lerna) - - [How to infer user metadata, like user name or email?](#how-to-infer-user-metadata-like-user-name-or-email) - - [How to infer GitHub user name?](#how-to-infer-github-user-name) -- [Change log](#change-log) -- [Contributing](#contributing) -- [Authors and license](#authors-and-license) - - - ## Motivation Most of the available tools are template based. Template approach works moderately well for new project generation but doesn’t work well for updating. Mrm’s approach is closer to [codemods](https://github.com/facebook/codemod) than templates. -Read more in my article, [Automating open source project configuration with Mrm](http://blog.sapegin.me/all/mrm), or watch [my talk on Mrm](https://www.youtube.com/watch?v=5tHfAf4bRcM). - -## Installation - -``` -npm install -g mrm -``` - -## Usage - -Print a list available of tasks: - -```shell -mrm -``` - -Run a task or an alias - -```shell -mrm gitignore -mrm license -``` - -Run multiple tasks: - -```shell -mrm gitignore license -``` - -Override config options (or run without a config file): - -```shell -mrm license --config:name "Gandalf the Grey" --config:email "gandalf@middleearth.com" --config:url "http://middleearth.com" -``` - -Custom config and tasks folder: - -```shell -mrm license --dir ~/unicorn -``` - -Run a task from a preset (globally installed `mrm-preset-unicorn` npm package, read more [about preset](#custom-presets)): - -```shell -mrm license --preset unicorn -``` - -## Usage via npx - -If you have npm 5.3 or newer you can use mrm without installation: +Read more in my article, [Automating open source project configuration with Mrm](https://blog.sapegin.me/all/mrm), or watch [my talk on Mrm](https://www.youtube.com/watch?v=5tHfAf4bRcM). -```shell -npx mrm -npx mrm gitignore -npx mrm license --config:name "Gandalf the Grey" --config:email "gandalf@middleearth.com" --config:url "http://middleearth.com" -``` +## Documentation -## Configuration - -Create `~/.mrm/config.json` or `~/dotfiles/mrm/config.json`: - -```json5 -{ - indent: 'tab', // "tab" or number of spaces - readmeFile: 'Readme.md', // Name of readme file - licenseFile: 'License.md', // Name of license file - aliases: { - // Aliases to run multiple tasks at once - node: ['license', 'readme', 'editorconfig', 'gitignore'] - } -} -``` - -See [tasks docs](https://github.com/sapegin/mrm-tasks) for available config options. - -_Config file isn’t required, you can also pass config options via command line. Default tasks will try to [read data](https://github.com/sapegin/user-meta) fom your npm and Git configuration._ +- [Getting started](docs/Getting_started.md) +- [Writing your own tasks](docs/Writing_tasks.md) +- [Sharing tasks via npm](docs/Sharing_tasks.md) +- [Custom presets](docs/Custom_presets.md) +- [FAQ](docs/FAQ.md) +- [Utilities to write codemods](packages/mrm-core/Readme.md) ## Tasks @@ -130,310 +36,28 @@ These tasks are included by default: -- [codecov](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-codecov) -- [contributing](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-contributing) -- [editorconfig](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-editorconfig) -- [eslint](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-eslint) -- [gitignore](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-gitignore) -- [jest](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-jest) -- [license](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-license) -- [lint-staged](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-lint-staged) -- [package](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-package) -- [prettier](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-prettier) -- [readme](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-readme) -- [semantic-release](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-semantic-release) -- [styleguidist](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-styleguidist) -- [stylelint](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-stylelint) -- [travis](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-travis) -- [typescript](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-typescript) +- [codecov](packages/mrm-task-codecov) +- [contributing](packages/mrm-task-contributing) +- [editorconfig](packages/mrm-task-editorconfig) +- [eslint](packages/mrm-task-eslint) +- [gitignore](packages/mrm-task-gitignore) +- [jest](packages/mrm-task-jest) +- [license](packages/mrm-task-license) +- [lint-staged](packages/mrm-task-lint-staged) +- [package](packages/mrm-task-package) +- [prettier](packages/mrm-task-prettier) +- [readme](packages/mrm-task-readme) +- [semantic-release](packages/mrm-task-semantic-release) +- [styleguidist](packages/mrm-task-styleguidist) +- [stylelint](packages/mrm-task-stylelint) +- [travis](packages/mrm-task-travis) +- [typescript](packages/mrm-task-typescript) -## Writing your own tasks - -Create either `~/.mrm//index.js` or `~/dotfiles/mrm//index.js`. If `` is the same as one of the default tasks your task will override a default one. - -The simplest task could look like this: - -```js -// Mrm module to work with new line separated text files -const { lines } = require('mrm-core'); - -function task() { - // Read .gitignore if it exists - lines('.gitignore') - // Add lines that do not exist in a file yet, - // but keep all existing lines - .add(['node_modules/', '.DS_Store']) - // Update or create a file - .save(); -} - -task.description = 'Adds .gitignore'; -module.exports = task; -``` - -Tasks can also be async by adding the `async` keyword or returning a `Promise`. - -```js -async function task() {} - -// or -function task() { - return new Promise(() => {}); -} -``` - -If your tasks have dependencies (such as `mrm-core`) you should initialize the `mrm` folder as an npm module and list your dependencies there: - -```bash -cd ~/.mrm # or cd ~/dotfiles/mrm -npm init -y -npm install --save mrm-core -``` - -[mrm-core](https://github.com/sapegin/mrm-core) is an utility library created to write Mrm tasks, it has function to work with common config files (JSON, YAML, INI, Markdown), npm dependencies, etc. - -Let’s take a look at a more complicated task: - -```js -const { - // JSON files - json, - // package.json - packageJson, - // New line separated text files - lines, - // Install npm packages - install -} = require('mrm-core'); - -function task(config) { - // Task options - // mrm eslint --config:name pizza - const { name, eslintPreset } = config - .defaults({ - // Default value - eslintPreset: 'eslint:recommended' - }) - // Required option - .require('name') - .values(); - - // Use custom preset package from npm - const packages = ['eslint']; - if (eslintPreset !== 'eslint:recommended') { - packages.push(`eslint-config-${eslintPreset}`); - } - - // Create or update .eslintignore - lines('.eslintignore') - .add(['node_modules/']) - .save(); - - // Read project’s package.json - const pkg = packageJson(); - - pkg - // Add lint script - .setScript('lint', 'eslint . --cache --fix') - // Add pretest script - .prependScript('pretest', 'npm run lint') - .save(); - - // Read .eslintrc if it exists - const eslintrc = json('.eslintrc'); - - // Use Babel parser if the project depends on Babel - if (pkg.get('devDependencies.babel-core')) { - const parser = 'babel-eslint'; - packages.push(parser); - eslintrc.merge({ parser }); - } - - // Set preset - eslintrc.set('extends', eslintPreset).save(); - - // Install npm dependencies - install(packages); -} - -task.description = 'Adds ESLint'; -module.exports = task; -``` - -There are more methods in `mrm-core` — check out [the docs](https://github.com/sapegin/mrm-core#api) and [the default tasks](https://github.com/sapegin/mrm-tasks). - -## Sharing tasks via npm - -The basic file structure of a shared task looks like this: - -``` -. -├── index.js -├── package.json -``` - -`index.js` is the same as described [in the previous section](#writing-custom-tasks). And the `package.json` would look like this: - -```json -{ - "name": "mrm-task-unicorn", - "version": "0.1.0", - "description": "Unicorn task for Mrm", - "author": { - "name": "Artem Sapegin", - "url": "http://sapegin.me" - }, - "homepage": "https://github.com/sapegin/mrm-tasks/packages/mrm-task-unicorn", - "repository": "sapegin/mrm-tasks", - "license": "MIT", - "engines": { - "node": ">=4" - }, - "main": "index.js", - "files": ["index.js"], - "keywords": ["mrm", "mrm-task", "unicorn"], - "dependencies": { - "mrm-core": "^2.1.3" - } -} -``` - -The package name should should follow this pattern: `mrm-task-`, otherwise you’ll have to type full package name when you run a task: - -``` -mrm unicorn # mrm-task-unicorn -mrm @mycompany/unicorn-task # @mycompany/unicorn-task -``` - -## Custom presets - -Preset is an npm package (or a directory) that contains a config and tasks. - -The file structure looks like this: - -``` -. -├── task1 -│   └── index.js -├── task2 -│   └── index.js -├── config.json -├── package.json -``` - -And the `package.json` would look like this: - -```json -{ - "name": "mrm-preset-default", - "version": "0.1.0", - "description": "Common tasks for Mrm", - "author": { - "name": "Artem Sapegin", - "url": "http://sapegin.me" - }, - "homepage": "https://github.com/sapegin/mrm-tasks/packages/mrm-preset-default", - "repository": "sapegin/mrm-tasks", - "license": "MIT", - "engines": { - "node": ">=4" - }, - "main": "config.json", - "files": ["config.json", "*/index.js"], - "keywords": ["mrm", "mrm-task", "mrm-preset"], - "dependencies": { - "mrm-core": "^2.1.3", - "mrm-task-gitignore": "^0.1.0" - } -} -``` - -See the [Writing custom tasks](#writing-custom-tasks) section above to learn how to write Mrm tasks. To add a task to a preset put it into a `/index.js` file in your preset package folder. - -If you want to use a task from npm (or any default task), you should include it as a dependency. That way you can be sure that you’ll always have a task version that works for your project. - -For example, if you want to use `mrm-task-gitignore` task, you need to create a `gitignore/index.js` file in your preset package folder: - -```js -module.exports = require('mrm-task-gitignore'); -``` - -The package name should should follow this pattern: `mrm-preset-`, otherwise you’ll have to type full package name when you run a task: - -``` -mrm license --preset unicorn # mrm-preset-unicorn -mrm license --preset @mycompany/unicorn-preset # @mycompany/unicorn-preset -``` - -## Config resolution rules - -- `/config.json` if `--dir ` command line option was passed -- `$HOME/dotfiles/mrm/config.json` -- `$HOME/.mrm/config.json` - -if you’re passing a `--preset ` command line option, then the only task directory will be: - -- `mrm-preset-/config.json` - -## Task resolution rules - -- `//index.js` if `--dir ` command line option was passed -- `$HOME/dotfiles/mrm//index.js` -- `$HOME/.mrm//index.js` -- `mrm-task-/index.js`, where `mrm-task-` is an npm package name -- `` in [mrm-preset-default](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-preset-default) - -if you’re passing a `--preset ` command line option, then the only task directory will be: - -- `mrm-preset-//index.js` - -## FAQ - -### How to use Mrm with Lerna? - -To run a task for each package in a [Lerna](https://github.com/lerna/lerna) repository: - -```bash -./node_modules/.bin/lerna exec -- mrm -``` - -### How to infer user metadata, like user name or email? - -Use the [user-meta](https://github.com/sapegin/user-meta) package to read user name, email and URL from `.npmrc` or `.gitconfig`: - -```js -const meta = require('user-meta'); -module.exports = function task(config) { - const { name, email, url } = config - .defaults(meta) - .require('name', 'email', 'url') - .values(); - /* ... */ -}; -``` - -### How to infer GitHub user name? - -Use the [git-username](https://github.com/jonschlinkert/git-username) package: - -```js -const gitUsername = require('git-username'); -module.exports = function task(config) { - const { github } = config - .defaults({ - github: gitUsername() - }) - .require('github') - .values(); - /* ... */ -}; -``` - -## Change log +## Changelog -The change log can be found on the [Releases page](https://github.com/sapegin/mrm/releases). +The changelog can be found on the [Releases page](https://github.com/sapegin/mrm/releases). ## Contributing @@ -441,6 +65,6 @@ Everyone is welcome to contribute. Please take a moment to review the [contribut ## Authors and license -[Artem Sapegin](http://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). MIT License, see the included [License.md](License.md) file. diff --git a/__mocks__/fs.js b/__mocks__/fs.js new file mode 100644 index 00000000..2b387053 --- /dev/null +++ b/__mocks__/fs.js @@ -0,0 +1,2 @@ +process.chdir('/'); +module.exports = require('memfs'); diff --git a/docs/Custom_presets.md b/docs/Custom_presets.md new file mode 100644 index 00000000..9b600a57 --- /dev/null +++ b/docs/Custom_presets.md @@ -0,0 +1,59 @@ +# Custom presets + +Preset is an npm package (or a directory) that contains a config and tasks. + +The file structure looks like this: + +``` +. +├── task1 +│   └── index.js +├── task2 +│   └── index.js +├── config.json +├── package.json +``` + +And the `package.json` would look like this: + +```json +{ + "name": "mrm-preset-default", + "version": "0.1.0", + "description": "Common tasks for Mrm", + "author": { + "name": "Artem Sapegin", + "url": "https://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-preset-default", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=4" + }, + "main": "config.json", + "files": ["config.json", "*/index.js"], + "keywords": ["mrm", "mrm-task", "mrm-preset"], + "dependencies": { + "mrm-core": "^2.1.3", + "mrm-task-gitignore": "^0.1.0" + } +} +``` + +See the [Writing custom tasks](#writing-custom-tasks) section above to learn how to write Mrm tasks. To add a task to a preset put it into a `/index.js` file in your preset package folder. + +If you want to use a task from npm (or any default task), you should include it as a dependency. That way you can be sure that you’ll always have a task version that works for your project. + +For example, if you want to use `mrm-task-gitignore` task, you need to create a `gitignore/index.js` file in your preset package folder: + +```js +module.exports = require('mrm-task-gitignore'); +``` + +The package name should should follow this pattern: `mrm-preset-`, otherwise you’ll have to type full package name when you run a task: + +``` +mrm license --preset unicorn # mrm-preset-unicorn +mrm license --preset @mycompany/unicorn-preset # @mycompany/unicorn-preset +``` diff --git a/docs/FAQ.md b/docs/FAQ.md new file mode 100644 index 00000000..540e02f5 --- /dev/null +++ b/docs/FAQ.md @@ -0,0 +1,63 @@ +# FAQ + +## How to use Mrm with Lerna? + +To run a task for each package in a [Lerna](https://github.com/lerna/lerna) repository: + +```bash +./node_modules/.bin/lerna exec -- mrm +``` + +## How to infer user metadata, like user name or email? + +Use the [user-meta](https://github.com/sapegin/user-meta) package to read user name, email and URL from `.npmrc` or `.gitconfig`: + +```js +const meta = require('user-meta'); +module.exports = function task(config) { + const { name, email, url } = config + .defaults(meta) + .require('name', 'email', 'url') + .values(); + /* ... */ +}; +``` + +## How to infer GitHub user name? + +Use the [git-username](https://github.com/jonschlinkert/git-username) package: + +```js +const gitUsername = require('git-username'); +module.exports = function task(config) { + const { github } = config + .defaults({ + github: gitUsername() + }) + .require('github') + .values(); + /* ... */ +}; +``` + +## Config resolution rules + +- `/config.json` if `--dir ` command line option was passed +- `$HOME/dotfiles/mrm/config.json` +- `$HOME/.mrm/config.json` + +if you’re passing a `--preset ` command line option, then the only task directory will be: + +- `mrm-preset-/config.json` + +## Task resolution rules + +- `//index.js` if `--dir ` command line option was passed +- `$HOME/dotfiles/mrm//index.js` +- `$HOME/.mrm//index.js` +- `mrm-task-/index.js`, where `mrm-task-` is an npm package name +- `` in [mrm-preset-default](../packages/mrm-preset-default) + +if you’re passing a `--preset ` command line option, then the only task directory will be: + +- `mrm-preset-//index.js` diff --git a/docs/Getting_started.md b/docs/Getting_started.md new file mode 100644 index 00000000..66dd1d39 --- /dev/null +++ b/docs/Getting_started.md @@ -0,0 +1,76 @@ +# Getting started with Mrm + +## Installation + +``` +npm install -g mrm +``` + +## Usage + +Print a list available of tasks: + +```shell +mrm +``` + +Run a task or an alias + +```shell +mrm gitignore +mrm license +``` + +Run multiple tasks: + +```shell +mrm gitignore license +``` + +Override config options (or run without a config file): + +```shell +mrm license --config:name "Gandalf the Grey" --config:email "gandalf@middleearth.com" --config:url "http://middleearth.com" +``` + +Custom config and tasks folder: + +```shell +mrm license --dir ~/unicorn +``` + +Run a task from a preset (globally installed `mrm-preset-unicorn` npm package, read more [about preset](#custom-presets)): + +```shell +mrm license --preset unicorn +``` + +## Usage via npx + +If you have npm 5.3 or newer you can use mrm without installation: + +```shell +npx mrm +npx mrm gitignore +npx mrm license --config:name "Gandalf the Grey" --config:email "gandalf@middleearth.com" --config:url "http://middleearth.com" +``` + +## Configuration + +Create `~/.mrm/config.json` or `~/dotfiles/mrm/config.json`: + +```json5 +{ + indent: 'tab', // "tab" or number of spaces + readmeFile: 'Readme.md', // Name of readme file + licenseFile: 'License.md', // Name of license file + aliases: { + // Aliases to run multiple tasks at once + node: ['license', 'readme', 'editorconfig', 'gitignore'] + } +} +``` + +See [tasks docs](../Readme.md#tasks) for available config options. + +_Config file isn’t required, you can also pass config options via command line. Default tasks will try to [read data](https://github.com/sapegin/user-meta) fom your npm and Git configuration._ diff --git a/docs/Sharing_tasks.md b/docs/Sharing_tasks.md new file mode 100644 index 00000000..6bb0d71d --- /dev/null +++ b/docs/Sharing_tasks.md @@ -0,0 +1,42 @@ +# Sharing tasks via npm + +The basic file structure of a shared task looks like this: + +``` +. +├── index.js +├── package.json +``` + +`index.js` is the same as described [in the previous section](#writing-custom-tasks). And the `package.json` would look like this: + +```json +{ + "name": "mrm-task-unicorn", + "version": "0.1.0", + "description": "Unicorn task for Mrm", + "author": { + "name": "Artem Sapegin", + "url": "https://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-unicorn", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=4" + }, + "main": "index.js", + "files": ["index.js"], + "keywords": ["mrm", "mrm-task", "unicorn"], + "dependencies": { + "mrm-core": "^2.1.3" + } +} +``` + +The package name should should follow this pattern: `mrm-task-`, otherwise you’ll have to type full package name when you run a task: + +``` +mrm unicorn # mrm-task-unicorn +mrm @mycompany/unicorn-task # @mycompany/unicorn-task +``` diff --git a/docs/Writing_tasks.md b/docs/Writing_tasks.md new file mode 100644 index 00000000..ff84f0e5 --- /dev/null +++ b/docs/Writing_tasks.md @@ -0,0 +1,114 @@ +# Writing your own tasks + +Create either `~/.mrm//index.js` or `~/dotfiles/mrm//index.js`. If `` is the same as one of the default tasks your task will override a default one. + +The simplest task could look like this: + +```js +// Mrm module to work with new line separated text files +const { lines } = require('mrm-core'); + +function task() { + // Read .gitignore if it exists + lines('.gitignore') + // Add lines that do not exist in a file yet, + // but keep all existing lines + .add(['node_modules/', '.DS_Store']) + // Update or create a file + .save(); +} + +task.description = 'Adds .gitignore'; +module.exports = task; +``` + +Tasks can also be async by adding the `async` keyword or returning a `Promise`. + +```js +async function task() {} + +// or +function task() { + return new Promise(() => {}); +} +``` + +If your tasks have dependencies (such as `mrm-core`) you should initialize the `mrm` folder as an npm module and list your dependencies there: + +```bash +cd ~/.mrm # or cd ~/dotfiles/mrm +npm init -y +npm install --save mrm-core +``` + +[mrm-core](../packages/mrm-core) is an utility library created to write Mrm tasks, it has functions to work with common config files (JSON, YAML, INI, Markdown), npm dependencies, etc. + +Let’s take a look at a more complicated task: + +```js +const { + // JSON files + json, + // package.json + packageJson, + // New line separated text files + lines, + // Install npm packages + install +} = require('mrm-core'); + +function task(config) { + // Task options + // mrm eslint --config:name pizza + const { name, eslintPreset } = config + .defaults({ + // Default value + eslintPreset: 'eslint:recommended' + }) + // Required option + .require('name') + .values(); + + // Use custom preset package from npm + const packages = ['eslint']; + if (eslintPreset !== 'eslint:recommended') { + packages.push(`eslint-config-${eslintPreset}`); + } + + // Create or update .eslintignore + lines('.eslintignore') + .add(['node_modules/']) + .save(); + + // Read project’s package.json + const pkg = packageJson(); + + pkg + // Add lint script + .setScript('lint', 'eslint . --cache --fix') + // Add pretest script + .prependScript('pretest', 'npm run lint') + .save(); + + // Read .eslintrc if it exists + const eslintrc = json('.eslintrc'); + + // Use Babel parser if the project depends on Babel + if (pkg.get('devDependencies.babel-core')) { + const parser = 'babel-eslint'; + packages.push(parser); + eslintrc.merge({ parser }); + } + + // Set preset + eslintrc.set('extends', eslintPreset).save(); + + // Install npm dependencies + install(packages); +} + +task.description = 'Adds ESLint'; +module.exports = task; +``` + +There are more methods in `mrm-core` — check out [the docs](../packages/mrm-core#api) and [the default tasks](../Readme.md#tasks). diff --git a/lerna.json b/lerna.json index be0cf53a..4c391d62 100644 --- a/lerna.json +++ b/lerna.json @@ -6,7 +6,7 @@ "command": { "version": { "allowBranch": "master", - "message": "chore: publish [skip ci]" + "message": "chore: Publish :shipit: [skip ci]" }, "publish": { "conventionalCommits": true, @@ -14,6 +14,7 @@ "package-lock.json", "Readme.md", "Changelog.md", + "CHANGELOG.md", "*.spec.js", "*.snap" ] diff --git a/package-lock.json b/package-lock.json index 6ef2a977..9a98fd2c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4307,9 +4307,9 @@ "dev": true }, "fast-extend": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/fast-extend/-/fast-extend-0.0.2.tgz", - "integrity": "sha1-9exCz0C5Rg9SGmOH37Ut7u1nHb0=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fast-extend/-/fast-extend-1.0.2.tgz", + "integrity": "sha512-XXA9RmlPatkFKUzqVZAFth18R4Wo+Xug/S+C7YlYA3xrXwfPlW3dqNwOb4hvQo7wZJ2cNDYhrYuPzVOfHy5/uQ==", "dev": true }, "fast-glob": { @@ -7796,13 +7796,13 @@ } }, "memfs": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-2.9.4.tgz", - "integrity": "sha512-wstvgqSTBGf9rQHoaRpX3wJiGzB/sj649XaO+byuHiPZQaR3Y/mOgU6n9iMFLtAHlR4BwwBWFgA4hobiU6EcCg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.0.4.tgz", + "integrity": "sha512-OcZEzwX9E5AoY8SXjuAvw0DbIAYwUzV/I236I8Pqvrlv7sL/Y0E9aRCon05DhaV8pg1b32uxj76RgW0s5xjHBA==", "dev": true, "requires": { - "fast-extend": "0.0.2", - "fs-monkey": "^0.3.3" + "fast-extend": "1.0.2", + "fs-monkey": "0.3.3" } }, "meow": { diff --git a/package.json b/package.json index 12d1ce41..6929b317 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "jest": "^24.9.0", "lerna": "^3.19.0", "lint-staged": "^9.4.3", - "memfs": "2.9.4", + "memfs": "3.0.4", "prettier": "^1.19.1", "typescript": "^3.7.3" }, @@ -52,6 +52,12 @@ "tool", "yaml" ], + "jest": { + "testPathIgnorePatterns": [ + "/node_modules/", + "/templates/" + ] + }, "lint-staged": { "*.js": [ "eslint --fix", diff --git a/packages/mrm-core/Readme.md b/packages/mrm-core/Readme.md index 03315820..e7359236 100644 --- a/packages/mrm-core/Readme.md +++ b/packages/mrm-core/Readme.md @@ -1,6 +1,6 @@ # Mrm core utils -[![npm](https://img.shields.io/npm/v/mrm-core.svg)](https://www.npmjs.com/package/mrm-core) [![Build Status](https://travis-ci.org/sapegin/mrm-core.svg)](https://travis-ci.org/sapegin/mrm-core) [![Codecov](https://codecov.io/gh/sapegin/mrm-core/branch/master/graph/badge.svg)](https://codecov.io/gh/sapegin/mrm-core) +[![npm](https://img.shields.io/npm/v/mrm-core.svg)](https://www.npmjs.com/package/mrm-core) Utilities to write codemods for config files (JSON, YAML, INI, Markdown, etc.). Can be used to make tasks for [Mrm](https://github.com/sapegin/mrm). @@ -410,13 +410,13 @@ if (!fs.existsSync('.travis.yml')) { } ``` -## Change log +## Changelog -The change log can be found on the [Releases page](https://github.com/sapegin/mrm/releases). +The changelog can be found on the [Releases page](https://github.com/sapegin/mrm/releases). ## Contributing -Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](Contributing.md). +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../Contributing.md). ## Authors and license diff --git a/packages/mrm-core/src/__tests__/__snapshots__/fs.spec.js.snap b/packages/mrm-core/src/__tests__/__snapshots__/fs.spec.js.snap index 47deeaf4..42ce1272 100644 --- a/packages/mrm-core/src/__tests__/__snapshots__/fs.spec.js.snap +++ b/packages/mrm-core/src/__tests__/__snapshots__/fs.spec.js.snap @@ -2,7 +2,6 @@ exports[`copyFiles() should copy a file 1`] = ` Object { - "/": null, "/a": "pizza", "/tmpl/a": "pizza", } @@ -10,7 +9,6 @@ Object { exports[`copyFiles() should copy multiple files 1`] = ` Object { - "/": null, "/a": "pizza", "/b": "coffee", "/tmpl/a": "pizza", @@ -20,7 +18,6 @@ Object { exports[`copyFiles() should not try to copy a file if contents is the same 1`] = ` Object { - "/": null, "/a": "pizza", "/b": "pizza", "/tmpl/a": "pizza", @@ -42,7 +39,6 @@ Object { exports[`updateFile() should create a file 1`] = ` Object { - "/": null, "/a": "pizza", } `; @@ -55,7 +51,6 @@ Object { exports[`updateFile() should update a file 1`] = ` Object { - "/": null, "/a": "pizza", } `; diff --git a/packages/mrm-core/src/files/__tests__/__snapshots__/packageJson.spec.js.snap b/packages/mrm-core/src/files/__tests__/__snapshots__/packageJson.spec.js.snap index ca836132..6b0e112e 100644 --- a/packages/mrm-core/src/files/__tests__/__snapshots__/packageJson.spec.js.snap +++ b/packages/mrm-core/src/files/__tests__/__snapshots__/packageJson.spec.js.snap @@ -2,7 +2,6 @@ exports[`packageJson() should create package.json file 1`] = ` Object { - "/": null, "/package.json": "{}", } `; diff --git a/packages/mrm-core/src/formats/__tests__/__snapshots__/file.spec.js.snap b/packages/mrm-core/src/formats/__tests__/__snapshots__/file.spec.js.snap index 413b6444..9a9ed6ba 100644 --- a/packages/mrm-core/src/formats/__tests__/__snapshots__/file.spec.js.snap +++ b/packages/mrm-core/src/formats/__tests__/__snapshots__/file.spec.js.snap @@ -8,14 +8,12 @@ Object { exports[`save() should create file 1`] = ` Object { - "/": null, "/test.txt": "coffee", } `; exports[`save() should keep a new line at the end of the file 1`] = ` Object { - "/": null, "/test.txt": "coffee ", } @@ -23,14 +21,12 @@ Object { exports[`save() should not add a new line at the end of the file 1`] = ` Object { - "/": null, "/test.txt": "coffee", } `; exports[`save() should update file 1`] = ` Object { - "/": null, "/test.txt": "coffee", } `; diff --git a/packages/mrm-core/src/formats/__tests__/__snapshots__/ini.spec.js.snap b/packages/mrm-core/src/formats/__tests__/__snapshots__/ini.spec.js.snap index 6a3241cc..74527fe4 100644 --- a/packages/mrm-core/src/formats/__tests__/__snapshots__/ini.spec.js.snap +++ b/packages/mrm-core/src/formats/__tests__/__snapshots__/ini.spec.js.snap @@ -2,7 +2,6 @@ exports[`save() should change prettify format to remove spaces around = 1`] = ` Object { - "/": null, "/test.ini": " [foo] bar=xxx @@ -12,7 +11,6 @@ bar=xxx exports[`save() should create file 1`] = ` Object { - "/": null, "/test.ini": " [foo] bar = xxx @@ -22,7 +20,6 @@ bar = xxx exports[`save() should create file with a comment 1`] = ` Object { - "/": null, "/test.ini": "# comment [foo] @@ -42,7 +39,6 @@ bar=42 exports[`save() should not add spaces to file if they did not exist before, ignore comments 1`] = ` Object { - "/": null, "/test.ini": " [foo] bar=42 @@ -52,7 +48,6 @@ bar=42 exports[`save() should update file 1`] = ` Object { - "/": null, "/test.ini": " [foo] bar = xxx diff --git a/packages/mrm-core/src/formats/__tests__/__snapshots__/json.spec.js.snap b/packages/mrm-core/src/formats/__tests__/__snapshots__/json.spec.js.snap index 2143eb00..a40194f7 100644 --- a/packages/mrm-core/src/formats/__tests__/__snapshots__/json.spec.js.snap +++ b/packages/mrm-core/src/formats/__tests__/__snapshots__/json.spec.js.snap @@ -2,7 +2,6 @@ exports[`save() should create file 1`] = ` Object { - "/": null, "/test.json": "{ \\"foo\\": 1 }", @@ -29,7 +28,6 @@ exports[`save() should keep indentation 1`] = ` exports[`save() should update file 1`] = ` Object { - "/": null, "/test.json": "{ \\"bar\\": 42, \\"baz\\": { diff --git a/packages/mrm-core/src/formats/__tests__/__snapshots__/markdown.spec.js.snap b/packages/mrm-core/src/formats/__tests__/__snapshots__/markdown.spec.js.snap index adfc1389..35334a2c 100644 --- a/packages/mrm-core/src/formats/__tests__/__snapshots__/markdown.spec.js.snap +++ b/packages/mrm-core/src/formats/__tests__/__snapshots__/markdown.spec.js.snap @@ -2,7 +2,6 @@ exports[`save() should update file 1`] = ` Object { - "/": null, "/test.md": " # Foo diff --git a/packages/mrm-core/src/formats/__tests__/__snapshots__/template.spec.js.snap b/packages/mrm-core/src/formats/__tests__/__snapshots__/template.spec.js.snap index 8a6b4060..6e2f9f76 100644 --- a/packages/mrm-core/src/formats/__tests__/__snapshots__/template.spec.js.snap +++ b/packages/mrm-core/src/formats/__tests__/__snapshots__/template.spec.js.snap @@ -2,7 +2,6 @@ exports[`save() should create file 1`] = ` Object { - "/": null, "/text.txt": "Hello, Bar!", "/tmpl.txt": "Hello, \${foo}!", } @@ -10,7 +9,6 @@ Object { exports[`save() should update file 1`] = ` Object { - "/": null, "/text.txt": "Hello, Bar!", "/tmpl.txt": "Hello, \${foo}!", } diff --git a/packages/mrm-core/src/formats/__tests__/__snapshots__/yaml.spec.js.snap b/packages/mrm-core/src/formats/__tests__/__snapshots__/yaml.spec.js.snap index c6c3fbe3..b04036d4 100644 --- a/packages/mrm-core/src/formats/__tests__/__snapshots__/yaml.spec.js.snap +++ b/packages/mrm-core/src/formats/__tests__/__snapshots__/yaml.spec.js.snap @@ -2,7 +2,6 @@ exports[`save() save() should create file 1`] = ` Object { - "/": null, "/test.yml": "foo: 1 ", } @@ -10,7 +9,6 @@ Object { exports[`save() save() should update file 1`] = ` Object { - "/": null, "/test.yml": "bar: 42 baz: foo: 43 diff --git a/packages/mrm-preset-default/License.md b/packages/mrm-preset-default/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-preset-default/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-preset-default/Readme.md b/packages/mrm-preset-default/Readme.md new file mode 100644 index 00000000..f561c98f --- /dev/null +++ b/packages/mrm-preset-default/Readme.md @@ -0,0 +1,42 @@ +# mrm-preset-default + +Default tasks for [Mrm](https://github.com/sapegin/mrm). You don’t have to install this module, these tasks are included by default. + +See [Mrm docs](https://github.com/sapegin/mrm#documentation) for more details. + +## Tasks + + + +- [codecov](../mrm-task-codecov) +- [contributing](../mrm-task-contributing) +- [editorconfig](../mrm-task-editorconfig) +- [eslint](../mrm-task-eslint) +- [gitignore](../mrm-task-gitignore) +- [jest](../mrm-task-jest) +- [license](../mrm-task-license) +- [lint-staged](../mrm-task-lint-staged) +- [package](../mrm-task-package) +- [prettier](../mrm-task-prettier) +- [readme](../mrm-task-readme) +- [semantic-release](../mrm-task-semantic-release) +- [styleguidist](../mrm-task-styleguidist) +- [stylelint](../mrm-task-stylelint) +- [travis](../mrm-task-travis) +- [typescript](../mrm-task-typescript) + + + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-preset-default/codecov/index.js b/packages/mrm-preset-default/codecov/index.js new file mode 100644 index 00000000..cb403934 --- /dev/null +++ b/packages/mrm-preset-default/codecov/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-codecov'); diff --git a/packages/mrm-preset-default/config.json b/packages/mrm-preset-default/config.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/mrm-preset-default/config.json @@ -0,0 +1 @@ +{} diff --git a/packages/mrm-preset-default/contributing/index.js b/packages/mrm-preset-default/contributing/index.js new file mode 100644 index 00000000..ccd48e20 --- /dev/null +++ b/packages/mrm-preset-default/contributing/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-contributing'); diff --git a/packages/mrm-preset-default/editorconfig/index.js b/packages/mrm-preset-default/editorconfig/index.js new file mode 100644 index 00000000..954f5e09 --- /dev/null +++ b/packages/mrm-preset-default/editorconfig/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-editorconfig'); diff --git a/packages/mrm-preset-default/eslint/index.js b/packages/mrm-preset-default/eslint/index.js new file mode 100644 index 00000000..fdc61100 --- /dev/null +++ b/packages/mrm-preset-default/eslint/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-eslint'); diff --git a/packages/mrm-preset-default/gitignore/index.js b/packages/mrm-preset-default/gitignore/index.js new file mode 100644 index 00000000..e65ff704 --- /dev/null +++ b/packages/mrm-preset-default/gitignore/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-gitignore'); diff --git a/packages/mrm-preset-default/index.spec.js b/packages/mrm-preset-default/index.spec.js new file mode 100644 index 00000000..0587c8eb --- /dev/null +++ b/packages/mrm-preset-default/index.spec.js @@ -0,0 +1,94 @@ +it('should have codecov task', () => { + const task = require('./codecov/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('Codecov'); +}); + +it('should have contributing task', () => { + const task = require('./contributing/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('contributing'); +}); + +it('should have editorconfig task', () => { + const task = require('./editorconfig/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('EditorConfig'); +}); + +it('should have eslint task', () => { + const task = require('./eslint/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('ESLint'); +}); + +it('should have gitignore task', () => { + const task = require('./gitignore/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('gitignore'); +}); + +it('should have jest task', () => { + const task = require('./jest/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('Jest'); +}); + +it('should have license task', () => { + const task = require('./license/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('license'); +}); + +it('should have lint-staged task', () => { + const task = require('./lint-staged/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('lint-staged'); +}); + +it('should have package task', () => { + const task = require('./package/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('package.json'); +}); + +it('should have prettier task', () => { + const task = require('./prettier/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('Prettier'); +}); + +it('should have readme task', () => { + const task = require('./readme/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('readme'); +}); + +it('should have semantic-release task', () => { + const task = require('./semantic-release/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('semantic-release'); +}); + +it('should have styleguidist task', () => { + const task = require('./styleguidist/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('React Styleguidist'); +}); +it('should have stylelint task', () => { + const task = require('./stylelint/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('Stylelint'); +}); + +it('should have travis task', () => { + const task = require('./travis/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('Travis CI'); +}); + +it('should have typescript task', () => { + const task = require('./typescript/index.js'); + expect(task).toEqual(expect.any(Function)); + expect(task.description).toMatch('TypeScript'); +}); diff --git a/packages/mrm-preset-default/jest/index.js b/packages/mrm-preset-default/jest/index.js new file mode 100644 index 00000000..9182fd6f --- /dev/null +++ b/packages/mrm-preset-default/jest/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-jest'); diff --git a/packages/mrm-preset-default/license/index.js b/packages/mrm-preset-default/license/index.js new file mode 100644 index 00000000..2c710b58 --- /dev/null +++ b/packages/mrm-preset-default/license/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-license'); diff --git a/packages/mrm-preset-default/lint-staged/index.js b/packages/mrm-preset-default/lint-staged/index.js new file mode 100644 index 00000000..be406a00 --- /dev/null +++ b/packages/mrm-preset-default/lint-staged/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-lint-staged'); diff --git a/packages/mrm-preset-default/package-lock.json b/packages/mrm-preset-default/package-lock.json new file mode 100644 index 00000000..7f455eab --- /dev/null +++ b/packages/mrm-preset-default/package-lock.json @@ -0,0 +1,356 @@ +{ + "name": "mrm-preset-default", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-preset-default/package.json b/packages/mrm-preset-default/package.json new file mode 100644 index 00000000..2f17d6cf --- /dev/null +++ b/packages/mrm-preset-default/package.json @@ -0,0 +1,45 @@ +{ + "name": "mrm-preset-default", + "version": "2.0.1", + "description": "Common tasks for Mrm", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-preset-default", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "config.json", + "files": [ + "config.json", + "*/index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "mrm-preset" + ], + "dependencies": { + "mrm-core": "^4.0.0", + "mrm-task-codecov": "^2.0.1", + "mrm-task-contributing": "^2.0.1", + "mrm-task-editorconfig": "^2.0.1", + "mrm-task-eslint": "^2.0.1", + "mrm-task-gitignore": "^2.0.1", + "mrm-task-jest": "^2.0.1", + "mrm-task-license": "^3.0.0", + "mrm-task-lint-staged": "^3.0.0", + "mrm-task-package": "^2.0.1", + "mrm-task-prettier": "^2.0.1", + "mrm-task-readme": "^2.0.1", + "mrm-task-semantic-release": "^3.0.1", + "mrm-task-styleguidist": "^2.0.1", + "mrm-task-stylelint": "^3.0.1", + "mrm-task-travis": "^2.0.1", + "mrm-task-typescript": "^2.0.1" + } +} diff --git a/packages/mrm-preset-default/package/index.js b/packages/mrm-preset-default/package/index.js new file mode 100644 index 00000000..c0490a39 --- /dev/null +++ b/packages/mrm-preset-default/package/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-package'); diff --git a/packages/mrm-preset-default/prettier/index.js b/packages/mrm-preset-default/prettier/index.js new file mode 100644 index 00000000..ca652bd4 --- /dev/null +++ b/packages/mrm-preset-default/prettier/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-prettier'); diff --git a/packages/mrm-preset-default/readme/index.js b/packages/mrm-preset-default/readme/index.js new file mode 100644 index 00000000..5f855faf --- /dev/null +++ b/packages/mrm-preset-default/readme/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-readme'); diff --git a/packages/mrm-preset-default/semantic-release/index.js b/packages/mrm-preset-default/semantic-release/index.js new file mode 100644 index 00000000..7751b651 --- /dev/null +++ b/packages/mrm-preset-default/semantic-release/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-semantic-release'); diff --git a/packages/mrm-preset-default/styleguidist/index.js b/packages/mrm-preset-default/styleguidist/index.js new file mode 100644 index 00000000..fdb04d02 --- /dev/null +++ b/packages/mrm-preset-default/styleguidist/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-styleguidist'); diff --git a/packages/mrm-preset-default/stylelint/index.js b/packages/mrm-preset-default/stylelint/index.js new file mode 100644 index 00000000..8c150140 --- /dev/null +++ b/packages/mrm-preset-default/stylelint/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-stylelint'); diff --git a/packages/mrm-preset-default/travis/index.js b/packages/mrm-preset-default/travis/index.js new file mode 100644 index 00000000..356ff309 --- /dev/null +++ b/packages/mrm-preset-default/travis/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-travis'); diff --git a/packages/mrm-preset-default/typescript/index.js b/packages/mrm-preset-default/typescript/index.js new file mode 100644 index 00000000..23e4bdec --- /dev/null +++ b/packages/mrm-preset-default/typescript/index.js @@ -0,0 +1 @@ +module.exports = require('mrm-task-typescript'); diff --git a/packages/mrm-task-codecov/License.md b/packages/mrm-task-codecov/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-codecov/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-codecov/Readme.md b/packages/mrm-task-codecov/Readme.md new file mode 100644 index 00000000..b4e08cf3 --- /dev/null +++ b/packages/mrm-task-codecov/Readme.md @@ -0,0 +1,36 @@ +# mrm-task-codecov + +[Mrm](https://github.com/sapegin/mrm) task that adds [Codecov](https://codecov.io/) to Travis CI config (see [travis](../travis) task) and a Readme badge. + +## Usage + +``` +npm install -g mrm mrm-task-codecov +mrm codecov +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `readmeFile` (default: `Readme.md`) + +Name of the Readme file. + +### `github` (default: extracted from `.git/config` file) + +Your GitHub user name. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-codecov/__snapshots__/index.spec.js.snap b/packages/mrm-task-codecov/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..ad5fe2d5 --- /dev/null +++ b/packages/mrm-task-codecov/__snapshots__/index.spec.js.snap @@ -0,0 +1,23 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add CodeCov 1`] = ` +Object { + "/.travis.yml": "language: node_js +node_js: + - 8 +script: + - npm run test -- --coverage +after_success: + - 'bash <(curl -s https://codecov.io/bash)' +", + "/Readme.md": "# Unicorn + +[![Codecov](https://codecov.io/gh/gh/unicorn/branch/master/graph/badge.svg)](https://codecov.io/gh/gh/unicorn)", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"test:coverage\\": \\"jest --coverage\\" + } +}", +} +`; diff --git a/packages/mrm-task-codecov/index.js b/packages/mrm-task-codecov/index.js new file mode 100644 index 00000000..86271949 --- /dev/null +++ b/packages/mrm-task-codecov/index.js @@ -0,0 +1,56 @@ +const gitUsername = require('git-username'); +const { MrmError, yaml, markdown, packageJson } = require('mrm-core'); + +const uploadCommand = 'bash <(curl -s https://codecov.io/bash)'; +const coverageScript = 'test:coverage'; + +function task(config) { + const { readmeFile, github } = config + .defaults({ readmeFile: 'Readme.md', github: gitUsername() }) + .require('github') + .values(); + + const travisYml = yaml('.travis.yml'); + + // Require .travis.yml + if (!travisYml.exists()) { + throw new MrmError( + `Run travis task first: + + mrm travis` + ); + } + + const pkg = packageJson(); + + // Require coverage npm script + if (!pkg.getScript(coverageScript)) { + throw new MrmError( + `${coverageScript} npm script not found. To add Jest run: + + mrm jest` + ); + } + + // .travis.yml + if (!travisYml.get('after_success', []).includes(uploadCommand)) { + travisYml + .merge({ + script: [`npm run test -- --coverage`], + after_success: [uploadCommand], + }) + .save(); + } + + // Add Codecov badge to Readme + const url = `https://codecov.io/gh/${github}/${pkg.get('name')}`; + const readme = markdown(readmeFile); + if (readme.exists()) { + readme + .addBadge(`${url}/branch/master/graph/badge.svg`, url, 'Codecov') + .save(); + } +} + +task.description = 'Adds Codecov'; +module.exports = task; diff --git a/packages/mrm-task-codecov/index.spec.js b/packages/mrm-task-codecov/index.spec.js new file mode 100644 index 00000000..33e5832c --- /dev/null +++ b/packages/mrm-task-codecov/index.spec.js @@ -0,0 +1,74 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); + +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const stringify = o => JSON.stringify(o, null, ' '); + +const config = getConfigGetter({ github: 'gh' }); + +const travisYml = `language: node_js +node_js: + - 8 +`; +const packageJson = stringify({ + name: 'unicorn', + scripts: { + 'test:coverage': 'jest --coverage', + }, +}); +const readmeMd = '# Unicorn'; + +afterEach(() => vol.reset()); + +it('should add CodeCov', () => { + vol.fromJSON({ + '/.travis.yml': travisYml, + '/package.json': packageJson, + '/Readme.md': readmeMd, + }); + + task(config); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should throw when .travis.yml not found', () => { + vol.fromJSON({ + '/package.json': packageJson, + '/Readme.md': readmeMd, + }); + + const fn = () => task(config); + + expect(fn).toThrowError('Run travis task'); +}); + +it('should throw when coverage script not found', () => { + vol.fromJSON({ + '/.travis.yml': travisYml, + '/package.json': stringify({ + name: 'unicorn', + }), + '/Readme.md': readmeMd, + }); + + const fn = () => task(config); + + expect(fn).toThrowError('npm script not found'); +}); + +it('should not throw when readme file not found', () => { + vol.fromJSON({ + '/.travis.yml': travisYml, + '/package.json': packageJson, + }); + + const fn = () => task(config); + + expect(fn).not.toThrowError(); +}); diff --git a/packages/mrm-task-codecov/package-lock.json b/packages/mrm-task-codecov/package-lock.json new file mode 100644 index 00000000..cbb0fe88 --- /dev/null +++ b/packages/mrm-task-codecov/package-lock.json @@ -0,0 +1,433 @@ +{ + "name": "mrm-task-codecov", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "git-config-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-1.0.1.tgz", + "integrity": "sha1-bTP37WPbDQ4RgTFQO6s6ykfVRmQ=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "homedir-polyfill": "^1.0.0" + } + }, + "git-username": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-username/-/git-username-1.0.0.tgz", + "integrity": "sha512-xm45KwBR6Eu1jO4umx/o2M84v9TC7tdOBuzLx8ayhdR9H1FBiiG9azz31uC0esDvaWVBTDINpJ5USomk+ja8OQ==", + "requires": { + "parse-github-url": "^1.0.2", + "remote-origin-url": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-git-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-1.1.1.tgz", + "integrity": "sha1-06mYQxcTL1c5hxK7pDjhKVkN34w=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "git-config-path": "^1.0.1", + "ini": "^1.3.4" + } + }, + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==" + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "remote-origin-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remote-origin-url/-/remote-origin-url-1.0.0.tgz", + "integrity": "sha512-xHDM6IBqivpiQ1e4WOuFpM/T6rbzA/WBsu+3WLtgPOhHyjA0nYlijV3NprlTb4FcXlQ5+Q+z174sQ1NnUF5FwA==", + "requires": { + "parse-git-config": "^1.1.1" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-codecov/package.json b/packages/mrm-task-codecov/package.json new file mode 100644 index 00000000..9686a436 --- /dev/null +++ b/packages/mrm-task-codecov/package.json @@ -0,0 +1,31 @@ +{ + "name": "mrm-task-codecov", + "version": "2.0.1", + "description": "Mrm task that adds Codecov to Travis CI config", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-codecov", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "codecov", + "travis", + "coverage" + ], + "dependencies": { + "git-username": "^1.0.0", + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-contributing/License.md b/packages/mrm-task-contributing/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-contributing/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-contributing/Readme.md b/packages/mrm-task-contributing/Readme.md new file mode 100644 index 00000000..1fa5c926 --- /dev/null +++ b/packages/mrm-task-contributing/Readme.md @@ -0,0 +1,44 @@ +# mrm-task-contributing + +[Mrm](https://github.com/sapegin/mrm) task that adds contributing guidelines. + +## What it does + +- Creates a contributing guidelines file + +## Usage + +``` +npm install -g mrm mrm-task-contributing +mrm contributing +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `github` (default: extracted from `.git/config` file) + +Your GitHub user name. + +### `contributingFile` (default: `Contributing.md`) + +Name of the contributing guidelines file. + +### `packageName` (default: `name` field in `package.json`) + +Package name. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-contributing/__snapshots__/index.spec.js.snap b/packages/mrm-task-contributing/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..fa5118da --- /dev/null +++ b/packages/mrm-task-contributing/__snapshots__/index.spec.js.snap @@ -0,0 +1,59 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add a Contributing.md file 1`] = ` +Object { + "/Contributing.md": "# How to contribute + +We love pull requests. And following this guidelines will make your pull request easier to merge. + +If you want to contribute but don’t know what to do, take a look at these two labels: [help wanted](https://github.com/gendalf/unicorn/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and [good first issue](https://github.com/gendalf/unicorn/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). + +_[Use GitHub interface](https://blog.sapegin.me/all/open-source-for-everyone/) for simple documentation changes, otherwise follow the steps below._ + +## Prerequisites + +- If it’s your first pull request, watch [this amazing course](http://makeapullrequest.com/) by [Kent C. Dodds](https://twitter.com/kentcdodds). +- Install [EditorConfig](http://editorconfig.org/) plugin for your code editor to make sure it uses correct settings. +- Fork the repository and clone your fork. +- Install dependencies: \`npm install\`. + +## Development workflow + +Run linters and tests: + +\`\`\`bash +npm test +\`\`\` + +Or run tests in watch mode: + +\`\`\`bash +npm run test:watch +\`\`\` + +To update Jest snapshots: + +\`\`\`bash +npm run test:jest -- -u +\`\`\` + +**Don’t forget to add tests and update documentation for your changes.** + +**Please update npm lock file (\`package-lock.json\`) if you add or update dependencies.** + +## Other notes + +- If you have commit access to repository and want to make big change or not sure about something, make a new branch and open pull request. +- We’re using [Prettier](https://github.com/prettier/prettier) to format code, so don’t worry much about code formatting. +- Don’t commit generated files, like minified JavaScript. +- Don’t change version number and change log. + +## Need help? + +If you want to contribute but have any questions, concerns or doubts, feel free to ping maintainers. Ideally create a pull request with \`WIP\` (Work in progress) in its title and ask questions in the pull request description. +", + "/package.json": "{ + \\"name\\": \\"unicorn\\" +}", +} +`; diff --git a/packages/mrm-task-contributing/index.js b/packages/mrm-task-contributing/index.js new file mode 100644 index 00000000..2eda70a2 --- /dev/null +++ b/packages/mrm-task-contributing/index.js @@ -0,0 +1,37 @@ +const path = require('path'); +const gitUsername = require('git-username'); +const { template, packageJson } = require('mrm-core'); + +function task(config) { + const { contributingFile } = config + .defaults({ + contributingFile: 'Contributing.md', + }) + .values(); + + // Create Contributing.md (no update) + const contributing = template( + contributingFile, + path.join(__dirname, 'templates/Contributing.md') + ); + if (!contributing.exists()) { + const { github, packageName } = config + .defaults({ + github: gitUsername(), + packageName: packageJson().get('name'), + }) + .require('github', 'packageName') + .values(); + + contributing + .apply({ + github, + contributingFile, + packageName, + }) + .save(); + } +} + +task.description = 'Adds contributing guidelines'; +module.exports = task; diff --git a/packages/mrm-task-contributing/index.spec.js b/packages/mrm-task-contributing/index.spec.js new file mode 100644 index 00000000..37bc7d73 --- /dev/null +++ b/packages/mrm-task-contributing/index.spec.js @@ -0,0 +1,36 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); + +const fs = require.requireActual('fs'); +const path = require('path'); +const { omitBy } = require('lodash'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const stringify = o => JSON.stringify(o, null, ' '); + +afterEach(() => vol.reset()); + +it('should add a Contributing.md file', () => { + vol.fromJSON({ + [`${__dirname}/templates/Contributing.md`]: fs + .readFileSync(path.join(__dirname, 'templates/Contributing.md')) + .toString(), + '/package.json': stringify({ + name: 'unicorn', + }), + }); + + task( + getConfigGetter({ + github: 'gendalf', + }) + ); + + expect( + omitBy(vol.toJSON(), (v, k) => k.startsWith(__dirname)) + ).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-contributing/package-lock.json b/packages/mrm-task-contributing/package-lock.json new file mode 100644 index 00000000..aca7af64 --- /dev/null +++ b/packages/mrm-task-contributing/package-lock.json @@ -0,0 +1,433 @@ +{ + "name": "mrm-task-contributing", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "git-config-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-1.0.1.tgz", + "integrity": "sha1-bTP37WPbDQ4RgTFQO6s6ykfVRmQ=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "homedir-polyfill": "^1.0.0" + } + }, + "git-username": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-username/-/git-username-1.0.0.tgz", + "integrity": "sha512-xm45KwBR6Eu1jO4umx/o2M84v9TC7tdOBuzLx8ayhdR9H1FBiiG9azz31uC0esDvaWVBTDINpJ5USomk+ja8OQ==", + "requires": { + "parse-github-url": "^1.0.2", + "remote-origin-url": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-git-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-1.1.1.tgz", + "integrity": "sha1-06mYQxcTL1c5hxK7pDjhKVkN34w=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "git-config-path": "^1.0.1", + "ini": "^1.3.4" + } + }, + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==" + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "remote-origin-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remote-origin-url/-/remote-origin-url-1.0.0.tgz", + "integrity": "sha512-xHDM6IBqivpiQ1e4WOuFpM/T6rbzA/WBsu+3WLtgPOhHyjA0nYlijV3NprlTb4FcXlQ5+Q+z174sQ1NnUF5FwA==", + "requires": { + "parse-git-config": "^1.1.1" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-contributing/package.json b/packages/mrm-task-contributing/package.json new file mode 100644 index 00000000..16529532 --- /dev/null +++ b/packages/mrm-task-contributing/package.json @@ -0,0 +1,30 @@ +{ + "name": "mrm-task-contributing", + "version": "2.0.1", + "description": "Mrm task that adds contributing guidelines", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-contributing", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js", + "templates" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "contributing" + ], + "dependencies": { + "git-username": "^1.0.0", + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-contributing/templates/Contributing.md b/packages/mrm-task-contributing/templates/Contributing.md new file mode 100644 index 00000000..6f2acae0 --- /dev/null +++ b/packages/mrm-task-contributing/templates/Contributing.md @@ -0,0 +1,49 @@ +# How to contribute + +We love pull requests. And following this guidelines will make your pull request easier to merge. + +If you want to contribute but don’t know what to do, take a look at these two labels: [help wanted](https://github.com/${github}/${packageName}/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and [good first issue](https://github.com/${github}/${packageName}/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). + +_[Use GitHub interface](https://blog.sapegin.me/all/open-source-for-everyone/) for simple documentation changes, otherwise follow the steps below._ + +## Prerequisites + +- If it’s your first pull request, watch [this amazing course](http://makeapullrequest.com/) by [Kent C. Dodds](https://twitter.com/kentcdodds). +- Install [EditorConfig](http://editorconfig.org/) plugin for your code editor to make sure it uses correct settings. +- Fork the repository and clone your fork. +- Install dependencies: `npm install`. + +## Development workflow + +Run linters and tests: + +```bash +npm test +``` + +Or run tests in watch mode: + +```bash +npm run test:watch +``` + +To update Jest snapshots: + +```bash +npm run test:jest -- -u +``` + +**Don’t forget to add tests and update documentation for your changes.** + +**Please update npm lock file (`package-lock.json`) if you add or update dependencies.** + +## Other notes + +- If you have commit access to repository and want to make big change or not sure about something, make a new branch and open pull request. +- We’re using [Prettier](https://github.com/prettier/prettier) to format code, so don’t worry much about code formatting. +- Don’t commit generated files, like minified JavaScript. +- Don’t change version number and change log. + +## Need help? + +If you want to contribute but have any questions, concerns or doubts, feel free to ping maintainers. Ideally create a pull request with `WIP` (Work in progress) in its title and ask questions in the pull request description. diff --git a/packages/mrm-task-editorconfig/License.md b/packages/mrm-task-editorconfig/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-editorconfig/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-editorconfig/Readme.md b/packages/mrm-task-editorconfig/Readme.md new file mode 100644 index 00000000..775300d6 --- /dev/null +++ b/packages/mrm-task-editorconfig/Readme.md @@ -0,0 +1,36 @@ +# mrm-task-editorconfig + +[Mrm](https://github.com/sapegin/mrm) task that adds [EditorConfig](http://editorconfig.org/). + +## What it does + +- Creates `.editorconfig`. + +## Usage + +``` +npm install -g mrm mrm-task-editorconfig +mrm editorconfig +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `indent` (default: `tab`) + +Indentation, `tab` or number of spaces. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-editorconfig/__snapshots__/index.spec.js.snap b/packages/mrm-task-editorconfig/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..3a960637 --- /dev/null +++ b/packages/mrm-task-editorconfig/__snapshots__/index.spec.js.snap @@ -0,0 +1,54 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add EditorConfig 1`] = ` +Object { + "/.editorconfig": "# editorconfig.org +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{json,yml,md,babelrc,remarkrc}] +indent_style = space +indent_size = 2 +", +} +`; + +exports[`should add a single section when indent=2 1`] = ` +Object { + "/.editorconfig": "# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +", +} +`; + +exports[`should update JSON section 1`] = ` +Object { + "/.editorconfig": "# editorconfig.org +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{json,yml,md,babelrc,remarkrc}] +indent_style = space +indent_size = 2", +} +`; diff --git a/packages/mrm-task-editorconfig/index.js b/packages/mrm-task-editorconfig/index.js new file mode 100644 index 00000000..be55a4ba --- /dev/null +++ b/packages/mrm-task-editorconfig/index.js @@ -0,0 +1,47 @@ +const { ini } = require('mrm-core'); + +const jsonRules = { + indent_style: 'space', + indent_size: 2, +}; +const jsonExtensions = ['json', 'yml', 'md', 'babelrc', 'remarkrc']; + +function task(config) { + const { indent } = config.defaults({ indent: 'tab' }).values(); + + const generalRules = Object.assign( + indent === 'tab' + ? { + indent_style: 'tab', + } + : { + indent_style: 'space', + indent_size: indent, + }, + { + end_of_line: 'lf', + charset: 'utf-8', + trim_trailing_whitespace: true, + insert_final_newline: true, + } + ); + + // .editorconfig + const editorconfig = ini('.editorconfig', 'editorconfig.org'); + editorconfig.set('_global', { root: true }).set('*', generalRules); + + // Set/update JSON-like section + const jsonSection = editorconfig.get().find(section => /json/.test(section)); + if (jsonSection) { + editorconfig.unset(jsonSection); + } + + if (indent !== jsonRules.indent_size) { + editorconfig.set('*.{' + jsonExtensions.join(',') + '}', jsonRules); + } + + editorconfig.save(); +} + +task.description = 'Adds EditorConfig'; +module.exports = task; diff --git a/packages/mrm-task-editorconfig/index.spec.js b/packages/mrm-task-editorconfig/index.spec.js new file mode 100644 index 00000000..5cb8cb52 --- /dev/null +++ b/packages/mrm-task-editorconfig/index.spec.js @@ -0,0 +1,37 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); + +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +afterEach(() => vol.reset()); + +it('should add EditorConfig', () => { + vol.fromJSON(); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should add a single section when indent=2', () => { + vol.fromJSON(); + + task(getConfigGetter({ indent: 2 })); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should update JSON section', () => { + vol.fromJSON({ + '/.editorconfig': `[*.{json,yml}] +indent_style = tab`, + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-editorconfig/package-lock.json b/packages/mrm-task-editorconfig/package-lock.json new file mode 100644 index 00000000..4c96aeb3 --- /dev/null +++ b/packages/mrm-task-editorconfig/package-lock.json @@ -0,0 +1,354 @@ +{ + "name": "mrm-task-editorconfig", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-editorconfig/package.json b/packages/mrm-task-editorconfig/package.json new file mode 100644 index 00000000..0d592857 --- /dev/null +++ b/packages/mrm-task-editorconfig/package.json @@ -0,0 +1,28 @@ +{ + "name": "mrm-task-editorconfig", + "version": "2.0.1", + "description": "Mrm task that adds EditorConfig", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-editorconfig", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "editorconfig" + ], + "dependencies": { + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-eslint/License.md b/packages/mrm-task-eslint/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-eslint/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-eslint/Readme.md b/packages/mrm-task-eslint/Readme.md new file mode 100644 index 00000000..0d33aca1 --- /dev/null +++ b/packages/mrm-task-eslint/Readme.md @@ -0,0 +1,52 @@ +# mrm-task-eslint + +[Mrm](https://github.com/sapegin/mrm) task that adds [ESLint](https://eslint.org/). + +Supports JavaScript and TypeScript. + +## What it does + +- Creates `.eslintrc.json` +- Adds an npm script to run ESLint before tests +- Installs dependencies + +## Usage + +``` +npm install -g mrm mrm-task-eslint +mrm eslint +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `eslintPreset` (default: `eslint:recommended`) + +ESLint preset name (not npm package name, e.g. `airbnb`). + +### `eslintPeerDependencies` (optional) + +Additional dependencies to install (e.g. `['prettier', 'eslint-plugin-prettier']`). + +### `eslintObsoleteDependencies` (optional) + +Dependencies that should be removed (e.g. `['eslint-plugin-prettier']`). + +### `eslintRules` (optional) + +Additional rules (e.g. `{ 'no-undef': 0 }`). + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-eslint/__snapshots__/index.spec.js.snap b/packages/mrm-task-eslint/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..612986cc --- /dev/null +++ b/packages/mrm-task-eslint/__snapshots__/index.spec.js.snap @@ -0,0 +1,219 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add ESLint 1`] = ` +Object { + "/.eslintignore": "node_modules/", + "/.eslintrc.json": "{ + \\"extends\\": \\"eslint:recommended\\" +}", + "/.gitignore": ".eslintcache", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"pretest\\": \\"npm run lint\\", + \\"test\\": \\"jest\\", + \\"lint\\": \\"eslint . --cache --fix\\" + } +}", +} +`; + +exports[`should add a custom preset (array) 1`] = ` +"{ + \\"extends\\": [ + \\"airbnb\\", + \\"coffee\\", + \\"pizza\\" + ] +}" +`; + +exports[`should add custom rules 1`] = ` +"{ + \\"extends\\": \\"eslint:recommended\\", + \\"rules\\": { + \\"no-undef\\": 0 + } +}" +`; + +exports[`should add extra plugin, parser and extensions for a TypeScript project 1`] = ` +Object { + "/.eslintignore": "node_modules/", + "/.eslintrc.json": "{ + \\"extends\\": \\"eslint:recommended\\", + \\"parser\\": \\"@typescript-eslint/parser\\", + \\"plugins\\": [ + \\"@typescript-eslint/eslint-plugin\\" + ], + \\"parserOptions\\": { + \\"project\\": \\"./tsconfig.json\\" + }, + \\"rules\\": {} +}", + "/.gitignore": ".eslintcache", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"typescript\\": \\"*\\" + }, + \\"scripts\\": { + \\"lint\\": \\"eslint . --cache --fix --ext .ts,.tsx\\", + \\"pretest\\": \\"npm run lint\\" + } +}", +} +`; + +exports[`should keep custom extensions defined in a package.json script 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"lint\\": \\"eslint . --cache --fix --ext .ts\\", + \\"pretest\\": \\"npm run lint\\", + \\"test\\": \\"jest\\" + } +}" +`; + +exports[`should migrate legacy config file 1`] = ` +Object { + "/.eslintignore": "node_modules/", + "/.eslintrc.json": "{ + \\"rules\\": { + \\"no-foo\\": 2 + }, + \\"extends\\": \\"eslint:recommended\\" +}", + "/.gitignore": ".eslintcache", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"pretest\\": \\"npm run lint\\", + \\"test\\": \\"jest\\", + \\"lint\\": \\"eslint . --cache --fix\\" + } +}", +} +`; + +exports[`should not add a custom preset if it’s already there (array) 1`] = ` +"{ + \\"extends\\": [ + \\"airbnb\\", + \\"pizza\\" + ] +}" +`; + +exports[`should not add a custom preset if it’s already there 1`] = ` +"{ + \\"extends\\": \\"airbnb\\" +}" +`; + +exports[`should not add custom extensions when they were not specified 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"lint\\": \\"eslint . --cache --fix\\", + \\"pretest\\": \\"npm run lint\\", + \\"test\\": \\"jest\\" + } +}" +`; + +exports[`should remove custom extension if it’s "js" (default value) 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"lint\\": \\"eslint . --cache --fix\\", + \\"pretest\\": \\"npm run lint\\", + \\"test\\": \\"jest\\" + } +}" +`; + +exports[`should replace scripts.test.eslint with scripts.lint and scripts.pretest 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"pretest\\": \\"npm run lint\\", + \\"test\\": \\"jest\\", + \\"lint\\": \\"eslint . --cache --fix --ext .ts\\" + } +}" +`; + +exports[`should turn off TypeScript-specific eslint rules that conflict with Prettier if prettier is installed 1`] = ` +Object { + "/.eslintignore": "node_modules/", + "/.eslintrc.json": "{ + \\"extends\\": [ + \\"eslint:recommended\\", + \\"prettier\\", + \\"prettier/@typescript-eslint\\" + ], + \\"parser\\": \\"@typescript-eslint/parser\\", + \\"plugins\\": [ + \\"@typescript-eslint/eslint-plugin\\" + ], + \\"parserOptions\\": { + \\"project\\": \\"./tsconfig.json\\" + }, + \\"rules\\": {} +}", + "/.gitignore": ".eslintcache", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"typescript\\": \\"*\\", + \\"prettier\\": \\"*\\" + }, + \\"scripts\\": { + \\"lint\\": \\"eslint . --cache --fix --ext .ts,.tsx\\", + \\"pretest\\": \\"npm run lint\\" + } +}", +} +`; + +exports[`should turn on JSX support in TypeScript parser if TypeScript and React are installed 1`] = ` +Object { + "/.eslintignore": "node_modules/", + "/.eslintrc.json": "{ + \\"extends\\": \\"eslint:recommended\\", + \\"parser\\": \\"@typescript-eslint/parser\\", + \\"plugins\\": [ + \\"@typescript-eslint/eslint-plugin\\" + ], + \\"parserOptions\\": { + \\"ecmaFeatures\\": { + \\"jsx\\": true + }, + \\"project\\": \\"./tsconfig.json\\" + }, + \\"rules\\": {} +}", + "/.gitignore": ".eslintcache", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"dependencies\\": { + \\"react\\": \\"*\\" + }, + \\"devDependencies\\": { + \\"typescript\\": \\"*\\" + }, + \\"scripts\\": { + \\"lint\\": \\"eslint . --cache --fix --ext .ts,.tsx\\", + \\"pretest\\": \\"npm run lint\\" + } +}", +} +`; + +exports[`should use a custom preset 1`] = ` +"{ + \\"extends\\": \\"airbnb\\" +}" +`; diff --git a/packages/mrm-task-eslint/index.js b/packages/mrm-task-eslint/index.js new file mode 100644 index 00000000..471959bf --- /dev/null +++ b/packages/mrm-task-eslint/index.js @@ -0,0 +1,151 @@ +const _ = require('lodash'); +const { + json, + packageJson, + lines, + install, + uninstall, + getExtsFromCommand, +} = require('mrm-core'); + +function task(config) { + let exts = ''; + const legacyConfigFile = '.eslintrc'; + const configFile = '.eslintrc.json'; + const ignores = ['node_modules/']; + const ignoresToRemove = ['node_modules']; + const gitIgnores = ['.eslintcache']; + const packages = ['eslint']; + const packagesToRemove = ['jslint', 'jshint']; + const { + eslintPreset, + eslintPeerDependencies, + eslintObsoleteDependencies, + eslintRules, + } = config + .defaults({ + eslintPreset: 'eslint:recommended', + eslintPeerDependencies: [], + eslintObsoleteDependencies: [], + }) + .values(); + + // Preset + if (eslintPreset !== 'eslint:recommended') { + packages.push(`eslint-config-${eslintPreset}`); + } + + // Peer dependencies + packages.push(...eslintPeerDependencies); + + // Migrate legacy config + const legacyEslintrc = json(legacyConfigFile); + const legacyConfig = legacyEslintrc.get(); + legacyEslintrc.delete(); + + // .eslintrc.json + const eslintrc = json(configFile, legacyConfig); + const hasCustomPreset = _.castArray(eslintrc.get('extends', [])).find(x => + x.startsWith(eslintPreset) + ); + if (!hasCustomPreset) { + const presets = eslintrc.get('extends'); + if (!presets) { + eslintrc.set('extends', eslintPreset); + } else { + eslintrc.set('extends', [eslintPreset, ..._.castArray(presets)]); + } + } + if (eslintRules) { + eslintrc.merge({ + rules: eslintRules, + }); + } + + const pkg = packageJson(); + + // TODO: Babel + // Not sure how to detect that we need it, checking for babel-core is not enough because + // babel-eslint is only needed for experimental features and Flow (this one is easy to test) + // Flow also needs this: https://github.com/gajus/eslint-plugin-flowtype + // if (pkg.get('devDependencies.babel-core')) { + // packages.push('babel-eslint'); + // eslintrc.set('parser', 'babel-eslint'); + // } + + // TypeScript + if (pkg.get('devDependencies.typescript')) { + const parser = '@typescript-eslint/parser'; + const plugin = '@typescript-eslint/eslint-plugin'; + packages.push(parser, plugin); + eslintrc.merge({ + parser, + plugins: [plugin], + parserOptions: { + // If using React, turn on JSX support in the TypeScript parser. + ...(pkg.get('dependencies.react') && { + ecmaFeatures: { + jsx: true, + }, + }), + project: './tsconfig.json', + }, + rules: eslintRules || {}, + }); + exts = ' --ext .ts,.tsx'; + + if (pkg.get('devDependencies.prettier')) { + packages.push('eslint-config-prettier'); + const extensions = eslintrc.get('extends', []); + eslintrc.merge({ + extends: [ + ...(Array.isArray(extensions) ? extensions : [extensions]), + 'prettier', + 'prettier/@typescript-eslint', + ], + }); + } + } + + eslintrc.save(); + + // .eslintignore + lines('.eslintignore') + .remove(ignoresToRemove) + .add(ignores) + .save(); + + // .gitignore + lines('.gitignore') + .add(gitIgnores) + .save(); + + // Keep custom extensions + const lintScript = + pkg.getScript('lint', 'eslint') || pkg.getScript('test', 'eslint'); + if (lintScript) { + const lintExts = getExtsFromCommand(lintScript, 'ext'); + if (lintExts && lintExts.toString() !== 'js') { + const extsPattern = lintExts.map(x => `.${x}`).join(','); + exts = ` --ext ${extsPattern}`; + } + } + + pkg + // Remove existing JS linters + .removeScript(/^(lint:js|eslint|jshint|jslint)$/) + .removeScript('test', / (lint|lint:js|eslint|jshint|jslint)( |$)/) // npm run jest && npm run lint + .removeScript('test', /\beslint|jshint|jslint\b/) // jest && eslint + // Add lint script + .setScript('lint', 'eslint . --cache --fix' + exts) + // Add pretest script + .prependScript('pretest', 'npm run lint') + .save(); + + // Dependencies + uninstall([...packagesToRemove, ...eslintObsoleteDependencies]); + install(packages); +} + +task.description = 'Adds ESLint'; +module.exports = task; diff --git a/packages/mrm-task-eslint/index.spec.js b/packages/mrm-task-eslint/index.spec.js new file mode 100644 index 00000000..0cf09006 --- /dev/null +++ b/packages/mrm-task-eslint/index.spec.js @@ -0,0 +1,252 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), + removed: jest.fn(), +})); +jest.mock('mrm-core/src/npm', () => ({ + install: jest.fn(), + uninstall: jest.fn(), +})); + +const { install, uninstall } = require('mrm-core'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const stringify = o => JSON.stringify(o, null, ' '); + +const legacyConfigFile = '/.eslintrc'; +const configFile = '/.eslintrc.json'; +const packageJson = stringify({ + name: 'unicorn', + scripts: { + test: 'jest', + }, +}); + +afterEach(() => { + vol.reset(); + install.mockClear(); + uninstall.mockClear(); +}); + +it('should add ESLint', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith(['eslint']); +}); + +it('should use a custom preset', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({ eslintPreset: 'airbnb' })); + + expect(vol.toJSON()[configFile]).toMatchSnapshot(); + expect(install).toBeCalledWith(['eslint', 'eslint-config-airbnb']); +}); + +it('should not add a custom preset if it’s already there', () => { + vol.fromJSON({ + '/package.json': packageJson, + [configFile]: stringify({ extends: 'airbnb' }), + }); + + task(getConfigGetter({ eslintPreset: 'airbnb' })); + + expect(vol.toJSON()[configFile]).toMatchSnapshot(); + expect(install).toBeCalledWith(['eslint', 'eslint-config-airbnb']); +}); + +it('should add a custom preset (array)', () => { + vol.fromJSON({ + '/package.json': packageJson, + [configFile]: stringify({ extends: ['coffee', 'pizza'] }), + }); + + task(getConfigGetter({ eslintPreset: 'airbnb' })); + + expect(vol.toJSON()[configFile]).toMatchSnapshot(); + expect(install).toBeCalledWith(['eslint', 'eslint-config-airbnb']); +}); + +it('should not add a custom preset if it’s already there (array)', () => { + vol.fromJSON({ + '/package.json': packageJson, + [configFile]: stringify({ extends: ['airbnb', 'pizza'] }), + }); + + task(getConfigGetter({ eslintPreset: 'airbnb' })); + + expect(vol.toJSON()[configFile]).toMatchSnapshot(); + expect(install).toBeCalledWith(['eslint', 'eslint-config-airbnb']); +}); + +it('should add custom rules', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({ eslintRules: { 'no-undef': 0 } })); + + expect(vol.toJSON()[configFile]).toMatchSnapshot(); +}); + +it('should install extra dependencies', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({ eslintPeerDependencies: ['eslint-plugin-react'] })); + + expect(install).toBeCalledWith(['eslint', 'eslint-plugin-react']); +}); + +it('should remove obsolete dependencies', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + prettier: '*', + }, + }), + }); + + task(getConfigGetter({ eslintObsoleteDependencies: ['prettier'] })); + + expect(uninstall).toBeCalledWith(['jslint', 'jshint', 'prettier']); +}); + +it('should keep custom extensions defined in a package.json script', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: { + lint: 'eslint --ext .ts', + test: 'jest', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); + +it('should not add custom extensions when they were not specified', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: { + lint: 'eslint . --cache --fix', + test: 'jest', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); + +it('should replace scripts.test.eslint with scripts.lint and scripts.pretest', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: { + test: 'eslint --ext .ts && jest', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); + +it('should remove custom extension if it’s "js" (default value)', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: { + lint: 'eslint --ext .js', + test: 'jest', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); + +it('should add extra plugin, parser and extensions for a TypeScript project', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + typescript: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith([ + 'eslint', + '@typescript-eslint/parser', + '@typescript-eslint/eslint-plugin', + ]); +}); + +it('should turn on JSX support in TypeScript parser if TypeScript and React are installed', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + dependencies: { + react: '*', + }, + devDependencies: { + typescript: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should turn off TypeScript-specific eslint rules that conflict with Prettier if prettier is installed', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + typescript: '*', + prettier: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should migrate legacy config file', () => { + vol.fromJSON({ + '/package.json': packageJson, + [legacyConfigFile]: stringify({ rules: { 'no-foo': 2 } }), + }); + + task(getConfigGetter()); + + expect(vol.toJSON()).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-eslint/package-lock.json b/packages/mrm-task-eslint/package-lock.json new file mode 100644 index 00000000..25c756f6 --- /dev/null +++ b/packages/mrm-task-eslint/package-lock.json @@ -0,0 +1,354 @@ +{ + "name": "mrm-task-eslint", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-eslint/package.json b/packages/mrm-task-eslint/package.json new file mode 100644 index 00000000..405ab101 --- /dev/null +++ b/packages/mrm-task-eslint/package.json @@ -0,0 +1,30 @@ +{ + "name": "mrm-task-eslint", + "version": "2.0.1", + "description": "Mrm task that adds ESLint", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-eslint", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "eslint", + "lint", + "javascript" + ], + "dependencies": { + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-gitignore/License.md b/packages/mrm-task-gitignore/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-gitignore/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-gitignore/Readme.md b/packages/mrm-task-gitignore/Readme.md new file mode 100644 index 00000000..446f4deb --- /dev/null +++ b/packages/mrm-task-gitignore/Readme.md @@ -0,0 +1,28 @@ +# mrm-task-gitignore + +[Mrm](https://github.com/sapegin/mrm) task that adds a `.gitignore` file. + +## What it does + +- Creates `.gitignore`. + +## Usage + +``` +npm install -g mrm mrm-task-gitignore +mrm gitignore +``` + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-gitignore/__snapshots__/index.spec.js.snap b/packages/mrm-task-gitignore/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..ef5e3c7d --- /dev/null +++ b/packages/mrm-task-gitignore/__snapshots__/index.spec.js.snap @@ -0,0 +1,44 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add .gitignore 1`] = ` +Object { + "/.gitignore": "node_modules/ +.DS_Store +Thumbs.db +.idea/ +.vscode/ +*.sublime-project +*.sublime-workspace +*.log", +} +`; + +exports[`should add package-lock.json, if yarn.lock exists 1`] = ` +Object { + "/.gitignore": "node_modules/ +.DS_Store +Thumbs.db +.idea/ +.vscode/ +*.sublime-project +*.sublime-workspace +*.log +package-lock.json", + "/yarn.lock": "", +} +`; + +exports[`should add yarn.lock, if package-lock.json exists 1`] = ` +Object { + "/.gitignore": "node_modules/ +.DS_Store +Thumbs.db +.idea/ +.vscode/ +*.sublime-project +*.sublime-workspace +*.log +yarn.lock", + "/package-lock.json": "", +} +`; diff --git a/packages/mrm-task-gitignore/index.js b/packages/mrm-task-gitignore/index.js new file mode 100644 index 00000000..fab0557e --- /dev/null +++ b/packages/mrm-task-gitignore/index.js @@ -0,0 +1,37 @@ +const fs = require('fs'); +const { lines } = require('mrm-core'); + +function task() { + const remove = ['node_modules']; + const add = [ + 'node_modules/', + '.DS_Store', + 'Thumbs.db', + '.idea/', + '.vscode/', + '*.sublime-project', + '*.sublime-workspace', + '*.log', + ]; + + // If project uses npm, ignore yarn.lock + if (fs.existsSync('package-lock.json')) { + add.push('yarn.lock'); + remove.push('package-lock.json'); + } + + // If project uses Yarn, ignore package-lock.json + if (fs.existsSync('yarn.lock')) { + remove.push('yarn.lock'); + add.push('package-lock.json'); + } + + // .gitignore + lines('.gitignore') + .remove(remove) + .add(add) + .save(); +} + +task.description = 'Adds .gitignore'; +module.exports = task; diff --git a/packages/mrm-task-gitignore/index.spec.js b/packages/mrm-task-gitignore/index.spec.js new file mode 100644 index 00000000..c43d2e98 --- /dev/null +++ b/packages/mrm-task-gitignore/index.spec.js @@ -0,0 +1,38 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); + +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +afterEach(() => vol.reset()); + +it('should add .gitignore', () => { + vol.fromJSON(); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should add package-lock.json, if yarn.lock exists', () => { + vol.fromJSON({ + '/yarn.lock': '', + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should add yarn.lock, if package-lock.json exists', () => { + vol.fromJSON({ + '/package-lock.json': '', + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-gitignore/package-lock.json b/packages/mrm-task-gitignore/package-lock.json new file mode 100644 index 00000000..339ee826 --- /dev/null +++ b/packages/mrm-task-gitignore/package-lock.json @@ -0,0 +1,354 @@ +{ + "name": "mrm-task-gitignore", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-gitignore/package.json b/packages/mrm-task-gitignore/package.json new file mode 100644 index 00000000..617a9055 --- /dev/null +++ b/packages/mrm-task-gitignore/package.json @@ -0,0 +1,29 @@ +{ + "name": "mrm-task-gitignore", + "version": "2.0.1", + "description": "Mrm task that adds .gitignore", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-gitignore", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "git", + "gitignore" + ], + "dependencies": { + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-gitter/License.md b/packages/mrm-task-gitter/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-gitter/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-gitter/Readme.md b/packages/mrm-task-gitter/Readme.md new file mode 100644 index 00000000..faa0b25a --- /dev/null +++ b/packages/mrm-task-gitter/Readme.md @@ -0,0 +1,32 @@ +# mrm-task-gitter + +[Mrm](https://github.com/sapegin/mrm) task that adds [Gitter](https://gitter.im/) badge to the readme. + +## Usage + +``` +npm install -g mrm mrm-task-gitter +mrm gitter +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `packageName` (default: `name` field in `package.json`) + +Gitter channel name. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-gitter/index.js b/packages/mrm-task-gitter/index.js new file mode 100644 index 00000000..24b94718 --- /dev/null +++ b/packages/mrm-task-gitter/index.js @@ -0,0 +1,17 @@ +const { markdown, packageJson } = require('mrm-core'); + +function task(config) { + const pkg = packageJson(); + const { packageName } = config + .defaults({ packageName: pkg.get('name') }) + .require('packageName') + .values(); + + const url = `https://gitter.im/${packageName}`; + markdown(config('readme', 'Readme.md')) + .addBadge(`https://badges.gitter.im/${packageName}.svg`, url, 'Gitter chat') + .save(); +} + +task.description = 'Adds Gitter badge to the readme'; +module.exports = task; diff --git a/packages/mrm-task-gitter/package-lock.json b/packages/mrm-task-gitter/package-lock.json new file mode 100644 index 00000000..9cf90f8c --- /dev/null +++ b/packages/mrm-task-gitter/package-lock.json @@ -0,0 +1,354 @@ +{ + "name": "mrm-task-gitter", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-gitter/package.json b/packages/mrm-task-gitter/package.json new file mode 100644 index 00000000..03bc5461 --- /dev/null +++ b/packages/mrm-task-gitter/package.json @@ -0,0 +1,30 @@ +{ + "name": "mrm-task-gitter", + "version": "2.0.1", + "description": "Mrm task that adds Gitter badge to the readme", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-gitter", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "gitter", + "readme", + "badge" + ], + "dependencies": { + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-jest/License.md b/packages/mrm-task-jest/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-jest/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-jest/Readme.md b/packages/mrm-task-jest/Readme.md new file mode 100644 index 00000000..e704e230 --- /dev/null +++ b/packages/mrm-task-jest/Readme.md @@ -0,0 +1,34 @@ +# mrm-task-jest + +[Mrm](https://github.com/sapegin/mrm) task that adds [Jest](https://facebook.github.io/jest/). + +Supports Babel (via [babel-jest](https://github.com/facebook/jest/tree/master/packages/babel-jest)) and TypeScript (via [ts-jest](https://github.com/kulshekhar/ts-jest)). + +## What it does + +- Adds npm scripts +- Updates `.gitignore`, `.npmignore`, `.eslintignore` with common patterns +- Creates a sample test file, `test.js`, when the project has `index.js` in the root folder +- Tries to get rid of Mocha and AVA configs and dependencies +- Installs dependencies + +## Usage + +``` +npm install -g mrm mrm-task-jest +mrm jest +``` + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-jest/__snapshots__/index.spec.js.snap b/packages/mrm-task-jest/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..448f46ac --- /dev/null +++ b/packages/mrm-task-jest/__snapshots__/index.spec.js.snap @@ -0,0 +1,146 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add Babel specific configuration if projects depends on Babel 1`] = ` +Object { + "/.gitignore": "coverage/", + "/.npmignore": "__tests__/", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"babel-core\\": \\"*\\" + }, + \\"scripts\\": { + \\"test:jest\\": \\"jest\\", + \\"test:watch\\": \\"jest --watch\\", + \\"test:coverage\\": \\"jest --coverage\\", + \\"test\\": \\"npm run test:jest --\\" + }, + \\"jest\\": { + \\"testPathIgnorePatterns\\": [ + \\"/node_modules/\\", + \\"/lib/\\" + ] + } +}", +} +`; + +exports[`should add Jest 1`] = ` +Object { + "/.gitignore": "coverage/", + "/.npmignore": "__tests__/", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"test:jest\\": \\"jest\\", + \\"test:watch\\": \\"jest --watch\\", + \\"test:coverage\\": \\"jest --coverage\\", + \\"test\\": \\"npm run test:jest --\\" + } +}", +} +`; + +exports[`should add React specific configuration if projects depends on React 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"dependencies\\": { + \\"react\\": \\"*\\" + }, + \\"scripts\\": { + \\"test:jest\\": \\"jest\\", + \\"test:watch\\": \\"jest --watch\\", + \\"test:coverage\\": \\"jest --coverage\\", + \\"test\\": \\"npm run test:jest --\\" + }, + \\"jest\\": { + \\"snapshotSerializers\\": [ + \\"enzyme-to-json/serializer\\" + ], + \\"setupFiles\\": [ + \\"./test/jestsetup.js\\" + ] + } +}" +`; + +exports[`should add React specific configuration if projects depends on React 2`] = ` +"import Enzyme from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; + +Enzyme.configure({ adapter: new Adapter() }); +" +`; + +exports[`should add TypeScript specific configuration if projects depends on TypeScript 1`] = ` +Object { + "/.gitignore": "coverage/", + "/.npmignore": "__tests__/", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"typescript\\": \\"*\\" + }, + \\"scripts\\": { + \\"test:jest\\": \\"jest\\", + \\"test:watch\\": \\"jest --watch\\", + \\"test:coverage\\": \\"jest --coverage\\", + \\"test\\": \\"npm run test:jest --\\" + }, + \\"jest\\": { + \\"testPathIgnorePatterns\\": [ + \\"/node_modules/\\", + \\"/lib/\\" + ], + \\"transform\\": { + \\"^.+\\\\\\\\.tsx?$\\": \\"/node_modules/ts-jest/preprocessor.js\\" + }, + \\"testRegex\\": \\"(/__tests__/.*|(\\\\\\\\.|/)(test|spec))\\\\\\\\.(jsx?|tsx?)$\\", + \\"moduleFileExtensions\\": [ + \\"ts\\", + \\"tsx\\", + \\"js\\", + \\"jsx\\", + \\"json\\" + ] + } +}", +} +`; + +exports[`should add a basic test case when index.js file is present 1`] = ` +"const uberUnicorn = require('./index'); + +test('uberUnicorn', () => { + const result = uberUnicorn(); + expect(result).toBeTruthy(); +}); +" +`; + +exports[`should not overwrite Jest setup file 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"dependencies\\": { + \\"react\\": \\"*\\" + }, + \\"scripts\\": { + \\"test:jest\\": \\"jest\\", + \\"test:watch\\": \\"jest --watch\\", + \\"test:coverage\\": \\"jest --coverage\\", + \\"test\\": \\"npm run test:jest --\\" + }, + \\"jest\\": { + \\"snapshotSerializers\\": [ + \\"enzyme-to-json/serializer\\" + ] + } +}" +`; + +exports[`should not overwrite test.js 1`] = `"still here"`; + +exports[`should update or create .eslintignore if projects depends on ESLint 1`] = ` +"coverage/* +lib/*" +`; diff --git a/packages/mrm-task-jest/index.js b/packages/mrm-task-jest/index.js new file mode 100644 index 00000000..a951be37 --- /dev/null +++ b/packages/mrm-task-jest/index.js @@ -0,0 +1,154 @@ +const fs = require('fs'); +const path = require('path'); +const { camelCase } = require('lodash'); +const { + lines, + packageJson, + template, + install, + uninstall, +} = require('mrm-core'); + +function task() { + const packages = ['jest']; + const oldPackages = ['mocha', 'chai', 'ava']; + + // package.json + const pkg = packageJson().merge({ + scripts: { + 'test:jest': 'jest', + 'test:watch': 'jest --watch', + 'test:coverage': 'jest --coverage', + }, + }); + + const needsMigration = oldPackages.some(name => + pkg.get(`devDependencies.${name}`) + ); + const hasBabel = pkg.get('devDependencies.babel-core'); + const hasTypeScript = pkg.get('devDependencies.typescript'); + const hasReact = pkg.get('dependencies.react'); + + // Babel + if (hasBabel) { + packages.push('babel-jest'); + pkg.merge({ + jest: { + testPathIgnorePatterns: ['/node_modules/', '/lib/'], + }, + }); + } + + // TypeScript + if (hasTypeScript) { + packages.push('ts-jest', '@types/jest'); + pkg.merge({ + jest: { + testPathIgnorePatterns: ['/node_modules/', '/lib/'], + transform: { + '^.+\\.tsx?$': '/node_modules/ts-jest/preprocessor.js', + }, + testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$', + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], + }, + }); + } + + // React + if (hasReact) { + packages.push( + 'react-test-renderer', + 'enzyme', + 'enzyme-adapter-react-16', + 'enzyme-to-json' + ); + + pkg.merge({ + jest: { + snapshotSerializers: ['enzyme-to-json/serializer'], + }, + }); + + const templateFile = path.join(__dirname, 'templates/jestsetup.js'); + const jestSetupFile = './test/jestsetup.js'; + if (!fs.existsSync(jestSetupFile)) { + pkg.merge({ + jest: { + setupFiles: [jestSetupFile], + }, + }); + template(jestSetupFile, templateFile) + .apply() + .save(); + } else { + const contents = fs.readFileSync(jestSetupFile, 'utf8'); + if (!contents.includes('enzyme-adapter-react-')) { + console.log(`\nCannot setup Enzyme. Add these lines to your Jest setup file: + +${fs.readFileSync(templateFile, 'utf8')} + +More info: +http://blog.sapegin.me/all/react-jest +`); + } + } + } + + // Clean up old scripts + pkg + .removeScript(/^mocha|mocha:.*?|ava|ava:.*?|test:mocha|test:ava$/) + .removeScript('test', /mocha|ava/); + + // package.json: test command + pkg.appendScript('test', 'npm run test:jest --'); + + pkg.save(); + + // .gitignore + lines('.gitignore') + .add('coverage/') + .save(); + + // .npmignore + if (!pkg.get('private')) { + lines('.npmignore') + .add('__tests__/') + .save(); + } + + // ESLint + if (pkg.get(`devDependencies.eslint`)) { + const eslintignore = lines('.eslintignore').add('coverage/*'); + if (hasBabel) { + eslintignore.add('lib/*'); + } + eslintignore.save(); + } + + // Test template for small projects + if (fs.existsSync('index.js') && !fs.existsSync('test.js')) { + template('test.js', path.join(__dirname, 'templates/test.js')) + .apply({ + func: camelCase(pkg.get('name')), + }) + .save(); + } + + // Dependencies + uninstall(oldPackages); + install(packages); + + // Suggest jest-codemods if projects used other test frameworks + if (needsMigration) { + console.log(`\nMigrate your tests to Jest: + + npx jest-codemods --force [--dry] + +More info: +https://github.com/skovhus/jest-codemods +`); + } +} + +task.description = 'Adds Jest'; +module.exports = task; diff --git a/packages/mrm-task-jest/index.spec.js b/packages/mrm-task-jest/index.spec.js new file mode 100644 index 00000000..2b88be0e --- /dev/null +++ b/packages/mrm-task-jest/index.spec.js @@ -0,0 +1,191 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); +jest.mock('mrm-core/src/npm', () => ({ + install: jest.fn(), + uninstall: jest.fn(), +})); + +const fs = require.requireActual('fs'); +const path = require('path'); +const { install, uninstall } = require('mrm-core'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const console$log = console.log; + +const stringify = o => JSON.stringify(o, null, ' '); + +const packageJson = stringify({ + name: 'unicorn', +}); + +beforeEach(() => { + console.log = jest.fn(); +}); + +afterEach(() => { + vol.reset(); + install.mockClear(); + uninstall.mockClear(); + console.log = console$log; +}); + +it('should add Jest', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith(['jest']); +}); + +it('should add Babel specific configuration if projects depends on Babel', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + 'babel-core': '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith(['jest', 'babel-jest']); +}); + +it('should add TypeScript specific configuration if projects depends on TypeScript', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + typescript: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith(['jest', 'ts-jest', '@types/jest']); +}); + +it('should add React specific configuration if projects depends on React', () => { + vol.fromJSON({ + [`${__dirname}/templates/jestsetup.js`]: fs + .readFileSync(path.join(__dirname, 'templates/jestsetup.js')) + .toString(), + '/package.json': stringify({ + name: 'unicorn', + dependencies: { + react: '*', + }, + }), + }); + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); + expect(vol.toJSON()['/test/jestsetup.js']).toMatchSnapshot(); + expect(install).toBeCalledWith(expect.arrayContaining(['jest', 'enzyme'])); +}); + +it('should not overwrite Jest setup file', () => { + vol.fromJSON({ + [`${__dirname}/templates/jestsetup.js`]: fs + .readFileSync(path.join(__dirname, 'templates/jestsetup.js')) + .toString(), + '/test/jestsetup.js': 'pizza', + '/package.json': stringify({ + name: 'unicorn', + dependencies: { + react: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); + expect(vol.toJSON()['/test/jestsetup.js']).toBe('pizza'); +}); + +it('should update or create .eslintignore if projects depends on ESLint', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + eslint: '*', + 'babel-core': '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/.eslintignore']).toMatchSnapshot(); +}); + +it('should add a basic test case when index.js file is present', () => { + vol.fromJSON({ + [`${__dirname}/templates/test.js`]: fs + .readFileSync(path.join(__dirname, 'templates/test.js')) + .toString(), + '/package.json': stringify({ + name: 'uber-unicorn', + }), + '/index.js': '', + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/test.js']).toMatchSnapshot(); +}); + +it('should not update .npmignore for private packages', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + private: true, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/.npmignore']).toBeUndefined(); +}); + +it('should not overwrite test.js', () => { + vol.fromJSON({ + '/package.json': packageJson, + '/index.js': '', + '/test.js': 'still here', + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/test.js']).toMatchSnapshot(); +}); + +it('should uninstall other test frameworks', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + mocha: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(uninstall).toBeCalledWith(['mocha', 'chai', 'ava']); + expect(console.log).toBeCalledWith( + expect.stringMatching('Migrate your tests to Jest') + ); +}); diff --git a/packages/mrm-task-jest/package-lock.json b/packages/mrm-task-jest/package-lock.json new file mode 100644 index 00000000..dfecdcd6 --- /dev/null +++ b/packages/mrm-task-jest/package-lock.json @@ -0,0 +1,354 @@ +{ + "name": "mrm-task-jest", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-jest/package.json b/packages/mrm-task-jest/package.json new file mode 100644 index 00000000..923764a7 --- /dev/null +++ b/packages/mrm-task-jest/package.json @@ -0,0 +1,31 @@ +{ + "name": "mrm-task-jest", + "version": "2.0.1", + "description": "Mrm task that adds Jest", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-jest", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js", + "templates" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "jest", + "testing" + ], + "dependencies": { + "lodash": "^4.17.15", + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-jest/templates/index.js b/packages/mrm-task-jest/templates/index.js new file mode 100644 index 00000000..be16a995 --- /dev/null +++ b/packages/mrm-task-jest/templates/index.js @@ -0,0 +1,5 @@ +function pizza(num) { + return num * 2; +} + +module.exports = pizza; diff --git a/packages/mrm-task-jest/templates/jestsetup.js b/packages/mrm-task-jest/templates/jestsetup.js new file mode 100644 index 00000000..fc7b0dce --- /dev/null +++ b/packages/mrm-task-jest/templates/jestsetup.js @@ -0,0 +1,4 @@ +import Enzyme from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; + +Enzyme.configure({ adapter: new Adapter() }); diff --git a/packages/mrm-task-jest/templates/test.js b/packages/mrm-task-jest/templates/test.js new file mode 100644 index 00000000..c0116eb7 --- /dev/null +++ b/packages/mrm-task-jest/templates/test.js @@ -0,0 +1,6 @@ +const ${func} = require('./index'); + +test('${func}', () => { + const result = ${func}(); + expect(result).toBeTruthy(); +}); diff --git a/packages/mrm-task-license/License.md b/packages/mrm-task-license/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-license/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-license/Readme.md b/packages/mrm-task-license/Readme.md new file mode 100644 index 00000000..0dd7d4d7 --- /dev/null +++ b/packages/mrm-task-license/Readme.md @@ -0,0 +1,52 @@ +# mrm-task-license + +[Mrm](https://github.com/sapegin/mrm) task that adds license file based on `license` field in `package.json`. + +## What it does + +- Creates a license file. + +## Usage + +``` +npm install -g mrm mrm-task-license +mrm license +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `license` (default: taken from `package.json`, if not found `MIT` is used) + +License name (like `MIT`, `Unlicense`). For full list of supported values see: [`/templates`](./templates/). + +### `licenseFile` (default: `License.md`) + +File name. + +### `name` (default: will try to read from your npm or Git config) + +Your name. + +### `email` (default: will try to read from your npm or Git config) + +Your email. + +### `url` (default: will try to read from your npm or Git config) + +Your site URL. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-license/__snapshots__/index.spec.js.snap b/packages/mrm-task-license/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..01fcabae --- /dev/null +++ b/packages/mrm-task-license/__snapshots__/index.spec.js.snap @@ -0,0 +1,40 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add EditorConfig 1`] = ` +"# The MIT License + +Copyright 2020 Gendalf, contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +" +`; + +exports[`should read lincese name from package.json 1`] = ` +"# Apache License, Version 2.0 (Apache-2.0) + +Copyright 2020 Gendalf, contributors + +Licensed under the Apache License, Version 2.0 (the \\"License\\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \\"AS IS\\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +" +`; + +exports[`should use license config argument 1`] = ` +"This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. + +In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. + +THE SOFTWARE IS PROVIDED \\"AS IS\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +" +`; diff --git a/packages/mrm-task-license/index.js b/packages/mrm-task-license/index.js new file mode 100644 index 00000000..9a4e30bc --- /dev/null +++ b/packages/mrm-task-license/index.js @@ -0,0 +1,56 @@ +const fs = require('fs'); +const path = require('path'); +const meta = require('user-meta'); +const { template, packageJson } = require('mrm-core'); + +const defaultLicense = 'MIT'; + +const ANONYMOUS_LICENSES = ['Unlicense']; + +const isAnonymouseLicense = name => ANONYMOUS_LICENSES.indexOf(name) > -1; + +function task(config) { + const pkg = packageJson(); + config + .defaults({ licenseFile: 'License.md' }) + .defaults({ name: pkg.get('author.name') }) + .defaults(meta); + + const configLicense = config.values().license; + + if (!isAnonymouseLicense(configLicense)) { + config.require('name', 'email'); + } + + const { name, email, licenseFile } = config.values(); + + let license = configLicense; + let shouldUpdatePkgLicense = false; + if (!license) { + license = pkg.get('license', defaultLicense); + shouldUpdatePkgLicense = true; + } + + const templateFile = path.join(__dirname, `templates/${license}.md`); + + if (!fs.existsSync(templateFile)) { + console.log(`No template for the "${license}" license found, skipping`); + return; + } + + if (shouldUpdatePkgLicense) { + pkg.set('license', license); + pkg.save(); + } + + template(licenseFile, templateFile) + .apply({ + name, + email, + year: new Date().getFullYear(), + }) + .save(); +} +task.description = 'Adds license file'; + +module.exports = task; diff --git a/packages/mrm-task-license/index.spec.js b/packages/mrm-task-license/index.spec.js new file mode 100644 index 00000000..6a90af18 --- /dev/null +++ b/packages/mrm-task-license/index.spec.js @@ -0,0 +1,98 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); + +const fs = require.requireActual('fs'); +const path = require('path'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); +const { json } = require('mrm-core'); + +const console$log = console.log; + +const stringify = o => JSON.stringify(o, null, ' '); + +const config = { + name: 'Gendalf', + email: 'gendalf@middleearth.com', + url: 'http://middleearth.com', +}; + +beforeEach(() => { + console.log = jest.fn(); +}); + +afterEach(() => { + vol.reset(); + console.log = console$log; +}); + +it('should add EditorConfig', () => { + vol.fromJSON({ + [`${__dirname}/templates/MIT.md`]: fs + .readFileSync(path.join(__dirname, 'templates/MIT.md')) + .toString(), + }); + + task(getConfigGetter(config)); + + expect(vol.toJSON()['/License.md']).toMatchSnapshot(); +}); + +it('should read lincese name from package.json', () => { + vol.fromJSON({ + [`${__dirname}/templates/Apache-2.0.md`]: fs + .readFileSync(path.join(__dirname, 'templates/Apache-2.0.md')) + .toString(), + '/package.json': stringify({ + name: 'unicorn', + license: 'Apache-2.0', + }), + }); + + task(getConfigGetter(config)); + + expect(vol.toJSON()['/License.md']).toMatchSnapshot(); +}); + +it('should skip when template not found', () => { + task( + getConfigGetter({ + name: 'Gendalf', + email: 'gendalf@middleearth.com', + url: 'http://middleearth.com', + }) + ); + + expect(console.log).toBeCalledWith(expect.stringMatching('skipping')); +}); + +it('should use license config argument', () => { + vol.fromJSON({ + [`${__dirname}/templates/Unlicense.md`]: fs + .readFileSync(path.join(__dirname, 'templates/Unlicense.md')) + .toString(), + }); + + task( + getConfigGetter({ + license: 'Unlicense', + }) + ); + + expect(vol.readFileSync('/License.md', 'utf8')).toMatchSnapshot(); +}); + +it('adds license to package.json if not set', () => { + vol.fromJSON({ + [`${__dirname}/templates/MIT.md`]: fs + .readFileSync(path.join(__dirname, 'templates/MIT.md')) + .toString(), + }); + + task(getConfigGetter(config)); + + expect(json('/package.json').get('license')).toBe('MIT'); +}); diff --git a/packages/mrm-task-license/package-lock.json b/packages/mrm-task-license/package-lock.json new file mode 100644 index 00000000..4fe05dea --- /dev/null +++ b/packages/mrm-task-license/package-lock.json @@ -0,0 +1,388 @@ +{ + "name": "mrm-task-license", + "version": "3.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "user-meta": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/user-meta/-/user-meta-1.0.0.tgz", + "integrity": "sha512-Q/opMgFhVbBkdlTs44UKzV7L5Uj2zrJ4MVPXTTzJmrU1bHb2cX6wJzBIqEf1gROTzZIH8u39WmHsa5EvfnMPrw==", + "requires": { + "rc": "^1.2.1" + } + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-license/package.json b/packages/mrm-task-license/package.json new file mode 100644 index 00000000..74bcfaa0 --- /dev/null +++ b/packages/mrm-task-license/package.json @@ -0,0 +1,32 @@ +{ + "name": "mrm-task-license", + "version": "3.0.0", + "description": "Mrm task that adds a license file", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-license", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js", + "templates" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "license", + "readme", + "badge" + ], + "dependencies": { + "mrm-core": "^4.0.0", + "user-meta": "^1.0.0" + } +} diff --git a/packages/mrm-task-license/templates/Apache-2.0.md b/packages/mrm-task-license/templates/Apache-2.0.md new file mode 100644 index 00000000..7448615c --- /dev/null +++ b/packages/mrm-task-license/templates/Apache-2.0.md @@ -0,0 +1,9 @@ +# Apache License, Version 2.0 (Apache-2.0) + +Copyright ${year} ${name}, contributors + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/mrm-task-license/templates/BSD-2-Clause.md b/packages/mrm-task-license/templates/BSD-2-Clause.md new file mode 100644 index 00000000..eb280d4c --- /dev/null +++ b/packages/mrm-task-license/templates/BSD-2-Clause.md @@ -0,0 +1,11 @@ +# The 2-Clause BSD License (BSD-2-Clause) + +Copyright ${year} ${name}, contributors + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/mrm-task-license/templates/BSD-3-Clause.md b/packages/mrm-task-license/templates/BSD-3-Clause.md new file mode 100644 index 00000000..68e79c02 --- /dev/null +++ b/packages/mrm-task-license/templates/BSD-3-Clause.md @@ -0,0 +1,13 @@ +# The 3-Clause BSD License (BSD-3-Clause) + +Copyright ${year} ${name}, contributors + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/mrm-task-license/templates/MIT.md b/packages/mrm-task-license/templates/MIT.md new file mode 100644 index 00000000..c01eeef4 --- /dev/null +++ b/packages/mrm-task-license/templates/MIT.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright ${year} ${name}, contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-license/templates/Unlicense.md b/packages/mrm-task-license/templates/Unlicense.md new file mode 100644 index 00000000..0a449f1f --- /dev/null +++ b/packages/mrm-task-license/templates/Unlicense.md @@ -0,0 +1,9 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. + +In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/packages/mrm-task-lint-staged/License.md b/packages/mrm-task-lint-staged/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-lint-staged/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-lint-staged/Readme.md b/packages/mrm-task-lint-staged/Readme.md new file mode 100644 index 00000000..f61d1071 --- /dev/null +++ b/packages/mrm-task-lint-staged/Readme.md @@ -0,0 +1,93 @@ +# mrm-task-lint-staged + +[Mrm](https://github.com/sapegin/mrm) task that adds [lint-staged](https://github.com/okonet/lint-staged). + +**Note:** supports only Prettier, ESLint and Stylelint now, pull requests are welcome. + +## What it does + +- Creates a config in `package.json` +- Sets up a pre-commit Git hook +- Installs dependencies + +This tasks will try to infer extensions from your npm scripts. For example, if you have `lint` script that runs ESLint for `js` and `ts` files, the task will add lint-staged rule that runs ESLint for the same extensions. And will overwrite an existing rule if you change it manually and run the task again, but it will try to keepy your custom rules. + +## Usage + +``` +npm install -g mrm mrm-task-lint-staged +mrm lint-staged +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) and [lint-staged docs](https://github.com/okonet/lint-staged/blob/master/README.md) for more details. + +### `lintStagedRules` (default: infer) + +Overrides and custom rules. By default will try to infer by project dependencies. + +For example, a custom extension: + +```json +{ + "lintStagedRules": { + "eslint": { + "extensions": ["js", "jsx", "mjs"] + } + } +} +``` + +Or a custom command: + +```json +{ + "lintStagedRules": { + "eslint": { + "command": "eslint --fix" + } + } +} +``` + +Or you can disable one of the default rules: + +```json +{ + "lintStagedRules": { + "prettier": { + "enabled": false + } + } +} +``` + +Or add a custom rule: + +```json +{ + "lintStagedRules": { + "jest": { + "extensions": ["js"], + "command": "jest --bail --findRelatedTests" + } + } +} +``` + +Available rules are `prettier`, `eslint` and `stylelint`. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-lint-staged/__snapshots__/index.spec.js.snap b/packages/mrm-task-lint-staged/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..4c52de93 --- /dev/null +++ b/packages/mrm-task-lint-staged/__snapshots__/index.spec.js.snap @@ -0,0 +1,303 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add ESLint if project depends on it 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"eslint\\": \\"*\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.js\\": \\"eslint --cache --fix\\" + } +}", +} +`; + +exports[`should add Prettier and ESLint 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": {}, + \\"devDependencies\\": { + \\"eslint\\": \\"4.0.1\\", + \\"prettier\\": \\"1.9.2\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.js\\": \\"eslint --cache --fix\\", + \\"*.{js,css,md}\\": \\"prettier --write\\" + } +}", +} +`; + +exports[`should add Prettier if project depends on it 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"prettier\\": \\"*\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.{js,css,md}\\": \\"prettier --write\\" + } +}", +} +`; + +exports[`should add a custom rule 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"eslint\\": \\"*\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.js\\": [ + \\"eslint --cache --fix\\", + \\"false\\" + ] + } +}", +} +`; + +exports[`should add stylelint if project depends on it 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"stylelint\\": \\"*\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.css\\": \\"stylelint --fix\\" + } +}", +} +`; + +exports[`should infer ESLint extension for an npm script 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"lint\\": \\"eslint --fix --ext .js,.jsx\\" + }, + \\"devDependencies\\": { + \\"eslint\\": \\"*\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.{js,jsx}\\": \\"eslint --cache --fix\\" + } +}" +`; + +exports[`should infer Prettier extensions from an npm script 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"format\\": \\"prettier --write '**/*.{js,jsx}'\\" + }, + \\"devDependencies\\": { + \\"prettier\\": \\"1.9.2\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.{js,jsx}\\": \\"prettier --write\\" + } +}" +`; + +exports[`should merge rules with the same pattern 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"eslint\\": \\"*\\", + \\"prettier\\": \\"*\\" + }, + \\"lint-staged\\": { + \\"*.md\\": \\"textlint --fix\\", + \\"*.js\\": [ + \\"eslint --cache --fix\\", + \\"prettier --write\\" + ] + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + } +}", +} +`; + +exports[`should remove husky 0.14 config from package.json 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": {}, + \\"devDependencies\\": { + \\"eslint\\": \\"*\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.js\\": \\"eslint --cache --fix\\" + } +}", +} +`; + +exports[`should update an existing rule 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"eslint\\": \\"*\\" + }, + \\"lint-staged\\": { + \\"*.md\\": \\"textlint --fix\\", + \\"*.js\\": \\"eslint --cache --fix\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + } +}", +} +`; + +exports[`should use a custom ESLint extension 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"eslint\\": \\"*\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.{js,jsx}\\": \\"eslint --cache --fix\\" + } +}", +} +`; + +exports[`should use a custom stylelint extension 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"stylelint\\": \\"*\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.scss\\": \\"stylelint --fix\\" + } +}", +} +`; + +exports[`should use custom Prettier extensions 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"prettier\\": \\"1.9.2\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.{js,jsx,mjs}\\": \\"prettier --write\\" + } +}", +} +`; + +exports[`should use default JS extension if eslint command has no --ext key 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"lint\\": \\"eslint --fix\\" + }, + \\"devDependencies\\": { + \\"eslint\\": \\"*\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.js\\": \\"eslint --cache --fix\\" + } +}" +`; + +exports[`shouldn’t add a default rule if it’s disabled in overrides 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"devDependencies\\": { + \\"eslint\\": \\"*\\", + \\"prettier\\": \\"*\\" + }, + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + }, + \\"lint-staged\\": { + \\"*.{js,css,md}\\": \\"prettier --write\\" + } +}", +} +`; diff --git a/packages/mrm-task-lint-staged/index.js b/packages/mrm-task-lint-staged/index.js new file mode 100644 index 00000000..0ce3bc9a --- /dev/null +++ b/packages/mrm-task-lint-staged/index.js @@ -0,0 +1,192 @@ +const { packageJson, install, getExtsFromCommand } = require('mrm-core'); +const { castArray } = require('lodash'); + +const packages = { + 'lint-staged': '>=10', + husky: '>=4', +}; + +/** + * Default lint-staged rules + * + * @param name Name of the rule to match user overrides + * @param [condition] Function that returns true when the rule should be added + * @param extensions Default extension (if we can't infer them from an npm script) + * @param [script] Name of an npm script to infer extensions + * @param [param] Command line parameter of an npm script to infer extensions (for example, `ext` for `--ext`) + * @param command Command to run for a lint-staged rule + */ +const defaultRules = [ + // ESLint + { + name: 'eslint', + condition: pkg => !!pkg.get('devDependencies.eslint'), + extensions: ['js'], + script: 'lint', + param: 'ext', + command: 'eslint --cache --fix', + }, + // Stylelint + { + name: 'stylelint', + condition: pkg => !!pkg.get('devDependencies.stylelint'), + extensions: ['css'], + script: 'lint:css', + command: 'stylelint --fix', + }, + // Prettier + { + name: 'prettier', + condition: pkg => + !!pkg.get('devDependencies.prettier') && + !pkg.get('devDependencies.eslint-plugin-prettier'), + extensions: ['js', 'css', 'md'], + script: 'format', + command: 'prettier --write', + }, +]; + +/** + * Merge default rules with user overrides + * + * @param {Array} defaults + * @param {Object} overrides + */ +function mergeRules(defaults, overrides) { + // Overrides for default rules + const rulesWithOverrides = defaults.map(rule => ({ + ...rule, + ...overrides[rule.name], + })); + + // Custom rules + return Object.entries(overrides).reduce((acc, [name, rule]) => { + if (acc.some(x => x.name === name)) { + return acc; + } + return [...acc, rule]; + }, rulesWithOverrides); +} + +/** + * Convert an array of extensions to a glob pattern + * + * Example: ['js', 'ts'] -> '*.{js,ts}' + * + * @param {string[]} exts + */ +function extsToGlob(exts) { + if (exts.length > 1) { + return `*.{${exts}}`; + } + + return `*.${exts}`; +} + +/** + * Generate a regular expression to detect a rule in existing rules. For simplicity + * assumes that the first word in the command is the binary you're running. + * + * Example: 'eslint --fix' -> /\beslint\b/ + * + * TODO: Allow overriding for more complex commands + * + * @param {string} command + */ +function getRuleRegExp(command) { + return new RegExp(`\\b${command.split(' ').shift()}\\b`); +} + +/** + * Check if a given command belongs to a rule + * + * @param {string | string[]} ruleCommands + * @param {string} command + */ +function isCommandBelongsToRule(ruleCommands, command) { + const regExp = getRuleRegExp(command); + return castArray(ruleCommands).some(x => regExp.test(x)); +} + +function task(config) { + const { lintStagedRules } = config.defaults({ lintStagedRules: {} }).values(); + + const pkg = packageJson(); + const allRules = mergeRules(defaultRules, lintStagedRules); + const existingRules = Object.entries(pkg.get('lint-staged', {})); + + // Remove exising rules that run any of default commands + const commandsToRemove = allRules.map(rule => rule.command); + const existingRulesToKeep = existingRules.filter(([, ruleCommands]) => + commandsToRemove + .map(command => isCommandBelongsToRule(ruleCommands, command)) + .every(x => x === false) + ); + + // New rules + const rulesToAdd = allRules.map( + ({ + condition = () => true, + extensions: defaultExtensions, + script, + param, + command, + enabled = true, + }) => { + if (!enabled || !condition(pkg)) { + return null; + } + + const extensions = + getExtsFromCommand(pkg.getScript(script), param) || defaultExtensions; + const pattern = extsToGlob(extensions); + + return [pattern, command]; + } + ); + + // Merge existing and new rules, clean up + const rulesToWrite = [...existingRulesToKeep, ...rulesToAdd].filter(Boolean); + + // Merge rules with the same pattern and convert to an object + // Wrap commands in an array only when a pattern has multiple commands + const rules = {}; + rulesToWrite.forEach(([pattern, command]) => { + if (rules[pattern]) { + rules[pattern] = [...castArray(rules[pattern]), command]; + } else { + rules[pattern] = command; + } + }); + + if (Object.keys(rules).length === 0) { + const names = defaultRules.map(rule => rule.name); + console.log( + `\nCannot add lint-staged: only ${names.join( + ', ' + )} or custom rules are supported.` + ); + return; + } + + // package.json + pkg + // Remove husky 0.14 config + .unset('scripts.precommit') + // Add new config + .merge({ + husky: { + hooks: { + 'pre-commit': 'lint-staged', + }, + }, + 'lint-staged': rules, + }) + .save(); + + // Install dependencies + install(packages); +} + +task.description = 'Adds lint-staged'; +module.exports = task; diff --git a/packages/mrm-task-lint-staged/index.spec.js b/packages/mrm-task-lint-staged/index.spec.js new file mode 100644 index 00000000..8ae74f21 --- /dev/null +++ b/packages/mrm-task-lint-staged/index.spec.js @@ -0,0 +1,343 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/npm', () => ({ + install: jest.fn(), +})); + +const { install } = require('mrm-core'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const stringify = o => JSON.stringify(o, null, ' '); + +const packageJson = stringify({ + name: 'unicorn', + scripts: { + test: 'jest', + }, +}); + +const console$log = console.log; + +beforeEach(() => { + console.log = jest.fn(); +}); + +afterEach(() => { + vol.reset(); + install.mockClear(); + console.log = console$log; +}); + +it('should not do anything if not supported tools are found', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({})); + + expect(Object.keys(vol.toJSON())).toEqual(['/package.json']); + expect(vol.toJSON()['/package.json']).toEqual(packageJson); + expect(console.log).toBeCalledWith( + expect.stringMatching('Cannot add lint-staged') + ); +}); + +it('should add Prettier if project depends on it', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + prettier: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith({ 'lint-staged': '>=10', husky: '>=4' }); +}); + +it('should add Prettier and ESLint', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: {}, + devDependencies: { + eslint: '4.0.1', + prettier: '1.9.2', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should infer Prettier extensions from an npm script', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: { + format: "prettier --write '**/*.{js,jsx}'", + }, + devDependencies: { + prettier: '1.9.2', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); + +it('should not do anything if project is using Prettier via ESLint plugin', () => { + const pkg = stringify({ + name: 'unicorn', + devDependencies: { + prettier: '*', + 'eslint-plugin-prettier': '*', + }, + }); + vol.fromJSON({ + '/package.json': pkg, + }); + + task(getConfigGetter({})); + + expect(Object.keys(vol.toJSON())).toEqual(['/package.json']); + expect(vol.toJSON()['/package.json']).toEqual(pkg); + expect(console.log).toBeCalledWith( + expect.stringMatching('Cannot add lint-staged') + ); +}); + +it('should add ESLint if project depends on it', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + eslint: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith({ 'lint-staged': '>=10', husky: '>=4' }); +}); + +it('should use default JS extension if eslint command has no --ext key', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: { + lint: 'eslint --fix', + }, + devDependencies: { + eslint: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); + +it('should infer ESLint extension for an npm script', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: { + lint: 'eslint --fix --ext .js,.jsx', + }, + devDependencies: { + eslint: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); + +it('should use custom Prettier extensions', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + prettier: '1.9.2', + }, + }), + }); + + task( + getConfigGetter({ + lintStagedRules: { prettier: { extensions: ['js', 'jsx', 'mjs'] } }, + }) + ); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should use a custom ESLint extension', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + eslint: '*', + }, + }), + }); + + task( + getConfigGetter({ + lintStagedRules: { eslint: { extensions: ['js', 'jsx'] } }, + }) + ); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('shouldn’t add a default rule if it’s disabled in overrides', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + eslint: '*', + prettier: '*', + }, + }), + }); + + task(getConfigGetter({ lintStagedRules: { eslint: { enabled: false } } })); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should add stylelint if project depends on it', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + stylelint: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith({ 'lint-staged': '>=10', husky: '>=4' }); +}); + +it('should use a custom stylelint extension', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + stylelint: '*', + }, + }), + }); + + task( + getConfigGetter({ + lintStagedRules: { stylelint: { extensions: ['scss'] } }, + }) + ); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should add a custom rule', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + eslint: '*', + }, + }), + }); + + task( + getConfigGetter({ + lintStagedRules: { false: { extensions: ['js'], command: 'false' } }, + }) + ); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith({ 'lint-staged': '>=10', husky: '>=4' }); +}); + +it('should update an existing rule', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + eslint: '*', + }, + 'lint-staged': { + '*.md': 'textlint --fix', + '*.js': 'eslint --fix', + }, + }), + }); + + task(getConfigGetter()); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith({ 'lint-staged': '>=10', husky: '>=4' }); +}); + +it('should merge rules with the same pattern', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + eslint: '*', + prettier: '*', + }, + 'lint-staged': { + '*.md': 'textlint --fix', + '*.js': 'eslint --fix', + }, + }), + }); + + task( + getConfigGetter({ + lintStagedRules: { + eslint: { extensions: ['js'] }, + prettier: { extensions: ['js'] }, + }, + }) + ); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith({ 'lint-staged': '>=10', husky: '>=4' }); +}); + +it('should remove husky 0.14 config from package.json', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: { + precommit: 'lint-staged', + }, + devDependencies: { + eslint: '*', + }, + }), + }); + + task(getConfigGetter()); + + expect(vol.toJSON()).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-lint-staged/package-lock.json b/packages/mrm-task-lint-staged/package-lock.json new file mode 100644 index 00000000..1f6f6dfe --- /dev/null +++ b/packages/mrm-task-lint-staged/package-lock.json @@ -0,0 +1,354 @@ +{ + "name": "mrm-task-lint-staged", + "version": "3.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-lint-staged/package.json b/packages/mrm-task-lint-staged/package.json new file mode 100644 index 00000000..30069245 --- /dev/null +++ b/packages/mrm-task-lint-staged/package.json @@ -0,0 +1,30 @@ +{ + "name": "mrm-task-lint-staged", + "version": "3.0.0", + "description": "Mrm task that adds lint-staged", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-lint-staged", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "lint-staged", + "lint" + ], + "dependencies": { + "lodash": "^4.17.15", + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-package/License.md b/packages/mrm-task-package/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-package/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-package/Readme.md b/packages/mrm-task-package/Readme.md new file mode 100644 index 00000000..95145626 --- /dev/null +++ b/packages/mrm-task-package/Readme.md @@ -0,0 +1,52 @@ +# mrm-task-package + +[Mrm](https://github.com/sapegin/mrm) task that adds `package.json`. + +## What it does + +- Creates `package.json` + +## Usage + +``` +npm install -g mrm mrm-task-package +mrm package +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `github` (default: extracted from `.git/config` file) + +Your GitHub user name. + +### `name` (default: will try to read from your npm or Git config) + +Your name. + +### `url` (default: will try to read from your npm or Git config) + +Your site URL. + +### `minNode` (default: 6.9) + +Minimum required Node.js version. + +### `license` (default: MIT) + +License. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-package/__snapshots__/index.spec.js.snap b/packages/mrm-task-package/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..21931c39 --- /dev/null +++ b/packages/mrm-task-package/__snapshots__/index.spec.js.snap @@ -0,0 +1,79 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add package.json 1`] = ` +"{ + \\"name\\": \\"mrm-task-package\\", + \\"version\\": \\"1.0.0\\", + \\"description\\": \\"\\", + \\"author\\": { + \\"name\\": \\"Gendalf\\", + \\"url\\": \\"http://middleearth.com\\" + }, + \\"homepage\\": \\"https://github.com/gendalf/mrm-task-package\\", + \\"repository\\": \\"gendalf/mrm-task-package\\", + \\"license\\": \\"MIT\\", + \\"engines\\": { + \\"node\\": \\">=6.9\\" + }, + \\"main\\": \\"index.js\\", + \\"files\\": [ + \\"index.js\\" + ], + \\"scripts\\": {}, + \\"keywords\\": [], + \\"dependencies\\": {}, + \\"devDependencies\\": {} +}" +`; + +exports[`should set custom Node.js version 1`] = ` +"{ + \\"name\\": \\"\\", + \\"version\\": \\"1.0.0\\", + \\"description\\": \\"\\", + \\"author\\": { + \\"name\\": \\"Gendalf\\", + \\"url\\": \\"http://middleearth.com\\" + }, + \\"homepage\\": \\"https://github.com/gendalf/\\", + \\"repository\\": \\"gendalf/\\", + \\"license\\": \\"MIT\\", + \\"engines\\": { + \\"node\\": \\">=9.1\\" + }, + \\"main\\": \\"index.js\\", + \\"files\\": [ + \\"index.js\\" + ], + \\"scripts\\": {}, + \\"keywords\\": [], + \\"dependencies\\": {}, + \\"devDependencies\\": {} +}" +`; + +exports[`should set custom license 1`] = ` +"{ + \\"name\\": \\"\\", + \\"version\\": \\"1.0.0\\", + \\"description\\": \\"\\", + \\"author\\": { + \\"name\\": \\"Gendalf\\", + \\"url\\": \\"http://middleearth.com\\" + }, + \\"homepage\\": \\"https://github.com/gendalf/\\", + \\"repository\\": \\"gendalf/\\", + \\"license\\": \\"BSD\\", + \\"engines\\": { + \\"node\\": \\">=6.9\\" + }, + \\"main\\": \\"index.js\\", + \\"files\\": [ + \\"index.js\\" + ], + \\"scripts\\": {}, + \\"keywords\\": [], + \\"dependencies\\": {}, + \\"devDependencies\\": {} +}" +`; diff --git a/packages/mrm-task-package/index.js b/packages/mrm-task-package/index.js new file mode 100644 index 00000000..74d37414 --- /dev/null +++ b/packages/mrm-task-package/index.js @@ -0,0 +1,52 @@ +const path = require('path'); +const meta = require('user-meta'); +const gitUsername = require('git-username'); +const { json } = require('mrm-core'); + +function task(config) { + const { name, url, github, minNode, license } = config + .defaults({ github: gitUsername(), minNode: 6.9, license: 'MIT' }) + .defaults(meta) + .require('name', 'url', 'github') + .values(); + + const packageName = path.basename(process.cwd()); + const repository = `${github}/${packageName}`; + + // Create package.json + const pkg = json('package.json', { + name: packageName, + version: '1.0.0', + description: '', + author: { + name, + url, + }, + homepage: `https://github.com/${repository}`, + repository, + license, + engines: { + node: `>=${minNode}`, + }, + main: 'index.js', + files: ['index.js'], + scripts: {}, + keywords: [], + dependencies: {}, + devDependencies: {}, + }); + + // Update + if (pkg.exists()) { + pkg.merge({ + engines: { + node: `>=${minNode}`, + }, + }); + } + + pkg.save(); +} + +task.description = 'Adds package.json'; +module.exports = task; diff --git a/packages/mrm-task-package/index.spec.js b/packages/mrm-task-package/index.spec.js new file mode 100644 index 00000000..879bbc7a --- /dev/null +++ b/packages/mrm-task-package/index.spec.js @@ -0,0 +1,52 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); + +const path = require('path'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const options = { + name: 'Gendalf', + url: 'http://middleearth.com', + github: 'gendalf', +}; + +afterEach(() => { + vol.reset(); + process.chdir('/'); +}); + +it('should add package.json', () => { + // The task will use the folder name as a package name + vol.mkdirpSync(__dirname); + process.chdir(__dirname); + + task(getConfigGetter(options)); + + expect(vol.toJSON()[path.join(__dirname, 'package.json')]).toMatchSnapshot(); +}); + +it('should set custom Node.js version', () => { + task( + getConfigGetter( + Object.assign({}, options, { + minNode: '9.1', + }) + ) + ); + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); + +it('should set custom license', () => { + task( + getConfigGetter( + Object.assign({}, options, { + license: 'BSD', + }) + ) + ); + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-package/package-lock.json b/packages/mrm-task-package/package-lock.json new file mode 100644 index 00000000..e9a58f1d --- /dev/null +++ b/packages/mrm-task-package/package-lock.json @@ -0,0 +1,462 @@ +{ + "name": "mrm-task-package", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "git-config-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-1.0.1.tgz", + "integrity": "sha1-bTP37WPbDQ4RgTFQO6s6ykfVRmQ=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "homedir-polyfill": "^1.0.0" + } + }, + "git-username": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-username/-/git-username-1.0.0.tgz", + "integrity": "sha512-xm45KwBR6Eu1jO4umx/o2M84v9TC7tdOBuzLx8ayhdR9H1FBiiG9azz31uC0esDvaWVBTDINpJ5USomk+ja8OQ==", + "requires": { + "parse-github-url": "^1.0.2", + "remote-origin-url": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-git-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-1.1.1.tgz", + "integrity": "sha1-06mYQxcTL1c5hxK7pDjhKVkN34w=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "git-config-path": "^1.0.1", + "ini": "^1.3.4" + } + }, + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==" + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "remote-origin-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remote-origin-url/-/remote-origin-url-1.0.0.tgz", + "integrity": "sha512-xHDM6IBqivpiQ1e4WOuFpM/T6rbzA/WBsu+3WLtgPOhHyjA0nYlijV3NprlTb4FcXlQ5+Q+z174sQ1NnUF5FwA==", + "requires": { + "parse-git-config": "^1.1.1" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "user-meta": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/user-meta/-/user-meta-1.0.0.tgz", + "integrity": "sha512-Q/opMgFhVbBkdlTs44UKzV7L5Uj2zrJ4MVPXTTzJmrU1bHb2cX6wJzBIqEf1gROTzZIH8u39WmHsa5EvfnMPrw==", + "requires": { + "rc": "^1.2.1" + } + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-package/package.json b/packages/mrm-task-package/package.json new file mode 100644 index 00000000..a4f0f72c --- /dev/null +++ b/packages/mrm-task-package/package.json @@ -0,0 +1,32 @@ +{ + "name": "mrm-task-package", + "version": "2.0.1", + "description": "Mrm task that adds package.json file", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-package", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "package", + "package.json", + "npm" + ], + "dependencies": { + "git-username": "^1.0.0", + "mrm-core": "^4.0.0", + "user-meta": "^1.0.0" + } +} diff --git a/packages/mrm-task-prettier/License.md b/packages/mrm-task-prettier/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-prettier/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-prettier/Readme.md b/packages/mrm-task-prettier/Readme.md new file mode 100644 index 00000000..7c6fdfb3 --- /dev/null +++ b/packages/mrm-task-prettier/Readme.md @@ -0,0 +1,56 @@ +# mrm-task-prettier + +[Mrm](https://github.com/sapegin/mrm) task that adds [Prettier](https://prettier.io/). + +## What it does + +- Creates `.prettierrc` +- Adds an npm script to run Prettier after tests +- Installs dependencies + +## Usage + +``` +npm install -g mrm mrm-task-prettier +mrm prettier +``` + +Now run: + +``` +npm run format +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `indent` (default: `tab`) + +Indentation, `tab` or number of spaces. Will be overwritten by options from EditorConfig. + +### `prettierOptions` + +Prettier options, by default will try to infer options from EditorConfig. + +### `prettierOverrides` + +[Prettier overrides](https://prettier.io/docs/en/configuration.html#configuration-overrides), by default will use overrides for Markdown to improve documentation readability. + +### `prettierPattern` (default: `**/*.{js,css,md}`) + +Glob pattern to match file that should be formatted. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-prettier/__snapshots__/index.spec.js.snap b/packages/mrm-task-prettier/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..bb14aa46 --- /dev/null +++ b/packages/mrm-task-prettier/__snapshots__/index.spec.js.snap @@ -0,0 +1,103 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add Prettier 1`] = ` +Object { + "/.prettierrc": "{ + \\"useTabs\\": true, + \\"overrides\\": [ + { + \\"files\\": \\"*.md\\", + \\"options\\": { + \\"printWidth\\": 70, + \\"useTabs\\": false, + \\"trailingComma\\": \\"none\\", + \\"proseWrap\\": \\"never\\" + } + } + ] +}", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"test\\": \\"jest\\", + \\"posttest\\": \\"npm run format\\", + \\"format\\": \\"prettier --loglevel warn --write \\\\\\"**/*.{js,css,md}\\\\\\"\\" + } +}", +} +`; + +exports[`should infer options from EditorConfig 1`] = ` +"{ + \\"overrides\\": [ + { + \\"files\\": \\"*.md\\", + \\"options\\": { + \\"printWidth\\": 70, + \\"useTabs\\": false, + \\"trailingComma\\": \\"none\\", + \\"proseWrap\\": \\"never\\" + } + } + ] +}" +`; + +exports[`should keep a custom pattern defined in a package.json script 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"format\\": \\"prettier --loglevel warn --write \\\\\\"**/*.{xxx,yyy}\\\\\\"\\", + \\"test\\": \\"jest\\", + \\"posttest\\": \\"npm run format\\" + } +}" +`; + +exports[`should use a custom indent 1`] = ` +"{ + \\"useTabs\\": true, + \\"overrides\\": [ + { + \\"files\\": \\"*.md\\", + \\"options\\": { + \\"printWidth\\": 70, + \\"useTabs\\": false, + \\"trailingComma\\": \\"none\\", + \\"proseWrap\\": \\"never\\" + } + } + ] +}" +`; + +exports[`should use a custom options 1`] = ` +"{ + \\"printWidth\\": 333, + \\"overrides\\": [ + { + \\"files\\": \\"*.md\\", + \\"options\\": { + \\"printWidth\\": 70, + \\"useTabs\\": false, + \\"trailingComma\\": \\"none\\", + \\"proseWrap\\": \\"never\\" + } + } + ] +}" +`; + +exports[`should use custom overrides 1`] = ` +"{ + \\"useTabs\\": true, + \\"overrides\\": [ + { + \\"files\\": \\"*.css\\", + \\"options\\": { + \\"printWidth\\": 42 + } + } + ] +}" +`; diff --git a/packages/mrm-task-prettier/index.js b/packages/mrm-task-prettier/index.js new file mode 100644 index 00000000..a3773e8f --- /dev/null +++ b/packages/mrm-task-prettier/index.js @@ -0,0 +1,96 @@ +const path = require('path'); +const editorConfigToPrettier = require('editorconfig-to-prettier'); +const { json, packageJson, install } = require('mrm-core'); +const { getStyleForFile, getExtsFromCommand } = require('mrm-core'); + +const defaultPattern = '**/*.{js,css,md}'; +const defaultOverrides = [ + { + files: '*.md', + options: { + printWidth: 70, + useTabs: false, + trailingComma: 'none', + proseWrap: 'never', + }, + }, +]; +const defaultPrettierOptions = { + printWidth: 80, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: false, + trailingComma: 'none', + bracketSpacing: true, + jsxBracketSameLine: false, +}; + +function task(config) { + const packages = ['prettier']; + + const { indent, prettierPattern, prettierOptions, prettierOverrides } = config + .defaults({ + indent: 'tab', + prettierPattern: defaultPattern, + }) + .values(); + + // Try to read options from EditorConfig + const testJsFile = path.join(process.cwd(), 'test.js'); + const editorconfigOptions = editorConfigToPrettier( + getStyleForFile(testJsFile) + ); + + const pkg = packageJson(); + + const overrides = prettierOverrides || defaultOverrides; + const options = Object.assign( + {}, + prettierOptions + ? {} + : { + useTabs: indent === 'tab', + }, + editorconfigOptions, + prettierOptions, + overrides && { overrides } + ); + + // Remove options that have the same values as Prettier defaults + for (const option in options) { + if (options[option] === defaultPrettierOptions[option]) { + delete options[option]; + } + } + + // .prettierrc + json('.prettierrc') + .merge(options) + .save(); + + // Keep custom pattern + let pattern = prettierPattern; + const formatScript = pkg.getScript('format'); + if (formatScript) { + const exts = getExtsFromCommand(formatScript); + if (exts) { + pattern = `**/*.{${exts}}`; + } + } + + pkg + // Add format script + // Double quotes are essential to support Windows: + // https://github.com/prettier/prettier/issues/4086#issuecomment-370228517 + .setScript('format', `prettier --loglevel warn --write "${pattern}"`) + // Add pretest script + .appendScript('posttest', 'npm run format') + .save(); + + // Dependencies + install(packages); +} + +task.description = 'Adds Prettier'; +module.exports = task; diff --git a/packages/mrm-task-prettier/index.spec.js b/packages/mrm-task-prettier/index.spec.js new file mode 100644 index 00000000..cc1df97a --- /dev/null +++ b/packages/mrm-task-prettier/index.spec.js @@ -0,0 +1,105 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); +jest.mock('mrm-core/src/npm', () => ({ + install: jest.fn(), +})); + +const { install } = require('mrm-core'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const stringify = o => JSON.stringify(o, null, ' '); + +const packageJson = stringify({ + name: 'unicorn', + scripts: { + test: 'jest', + }, +}); + +afterEach(() => { + vol.reset(); + install.mockClear(); +}); + +it('should add Prettier', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith(['prettier']); +}); + +it('should use a custom indent', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({ indent: 'tab' })); + + expect(vol.toJSON()['/.prettierrc']).toMatchSnapshot(); +}); + +it('should use a custom options', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({ prettierOptions: { printWidth: 333 } })); + + expect(vol.toJSON()['/.prettierrc']).toMatchSnapshot(); +}); + +it('should use custom overrides', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task( + getConfigGetter({ + prettierOverrides: [ + { + files: '*.css', + options: { + printWidth: 42, + }, + }, + ], + }) + ); + + expect(vol.toJSON()['/.prettierrc']).toMatchSnapshot(); +}); + +it('should infer options from EditorConfig', () => { + vol.fromJSON({ + '/.editorconfig': '[*]\nindent_style = space\nindent_size = 2', + '/package.json': packageJson, + }); + + task(getConfigGetter()); + + expect(vol.toJSON()['/.prettierrc']).toMatchSnapshot(); +}); + +it('should keep a custom pattern defined in a package.json script', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: { + format: "prettier --write '**/*.{xxx,yyy}'", + test: 'jest', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-prettier/package-lock.json b/packages/mrm-task-prettier/package-lock.json new file mode 100644 index 00000000..d681bbc6 --- /dev/null +++ b/packages/mrm-task-prettier/package-lock.json @@ -0,0 +1,359 @@ +{ + "name": "mrm-task-prettier", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "editorconfig-to-prettier": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/editorconfig-to-prettier/-/editorconfig-to-prettier-0.1.1.tgz", + "integrity": "sha512-MMadSSVRDb4uKdxV6bCXXN4cTsxIsXYtV4XdPu6FOCSAw6zsCIDA+QEktEU+u6h+c/mTrul5NR+pwFpPxwetiQ==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-prettier/package.json b/packages/mrm-task-prettier/package.json new file mode 100644 index 00000000..56055ec4 --- /dev/null +++ b/packages/mrm-task-prettier/package.json @@ -0,0 +1,34 @@ +{ + "name": "mrm-task-prettier", + "version": "2.0.1", + "description": "Mrm task that adds Prettier", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-prettier", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "prettier", + "format", + "formatting", + "javascript", + "css", + "markdown" + ], + "dependencies": { + "editorconfig-to-prettier": "0.1.1", + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-readme/License.md b/packages/mrm-task-readme/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-readme/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-readme/Readme.md b/packages/mrm-task-readme/Readme.md new file mode 100644 index 00000000..21083a37 --- /dev/null +++ b/packages/mrm-task-readme/Readme.md @@ -0,0 +1,56 @@ +# mrm-task-readme + +[Mrm](https://github.com/sapegin/mrm) task that adds a Readme file. + +## What it does + +- Creates a Readme file + +## Usage + +``` +npm install -g mrm mrm-task-readme +mrm readme +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `github` (default: extracted from `.git/config` file) + +Your GitHub user name. + +### `name` (default: will try to read from your npm or Git config) + +Your name. + +### `url` (default: will try to read from your npm or Git config) + +Your site URL. + +### `readmeFile` (default: `Readme.md`) + +Name of the Readme file. + +### `licenseFile` (default: `License.md`) + +Name of the license file. + +### `packageName` (default: `name` field in `package.json`) + +Package name. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-readme/__snapshots__/index.spec.js.snap b/packages/mrm-task-readme/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..caabc428 --- /dev/null +++ b/packages/mrm-task-readme/__snapshots__/index.spec.js.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add a readme 1`] = ` +Object { + "/Readme.md": "# unicorn + +... + +## Change log + +The change log can be found on the [Releases page](https://github.com/gendalf/unicorn/releases). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](Contributing.md). + +## Authors and license + +[Gendalf](http://middleearth.com) and [contributors](https://github.com/gendalf/unicorn/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. +", + "/package.json": "{ + \\"name\\": \\"unicorn\\" +}", +} +`; diff --git a/packages/mrm-task-readme/index.js b/packages/mrm-task-readme/index.js new file mode 100644 index 00000000..ff4761cd --- /dev/null +++ b/packages/mrm-task-readme/index.js @@ -0,0 +1,37 @@ +const path = require('path'); +const meta = require('user-meta'); +const gitUsername = require('git-username'); +const { template, packageJson } = require('mrm-core'); + +function task(config) { + const { name, url, github, readmeFile, licenseFile, packageName } = config + .defaults({ + github: gitUsername(), + readmeFile: 'Readme.md', + licenseFile: 'License.md', + packageName: packageJson().get('name'), + }) + .defaults(meta) + .require('name', 'url', 'github', 'packageName') + .values(); + + // Create Readme.md (no update) + const readme = template( + readmeFile, + path.join(__dirname, 'templates/Readme.md') + ); + if (!readme.exists()) { + readme + .apply({ + name, + url, + github, + license: licenseFile, + package: packageName, + }) + .save(); + } +} + +task.description = 'Adds readme file'; +module.exports = task; diff --git a/packages/mrm-task-readme/index.spec.js b/packages/mrm-task-readme/index.spec.js new file mode 100644 index 00000000..661c79a2 --- /dev/null +++ b/packages/mrm-task-readme/index.spec.js @@ -0,0 +1,38 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); + +const fs = require.requireActual('fs'); +const path = require('path'); +const { omitBy } = require('lodash'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const stringify = o => JSON.stringify(o, null, ' '); + +afterEach(() => vol.reset()); + +it('should add a readme', () => { + vol.fromJSON({ + [`${__dirname}/templates/Readme.md`]: fs + .readFileSync(path.join(__dirname, 'templates/Readme.md')) + .toString(), + '/package.json': stringify({ + name: 'unicorn', + }), + }); + + task( + getConfigGetter({ + name: 'Gendalf', + url: 'http://middleearth.com', + github: 'gendalf', + }) + ); + + expect( + omitBy(vol.toJSON(), (v, k) => k.startsWith(__dirname)) + ).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-readme/package-lock.json b/packages/mrm-task-readme/package-lock.json new file mode 100644 index 00000000..9f2f0899 --- /dev/null +++ b/packages/mrm-task-readme/package-lock.json @@ -0,0 +1,462 @@ +{ + "name": "mrm-task-readme", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "git-config-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-1.0.1.tgz", + "integrity": "sha1-bTP37WPbDQ4RgTFQO6s6ykfVRmQ=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "homedir-polyfill": "^1.0.0" + } + }, + "git-username": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-username/-/git-username-1.0.0.tgz", + "integrity": "sha512-xm45KwBR6Eu1jO4umx/o2M84v9TC7tdOBuzLx8ayhdR9H1FBiiG9azz31uC0esDvaWVBTDINpJ5USomk+ja8OQ==", + "requires": { + "parse-github-url": "^1.0.2", + "remote-origin-url": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-git-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-1.1.1.tgz", + "integrity": "sha1-06mYQxcTL1c5hxK7pDjhKVkN34w=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "git-config-path": "^1.0.1", + "ini": "^1.3.4" + } + }, + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==" + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "remote-origin-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remote-origin-url/-/remote-origin-url-1.0.0.tgz", + "integrity": "sha512-xHDM6IBqivpiQ1e4WOuFpM/T6rbzA/WBsu+3WLtgPOhHyjA0nYlijV3NprlTb4FcXlQ5+Q+z174sQ1NnUF5FwA==", + "requires": { + "parse-git-config": "^1.1.1" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "user-meta": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/user-meta/-/user-meta-1.0.0.tgz", + "integrity": "sha512-Q/opMgFhVbBkdlTs44UKzV7L5Uj2zrJ4MVPXTTzJmrU1bHb2cX6wJzBIqEf1gROTzZIH8u39WmHsa5EvfnMPrw==", + "requires": { + "rc": "^1.2.1" + } + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-readme/package.json b/packages/mrm-task-readme/package.json new file mode 100644 index 00000000..e5bd4ae7 --- /dev/null +++ b/packages/mrm-task-readme/package.json @@ -0,0 +1,31 @@ +{ + "name": "mrm-task-readme", + "version": "2.0.1", + "description": "Mrm task that adds a readme file", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-readme", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js", + "templates" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "readme" + ], + "dependencies": { + "git-username": "^1.0.0", + "mrm-core": "^4.0.0", + "user-meta": "^1.0.0" + } +} diff --git a/packages/mrm-task-readme/templates/Readme.md b/packages/mrm-task-readme/templates/Readme.md new file mode 100644 index 00000000..30cb27b8 --- /dev/null +++ b/packages/mrm-task-readme/templates/Readme.md @@ -0,0 +1,17 @@ +# ${package} + +... + +## Change log + +The change log can be found on the [Releases page](https://github.com/${github}/${package}/releases). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](Contributing.md). + +## Authors and license + +[${name}](${url}) and [contributors](https://github.com/${github}/${package}/graphs/contributors). + +MIT License, see the included [${license}](${license}) file. diff --git a/packages/mrm-task-semantic-release/License.md b/packages/mrm-task-semantic-release/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-semantic-release/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-semantic-release/Readme.md b/packages/mrm-task-semantic-release/Readme.md new file mode 100644 index 00000000..41691188 --- /dev/null +++ b/packages/mrm-task-semantic-release/Readme.md @@ -0,0 +1,54 @@ +# mrm-task-semantic-release + +[Mrm](https://github.com/sapegin/mrm) task that adds [semantic-release](https://github.com/semantic-release/semantic-release). + +## What it does + +- Runs semantic-release on Travis CI +- Adds an npm version badge to the Readme +- Adds `.releaserc.json` file with a custom preset if needed + +## Usage + +``` +npm install -g mrm mrm-task-semantic-release +mrm semantic-release +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `semanticConfig` (object, optional) + +A semantic-release [config object](https://semantic-release.gitbooks.io/semantic-release/content/docs/usage/plugins.html#configuration), will be added to `package.json` as a `release` key. + +### `semanticArgs` (string, optional) + +Extra arguments for `semantic-release` command. For example `--analyze-commits semantic-release-tamia/analyzeCommits`. + +### `semanticPeerDependencies` (array, optional) + +Additional dependencies to install. + +## `semanticPreset` (default: `null`) + +Name of the semantic-release preset, like `eslint`. + +### `readmeFile` (default: `Readme.md`) + +Name of the Readme file. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-semantic-release/__snapshots__/index.spec.js.snap b/packages/mrm-task-semantic-release/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..d03dec36 --- /dev/null +++ b/packages/mrm-task-semantic-release/__snapshots__/index.spec.js.snap @@ -0,0 +1,111 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add custom arguments to semantic-release command 1`] = ` +"language: node_js +node_js: + - 8 +after_success: + - npx semantic-release --arg val +branches: + except: + - /^v\\\\d+\\\\.\\\\d+\\\\.\\\\d+$/ +" +`; + +exports[`should add custom config to package.json 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": {}, + \\"release\\": { + \\"pizza\\": 42 + } +}" +`; + +exports[`should add semantic-release 1`] = ` +Object { + "/.travis.yml": "language: node_js +node_js: + - 8 +after_success: + - npx semantic-release +branches: + except: + - /^v\\\\d+\\\\.\\\\d+\\\\.\\\\d+$/ +", + "/Readme.md": "# Unicorn + +[![npm](https://img.shields.io/npm/v/unicorn.svg)](https://www.npmjs.com/package/unicorn)", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": {} +}", +} +`; + +exports[`should crate semantic-release config and install extra dependencies when a preset is defined 1`] = ` +"language: node_js +node_js: + - 8 +after_success: + - npm install --no-save conventional-changelog-pizza + - npx semantic-release +branches: + except: + - /^v\\\\d+\\\\.\\\\d+\\\\.\\\\d+$/ +" +`; + +exports[`should crate semantic-release config and install extra dependencies when a preset is defined 2`] = ` +"{ + \\"plugins\\": [ + [ + \\"@semantic-release/commit-analyzer\\", + { + \\"preset\\": \\"pizza\\" + } + ], + [ + \\"@semantic-release/release-notes-generator\\", + { + \\"preset\\": \\"pizza\\" + } + ], + \\"@semantic-release/npm\\", + \\"@semantic-release/github\\" + ] +}" +`; + +exports[`should install extra dependencies on CI 1`] = ` +"language: node_js +node_js: + - 8 +after_success: + - npm install --no-save pizza + - npx semantic-release +branches: + except: + - /^v\\\\d+\\\\.\\\\d+\\\\.\\\\d+$/ +" +`; + +exports[`should remove custom config from package.json 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": {} +}" +`; + +exports[`should remove the official semantic-release runner 1`] = ` +"language: node_js +node_js: + - 8 +after_success: + - 'bash <(curl -s https://codecov.io/bash)' + - npx semantic-release +branches: + except: + - /^v\\\\d+\\\\.\\\\d+\\\\.\\\\d+$/ +" +`; diff --git a/packages/mrm-task-semantic-release/index.js b/packages/mrm-task-semantic-release/index.js new file mode 100644 index 00000000..0ca324a4 --- /dev/null +++ b/packages/mrm-task-semantic-release/index.js @@ -0,0 +1,162 @@ +const fs = require('fs'); +const gitUsername = require('git-username'); +const { + MrmError, + packageJson, + json, + yaml, + markdown, + uninstall, +} = require('mrm-core'); + +function task(config) { + const { + github, + readmeFile, + semanticConfig, + semanticArgs, + semanticPeerDependencies, + semanticPreset, + } = config + .defaults({ + github: gitUsername(), + readmeFile: 'Readme.md', + semanticArgs: '', + semanticPeerDependencies: [], + semanticPreset: null, + }) + .values(); + + // Require .travis.yml + if (!fs.existsSync('.travis.yml')) { + throw new MrmError( + `Run travis task first: + mrm travis` + ); + } + + // package.json + const pkg = packageJson(); + + // Remove semantic-release script + pkg.removeScript('semantic-release'); + pkg.removeScript('travis-deploy-once'); + + // Add or remove custom semantic-release config + if (semanticConfig) { + pkg.merge({ + release: semanticConfig, + }); + } else { + pkg.unset('release'); + } + + // Save package.json + pkg.save(); + + const travisYml = yaml('.travis.yml'); + const afterSuccess = travisYml.get('after_success'); + + // Remove the official semantic-release runner from commands list on .travis.yml + if (Array.isArray(afterSuccess)) { + travisYml.set( + 'after_success', + afterSuccess.filter(cmd => cmd !== 'npm run semantic-release') + ); + } + + // Add semantic-release runner to .travis.yml + const dependencies = [ + ...semanticPeerDependencies, + semanticPreset ? `conventional-changelog-${semanticPreset}` : null, + ].filter(Boolean); + const commands = [ + dependencies.length > 0 + ? `npm install --no-save ${dependencies.join(' ')}` + : null, + `npx semantic-release ${semanticArgs}`.trim(), + ].filter(Boolean); + travisYml + .merge({ + after_success: commands, + branches: { + except: ['/^v\\d+\\.\\d+\\.\\d+$/'], + }, + }) + .save(); + + // Add semantic-release config if we’re using a preset + if (semanticPreset) { + json('.releaserc.json') + .set({ + plugins: [ + [ + '@semantic-release/commit-analyzer', + { + preset: semanticPreset, + }, + ], + [ + '@semantic-release/release-notes-generator', + { + preset: semanticPreset, + }, + ], + '@semantic-release/npm', + '@semantic-release/github', + ], + }) + .save(); + } + + // Add npm package version badge to Readme.md + const packageName = pkg.get('name'); + const readme = markdown(readmeFile); + if (readme.exists()) { + readme + .addBadge( + `https://img.shields.io/npm/v/${packageName}.svg`, + `https://www.npmjs.com/package/${packageName}`, + 'npm' + ) + .save(); + } + + // Remove semantic-release from project dependencies + uninstall(['semantic-release', 'travis-deploy-once']); + + console.log( + `Please setup semantic-release authentication on Travis CI: + +1. Generate npm token: + + npm token create + + Note: Only the auth-only level of npm two-factor authentication is supported. + + More info: https://docs.npmjs.com/getting-started/working_with_tokens#how-to-create-new-tokens + +2. Generate GitHub token: + + https://github.com/settings/tokens/new + + Select the “repo” scope. + + More info: https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line + +3. Add environment variables to Travis CI: + + https://travis-ci.org/${github}/${packageName}/settings + + NPM_TOKEN = + GH_TOKEN = + + DO NOT enable “Display value in build log”. + + More info: https://semantic-release.gitbook.io/semantic-release/usage/ci-configuration +` + ); +} + +task.description = 'Adds semantic-release'; +module.exports = task; diff --git a/packages/mrm-task-semantic-release/index.spec.js b/packages/mrm-task-semantic-release/index.spec.js new file mode 100644 index 00000000..09c77967 --- /dev/null +++ b/packages/mrm-task-semantic-release/index.spec.js @@ -0,0 +1,158 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); +jest.mock('mrm-core/src/npm', () => ({ + uninstall: jest.fn(), +})); + +const { uninstall } = require('mrm-core'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const console$log = console.log; + +const stringify = o => JSON.stringify(o, null, ' '); + +const travisYml = `language: node_js +node_js: + - 8 +`; +const packageJson = stringify({ + name: 'unicorn', + scripts: { + 'semantic-release': 'semantic-release', + }, +}); +const readmeMd = '# Unicorn'; + +beforeEach(() => { + console.log = jest.fn(); +}); + +afterEach(() => { + vol.reset(); + uninstall.mockClear(); + console.log = console$log; +}); + +it('should add semantic-release', () => { + vol.fromJSON({ + '/.travis.yml': travisYml, + '/package.json': packageJson, + '/Readme.md': readmeMd, + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should add custom config to package.json', () => { + vol.fromJSON({ + '/.travis.yml': travisYml, + '/package.json': packageJson, + }); + + task( + getConfigGetter({ + semanticConfig: { pizza: 42 }, + }) + ); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); + +it('should remove custom config from package.json', () => { + vol.fromJSON({ + '/.travis.yml': travisYml, + '/package.json': stringify({ + name: 'unicorn', + scripts: { + 'semantic-release': 'semantic-release', + }, + release: { + analyzeCommits: 'semantic-release-tamia/analyzeCommits', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); + +it('should add custom arguments to semantic-release command', () => { + vol.fromJSON({ + '/.travis.yml': travisYml, + '/package.json': packageJson, + }); + + task( + getConfigGetter({ + semanticArgs: '--arg val', + }) + ); + + expect(vol.toJSON()['/.travis.yml']).toMatchSnapshot(); +}); + +it('should install extra dependencies on CI', () => { + vol.fromJSON({ + '/.travis.yml': travisYml, + '/package.json': packageJson, + }); + + task( + getConfigGetter({ + semanticPeerDependencies: ['pizza'], + }) + ); + + expect(vol.toJSON()['/.travis.yml']).toMatchSnapshot(); +}); + +it('should crate semantic-release config and install extra dependencies when a preset is defined', () => { + vol.fromJSON({ + '/.travis.yml': travisYml, + '/package.json': packageJson, + }); + + task( + getConfigGetter({ + semanticPreset: 'pizza', + }) + ); + + expect(vol.toJSON()['/.travis.yml']).toMatchSnapshot(); + expect(vol.toJSON()['/.releaserc.json']).toMatchSnapshot(); +}); + +it('should remove the official semantic-release runner', () => { + vol.fromJSON({ + '/.travis.yml': `language: node_js +node_js: + - 8 +after_success: + - bash <(curl -s https://codecov.io/bash) + - npm run semantic-release +`, + '/package.json': packageJson, + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/.travis.yml']).toMatchSnapshot(); + expect(uninstall).toBeCalledWith(['semantic-release', 'travis-deploy-once']); +}); + +it('should throw when .travis.yml not found', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + const fn = () => task(getConfigGetter({})); + + expect(fn).toThrowError('Run travis task'); +}); diff --git a/packages/mrm-task-semantic-release/package-lock.json b/packages/mrm-task-semantic-release/package-lock.json new file mode 100644 index 00000000..c9e03767 --- /dev/null +++ b/packages/mrm-task-semantic-release/package-lock.json @@ -0,0 +1,433 @@ +{ + "name": "mrm-task-semantic-release", + "version": "3.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "git-config-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-1.0.1.tgz", + "integrity": "sha1-bTP37WPbDQ4RgTFQO6s6ykfVRmQ=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "homedir-polyfill": "^1.0.0" + } + }, + "git-username": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-username/-/git-username-1.0.0.tgz", + "integrity": "sha512-xm45KwBR6Eu1jO4umx/o2M84v9TC7tdOBuzLx8ayhdR9H1FBiiG9azz31uC0esDvaWVBTDINpJ5USomk+ja8OQ==", + "requires": { + "parse-github-url": "^1.0.2", + "remote-origin-url": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-git-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-1.1.1.tgz", + "integrity": "sha1-06mYQxcTL1c5hxK7pDjhKVkN34w=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "git-config-path": "^1.0.1", + "ini": "^1.3.4" + } + }, + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==" + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "remote-origin-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remote-origin-url/-/remote-origin-url-1.0.0.tgz", + "integrity": "sha512-xHDM6IBqivpiQ1e4WOuFpM/T6rbzA/WBsu+3WLtgPOhHyjA0nYlijV3NprlTb4FcXlQ5+Q+z174sQ1NnUF5FwA==", + "requires": { + "parse-git-config": "^1.1.1" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-semantic-release/package.json b/packages/mrm-task-semantic-release/package.json new file mode 100644 index 00000000..37e5d26e --- /dev/null +++ b/packages/mrm-task-semantic-release/package.json @@ -0,0 +1,29 @@ +{ + "name": "mrm-task-semantic-release", + "version": "3.0.1", + "description": "Mrm task that adds semantic-release", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-semantic-release", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "semantic-release" + ], + "dependencies": { + "git-username": "^1.0.0", + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-styleguidist/License.md b/packages/mrm-task-styleguidist/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-styleguidist/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-styleguidist/Readme.md b/packages/mrm-task-styleguidist/Readme.md new file mode 100644 index 00000000..cd14035a --- /dev/null +++ b/packages/mrm-task-styleguidist/Readme.md @@ -0,0 +1,29 @@ +# mrm-task-styleguidist + +[Mrm](https://github.com/sapegin/mrm) task that adds [React Styleguidist](https://react-styleguidist.js.org/). + +## What it does + +- Creates a style guide config +- Installs dependencies + +## Usage + +``` +npm install -g mrm mrm-task-styleguidist +mrm styleguidist +``` + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-styleguidist/__snapshots__/index.spec.js.snap b/packages/mrm-task-styleguidist/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..587ab0eb --- /dev/null +++ b/packages/mrm-task-styleguidist/__snapshots__/index.spec.js.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add React Styleguidist 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"styleguide\\": \\"styleguidist server\\", + \\"styleguide:build\\": \\"styleguidist build\\", + \\"start\\": \\"styleguidist server\\" + } +}", + "/styleguide.config.js": "module.exports = { + components: 'src/components/**/[A-Z]*.js', +}; +", +} +`; + +exports[`should use a TypeScript template for a TypeScript project 1`] = ` +"module.exports = { + components: 'src/components/**/[A-Z]*.tsx', + propsParser: require('react-docgen-typescript').parse, +}; +" +`; diff --git a/packages/mrm-task-styleguidist/index.js b/packages/mrm-task-styleguidist/index.js new file mode 100644 index 00000000..8838c36b --- /dev/null +++ b/packages/mrm-task-styleguidist/index.js @@ -0,0 +1,49 @@ +const path = require('path'); +const { packageJson, template, install } = require('mrm-core'); + +const configFile = 'styleguide.config.js'; + +function task() { + const prodPackages = ['react', 'react-dom']; + const packages = ['react-styleguidist']; + let templateFile = configFile; + + const pkg = packageJson(); + const isCra = pkg.get('dependencies.react-scripts'); + + // Create React App has its own webpack + if (!isCra) { + packages.push('webpack'); + } + + // TypeScript + if (pkg.get('devDependencies.typescript')) { + packages.push('react-docgen-typescript'); + templateFile = 'styleguide.config.typescript.js'; + } + + // Style guide config + if (!isCra) { + template(configFile, path.join(__dirname, 'templates', templateFile)) + .apply() + .save(); + } + + // package.json + pkg + .appendScript('styleguide', 'styleguidist server') + .appendScript('styleguide:build', 'styleguidist build'); + + if (!pkg.getScript('start')) { + pkg.setScript('start', 'styleguidist server'); + } + + pkg.save(); + + // Dependencies + install(prodPackages, { dev: false }); + install(packages); +} + +task.description = 'Adds React Styleguidist'; +module.exports = task; diff --git a/packages/mrm-task-styleguidist/index.spec.js b/packages/mrm-task-styleguidist/index.spec.js new file mode 100644 index 00000000..14340bec --- /dev/null +++ b/packages/mrm-task-styleguidist/index.spec.js @@ -0,0 +1,84 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); +jest.mock('mrm-core/src/npm', () => ({ + install: jest.fn(), +})); + +const fs = require.requireActual('fs'); +const path = require('path'); +const { install } = require('mrm-core'); +const { omitBy } = require('lodash'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const stringify = o => JSON.stringify(o, null, ' '); + +afterEach(() => { + vol.reset(); + install.mockClear(); +}); + +it('should add React Styleguidist', () => { + vol.fromJSON({ + [`${__dirname}/templates/styleguide.config.js`]: fs + .readFileSync(path.join(__dirname, 'templates/styleguide.config.js')) + .toString(), + '/package.json': stringify({ + name: 'unicorn', + }), + }); + + task(getConfigGetter({})); + + expect( + omitBy(vol.toJSON(), (v, k) => k.startsWith(__dirname)) + ).toMatchSnapshot(); + expect(install.mock.calls).toEqual([ + [['react', 'react-dom'], { dev: false }], + [['react-styleguidist', 'webpack']], + ]); +}); + +it('should use a TypeScript template for a TypeScript project', () => { + vol.fromJSON({ + [`${__dirname}/templates/styleguide.config.typescript.js`]: fs + .readFileSync( + path.join(__dirname, 'templates/styleguide.config.typescript.js') + ) + .toString(), + '/package.json': stringify({ + name: 'unicorn', + devDependencies: { + typescript: '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()['/styleguide.config.js']).toMatchSnapshot(); +}); + +it('should not install webpack when used with CRA', () => { + vol.fromJSON({ + [`${__dirname}/templates/styleguide.config.js`]: fs + .readFileSync(path.join(__dirname, 'templates/styleguide.config.js')) + .toString(), + '/package.json': stringify({ + name: 'unicorn', + dependencies: { + 'react-scripts': '*', + }, + }), + }); + + task(getConfigGetter({})); + + expect(install.mock.calls).toEqual([ + [['react', 'react-dom'], { dev: false }], + [['react-styleguidist']], + ]); +}); diff --git a/packages/mrm-task-styleguidist/package-lock.json b/packages/mrm-task-styleguidist/package-lock.json new file mode 100644 index 00000000..2f005a64 --- /dev/null +++ b/packages/mrm-task-styleguidist/package-lock.json @@ -0,0 +1,354 @@ +{ + "name": "mrm-task-styleguidist", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-styleguidist/package.json b/packages/mrm-task-styleguidist/package.json new file mode 100644 index 00000000..bfbbb6bf --- /dev/null +++ b/packages/mrm-task-styleguidist/package.json @@ -0,0 +1,30 @@ +{ + "name": "mrm-task-styleguidist", + "version": "2.0.1", + "description": "Mrm task that adds React Styleguidist", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-styleguidist", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js", + "templates" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "styleguidist", + "react" + ], + "dependencies": { + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-styleguidist/templates/styleguide.config.js b/packages/mrm-task-styleguidist/templates/styleguide.config.js new file mode 100644 index 00000000..0670e5de --- /dev/null +++ b/packages/mrm-task-styleguidist/templates/styleguide.config.js @@ -0,0 +1,3 @@ +module.exports = { + components: 'src/components/**/[A-Z]*.js', +}; diff --git a/packages/mrm-task-styleguidist/templates/styleguide.config.typescript.js b/packages/mrm-task-styleguidist/templates/styleguide.config.typescript.js new file mode 100644 index 00000000..ce6f9f25 --- /dev/null +++ b/packages/mrm-task-styleguidist/templates/styleguide.config.typescript.js @@ -0,0 +1,4 @@ +module.exports = { + components: 'src/components/**/[A-Z]*.tsx', + propsParser: require('react-docgen-typescript').parse, +}; diff --git a/packages/mrm-task-stylelint/License.md b/packages/mrm-task-stylelint/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-stylelint/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-stylelint/Readme.md b/packages/mrm-task-stylelint/Readme.md new file mode 100644 index 00000000..94a7f80e --- /dev/null +++ b/packages/mrm-task-stylelint/Readme.md @@ -0,0 +1,46 @@ +# mrm-task-stylelint + +[Mrm](https://github.com/sapegin/mrm) task that adds [stylelint](https://stylelint.io/). + +## What it does + +- Creates `.stylelintrc` +- Adds npm script to run stylelint before tests +- Installs dependencies + +## Usage + +``` +npm install -g mrm mrm-task-stylelint +mrm stylelint +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) and [stylelint docs](https://stylelint.io/user-guide/configuration/) for more details. + +### `stylelintPreset` (default: `stylelint-config-standard`) + +Stylelint preset name. + +### `stylelintRules` + +Stylelint rules. + +### `stylelintExtensions` (default: `.css`) + +File extensions to lint. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-stylelint/__snapshots__/index.spec.js.snap b/packages/mrm-task-stylelint/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..5ae2a9f9 --- /dev/null +++ b/packages/mrm-task-stylelint/__snapshots__/index.spec.js.snap @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add custom rules 1`] = ` +"{ + \\"rules\\": { + \\"max-empty-lines\\": 2 + } +}" +`; + +exports[`should add stylelint 1`] = ` +Object { + "/.stylelintrc": "{ + \\"extends\\": \\"stylelint-config-standard\\" +}", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"pretest\\": \\"npm run lint:css\\", + \\"test\\": \\"jest\\", + \\"lint:css\\": \\"stylelint '**/*.css'\\" + } +}", +} +`; + +exports[`should install a custom preset 1`] = ` +"{ + \\"extends\\": \\"stylelint-config-pizza\\" +}" +`; + +exports[`should use custom extension 1`] = ` +"{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"pretest\\": \\"npm run lint:css\\", + \\"test\\": \\"jest\\", + \\"lint:css\\": \\"stylelint '**/*.sass'\\" + } +}" +`; diff --git a/packages/mrm-task-stylelint/index.js b/packages/mrm-task-stylelint/index.js new file mode 100644 index 00000000..e6ae4709 --- /dev/null +++ b/packages/mrm-task-stylelint/index.js @@ -0,0 +1,52 @@ +const { json, packageJson, install } = require('mrm-core'); + +function task(config) { + config.defaults({ + stylelintExtensions: '.css', + stylelintPreset: 'stylelint-config-standard', + }); + const { + stylelintRules, + stylelintPreset, + stylelintExtensions, + } = config.values(); + + const packages = ['stylelint']; + + if (stylelintPreset) { + packages.push(stylelintPreset); + } + + // .stylelintrc + const stylelintrc = json('.stylelintrc'); + + if (stylelintPreset) { + stylelintrc.merge({ + extends: stylelintPreset, + }); + } + + if (stylelintRules) { + stylelintrc.merge({ + rules: stylelintRules, + }); + } + + stylelintrc.save(); + + // package.json + const pkg = packageJson(); + + pkg + // Add lint script + .setScript('lint:css', `stylelint '**/*${stylelintExtensions}'`) + // Add pretest script + .prependScript('pretest', 'npm run lint:css') + .save(); + + // Dependencies + install(packages); +} + +task.description = 'Adds Stylelint'; +module.exports = task; diff --git a/packages/mrm-task-stylelint/index.spec.js b/packages/mrm-task-stylelint/index.spec.js new file mode 100644 index 00000000..fe7b0a9c --- /dev/null +++ b/packages/mrm-task-stylelint/index.spec.js @@ -0,0 +1,73 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); +jest.mock('mrm-core/src/npm', () => ({ + install: jest.fn(), +})); + +const { install } = require('mrm-core'); +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const stringify = o => JSON.stringify(o, null, ' '); + +const packageJson = stringify({ + name: 'unicorn', + scripts: { + test: 'jest', + }, +}); + +afterEach(() => { + vol.reset(); + install.mockClear(); +}); + +it('should add stylelint', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); + expect(install).toBeCalledWith(['stylelint', 'stylelint-config-standard']); +}); + +it('should install a custom preset', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({ stylelintPreset: 'stylelint-config-pizza' })); + + expect(vol.toJSON()['/.stylelintrc']).toMatchSnapshot(); + expect(install).toBeCalledWith(['stylelint', 'stylelint-config-pizza']); +}); + +it('should add custom rules', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task( + getConfigGetter({ + stylelintPreset: undefined, + stylelintRules: { 'max-empty-lines': 2 }, + }) + ); + + expect(vol.toJSON()['/.stylelintrc']).toMatchSnapshot(); +}); + +it('should use custom extension', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({ stylelintExtensions: '.sass' })); + + expect(vol.toJSON()['/package.json']).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-stylelint/package-lock.json b/packages/mrm-task-stylelint/package-lock.json new file mode 100644 index 00000000..c3911d8a --- /dev/null +++ b/packages/mrm-task-stylelint/package-lock.json @@ -0,0 +1,354 @@ +{ + "name": "mrm-task-stylelint", + "version": "3.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-stylelint/package.json b/packages/mrm-task-stylelint/package.json new file mode 100644 index 00000000..8577a011 --- /dev/null +++ b/packages/mrm-task-stylelint/package.json @@ -0,0 +1,30 @@ +{ + "name": "mrm-task-stylelint", + "version": "3.0.1", + "description": "Mrm task that adds stylelint", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-stylelint", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "stylelint", + "css", + "lint" + ], + "dependencies": { + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm-task-travis/License.md b/packages/mrm-task-travis/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-travis/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-travis/Readme.md b/packages/mrm-task-travis/Readme.md new file mode 100644 index 00000000..4133a8ec --- /dev/null +++ b/packages/mrm-task-travis/Readme.md @@ -0,0 +1,45 @@ +# mrm-task-travis + +[Mrm](https://github.com/sapegin/mrm) task that adds [Travis CI](https://travis-ci.org/). + +## What it does + +- Creates `.travis.yml` +- Adds Travis CI badge to the Readme + +## Usage + +``` +npm install -g mrm mrm-task-travis +mrm travis +``` + +## Options + +See [Mrm docs](https://github.com/sapegin/mrm#usage) for more details. + +### `github` (default: extracted from `.git/config` file) + +Your GitHub user name. + +### `readmeFile` (default: `Readme.md`) + +Name of the Readme file. + +### `maxNode` (default: 9) + +Maximum Node.js version to run tests. Minimum version will be taken from `engines.node` field of you `package.json`. + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-travis/__snapshots__/index.spec.js.snap b/packages/mrm-task-travis/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..8a399d88 --- /dev/null +++ b/packages/mrm-task-travis/__snapshots__/index.spec.js.snap @@ -0,0 +1,53 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add Travis CI 1`] = ` +Object { + "/.travis.yml": "language: node_js +cache: + directories: + - node_modules +node_js: + - 4 + - 6 + - 8 + - 9 +", + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"engines\\": { + \\"node\\": 4 + }, + \\"scripts\\": { + \\"test\\": \\"jest\\" + } +}", +} +`; + +exports[`should add a badge to the Readme 1`] = ` +"# Unicorn + +[![Build Status](https://travis-ci.org/gh/unicorn.svg)](https://travis-ci.org/gh/unicorn)" +`; + +exports[`should add latest Node version if engines field is not defined 1`] = ` +"language: node_js +cache: + directories: + - node_modules +node_js: + - 9 +" +`; + +exports[`should add latest Node version if engines field is not defined 2`] = ` +"language: node_js +cache: + directories: + - node_modules +node_js: + - 4 + - 6 + - 7 +" +`; diff --git a/packages/mrm-task-travis/index.js b/packages/mrm-task-travis/index.js new file mode 100644 index 00000000..776cd40c --- /dev/null +++ b/packages/mrm-task-travis/index.js @@ -0,0 +1,60 @@ +const fs = require('fs'); +const { range } = require('lodash'); +const semverUtils = require('semver-utils'); +const gitUsername = require('git-username'); +const { yaml, json, markdown } = require('mrm-core'); + +function task(config) { + const { github, readmeFile, maxNode } = config + .defaults({ github: gitUsername(), readmeFile: 'Readme.md', maxNode: 9 }) + .require('github') + .values(); + + const pkg = json('package.json'); + + // .travis.yml + const travisYml = yaml('.travis.yml'); + + travisYml.merge({ + language: 'node_js', + cache: { + directories: ['node_modules'], + }, + }); + + // Enable caching for Yarn + if (fs.existsSync('yarn.lock')) { + travisYml.set('cache.yarn', true); + } + + // Node versions range + const requireNodeVersion = pkg.get('engines.node'); + const minNodeVersion = requireNodeVersion + ? semverUtils.parseRange(requireNodeVersion)[0].major + : maxNode; + + // Only LTS or latest + const nodeVersions = range(minNodeVersion, maxNode + 1).filter( + ver => ver % 2 === 0 || ver === maxNode + ); + travisYml.set('node_js', nodeVersions); + + travisYml.save(); + + // Add Travis package badge to Readme + const url = `https://travis-ci.org/${github}/${pkg.get('name')}`; + const readme = markdown(readmeFile); + if (readme.exists()) { + readme.addBadge(`${url}.svg`, url, 'Build Status').save(); + } + + console.log(` +1. Activate your repository on Travis CI: +${url} + +2. Commit and push your changes +`); +} + +task.description = 'Adds Travis CI'; +module.exports = task; diff --git a/packages/mrm-task-travis/index.spec.js b/packages/mrm-task-travis/index.spec.js new file mode 100644 index 00000000..ba69f2ad --- /dev/null +++ b/packages/mrm-task-travis/index.spec.js @@ -0,0 +1,77 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); + +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const console$log = console.log; + +const stringify = o => JSON.stringify(o, null, ' '); + +const packageJson = stringify({ + name: 'unicorn', + engines: { + node: 4, + }, + scripts: { + test: 'jest', + }, +}); + +beforeEach(() => { + console.log = jest.fn(); +}); + +afterEach(() => { + vol.reset(); + console.log = console$log; +}); + +it('should add Travis CI', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({ github: 'gh' })); + + expect(vol.toJSON()).toMatchSnapshot(); +}); + +it('should add latest Node version if engines field is not defined', () => { + vol.fromJSON({ + '/package.json': stringify({ + name: 'unicorn', + scripts: { + test: 'jest', + }, + }), + }); + + task(getConfigGetter({ github: 'gh' })); + + expect(vol.toJSON()['/.travis.yml']).toMatchSnapshot(); +}); + +it('should add latest Node version if engines field is not defined', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({ github: 'gh', maxNode: 7 })); + + expect(vol.toJSON()['/.travis.yml']).toMatchSnapshot(); +}); + +it('should add a badge to the Readme', () => { + vol.fromJSON({ + '/package.json': packageJson, + '/Readme.md': '# Unicorn', + }); + + task(getConfigGetter({ github: 'gh' })); + + expect(vol.toJSON()['/Readme.md']).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-travis/package-lock.json b/packages/mrm-task-travis/package-lock.json new file mode 100644 index 00000000..cc1d4dba --- /dev/null +++ b/packages/mrm-task-travis/package-lock.json @@ -0,0 +1,438 @@ +{ + "name": "mrm-task-travis", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "git-config-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-1.0.1.tgz", + "integrity": "sha1-bTP37WPbDQ4RgTFQO6s6ykfVRmQ=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "homedir-polyfill": "^1.0.0" + } + }, + "git-username": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-username/-/git-username-1.0.0.tgz", + "integrity": "sha512-xm45KwBR6Eu1jO4umx/o2M84v9TC7tdOBuzLx8ayhdR9H1FBiiG9azz31uC0esDvaWVBTDINpJ5USomk+ja8OQ==", + "requires": { + "parse-github-url": "^1.0.2", + "remote-origin-url": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-git-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-1.1.1.tgz", + "integrity": "sha1-06mYQxcTL1c5hxK7pDjhKVkN34w=", + "requires": { + "extend-shallow": "^2.0.1", + "fs-exists-sync": "^0.1.0", + "git-config-path": "^1.0.1", + "ini": "^1.3.4" + } + }, + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==" + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "remote-origin-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remote-origin-url/-/remote-origin-url-1.0.0.tgz", + "integrity": "sha512-xHDM6IBqivpiQ1e4WOuFpM/T6rbzA/WBsu+3WLtgPOhHyjA0nYlijV3NprlTb4FcXlQ5+Q+z174sQ1NnUF5FwA==", + "requires": { + "parse-git-config": "^1.1.1" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "semver-utils": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/semver-utils/-/semver-utils-1.1.4.tgz", + "integrity": "sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-travis/package.json b/packages/mrm-task-travis/package.json new file mode 100644 index 00000000..570d3046 --- /dev/null +++ b/packages/mrm-task-travis/package.json @@ -0,0 +1,31 @@ +{ + "name": "mrm-task-travis", + "version": "2.0.1", + "description": "Mrm task that adds Travis CI", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-travis", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "travis ci" + ], + "dependencies": { + "git-username": "^1.0.0", + "lodash": "^4.17.15", + "mrm-core": "^4.0.0", + "semver-utils": "^1.1.4" + } +} diff --git a/packages/mrm-task-typescript/License.md b/packages/mrm-task-typescript/License.md new file mode 100644 index 00000000..28c780fe --- /dev/null +++ b/packages/mrm-task-typescript/License.md @@ -0,0 +1,9 @@ +# The MIT License + +Copyright 2017 Artem Sapegin (http://sapegin.me), contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/mrm-task-typescript/Readme.md b/packages/mrm-task-typescript/Readme.md new file mode 100644 index 00000000..c5a11c98 --- /dev/null +++ b/packages/mrm-task-typescript/Readme.md @@ -0,0 +1,30 @@ +# mrm-task-typescript + +[Mrm](https://github.com/sapegin/mrm) task that adds [TypeScript](https://stylelint.io/). + +## What it does + +- Creates `tsconfig.json` +- Adds an npm script to run type check before tests +- Installs dependencies + +## Usage + +``` +npm install -g mrm mrm-task-typescript +mrm typescript +``` + +## Changelog + +The changelog can be found in [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). + +## Authors and license + +[Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). + +MIT License, see the included [License.md](License.md) file. diff --git a/packages/mrm-task-typescript/__snapshots__/index.spec.js.snap b/packages/mrm-task-typescript/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000..93eb8bf2 --- /dev/null +++ b/packages/mrm-task-typescript/__snapshots__/index.spec.js.snap @@ -0,0 +1,28 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should add TypeScript 1`] = ` +Object { + "/package.json": "{ + \\"name\\": \\"unicorn\\", + \\"scripts\\": { + \\"pretest\\": \\"tsc --noEmit\\", + \\"test\\": \\"jest\\" + } +}", + "/tsconfig.json": "{ + \\"compilerOptions\\": { + \\"target\\": \\"es6\\", + \\"module\\": \\"commonjs\\", + \\"moduleResolution\\": \\"node\\", + \\"strict\\": true, + \\"experimentalDecorators\\": true, + \\"emitDecoratorMetadata\\": true, + \\"noUnusedLocals\\": true, + \\"pretty\\": true, + \\"lib\\": [ + \\"esnext\\" + ] + } +}", +} +`; diff --git a/packages/mrm-task-typescript/index.js b/packages/mrm-task-typescript/index.js new file mode 100644 index 00000000..19d7bf38 --- /dev/null +++ b/packages/mrm-task-typescript/index.js @@ -0,0 +1,33 @@ +const { json, packageJson, install } = require('mrm-core'); + +const packages = ['typescript']; + +function task() { + // tsconfig.json + json('tsconfig.json') + .merge({ + compilerOptions: { + target: 'es6', + module: 'commonjs', + moduleResolution: 'node', + strict: true, + experimentalDecorators: true, + emitDecoratorMetadata: true, + noUnusedLocals: true, + pretty: true, + lib: ['esnext'], + }, + }) + .save(); + + // package.json + packageJson() + .appendScript('pretest', 'tsc --noEmit') + .save(); + + // Dependencies + install(packages); +} +task.description = 'Adds TypeScript'; + +module.exports = task; diff --git a/packages/mrm-task-typescript/index.spec.js b/packages/mrm-task-typescript/index.spec.js new file mode 100644 index 00000000..b43813cb --- /dev/null +++ b/packages/mrm-task-typescript/index.spec.js @@ -0,0 +1,32 @@ +jest.mock('fs'); +jest.mock('mrm-core/src/util/log', () => ({ + added: jest.fn(), +})); +jest.mock('mrm-core/src/npm', () => ({ + install: jest.fn(), +})); + +const { getConfigGetter } = require('mrm'); +const vol = require('memfs').vol; +const task = require('./index'); + +const stringify = o => JSON.stringify(o, null, ' '); + +const packageJson = stringify({ + name: 'unicorn', + scripts: { + test: 'jest', + }, +}); + +afterEach(() => vol.reset()); + +it('should add TypeScript', () => { + vol.fromJSON({ + '/package.json': packageJson, + }); + + task(getConfigGetter({})); + + expect(vol.toJSON()).toMatchSnapshot(); +}); diff --git a/packages/mrm-task-typescript/package-lock.json b/packages/mrm-task-typescript/package-lock.json new file mode 100644 index 00000000..b001fc85 --- /dev/null +++ b/packages/mrm-task-typescript/package-lock.json @@ -0,0 +1,354 @@ +{ + "name": "mrm-task-typescript", + "version": "2.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "comment-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-2.2.0.tgz", + "integrity": "sha512-C8Xm1HF5d4/Hg1MYM8xvae9qtFFpOn1Q3dTCzmFbFaj8VCtcSliu7oYtfYcmOnbxqU+vvxj7MN5Srwpr6qCmvw==", + "requires": { + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "listify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz", + "integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mrm-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mrm-core/-/mrm-core-4.0.0.tgz", + "integrity": "sha512-4Ui3gfSMUvgiSYfIHZbjqWXClwwIlXaCyDmI9xdN675DAuOG+WRE2TvKQkB7dh6JG4EpoI0XAsbXrLpg/z3OxQ==", + "requires": { + "babel-code-frame": "^6.26.0", + "comment-json": "^2.2.0", + "detect-indent": "^6.0.0", + "editorconfig": "^0.15.3", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "js-yaml": "^3.13.1", + "kleur": "^3.0.3", + "listify": "^1.0.0", + "lodash": "^4.17.15", + "minimist": "^1.2.0", + "prop-ini": "^0.0.2", + "readme-badger": "^0.3.0", + "semver": "^6.3.0", + "smpltmpl": "^1.0.2", + "split-lines": "^2.0.0", + "strip-bom": "^4.0.0", + "webpack-merge": "^4.2.2" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "prop-ini": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/prop-ini/-/prop-ini-0.0.2.tgz", + "integrity": "sha1-ZzOny1JCrKsr5C5gdYPYEksXKls=", + "requires": { + "extend": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "readme-badger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/readme-badger/-/readme-badger-0.3.0.tgz", + "integrity": "sha512-+sMOLSs1imZUISZ2Rhz7qqVd77QtpcAPbGeIraFdgJmijb04YtdlPjGNBvDChTNtLbeQ6JNGQy3pOgslWfaP3g==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "smpltmpl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/smpltmpl/-/smpltmpl-1.0.2.tgz", + "integrity": "sha512-Hq23NNgeZigOzIiX1dkb6W3gFn2/XQj43KhPxu65IMieG/gIwf/lQb1IudjYv0c/5LwJeS/mPayYzyo+8WJMxQ==", + "requires": { + "babel-code-frame": "^6.26.0" + } + }, + "split-lines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/split-lines/-/split-lines-2.0.0.tgz", + "integrity": "sha512-gaIdhbqxkB5/VflPXsJwZvEzh/kdwiRPF9iqpkxX4us+lzB8INedFwjCyo6vwuz5x2Ddlnav2zh270CEjCG8mA==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "requires": { + "lodash": "^4.17.15" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/packages/mrm-task-typescript/package.json b/packages/mrm-task-typescript/package.json new file mode 100644 index 00000000..e18341d9 --- /dev/null +++ b/packages/mrm-task-typescript/package.json @@ -0,0 +1,28 @@ +{ + "name": "mrm-task-typescript", + "version": "2.0.1", + "description": "Mrm task that adds TypeScript", + "author": { + "name": "Artem Sapegin", + "url": "http://sapegin.me" + }, + "homepage": "https://github.com/sapegin/mrm/packages/mrm-task-typescript", + "repository": "sapegin/mrm", + "license": "MIT", + "engines": { + "node": ">=8.9" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": {}, + "keywords": [ + "mrm", + "mrm-task", + "typescript" + ], + "dependencies": { + "mrm-core": "^4.0.0" + } +} diff --git a/packages/mrm/Readme.md b/packages/mrm/Readme.md index e07660ea..622dddea 100644 --- a/packages/mrm/Readme.md +++ b/packages/mrm/Readme.md @@ -1,443 +1,18 @@ # Mrm -[![Build Status](https://travis-ci.org/sapegin/mrm.svg)](https://travis-ci.org/sapegin/mrm) [![npm](https://img.shields.io/npm/v/mrm.svg)](https://www.npmjs.com/package/mrm) +[![npm](https://img.shields.io/npm/v/mrm.svg)](https://www.npmjs.com/package/mrm) Command line tool to help you keep configuration (`package.json`, `.gitignore`, `.eslintrc`, etc.) of your open source projects in sync. -## Features +See [../Readme.md](documentation). -- Will not overwrite your data if you don’t want it to -- Minimal changes: will keep the original file formatting or read the style from EditorConfig -- Minimal configuration: will try to infer configuration from the project itself or from the environment -- Bunch of [customizable tasks](#tasks) included -- Tools to work with JSON, YAML, INI, Markdown and new line separated text files -- Easy to write [your own tasks](#writing-your-own-tasks) -- Share tasks via npm and group them into [presets](#custom-presets) +## Changelog -![](https://d3vv6lp55qjaqc.cloudfront.net/items/1g0e2M3m2Y3j0m3B3n1t/Image%202017-06-20%20at%209.00.39%20PM.png) - -## Table of contents - - - - - -- [Motivation](#motivation) -- [Installation](#installation) -- [Usage](#usage) -- [Usage via npx](#usage-via-npx) -- [Configuration](#configuration) -- [Tasks](#tasks) -- [Writing your own tasks](#writing-your-own-tasks) -- [Sharing tasks via npm](#sharing-tasks-via-npm) -- [Custom presets](#custom-presets) -- [Config resolution rules](#config-resolution-rules) -- [Task resolution rules](#task-resolution-rules) -- [FAQ](#faq) - - [How to use Mrm with Lerna?](#how-to-use-mrm-with-lerna) - - [How to infer user metadata, like user name or email?](#how-to-infer-user-metadata-like-user-name-or-email) - - [How to infer GitHub user name?](#how-to-infer-github-user-name) -- [Change log](#change-log) -- [Contributing](#contributing) -- [Authors and license](#authors-and-license) - - - -## Motivation - -Most of the available tools are template based. Template approach works moderately well for new project generation but doesn’t work well for updating. Mrm’s approach is closer to [codemods](https://github.com/facebook/codemod) than templates. - -Read more in my article, [Automating open source project configuration with Mrm](http://blog.sapegin.me/all/mrm), or watch [my talk on Mrm](https://www.youtube.com/watch?v=5tHfAf4bRcM). - -## Installation - -``` -npm install -g mrm -``` - -## Usage - -Print a list available of tasks: - -```shell -mrm -``` - -Run a task or an alias - -```shell -mrm gitignore -mrm license -``` - -Run multiple tasks: - -```shell -mrm gitignore license -``` - -Override config options (or run without a config file): - -```shell -mrm license --config:name "Gandalf the Grey" --config:email "gandalf@middleearth.com" --config:url "http://middleearth.com" -``` - -Custom config and tasks folder: - -```shell -mrm license --dir ~/unicorn -``` - -Run a task from a preset (globally installed `mrm-preset-unicorn` npm package, read more [about preset](#custom-presets)): - -```shell -mrm license --preset unicorn -``` - -## Usage via npx - -If you have npm 5.3 or newer you can use mrm without installation: - -```shell -npx mrm -npx mrm gitignore -npx mrm license --config:name "Gandalf the Grey" --config:email "gandalf@middleearth.com" --config:url "http://middleearth.com" -``` - -## Configuration - -Create `~/.mrm/config.json` or `~/dotfiles/mrm/config.json`: - -```json5 -{ - indent: 'tab', // "tab" or number of spaces - readmeFile: 'Readme.md', // Name of readme file - licenseFile: 'License.md', // Name of license file - aliases: { - // Aliases to run multiple tasks at once - node: ['license', 'readme', 'editorconfig', 'gitignore'] - } -} -``` - -See [tasks docs](https://github.com/sapegin/mrm-tasks) for available config options. - -_Config file isn’t required, you can also pass config options via command line. Default tasks will try to [read data](https://github.com/sapegin/user-meta) fom your npm and Git configuration._ - -## Tasks - -These tasks are included by default: - - - -- [codecov](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-codecov) -- [contributing](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-contributing) -- [editorconfig](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-editorconfig) -- [eslint](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-eslint) -- [gitignore](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-gitignore) -- [jest](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-jest) -- [license](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-license) -- [lint-staged](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-lint-staged) -- [package](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-package) -- [prettier](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-prettier) -- [readme](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-readme) -- [semantic-release](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-semantic-release) -- [styleguidist](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-styleguidist) -- [stylelint](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-stylelint) -- [travis](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-travis) -- [typescript](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-typescript) - - - -## Writing your own tasks - -Create either `~/.mrm//index.js` or `~/dotfiles/mrm//index.js`. If `` is the same as one of the default tasks your task will override a default one. - -The simplest task could look like this: - -```js -// Mrm module to work with new line separated text files -const { lines } = require('mrm-core'); - -function task() { - // Read .gitignore if it exists - lines('.gitignore') - // Add lines that do not exist in a file yet, - // but keep all existing lines - .add(['node_modules/', '.DS_Store']) - // Update or create a file - .save(); -} - -task.description = 'Adds .gitignore'; -module.exports = task; -``` - -Tasks can also be async by adding the `async` keyword or returning a `Promise`. - -```js -async function task() {} - -// or -function task() { - return new Promise(() => {}); -} -``` - -If your tasks have dependencies (such as `mrm-core`) you should initialize the `mrm` folder as an npm module and list your dependencies there: - -```bash -cd ~/.mrm # or cd ~/dotfiles/mrm -npm init -y -npm install --save mrm-core -``` - -[mrm-core](https://github.com/sapegin/mrm-core) is an utility library created to write Mrm tasks, it has function to work with common config files (JSON, YAML, INI, Markdown), npm dependencies, etc. - -Let’s take a look at a more complicated task: - -```js -const { - // JSON files - json, - // package.json - packageJson, - // New line separated text files - lines, - // Install npm packages - install -} = require('mrm-core'); - -function task(config) { - // Task options - // mrm eslint --config:name pizza - const { name, eslintPreset } = config - .defaults({ - // Default value - eslintPreset: 'eslint:recommended' - }) - // Required option - .require('name') - .values(); - - // Use custom preset package from npm - const packages = ['eslint']; - if (eslintPreset !== 'eslint:recommended') { - packages.push(`eslint-config-${eslintPreset}`); - } - - // Create or update .eslintignore - lines('.eslintignore') - .add(['node_modules/']) - .save(); - - // Read project’s package.json - const pkg = packageJson(); - - pkg - // Add lint script - .setScript('lint', 'eslint . --cache --fix') - // Add pretest script - .prependScript('pretest', 'npm run lint') - .save(); - - // Read .eslintrc if it exists - const eslintrc = json('.eslintrc'); - - // Use Babel parser if the project depends on Babel - if (pkg.get('devDependencies.babel-core')) { - const parser = 'babel-eslint'; - packages.push(parser); - eslintrc.merge({ parser }); - } - - // Set preset - eslintrc.set('extends', eslintPreset).save(); - - // Install npm dependencies - install(packages); -} - -task.description = 'Adds ESLint'; -module.exports = task; -``` - -There are more methods in `mrm-core` — check out [the docs](https://github.com/sapegin/mrm-core#api) and [the default tasks](https://github.com/sapegin/mrm-tasks). - -## Sharing tasks via npm - -The basic file structure of a shared task looks like this: - -``` -. -├── index.js -├── package.json -``` - -`index.js` is the same as described [in the previous section](#writing-custom-tasks). And the `package.json` would look like this: - -```json -{ - "name": "mrm-task-unicorn", - "version": "0.1.0", - "description": "Unicorn task for Mrm", - "author": { - "name": "Artem Sapegin", - "url": "http://sapegin.me" - }, - "homepage": "https://github.com/sapegin/mrm-tasks/packages/mrm-task-unicorn", - "repository": "sapegin/mrm-tasks", - "license": "MIT", - "engines": { - "node": ">=4" - }, - "main": "index.js", - "files": ["index.js"], - "keywords": ["mrm", "mrm-task", "unicorn"], - "dependencies": { - "mrm-core": "^2.1.3" - } -} -``` - -The package name should should follow this pattern: `mrm-task-`, otherwise you’ll have to type full package name when you run a task: - -``` -mrm unicorn # mrm-task-unicorn -mrm @mycompany/unicorn-task # @mycompany/unicorn-task -``` - -## Custom presets - -Preset is an npm package (or a directory) that contains a config and tasks. - -The file structure looks like this: - -``` -. -├── task1 -│   └── index.js -├── task2 -│   └── index.js -├── config.json -├── package.json -``` - -And the `package.json` would look like this: - -```json -{ - "name": "mrm-preset-default", - "version": "0.1.0", - "description": "Common tasks for Mrm", - "author": { - "name": "Artem Sapegin", - "url": "http://sapegin.me" - }, - "homepage": "https://github.com/sapegin/mrm-tasks/packages/mrm-preset-default", - "repository": "sapegin/mrm-tasks", - "license": "MIT", - "engines": { - "node": ">=4" - }, - "main": "config.json", - "files": ["config.json", "*/index.js"], - "keywords": ["mrm", "mrm-task", "mrm-preset"], - "dependencies": { - "mrm-core": "^2.1.3", - "mrm-task-gitignore": "^0.1.0" - } -} -``` - -See the [Writing custom tasks](#writing-custom-tasks) section above to learn how to write Mrm tasks. To add a task to a preset put it into a `/index.js` file in your preset package folder. - -If you want to use a task from npm (or any default task), you should include it as a dependency. That way you can be sure that you’ll always have a task version that works for your project. - -For example, if you want to use `mrm-task-gitignore` task, you need to create a `gitignore/index.js` file in your preset package folder: - -```js -module.exports = require('mrm-task-gitignore'); -``` - -The package name should should follow this pattern: `mrm-preset-`, otherwise you’ll have to type full package name when you run a task: - -``` -mrm license --preset unicorn # mrm-preset-unicorn -mrm license --preset @mycompany/unicorn-preset # @mycompany/unicorn-preset -``` - -## Config resolution rules - -- `/config.json` if `--dir ` command line option was passed -- `$HOME/dotfiles/mrm/config.json` -- `$HOME/.mrm/config.json` - -if you’re passing a `--preset ` command line option, then the only task directory will be: - -- `mrm-preset-/config.json` - -## Task resolution rules - -- `//index.js` if `--dir ` command line option was passed -- `$HOME/dotfiles/mrm//index.js` -- `$HOME/.mrm//index.js` -- `mrm-task-/index.js`, where `mrm-task-` is an npm package name -- `` in [mrm-preset-default](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-preset-default) - -if you’re passing a `--preset ` command line option, then the only task directory will be: - -- `mrm-preset-//index.js` - -## FAQ - -### How to use Mrm with Lerna? - -To run a task for each package in a [Lerna](https://github.com/lerna/lerna) repository: - -```bash -./node_modules/.bin/lerna exec -- mrm -``` - -### How to infer user metadata, like user name or email? - -Use the [user-meta](https://github.com/sapegin/user-meta) package to read user name, email and URL from `.npmrc` or `.gitconfig`: - -```js -const meta = require('user-meta'); -module.exports = function task(config) { - const { name, email, url } = config - .defaults(meta) - .require('name', 'email', 'url') - .values(); - /* ... */ -}; -``` - -### How to infer GitHub user name? - -Use the [git-username](https://github.com/jonschlinkert/git-username) package: - -```js -const gitUsername = require('git-username'); -module.exports = function task(config) { - const { github } = config - .defaults({ - github: gitUsername() - }) - .require('github') - .values(); - /* ... */ -}; -``` - -## Change log - -The change log can be found on the [Releases page](https://github.com/sapegin/mrm/releases). +The changelog can be found on the [Releases page](https://github.com/sapegin/mrm/releases). ## Contributing -Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](Contributing.md). +Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../Contributing.md). ## Authors and license