├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE │ └── config.yml └── workflows │ ├── coverage.yml │ ├── node.js.yml │ └── release.yml ├── .gitignore ├── .npmignore ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── CNAME ├── Contributing.md ├── FUNDING.yml ├── License.md ├── Readme.md ├── __mocks__ ├── fs.js └── git-username.js ├── docs ├── FAQ.md ├── Getting_started.md ├── Making_presets.md ├── Making_tasks.md └── Sharing_tasks.md ├── jsconfig.json ├── lerna.json ├── netlify.toml ├── package-lock.json ├── package.json ├── packages ├── mrm-core │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ ├── __snapshots__ │ │ │ │ └── fs.spec.js.snap │ │ │ ├── commands.spec.js │ │ │ ├── editorconfig.spec.js │ │ │ ├── error.spec.js │ │ │ ├── fs.spec.js │ │ │ ├── index.spec.js │ │ │ └── npm.spec.js │ │ ├── commands.js │ │ ├── editorconfig.js │ │ ├── error.js │ │ ├── files │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── packageJson.spec.js.snap │ │ │ │ └── packageJson.spec.js │ │ │ └── packageJson.js │ │ ├── formats │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ ├── file.spec.js.snap │ │ │ │ │ ├── ini.spec.js.snap │ │ │ │ │ ├── json.spec.js.snap │ │ │ │ │ ├── lines.spec.js.snap │ │ │ │ │ ├── markdown.spec.js.snap │ │ │ │ │ ├── template.spec.js.snap │ │ │ │ │ └── yaml.spec.js.snap │ │ │ │ ├── file.spec.js │ │ │ │ ├── ini.spec.js │ │ │ │ ├── json.spec.js │ │ │ │ ├── lines.spec.js │ │ │ │ ├── markdown.spec.js │ │ │ │ ├── template.spec.js │ │ │ │ └── yaml.spec.js │ │ │ ├── file.js │ │ │ ├── ini.js │ │ │ ├── json.js │ │ │ ├── lines.js │ │ │ ├── markdown.js │ │ │ ├── template.js │ │ │ └── yaml.js │ │ ├── fs.js │ │ ├── index.js │ │ ├── npm.js │ │ └── util │ │ │ ├── __tests__ │ │ │ ├── escapeArguments.js │ │ │ ├── execCommand.spec.js │ │ │ ├── log.spec.js │ │ │ └── merge.spec.js │ │ │ ├── escapeArguments.js │ │ │ ├── execCommand.js │ │ │ ├── isWindows.js │ │ │ ├── log.js │ │ │ └── merge.js │ └── types │ │ └── index.d.ts ├── mrm-preset-default │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── ci │ │ └── index.js │ ├── codecov │ │ └── index.js │ ├── config.json │ ├── contributing │ │ └── index.js │ ├── dependabot │ │ └── index.js │ ├── editorconfig │ │ └── index.js │ ├── eslint │ │ └── index.js │ ├── gitignore │ │ └── index.js │ ├── index.spec.js │ ├── jest │ │ └── index.js │ ├── license │ │ └── index.js │ ├── lint-staged │ │ └── index.js │ ├── package-lock.json │ ├── package.json │ ├── package │ │ └── index.js │ ├── prettier │ │ └── index.js │ ├── readme │ │ └── index.js │ ├── semantic-release │ │ └── index.js │ ├── styleguidist │ │ └── index.js │ ├── stylelint │ │ └── index.js │ ├── travis │ │ └── index.js │ └── typescript │ │ └── index.js ├── mrm-task-ci │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-codecov │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-contributing │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ ├── package.json │ └── templates │ │ └── Contributing.md ├── mrm-task-dependabot │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-editorconfig │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-eslint │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-gitignore │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-gitter │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── index.js │ ├── package-lock.json │ └── package.json ├── mrm-task-jest │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ ├── package.json │ └── templates │ │ ├── index.js │ │ ├── jestsetup.js │ │ └── test.js ├── mrm-task-license │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ ├── package.json │ └── templates │ │ ├── Apache-2.0.md │ │ ├── BSD-2-Clause.md │ │ ├── BSD-3-Clause.md │ │ ├── MIT.md │ │ └── Unlicense.md ├── mrm-task-lint-staged │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-package │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-prettier │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-readme │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ ├── package.json │ └── templates │ │ ├── Contributing.md │ │ └── Readme.md ├── mrm-task-semantic-release │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-styleguidist │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ ├── package.json │ └── templates │ │ ├── styleguide.config.js │ │ └── styleguide.config.typescript.js ├── mrm-task-stylelint │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-travis │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json ├── mrm-task-typescript │ ├── CHANGELOG.md │ ├── License.md │ ├── Readme.md │ ├── __snapshots__ │ │ └── index.spec.js.snap │ ├── index.js │ ├── index.spec.js │ ├── package-lock.json │ └── package.json └── mrm │ ├── CHANGELOG.md │ ├── Readme.md │ ├── bin │ └── mrm.js │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── __tests__ │ │ └── index.spec.js │ ├── errors.js │ └── index.js │ └── test │ ├── dir1 │ ├── config.json │ ├── task1 │ │ └── index.js │ └── task2 │ │ └── index.js │ ├── dir2 │ ├── task2 │ │ └── index.js │ ├── task3 │ │ └── index.js │ ├── task4 │ │ └── index.js │ └── task5 │ │ └── index.js │ ├── dir3 │ └── task6 │ │ └── index.js │ ├── dir4 │ └── task7 │ │ └── index.js │ ├── dir5 │ └── task8 │ │ └── index.js │ ├── dir6 │ └── task1 │ │ └── index.js │ └── inquirer-mock.js ├── site ├── .gitignore ├── Readme.md ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── remark.js ├── scripts │ └── sync.js ├── sidebars.js ├── src │ ├── .eslintrc.json │ ├── components │ │ ├── CarbonAds.js │ │ ├── CarbonAds.module.css │ │ ├── Terminal.js │ │ ├── Terminal.module.css │ │ ├── VisuallyHidden.js │ │ └── VisuallyHidden.module.css │ ├── css │ │ └── custom.css │ ├── pages │ │ ├── index.js │ │ └── index.module.css │ ├── plugins │ │ └── goatcounter-plugin.js │ └── theme │ │ └── DocSidebar │ │ ├── index.js │ │ └── styles.module.css └── static │ └── img │ ├── favicon.png │ ├── mrm-article.png │ └── mrm-video.jpg └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = tab 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.{json,yml,md,babelrc,eslintrc,lintstagedrc,remarkrc}] 12 | indent_style = space 13 | indent_size = 2 14 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | coverage/ 3 | packages/*/templates/ 4 | site/build/ 5 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tamia", 3 | "parserOptions": { 4 | "sourceType": "script" 5 | }, 6 | "rules": { 7 | "no-console": 0 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Get help 4 | url: https://github.com/sapegin/mrm/discussions/new?category=q-a 5 | about: If you can’t get something to work the way you expect, open a question in our discussion forums. 6 | - name: Report a bug 7 | url: https://github.com/sapegin/mrm/discussions/new?category=bugs 8 | about: If something is broken in the project itself, create a bug report. 9 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: Codecov 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Set up Git 14 | run: | 15 | git config --global user.name "Mrm Bot" 16 | git config --global user.email "${BOT_EMAIL}" 17 | env: 18 | BOT_EMAIL: ${{ secrets.BOT_EMAIL }} 19 | - uses: actions/checkout@v2 20 | - uses: actions/setup-node@v2 21 | - run: npm ci 22 | - run: npm run bootstrap 23 | - run: npm run test:coverage 24 | - uses: codecov/codecov-action@v2 25 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | node-version: 15 | - 16.x 16 | - 18.x 17 | steps: 18 | - name: Set up Git 19 | run: | 20 | git config --global user.name "Mrm Bot" 21 | git config --global user.email "${BOT_EMAIL}" 22 | env: 23 | BOT_EMAIL: ${{ secrets.BOT_EMAIL }} 24 | - uses: actions/checkout@v2 25 | - name: Use Node.js ${{ matrix.node-version }} 26 | uses: actions/setup-node@v2 27 | with: 28 | node-version: ${{ matrix.node-version }} 29 | - run: npm ci 30 | - run: npm run bootstrap 31 | - run: npm test 32 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: actions/setup-node@v2 12 | - name: Set up Git 13 | run: | 14 | git config --global user.name "Mrm Bot" 15 | git config --global user.email "${BOT_EMAIL}" 16 | git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/sapegin/mrm.git" 17 | env: 18 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 19 | BOT_EMAIL: ${{ secrets.BOT_EMAIL }} 20 | - name: Set up npm 21 | run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> ~/.npmrc 2> /dev/null 22 | env: 23 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 24 | - run: npm ci 25 | - name: Publish 26 | run: | 27 | npx lerna version --yes --create-release=github 28 | npx lerna publish from-git --yes 29 | env: 30 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 31 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Changelog.md 2 | node_modules 3 | .DS_Store 4 | Thumbs.db 5 | .idea 6 | .vscode 7 | *.sublime-project 8 | *.sublime-workspace 9 | *.log 10 | coverage/ 11 | .eslintcache -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | __tests__/ -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v16 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | packages/mrm-task-jest/templates/test.js 2 | packages/mrm-task-readme/templates/Readme.md 3 | site/build/ 4 | site/docs/ 5 | site/.docusaurus/ 6 | CHANGELOG.md 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "singleQuote": true, 4 | "trailingComma": "es5", 5 | "overrides": [ 6 | { 7 | "files": "*.md", 8 | "options": { 9 | "printWidth": 70, 10 | "useTabs": false, 11 | "trailingComma": "none", 12 | "proseWrap": "never" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | mrm.js.org 2 | -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | Bug fixes are welcome, but not new features. [See more details](https://github.com/sapegin/mrm/discussions/298). 4 | 5 | ## Building and running tests 6 | 7 | _Run these commands in the root folder of the repository._ 8 | 9 | Install dependencies and bootstrap [Lerna](https://github.com/lerna/lerna): 10 | 11 | ```bash 12 | npm run bootstrap 13 | ``` 14 | 15 | Run tests for all packages: 16 | 17 | ```bash 18 | npm test 19 | ``` 20 | 21 | Or run a watch mode: 22 | 23 | ```bash 24 | npm run test:watch 25 | ``` 26 | -------------------------------------------------------------------------------- /FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: sapegin 2 | ko_fi: sapegin 3 | custom: https://www.buymeacoffee.com/sapegin 4 | -------------------------------------------------------------------------------- /License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2016 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /__mocks__/fs.js: -------------------------------------------------------------------------------- 1 | process.chdir('/'); 2 | module.exports = require('memfs'); 3 | -------------------------------------------------------------------------------- /__mocks__/git-username.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return 'mrm'; 3 | }; 4 | -------------------------------------------------------------------------------- /docs/FAQ.md: -------------------------------------------------------------------------------- 1 | # FAQ 2 | 3 | ## How to use Mrm with Lerna? 4 | 5 | To run a task for each package in a [Lerna](https://github.com/lerna/lerna) repository: 6 | 7 | ```bash 8 | ./node_modules/.bin/lerna exec -- mrm 9 | ``` 10 | 11 | ## How to infer user metadata, like user name or email? 12 | 13 | Use the [user-meta](https://github.com/sapegin/user-meta) package to read user name, email and URL from `.npmrc` or `.gitconfig`: 14 | 15 | ```js 16 | const meta = require('user-meta'); 17 | module.exports = function task(config) { 18 | const { name, email, url } = config 19 | .defaults(meta) 20 | .require('name', 'email', 'url') 21 | .values(); 22 | /* ... */ 23 | }; 24 | ``` 25 | 26 | ## How to infer GitHub user name? 27 | 28 | Use the [git-username](https://github.com/jonschlinkert/git-username) package: 29 | 30 | ```js 31 | const gitUsername = require('git-username'); 32 | module.exports = function task(config) { 33 | const { github } = config 34 | .defaults({ 35 | github: gitUsername() 36 | }) 37 | .require('github') 38 | .values(); 39 | /* ... */ 40 | }; 41 | ``` 42 | 43 | ## Config resolution rules 44 | 45 | - `/config.json` if `--dir ` command line option was passed 46 | - `$HOME/dotfiles/mrm/config.json` 47 | - `$HOME/.mrm/config.json` 48 | 49 | if you’re passing a `--preset ` command line option, then the only task directory will be: 50 | 51 | - `mrm-preset-/config.json` 52 | 53 | ## Task resolution rules 54 | 55 | - `//index.js` if `--dir ` command line option was passed 56 | - `$HOME/dotfiles/mrm//index.js` 57 | - `$HOME/.mrm//index.js` 58 | - `mrm-task-/index.js`, where `mrm-task-` is an npm package name 59 | 60 | if you’re passing a `--preset ` command line option, then the only task directory will be: 61 | 62 | - `mrm-preset-//index.js` 63 | -------------------------------------------------------------------------------- /docs/Making_presets.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Making your own presets 4 | 5 | Preset is an npm package (or a directory) that contains a shared config and tasks. 6 | 7 | The file structure looks like this: 8 | 9 | ``` 10 | . 11 | ├── task1 12 | │   └── index.js 13 | ├── task2 14 | │   └── index.js 15 | ├── config.json 16 | ├── package.json 17 | ``` 18 | 19 | And the `package.json` would look like this: 20 | 21 | ```json 22 | { 23 | "name": "mrm-preset-default", 24 | "version": "0.1.0", 25 | "description": "Common tasks for Mrm", 26 | "author": { 27 | "name": "Artem Sapegin", 28 | "url": "https://sapegin.me" 29 | }, 30 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-preset-default", 31 | "repository": "sapegin/mrm", 32 | "license": "MIT", 33 | "engines": { 34 | "node": ">=4" 35 | }, 36 | "main": "config.json", 37 | "files": ["config.json", "*/index.js"], 38 | "keywords": ["mrm", "mrm-preset"], 39 | "dependencies": { 40 | "mrm-core": "^2.1.3", 41 | "mrm-task-gitignore": "^0.1.0" 42 | } 43 | } 44 | ``` 45 | 46 | See [Making tasks](./Making_tasks.md) to learn how to create Mrm tasks. To add a task to a preset put it into a `/index.js` file in your preset package folder. 47 | 48 | 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. 49 | 50 | 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: 51 | 52 | ```js 53 | module.exports = require('mrm-task-gitignore'); 54 | ``` 55 | 56 | The package name should follow this pattern: `mrm-preset-`, otherwise you’ll have to type full package name when you run a task: 57 | 58 | ``` 59 | mrm license --preset unicorn # mrm-preset-unicorn 60 | mrm license --preset @mycompany/unicorn-preset # @mycompany/unicorn-preset 61 | ``` 62 | -------------------------------------------------------------------------------- /docs/Sharing_tasks.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Sharing tasks via npm 4 | 5 | The basic file structure of a shared task looks like this: 6 | 7 | ``` 8 | . 9 | ├── index.js 10 | ├── package.json 11 | ``` 12 | 13 | `index.js` is the same as described in [Making tasks](./Making_tasks.md). And the `package.json` would look like this: 14 | 15 | ```json 16 | { 17 | "name": "mrm-task-unicorn", 18 | "version": "0.1.0", 19 | "description": "Unicorn task for Mrm", 20 | "author": { 21 | "name": "Artem Sapegin", 22 | "url": "https://sapegin.me" 23 | }, 24 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-unicorn", 25 | "repository": "sapegin/mrm", 26 | "license": "MIT", 27 | "engines": { 28 | "node": ">=4" 29 | }, 30 | "main": "index.js", 31 | "files": ["index.js"], 32 | "keywords": ["mrm", "mrm-task", "unicorn"], 33 | "dependencies": { 34 | "mrm-core": "^2.1.3" 35 | } 36 | } 37 | ``` 38 | 39 | The package name should should follow this pattern: `mrm-task-`, otherwise you’ll have to type full package name when you run a task: 40 | 41 | ```bash 42 | mrm unicorn # mrm-task-unicorn 43 | mrm @mycompany/unicorn-task # @mycompany/unicorn-task 44 | ``` 45 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "lib": ["esnext"] 5 | }, 6 | "exclude": ["node_modules"] 7 | } 8 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "independent", 3 | "useWorkspaces": true, 4 | "command": { 5 | "version": { 6 | "allowBranch": "master", 7 | "conventionalCommits": true, 8 | "noPrivate": true, 9 | "message": "chore: Publish :shipit: [skip ci]" 10 | } 11 | }, 12 | "ignoreChanges": [ 13 | "package-lock.json", 14 | "Readme.md", 15 | "Changelog.md", 16 | "CHANGELOG.md", 17 | "*.spec.js", 18 | "*.snap" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | ignore = "/bin/false" 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-monorepo", 3 | "private": true, 4 | "description": "Codemods for your project config files", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "https://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "workspaces": [ 13 | "packages/*" 14 | ], 15 | "scripts": { 16 | "bootstrap": "lerna bootstrap", 17 | "pretest": "npm run lint", 18 | "test": "npm run test:jest", 19 | "posttest": "npm run typecheck && npm run format", 20 | "test:jest": "jest", 21 | "test:watch": "jest --watch", 22 | "test:coverage": "jest --coverage", 23 | "lint": "eslint . --cache --fix", 24 | "typecheck": "tsc --noEmit", 25 | "format": "prettier --loglevel warn --write \"**/*.{js,md}\"" 26 | }, 27 | "engines": { 28 | "node": ">=10.13" 29 | }, 30 | "devDependencies": { 31 | "@types/lodash": "^4.14.149", 32 | "eslint": "^6.7.1", 33 | "eslint-config-tamia": "^7.1.1", 34 | "eslint-plugin-react": "^7.19.0", 35 | "husky": "^3.1.0", 36 | "jest": "^24.9.0", 37 | "lerna": "^6.0.1", 38 | "lint-staged": "^9.4.3", 39 | "memfs": "3.2.0", 40 | "prettier": "^1.19.1", 41 | "typescript": "^3.7.3" 42 | }, 43 | "keywords": [ 44 | "boilerplate", 45 | "cli", 46 | "codemod", 47 | "command line", 48 | "generate", 49 | "generator", 50 | "ini", 51 | "json", 52 | "markdown", 53 | "runner", 54 | "scaffold", 55 | "task", 56 | "template", 57 | "tool", 58 | "yaml" 59 | ], 60 | "jest": { 61 | "testPathIgnorePatterns": [ 62 | "/node_modules/", 63 | "/templates/" 64 | ] 65 | }, 66 | "lint-staged": { 67 | "*.js": [ 68 | "eslint --fix", 69 | "git add" 70 | ], 71 | "*.{js,md}": [ 72 | "prettier --write", 73 | "git add" 74 | ] 75 | }, 76 | "husky": { 77 | "hooks": { 78 | "pre-commit": "lint-staged" 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /packages/mrm-core/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-core", 3 | "version": "7.1.23", 4 | "description": "Utilities to make tasks for Mrm", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "https://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "main": "src/index.js", 13 | "types": "types/index.d.ts", 14 | "engines": { 15 | "node": ">=10.13" 16 | }, 17 | "files": [ 18 | "src", 19 | "types" 20 | ], 21 | "dependencies": { 22 | "babel-code-frame": "^6.26.0", 23 | "comment-json": "^2.2.0", 24 | "detect-indent": "^6.0.0", 25 | "editorconfig": "^0.15.3", 26 | "find-up": "^4.1.0", 27 | "fs-extra": "^8.1.0", 28 | "kleur": "^3.0.3", 29 | "listify": "^1.0.0", 30 | "lodash": "^4.17.15", 31 | "minimist": "^1.2.0", 32 | "prop-ini": "^0.0.2", 33 | "rc": "^1.2.8", 34 | "readme-badger": "^0.3.0", 35 | "semver": "^6.3.0", 36 | "smpltmpl": "^1.0.2", 37 | "split-lines": "^2.0.0", 38 | "strip-bom": "^4.0.0", 39 | "validate-npm-package-name": "^3.0.0", 40 | "webpack-merge": "^4.2.2", 41 | "yaml": "^2.0.0-1" 42 | }, 43 | "keywords": [ 44 | "mrm", 45 | "boilerplate", 46 | "codemod", 47 | "template", 48 | "generate", 49 | "generator", 50 | "scaffold", 51 | "npm", 52 | "yaml", 53 | "json", 54 | "ini", 55 | "markdown" 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /packages/mrm-core/src/__tests__/__snapshots__/fs.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`copyFiles() should copy a file 1`] = ` 4 | Object { 5 | "/a": "pizza", 6 | "/tmpl/a": "pizza", 7 | } 8 | `; 9 | 10 | exports[`copyFiles() should copy multiple files 1`] = ` 11 | Object { 12 | "/a": "pizza", 13 | "/b": "coffee", 14 | "/tmpl/a": "pizza", 15 | "/tmpl/b": "coffee", 16 | } 17 | `; 18 | 19 | exports[`copyFiles() should not try to copy a file if contents is the same 1`] = ` 20 | Object { 21 | "/a": "pizza", 22 | "/b": "pizza", 23 | "/tmpl/a": "pizza", 24 | "/tmpl/b": "pizza", 25 | } 26 | `; 27 | 28 | exports[`deleteFiles() should delete a file 1`] = ` 29 | Object { 30 | "/b": "coffee", 31 | } 32 | `; 33 | 34 | exports[`deleteFiles() should delete multiple files 1`] = ` 35 | Object { 36 | "/c": "schawarma", 37 | } 38 | `; 39 | 40 | exports[`updateFile() should create a file 1`] = ` 41 | Object { 42 | "/a": "pizza", 43 | } 44 | `; 45 | 46 | exports[`updateFile() should create a folder 1`] = ` 47 | Object { 48 | "/a/b": "pizza", 49 | } 50 | `; 51 | 52 | exports[`updateFile() should update a file 1`] = ` 53 | Object { 54 | "/a": "pizza", 55 | } 56 | `; 57 | -------------------------------------------------------------------------------- /packages/mrm-core/src/__tests__/commands.spec.js: -------------------------------------------------------------------------------- 1 | const { getExtsFromCommand } = require('../commands'); 2 | 3 | describe('getExtsFromCommand', () => { 4 | it('prettier: single quotes', () => { 5 | const result = getExtsFromCommand(`prettier --write '**/*.js'`); 6 | expect(result).toEqual(['js']); 7 | }); 8 | 9 | it('prettier: double quotes', () => { 10 | const result = getExtsFromCommand(`prettier --write "**/*.js"`); 11 | expect(result).toEqual(['js']); 12 | }); 13 | 14 | it('prettier: no quotes', () => { 15 | const result = getExtsFromCommand(`prettier --write **/*.js`); 16 | expect(result).toEqual(['js']); 17 | }); 18 | 19 | it('prettier: multiple extensions', () => { 20 | const result = getExtsFromCommand(`prettier --write '**/*.{js,md}'`); 21 | expect(result).toEqual(['js', 'md']); 22 | }); 23 | 24 | it('eslint: no extensions', () => { 25 | const result = getExtsFromCommand(`eslint . --fix`, 'ext'); 26 | expect(result).toBe(undefined); 27 | }); 28 | 29 | it('eslint: one extension', () => { 30 | const result = getExtsFromCommand(`eslint . --fix --ext .js`, 'ext'); 31 | expect(result).toEqual(['js']); 32 | }); 33 | 34 | it('eslint: multiple extensions', () => { 35 | const result = getExtsFromCommand(`eslint . --fix --ext .js,.jsx`, 'ext'); 36 | expect(result).toEqual(['js', 'jsx']); 37 | }); 38 | 39 | it('env variables', () => { 40 | const result = getExtsFromCommand( 41 | `NODE_ENV=development prettier --write '**/*.js'` 42 | ); 43 | expect(result).toEqual(['js']); 44 | }); 45 | 46 | it('cross-env', () => { 47 | const result = getExtsFromCommand( 48 | `cross-env NODE_ENV=development prettier --write '**/*.js'` 49 | ); 50 | expect(result).toEqual(['js']); 51 | }); 52 | 53 | it('ignore empty command', () => { 54 | const result = getExtsFromCommand(``); 55 | expect(result).toBe(undefined); 56 | }); 57 | 58 | it('ignore undefined command', () => { 59 | const result = getExtsFromCommand(); 60 | expect(result).toBe(undefined); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /packages/mrm-core/src/__tests__/error.spec.js: -------------------------------------------------------------------------------- 1 | const MrmError = require('../error'); 2 | 3 | it('MrmError should be Error descendant', () => { 4 | const err = new MrmError(); 5 | expect(err instanceof Error).toBeTruthy(); 6 | }); 7 | 8 | it('toString() should contain a proper class name', () => { 9 | const err = new MrmError('nope'); 10 | expect(err.toString()).toMatch('MrmError'); 11 | }); 12 | 13 | it('toString() should contain a message', () => { 14 | const err = new MrmError('nope'); 15 | expect(err.toString()).toMatch('nope'); 16 | }); 17 | 18 | it('should contain an extra data', () => { 19 | const extra = { foo: 42 }; 20 | const err = new MrmError('nope', extra); 21 | expect(err.extra).toEqual(extra); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/mrm-core/src/__tests__/index.spec.js: -------------------------------------------------------------------------------- 1 | const index = require('../index'); 2 | 3 | it('should contain all API functions', () => { 4 | expect(index).toEqual( 5 | expect.objectContaining({ 6 | readFile: expect.any(Function), 7 | updateFile: expect.any(Function), 8 | copyFiles: expect.any(Function), 9 | makeDirs: expect.any(Function), 10 | MrmError: expect.any(Function), 11 | file: expect.any(Function), 12 | ini: expect.any(Function), 13 | json: expect.any(Function), 14 | lines: expect.any(Function), 15 | markdown: expect.any(Function), 16 | template: expect.any(Function), 17 | yaml: expect.any(Function), 18 | packageJson: expect.any(Function), 19 | install: expect.any(Function), 20 | uninstall: expect.any(Function), 21 | inferStyle: expect.any(Function), 22 | getStyleForFile: expect.any(Function), 23 | getIndent: expect.any(Function), 24 | format: expect.any(Function), 25 | getExtsFromCommand: expect.any(Function), 26 | }) 27 | ); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/mrm-core/src/commands.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const _ = require('lodash'); 3 | const minimist = require('minimist'); 4 | 5 | const unquote = (/** @type {string} */ s) => _.trim(s, `'"`); 6 | const unbracket = (/** @type {string} */ s) => _.trim(s, `{}`); 7 | const undot = (/** @type {string} */ s) => s.replace(/\./g, ''); 8 | 9 | /** 10 | * 11 | * @param {string[]} args 12 | * @param {string} [arg] 13 | * @returns {string} 14 | */ 15 | function getExtsFromArgs(args, arg) { 16 | if (arg) { 17 | const parsedArgs = minimist(args); 18 | return undot(unquote(parsedArgs[arg])); 19 | } else { 20 | // If no argument is specified, assume that the pattern is the last section 21 | const pattern = unquote(args.pop()); 22 | return unbracket(pattern.split('.').pop()); 23 | } 24 | } 25 | 26 | /** 27 | * 28 | * @param {string} command 29 | * @param {string} [arg] 30 | * @returns {string[]|undefined} 31 | */ 32 | function getExtsFromCommand(command, arg) { 33 | if (!command) { 34 | return undefined; 35 | } 36 | 37 | const args = command.split(' '); 38 | const exts = getExtsFromArgs(args, arg); 39 | return exts ? exts.split(',') : undefined; 40 | } 41 | 42 | module.exports = { 43 | getExtsFromCommand, 44 | }; 45 | -------------------------------------------------------------------------------- /packages/mrm-core/src/error.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | class MrmError extends Error { 4 | /** 5 | * @param {string} message 6 | * @param {any} [extra] 7 | */ 8 | constructor(message, extra) { 9 | super(message); 10 | Error.captureStackTrace(this, this.constructor); 11 | Object.defineProperty(this, 'name', { 12 | value: this.constructor.name, 13 | }); 14 | Object.defineProperty(this, 'extra', { 15 | value: extra, 16 | }); 17 | } 18 | } 19 | 20 | module.exports = MrmError; 21 | -------------------------------------------------------------------------------- /packages/mrm-core/src/files/__tests__/__snapshots__/packageJson.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`packageJson() should create package.json file 1`] = ` 4 | Object { 5 | "/package.json": "{}", 6 | } 7 | `; 8 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/__tests__/__snapshots__/file.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`save() should create a folder 1`] = ` 4 | Object { 5 | "/pizza/test.txt": "coffee", 6 | } 7 | `; 8 | 9 | exports[`save() should create file 1`] = ` 10 | Object { 11 | "/test.txt": "coffee", 12 | } 13 | `; 14 | 15 | exports[`save() should keep a new line at the end of the file 1`] = ` 16 | Object { 17 | "/test.txt": "coffee 18 | ", 19 | } 20 | `; 21 | 22 | exports[`save() should not add a new line at the end of the file 1`] = ` 23 | Object { 24 | "/test.txt": "coffee", 25 | } 26 | `; 27 | 28 | exports[`save() should update file 1`] = ` 29 | Object { 30 | "/test.txt": "coffee", 31 | } 32 | `; 33 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/__tests__/__snapshots__/ini.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`save() should change prettify format to remove spaces around = 1`] = ` 4 | Object { 5 | "/test.ini": " 6 | [foo] 7 | bar=xxx 8 | ", 9 | } 10 | `; 11 | 12 | exports[`save() should create file 1`] = ` 13 | Object { 14 | "/test.ini": " 15 | [foo] 16 | bar = xxx 17 | ", 18 | } 19 | `; 20 | 21 | exports[`save() should create file with a comment 1`] = ` 22 | Object { 23 | "/test.ini": "# comment 24 | 25 | [foo] 26 | bar = xxx 27 | ", 28 | } 29 | `; 30 | 31 | exports[`save() should not add spaces to file if they did not exist before 1`] = ` 32 | Object { 33 | "/test.ini": " 34 | [foo] 35 | bar=42 36 | ", 37 | } 38 | `; 39 | 40 | exports[`save() should not add spaces to file if they did not exist before, ignore comments 1`] = ` 41 | Object { 42 | "/test.ini": " 43 | [foo] 44 | bar=42 45 | ", 46 | } 47 | `; 48 | 49 | exports[`save() should update file 1`] = ` 50 | Object { 51 | "/test.ini": " 52 | [foo] 53 | bar = xxx 54 | ", 55 | } 56 | `; 57 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/__tests__/__snapshots__/json.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`save() should create file 1`] = ` 4 | Object { 5 | "/test.json": "{ 6 | \\"foo\\": 1 7 | }", 8 | } 9 | `; 10 | 11 | exports[`save() should keep comments 1`] = ` 12 | "{ 13 | // pizza 14 | \\"bar\\": 43 15 | /* pasta */ 16 | }" 17 | `; 18 | 19 | exports[`save() should keep indentation 1`] = ` 20 | "{ 21 | \\"bar\\": 42, 22 | \\"baz\\": { 23 | \\"foo\\": 43 24 | }, 25 | \\"foo\\": 1 26 | }" 27 | `; 28 | 29 | exports[`save() should update file 1`] = ` 30 | Object { 31 | "/test.json": "{ 32 | \\"bar\\": 42, 33 | \\"baz\\": { 34 | \\"foo\\": 43 35 | }, 36 | \\"foo\\": 1 37 | }", 38 | } 39 | `; 40 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/__tests__/__snapshots__/lines.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`save() should save file with empty lines 1`] = ` 4 | "one 5 | 6 | 7 | two 8 | foo 9 | bar 10 | " 11 | `; 12 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/__tests__/__snapshots__/markdown.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`save() should update file 1`] = ` 4 | Object { 5 | "/test.md": " 6 | # Foo 7 | 8 | [![Example](http://example.com/badge.svg)](http://example.com/) 9 | 10 | Hello. 11 | ", 12 | } 13 | `; 14 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/__tests__/__snapshots__/template.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`save() should create file 1`] = ` 4 | Object { 5 | "/text.txt": "Hello, Bar!", 6 | "/tmpl.txt": "Hello, \${foo}!", 7 | } 8 | `; 9 | 10 | exports[`save() should update file 1`] = ` 11 | Object { 12 | "/text.txt": "Hello, Bar!", 13 | "/tmpl.txt": "Hello, \${foo}!", 14 | } 15 | `; 16 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/__tests__/__snapshots__/yaml.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`save() save() should create file 1`] = ` 4 | Object { 5 | "/test.yml": "foo: 1 6 | ", 7 | } 8 | `; 9 | 10 | exports[`save() save() should update file 1`] = ` 11 | Object { 12 | "/test.yml": "bar: 42 13 | baz: 14 | foo: 43 15 | foo: 1 16 | ", 17 | } 18 | `; 19 | 20 | exports[`yaml() can specify YAML version 1`] = ` 21 | Object { 22 | "/test.yml": "bool: true 23 | string: \\"yes\\"", 24 | } 25 | `; 26 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/file.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const { readFile, updateFile, deleteFiles } = require('../fs'); 3 | const editorconfig = require('../editorconfig'); 4 | 5 | /** 6 | * Base file reader / writer 7 | * @param {string} filename 8 | */ 9 | module.exports = function(filename) { 10 | let exists = true; 11 | let originalContent = ''; 12 | try { 13 | originalContent = readFile(filename); 14 | } catch (err) { 15 | if (err.code === 'ENOENT') { 16 | exists = false; 17 | } else { 18 | throw err; 19 | } 20 | } 21 | 22 | return { 23 | /** Return true if a file exists */ 24 | exists() { 25 | return exists; 26 | }, 27 | 28 | /** Return file content */ 29 | get() { 30 | return originalContent; 31 | }, 32 | 33 | /** Return EditorCofig style for a file */ 34 | getStyle() { 35 | if (originalContent) { 36 | return editorconfig.inferStyle(originalContent); 37 | } 38 | 39 | return editorconfig.getStyleForFile(filename); 40 | }, 41 | 42 | /** Return indentation string for a file */ 43 | getIndent() { 44 | return editorconfig.getIndent(this.getStyle()); 45 | }, 46 | 47 | /** 48 | * Save file 49 | * @param {string} content 50 | */ 51 | save(content) { 52 | if (content.trim() !== originalContent.trim()) { 53 | content = editorconfig.format(content, this.getStyle()); 54 | updateFile(filename, content, exists); 55 | } 56 | 57 | return this; 58 | }, 59 | 60 | /** Delete file */ 61 | delete() { 62 | deleteFiles(filename); 63 | }, 64 | }; 65 | }; 66 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/ini.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const propIni = require('prop-ini'); 3 | const base = require('./file'); 4 | 5 | /** 6 | * Adds (or removes) spaces before and after `=`. 7 | * 8 | * @param {string} content 9 | * @param {boolean} withSpaces 10 | * @returns {string} 11 | */ 12 | function prettify(content, withSpaces = true) { 13 | const replaceValue = withSpaces ? ' = ' : '='; 14 | return `${content}\n`.replace(/\s*=\s*/g, replaceValue); 15 | } 16 | 17 | const detectSpacesRegex = /^\w+(\s*=\s*)/gm; 18 | 19 | /** 20 | * Detect withSpaces parameter for prettify. 21 | * Uses first line of file to see if it has spaces around = or not. 22 | * 23 | * @param {string} content 24 | * @returns {boolean} 25 | */ 26 | function detectWithSpaces(content) { 27 | const matchResult = detectSpacesRegex.exec(content); 28 | return !(matchResult && matchResult[1] === '='); 29 | } 30 | 31 | /** 32 | * @param {string} filename 33 | * @param {string} [comment] 34 | */ 35 | module.exports = function(filename, comment) { 36 | const file = base(filename); 37 | 38 | const ini = propIni.createInstance({}); 39 | ini.decode({ 40 | data: file.get(), 41 | }); 42 | 43 | const originalWithSpaces = detectWithSpaces(file.get()); 44 | 45 | return { 46 | /** Return true if a file exists */ 47 | exists() { 48 | return file.exists(); 49 | }, 50 | 51 | /** 52 | * Get a value of a given section 53 | * @param {string} section 54 | */ 55 | get(section) { 56 | if (!section) { 57 | return ini.getSections(); 58 | } 59 | 60 | return ini.getData(section); 61 | }, 62 | 63 | /** 64 | * Set a value of a given section 65 | * @param {string} section 66 | * @param {any} value 67 | */ 68 | set(section, value) { 69 | ini.addData(value, section); 70 | return this; 71 | }, 72 | 73 | /** 74 | * Remove a given section 75 | * @param {string} section 76 | */ 77 | unset(section) { 78 | ini.removeData(section); 79 | return this; 80 | }, 81 | 82 | /** 83 | * Save file 84 | * @param {{withSpaces: boolean}} options 85 | */ 86 | save({ withSpaces } = { withSpaces: originalWithSpaces }) { 87 | const encoded = prettify(ini.encode(), withSpaces); 88 | const content = comment ? `# ${comment}\n${encoded}` : encoded; 89 | file.save(content); 90 | return this; 91 | }, 92 | 93 | /** Delete file */ 94 | delete() { 95 | return file.delete(); 96 | }, 97 | }; 98 | }; 99 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/json.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const _ = require('lodash'); 3 | const commentsJson = require('comment-json'); 4 | const merge = require('../util/merge'); 5 | const base = require('./file'); 6 | 7 | /** 8 | * @param {string} filename 9 | * @param {{}} [defaultValues] 10 | */ 11 | module.exports = function(filename, defaultValues) { 12 | const file = base(filename); 13 | let json = file.get() ? commentsJson.parse(file.get()) : defaultValues || {}; 14 | 15 | return { 16 | /** Return true if a file exists */ 17 | exists() { 18 | return file.exists(); 19 | }, 20 | 21 | /** 22 | * Get a value at a given address 23 | * @param {string | string[]} address 24 | * @param {{}} [defaultValue] 25 | */ 26 | get(address, defaultValue) { 27 | if (!address) { 28 | return json; 29 | } 30 | 31 | return _.get(json, address, defaultValue); 32 | }, 33 | 34 | /** 35 | * Set a value at a given address 36 | * @param {string | string[]} address 37 | * @param {any} value 38 | */ 39 | set(address, value) { 40 | if (value === undefined) { 41 | json = address; 42 | } else { 43 | _.set(json, address, value); 44 | } 45 | return this; 46 | }, 47 | 48 | /** 49 | * Remove a section with a given address 50 | * @param {string | string[]} address 51 | */ 52 | unset(address) { 53 | _.unset(json, address); 54 | return this; 55 | }, 56 | 57 | /** 58 | * Merge a given value with the current value 59 | * @param {any} value 60 | */ 61 | merge(value) { 62 | json = merge(json, value); 63 | return this; 64 | }, 65 | 66 | /** Save file */ 67 | save() { 68 | const content = commentsJson.stringify(json, null, file.getIndent()); 69 | file.save(content); 70 | return this; 71 | }, 72 | 73 | /** Delete file */ 74 | delete() { 75 | return file.delete(); 76 | }, 77 | }; 78 | }; 79 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/lines.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const _ = require('lodash'); 3 | const splitLines = require('split-lines'); 4 | const base = require('./file'); 5 | 6 | /** 7 | * @param {string} filename 8 | * @param {string[]} [defaultValue] 9 | */ 10 | module.exports = function(filename, defaultValue) { 11 | const file = base(filename); 12 | 13 | /** @type string[] */ 14 | let lines = file.get() ? splitLines(file.get().trim()) : defaultValue || []; 15 | 16 | return { 17 | /** Return true if a file exists */ 18 | exists() { 19 | return file.exists(); 20 | }, 21 | 22 | /** Return all values */ 23 | get() { 24 | return lines; 25 | }, 26 | 27 | /** 28 | * Replace all with given values 29 | * @param {string[]} [values] 30 | */ 31 | set(values) { 32 | lines = values; 33 | return this; 34 | }, 35 | 36 | /** 37 | * Add given values 38 | * @param {string[]} [values] 39 | */ 40 | add(values) { 41 | values = _.castArray(values); 42 | const newValues = values.filter(value => lines.indexOf(value) === -1); 43 | lines = lines.concat(newValues); 44 | return this; 45 | }, 46 | 47 | /** 48 | * Remove given values 49 | * @param {string[]} [values] 50 | */ 51 | remove(values) { 52 | values = _.castArray(values); 53 | lines = lines.filter(value => values.indexOf(value.trim()) === -1); 54 | return this; 55 | }, 56 | 57 | /** Save file */ 58 | save() { 59 | const content = lines.join('\n'); 60 | file.save(content); 61 | return this; 62 | }, 63 | 64 | /** Delete file */ 65 | delete() { 66 | return file.delete(); 67 | }, 68 | }; 69 | }; 70 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/markdown.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const addBadge = require('readme-badger').addBadge; 3 | const MrmError = require('../error'); 4 | const base = require('./file'); 5 | 6 | // [![altText](imageUrl)](linkUrl) 7 | const BADGE_REGEXP = /\s?\[!\[([^\]]*)\]\(([^)]+)\)\]\(([^)]+)\)/g; 8 | 9 | /** 10 | * @param {string} filename 11 | */ 12 | module.exports = function(filename) { 13 | const file = base(filename); 14 | 15 | let content = file.get(); 16 | 17 | return { 18 | /** Return true if a file exists */ 19 | exists() { 20 | return file.exists(); 21 | }, 22 | 23 | /** Get file content */ 24 | get() { 25 | return content; 26 | }, 27 | 28 | /** 29 | * Add a badge 30 | * @param {string} imageUrl 31 | * @param {string} linkUrl 32 | * @param {string} altText 33 | */ 34 | addBadge(imageUrl, linkUrl, altText) { 35 | if (!file.exists()) { 36 | throw new MrmError(`Can’t add badge: file “${filename}” not found.`); 37 | } 38 | 39 | if (content.includes(linkUrl)) { 40 | return this; 41 | } 42 | 43 | content = addBadge(content, 'md', imageUrl, linkUrl, altText); 44 | return this; 45 | }, 46 | 47 | /** 48 | * Remove a badge 49 | * @param {predicate} Function 50 | */ 51 | removeBadge(predicate) { 52 | content = content.replace( 53 | BADGE_REGEXP, 54 | (match, altText, imageUrl, linkUrl) => 55 | predicate({ altText, imageUrl, linkUrl }) ? '' : match 56 | ); 57 | return this; 58 | }, 59 | 60 | /** Save file */ 61 | save() { 62 | file.save(content); 63 | return this; 64 | }, 65 | 66 | /** Delete file */ 67 | delete() { 68 | return file.delete(); 69 | }, 70 | }; 71 | }; 72 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/template.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const { templateFromFile } = require('smpltmpl'); 3 | const base = require('./file'); 4 | 5 | /** 6 | * @param {string} filename 7 | * @param {string} templateFile 8 | */ 9 | module.exports = function(filename, templateFile) { 10 | const file = base(filename); 11 | 12 | let content = file.get(); 13 | let applied = false; 14 | 15 | return { 16 | /** Return true if a file exists */ 17 | exists() { 18 | return file.exists(); 19 | }, 20 | 21 | /** Get file content */ 22 | get() { 23 | return content; 24 | }, 25 | 26 | /** 27 | * Expand a template with given objects as a context 28 | * @param {...any} contexts 29 | */ 30 | apply(...contexts) { 31 | applied = true; 32 | const context = Object.assign({}, ...contexts); 33 | content = templateFromFile(templateFile, context); 34 | return this; 35 | }, 36 | 37 | /** Save file */ 38 | save() { 39 | if (!applied) { 40 | throw Error( 41 | `Attempt to save the template "${filename}" without expanding: it doesn’t make sense. Call apply() before save().` 42 | ); 43 | } 44 | 45 | file.save(content); 46 | return this; 47 | }, 48 | 49 | /** Delete file */ 50 | delete() { 51 | return file.delete(); 52 | }, 53 | }; 54 | }; 55 | -------------------------------------------------------------------------------- /packages/mrm-core/src/formats/yaml.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const _ = require('lodash'); 3 | const yaml = require('yaml'); 4 | const merge = require('../util/merge'); 5 | const base = require('./file'); 6 | 7 | const YAML_READ_OPTIONS = { 8 | prettyErrors: true, 9 | }; 10 | const DEFAULT_INDENT = 2; 11 | 12 | /** 13 | * @param {string} filename 14 | * @param {{}} [defaultValues] 15 | * @param {{}} [options] 16 | */ 17 | module.exports = function(filename, defaultValues, options) { 18 | const yamlOptions = _.pick(options, ['version']); 19 | const file = base(filename); 20 | 21 | const yamlReadOptions = _.defaults(yamlOptions, YAML_READ_OPTIONS); 22 | let json = yaml.parse(file.get(), yamlReadOptions) || defaultValues || {}; 23 | 24 | return { 25 | /** Return true if a file exists */ 26 | exists() { 27 | return file.exists(); 28 | }, 29 | 30 | /** 31 | * Get a value at a given address 32 | * @param {string | string[]} address 33 | * @param {{}} [defaultValue] 34 | */ 35 | get(address, defaultValue) { 36 | if (!address) { 37 | return json; 38 | } 39 | 40 | return _.get(json, address, defaultValue); 41 | }, 42 | 43 | /** 44 | * Set a value at a given address 45 | * @param {string | string[]} address 46 | * @param {any} value 47 | */ 48 | set(address, value) { 49 | if (value === undefined) { 50 | json = address; 51 | } else { 52 | _.set(json, address, value); 53 | } 54 | return this; 55 | }, 56 | 57 | /** 58 | * Remove a section with a given address 59 | * @param {string | string[]} address 60 | */ 61 | unset(address) { 62 | _.unset(json, address); 63 | return this; 64 | }, 65 | 66 | /** 67 | * Merge a given value with the current value 68 | * @param {any} value 69 | */ 70 | merge(value) { 71 | json = merge(json, value); 72 | return this; 73 | }, 74 | 75 | /** Save file */ 76 | save() { 77 | const yamlWriteOptions = _.defaults(yamlOptions, { 78 | indent: file.getStyle().indent_size || DEFAULT_INDENT, 79 | }); 80 | const content = yaml.stringify(json, yamlWriteOptions); 81 | file.save(content); 82 | return this; 83 | }, 84 | 85 | /** Delete file */ 86 | delete() { 87 | return file.delete(); 88 | }, 89 | }; 90 | }; 91 | -------------------------------------------------------------------------------- /packages/mrm-core/src/fs.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const path = require('path'); 3 | const fs = require('fs-extra'); 4 | const stripBom = require('strip-bom'); 5 | const _ = require('lodash'); 6 | const log = require('./util/log'); 7 | const MrmError = require('./error'); 8 | 9 | /** 10 | * @param {string} file 11 | */ 12 | const read = file => (fs.existsSync(file) ? readFile(file).trim() : ''); 13 | 14 | /** 15 | * Read a text file as UTF-8 16 | * @param {string} filename 17 | */ 18 | function readFile(filename) { 19 | return stripBom(fs.readFileSync(filename, 'utf8')); 20 | } 21 | 22 | /** 23 | * Write a file if the content was changed and print a message. 24 | * @param {string} filename 25 | * @param {string} content 26 | * @param {boolean} exists 27 | */ 28 | function updateFile(filename, content, exists) { 29 | fs.ensureDirSync(path.dirname(filename)); 30 | fs.writeFileSync(filename, content); 31 | log.added(`${exists ? 'Update' : 'Create'} ${filename}`); 32 | } 33 | 34 | /** 35 | * Copy files from a given directory to the current working directory 36 | * @param {string} sourceDir 37 | * @param {string|string[]} files 38 | */ 39 | function copyFiles(sourceDir, files, options = {}) { 40 | const { overwrite = true, errorOnExist } = options; 41 | 42 | _.castArray(files).forEach(file => { 43 | const sourcePath = path.resolve(sourceDir, file); 44 | if (!fs.existsSync(sourcePath)) { 45 | throw new MrmError(`copyFiles: source file not found: ${sourcePath}`); 46 | } 47 | 48 | const targetExist = fs.existsSync(file); 49 | if (targetExist && !overwrite) { 50 | if (errorOnExist) { 51 | throw new MrmError(`copyFiles: target file already exists: ${file}`); 52 | } 53 | return; 54 | } 55 | 56 | const content = read(sourcePath); 57 | 58 | // Skip copy if file contents are the same 59 | if (content === read(file)) { 60 | return; 61 | } 62 | 63 | updateFile(file, content, targetExist); 64 | }); 65 | } 66 | 67 | /** 68 | * Delete files or folders 69 | * @param {string|string[]} files 70 | */ 71 | function deleteFiles(files) { 72 | _.castArray(files).forEach(file => { 73 | if (!fs.existsSync(file)) { 74 | return; 75 | } 76 | 77 | log.removed(`Delete ${file}`); 78 | fs.removeSync(file); 79 | }); 80 | } 81 | 82 | /** 83 | * Create directories if they don’t exist 84 | * @param {string|string[]} dirs 85 | */ 86 | function makeDirs(dirs) { 87 | _.castArray(dirs).forEach(dir => { 88 | if (fs.existsSync(dir)) { 89 | return; 90 | } 91 | 92 | log.added(`Create folder ${dir}`); 93 | fs.ensureDirSync(dir); 94 | }); 95 | } 96 | 97 | module.exports = { 98 | readFile, 99 | updateFile, 100 | copyFiles, 101 | deleteFiles, 102 | makeDirs, 103 | }; 104 | -------------------------------------------------------------------------------- /packages/mrm-core/src/index.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const fs = require('./fs'); 3 | const npm = require('./npm'); 4 | const editorconfig = require('./editorconfig'); 5 | const commands = require('./commands'); 6 | const MrmError = require('./error'); 7 | const file = require('./formats/file'); 8 | const ini = require('./formats/ini'); 9 | const json = require('./formats/json'); 10 | const lines = require('./formats/lines'); 11 | const markdown = require('./formats/markdown'); 12 | const template = require('./formats/template'); 13 | const yaml = require('./formats/yaml'); 14 | const packageJson = require('./files/packageJson'); 15 | 16 | module.exports = { 17 | readFile: fs.readFile, 18 | updateFile: fs.updateFile, 19 | copyFiles: fs.copyFiles, 20 | deleteFiles: fs.deleteFiles, 21 | makeDirs: fs.makeDirs, 22 | init: npm.init, 23 | install: npm.install, 24 | uninstall: npm.uninstall, 25 | inferStyle: editorconfig.inferStyle, 26 | getStyleForFile: editorconfig.getStyleForFile, 27 | getIndent: editorconfig.getIndent, 28 | format: editorconfig.format, 29 | getExtsFromCommand: commands.getExtsFromCommand, 30 | MrmError, 31 | file, 32 | ini, 33 | json, 34 | lines, 35 | markdown, 36 | template, 37 | yaml, 38 | packageJson, 39 | }; 40 | -------------------------------------------------------------------------------- /packages/mrm-core/src/util/__tests__/escapeArguments.js: -------------------------------------------------------------------------------- 1 | const escapeArguments = require('../escapeArguments'); 2 | 3 | it('escapeArguments should escape the ^', () => { 4 | const result = escapeArguments(['install', '--save-dev', 'eslint@^6.0.0']); 5 | 6 | expect(result).toEqual([ 7 | 'install', 8 | '--save-dev', 9 | // Since the result depend on the platform 10 | // we need to allow both output 11 | expect.stringMatching(/eslint@(\^{1}|\^{4})6.0.0/), 12 | ]); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/mrm-core/src/util/__tests__/execCommand.spec.js: -------------------------------------------------------------------------------- 1 | const { execFileSync } = require('child_process'); 2 | 3 | const execCommand = require('../execCommand'); 4 | 5 | it('execCommand should run spawnSync by default with arguments', () => { 6 | const result = execCommand(undefined, 'npm', ['--version']); 7 | expect(result.status).toBe(0); 8 | expect(result.stdout.toString()).toMatch(/[0-9]+\.[0-9]+.[0-9]+\n/); 9 | }); 10 | 11 | it('execCommand should run custom exec with arguments', () => { 12 | const result = execCommand(execFileSync, 'npm', ['--version']); 13 | expect(result.toString()).toMatch(/[0-9]+\.[0-9]+.[0-9]+\n/); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/mrm-core/src/util/__tests__/log.spec.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | const _log = require('../log'); 4 | const info = _log.info; 5 | const added = _log.added; 6 | const removed = _log.removed; 7 | 8 | const console$log = console.log; 9 | 10 | beforeEach(() => { 11 | console.log = jest.fn(); 12 | }); 13 | 14 | afterEach(() => { 15 | console.log = console$log; 16 | }); 17 | 18 | describe('info()', () => { 19 | it('should print a regular message', () => { 20 | info('pizza'); 21 | expect(console.log).toBeCalledWith('pizza'); 22 | }); 23 | }); 24 | 25 | describe('added()', () => { 26 | it('should print a message', () => { 27 | added('coffee'); 28 | expect(console.log).toBeCalledWith(expect.stringMatching('coffee')); 29 | }); 30 | }); 31 | 32 | describe('remove()', () => { 33 | it('should print a message', () => { 34 | removed('shawarma'); 35 | expect(console.log).toBeCalledWith(expect.stringMatching('shawarma')); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/mrm-core/src/util/__tests__/merge.spec.js: -------------------------------------------------------------------------------- 1 | const merge = require('../merge'); 2 | 3 | it('merge() should merge arrays without duplicates', () => { 4 | const result = merge({ _: ['a', 'b'] }, { _: ['a', 'c'] }); 5 | expect(result).toEqual({ _: ['a', 'b', 'c'] }); 6 | }); 7 | 8 | it('merge() should merge arrays of objects without duplicates', () => { 9 | const result = merge( 10 | { _: [{ a: 1 }, { b: 2 }] }, 11 | { _: [{ a: 1 }, { c: 3 }] } 12 | ); 13 | expect(result).toEqual({ _: [{ a: 1 }, { b: 2 }, { c: 3 }] }); 14 | }); 15 | 16 | it('merge() should not remove existing array items', () => { 17 | const result = merge({ _: ['a', 'a', 'b'] }, { _: ['a'] }); 18 | expect(result).toEqual({ _: ['a', 'a', 'b'] }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/mrm-core/src/util/escapeArguments.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const isWindows = require('./isWindows'); 3 | 4 | /** 5 | * Escape the circumflex character when we are on Windows 6 | * since Batch will interpret it. 7 | * 8 | * @param {string[]} strings 9 | */ 10 | function escapeArguments(strings) { 11 | return isWindows() ? strings.map(arg => arg.replace(/\^/g, '^^^^')) : strings; 12 | } 13 | 14 | module.exports = escapeArguments; 15 | -------------------------------------------------------------------------------- /packages/mrm-core/src/util/execCommand.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const { spawnSync } = require('child_process'); 3 | const escapeArguments = require('./escapeArguments'); 4 | 5 | /** 6 | * Execute a given command while being compatible with Windows. 7 | * 8 | * @param {Function} exec 9 | * @param {string} command 10 | * @param {...any} args 11 | */ 12 | function execCommand(exec, command, ...args) { 13 | exec = exec || spawnSync; 14 | args[0] = escapeArguments(args[0]); 15 | 16 | return exec(command, ...args); 17 | } 18 | 19 | module.exports = execCommand; 20 | -------------------------------------------------------------------------------- /packages/mrm-core/src/util/isWindows.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const os = require('os'); 3 | 4 | /** 5 | * Return true when we are in a win32 environment 6 | */ 7 | function isWindows() { 8 | return os.platform() === 'win32'; 9 | } 10 | 11 | module.exports = isWindows; 12 | -------------------------------------------------------------------------------- /packages/mrm-core/src/util/log.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | /* eslint-disable no-console */ 3 | 4 | const kleur = require('kleur'); 5 | 6 | /** 7 | * @param {string} message 8 | */ 9 | function info(message) { 10 | console.log(message); 11 | } 12 | 13 | /** 14 | * @param {string} message 15 | */ 16 | function added(message) { 17 | console.log(kleur.green(message)); 18 | } 19 | 20 | /** 21 | * @param {string} message 22 | */ 23 | function removed(message) { 24 | console.log(kleur.yellow(message)); 25 | } 26 | 27 | module.exports = { 28 | info, 29 | added, 30 | removed, 31 | }; 32 | -------------------------------------------------------------------------------- /packages/mrm-core/src/util/merge.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const mergeBase = require('webpack-merge'); 3 | const _ = require('lodash'); 4 | 5 | /** 6 | * Deep merge that merge arrays without duplicates 7 | */ 8 | const merge = mergeBase({ 9 | customizeArray: (/** @type any[] */ a, /** @type any[] */ b) => 10 | a.concat(_.differenceWith(b, a, _.isEqual)), 11 | }); 12 | 13 | module.exports = merge; 14 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # [DEPRECATED] mrm-preset-default 4 | 5 | **This preset is deprecated and no longer needed. Mrm installs tasks automatically.** 6 | 7 | Default tasks for [Mrm](https://github.com/sapegin/mrm). You don’t have to install this module, these tasks are included by default. 8 | 9 | See [Mrm docs](https://mrm.js.org/docs/getting-started) for more details. 10 | 11 | ## Tasks 12 | 13 | 14 | 15 | - [ci](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-ci) 16 | - [codecov](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-codecov) 17 | - [contributing](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-contributing) 18 | - [dependabot](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-dependabot) 19 | - [editorconfig](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-editorconfig) 20 | - [eslint](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-eslint) 21 | - [gitignore](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-gitignore) 22 | - [jest](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-jest) 23 | - [license](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-license) 24 | - [lint-staged](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-lint-staged) 25 | - [package](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-package) 26 | - [prettier](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-prettier) 27 | - [readme](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-readme) 28 | - [semantic-release](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-semantic-release) 29 | - [styleguidist](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-styleguidist) 30 | - [stylelint](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-stylelint) 31 | - [travis](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-travis) 32 | - [typescript](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-typescript) 33 | 34 | 35 | 36 | ## Changelog 37 | 38 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 39 | 40 | ## Contributing 41 | 42 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 43 | 44 | ## Authors and license 45 | 46 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 47 | 48 | MIT License, see the included [License.md](License.md) file. 49 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/ci/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-ci'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/codecov/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-codecov'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/config.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/contributing/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-contributing'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/dependabot/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-dependabot'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/editorconfig/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-editorconfig'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/eslint/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-eslint'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/gitignore/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-gitignore'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/jest/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-jest'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/license/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-license'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/lint-staged/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-lint-staged'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-preset-default", 3 | "version": "4.1.23", 4 | "private": true, 5 | "description": "Common tasks for Mrm", 6 | "author": { 7 | "name": "Artem Sapegin", 8 | "url": "https://sapegin.me" 9 | }, 10 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-preset-default", 11 | "repository": "sapegin/mrm", 12 | "license": "MIT", 13 | "engines": { 14 | "node": ">=10.13" 15 | }, 16 | "main": "config.json", 17 | "files": [ 18 | "config.json", 19 | "*/index.js" 20 | ], 21 | "scripts": {}, 22 | "keywords": [ 23 | "mrm", 24 | "mrm-task", 25 | "mrm-preset" 26 | ], 27 | "dependencies": { 28 | "mrm-core": "^7.1.23", 29 | "mrm-task-ci": "^2.1.23", 30 | "mrm-task-codecov": "^5.1.23", 31 | "mrm-task-contributing": "^4.1.23", 32 | "mrm-task-dependabot": "^3.1.23", 33 | "mrm-task-editorconfig": "^4.1.23", 34 | "mrm-task-eslint": "^4.1.23", 35 | "mrm-task-gitignore": "^4.1.23", 36 | "mrm-task-jest": "^4.1.23", 37 | "mrm-task-license": "^5.1.23", 38 | "mrm-task-lint-staged": "^7.1.23", 39 | "mrm-task-package": "^4.1.23", 40 | "mrm-task-prettier": "^5.1.23", 41 | "mrm-task-readme": "^4.1.23", 42 | "mrm-task-semantic-release": "^6.1.23", 43 | "mrm-task-styleguidist": "^4.1.23", 44 | "mrm-task-stylelint": "^5.1.23", 45 | "mrm-task-travis": "^4.1.23", 46 | "mrm-task-typescript": "^4.1.23" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/package/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-package'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/prettier/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-prettier'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/readme/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-readme'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/semantic-release/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-semantic-release'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/styleguidist/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-styleguidist'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/stylelint/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-stylelint'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/travis/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-travis'); 2 | -------------------------------------------------------------------------------- /packages/mrm-preset-default/typescript/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('mrm-task-typescript'); 2 | -------------------------------------------------------------------------------- /packages/mrm-task-ci/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2020 Artem Sapegin (https://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-ci/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-ci 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds GitHub Action workflow that runs Node.js tests. 6 | 7 | ## What it does 8 | 9 | - Creates GitHub Action workflow file 10 | - Sets up tests for currently supported [Node.js LTS versions](https://nodejs.org/en/about/releases/) 11 | - Adds a status badge to the Readme 12 | - Removes Travis CI badge from the Readme 13 | - Removes Travis CI config if it only runs Node.js tests without custom scripts 14 | 15 | ## Usage 16 | 17 | ``` 18 | npx mrm ci 19 | ``` 20 | 21 | ## Options 22 | 23 | See [Mrm docs](../../docs/Getting_started.md) for more details. 24 | 25 | ### `workflowFile` (default: `.github/workflows/node.js.yml`) 26 | 27 | Location of the GitHub Actions workflow file. 28 | 29 | ### `readmeFile` (default: `Readme.md`) 30 | 31 | Name of the Readme file. 32 | 33 | ## Changelog 34 | 35 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 36 | 37 | ## Contributing 38 | 39 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 40 | 41 | ## Authors and license 42 | 43 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 44 | 45 | MIT License, see the included [License.md](License.md) file. 46 | -------------------------------------------------------------------------------- /packages/mrm-task-ci/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add GitHub Action workflow 1`] = ` 4 | "name: Node.js CI 5 | on: 6 | push: 7 | branches: 8 | - master 9 | pull_request: 10 | branches: 11 | - master 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | strategy: 16 | matrix: 17 | node-version: 18 | - 4.x 19 | - 6.x 20 | - 8.x 21 | - 10.x 22 | - 12.x 23 | - 14.x 24 | steps: 25 | - uses: actions/checkout@v2 26 | - name: Use Node.js \${{ matrix.node-version }} 27 | uses: actions/setup-node@v2 28 | with: 29 | node-version: \${{ matrix.node-version }} 30 | - run: npm ci 31 | - run: npm run build --if-present 32 | - run: npm test 33 | " 34 | `; 35 | 36 | exports[`should add a badge to the Readme 1`] = ` 37 | "# Unicorn 38 | 39 | [![Node.js CI status](https://github.com/mrm/unicorn/workflows/Node.js%20CI/badge.svg)](https://github.com/mrm/unicorn/actions)" 40 | `; 41 | 42 | exports[`should add latest Node version if engines field is not defined 1`] = ` 43 | "name: Node.js CI 44 | on: 45 | push: 46 | branches: 47 | - master 48 | pull_request: 49 | branches: 50 | - master 51 | jobs: 52 | build: 53 | runs-on: ubuntu-latest 54 | strategy: 55 | matrix: 56 | node-version: 57 | - 14.x 58 | steps: 59 | - uses: actions/checkout@v2 60 | - name: Use Node.js \${{ matrix.node-version }} 61 | uses: actions/setup-node@v2 62 | with: 63 | node-version: \${{ matrix.node-version }} 64 | - run: npm ci 65 | - run: npm run build --if-present 66 | - run: npm test 67 | " 68 | `; 69 | 70 | exports[`should remove Travis badge from the Readme 1`] = ` 71 | "# Unicorn 72 | 73 | [![Node.js CI status](https://github.com/mrm/unicorn/workflows/Node.js%20CI/badge.svg)](https://github.com/mrm/unicorn/actions)" 74 | `; 75 | -------------------------------------------------------------------------------- /packages/mrm-task-ci/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-ci", 3 | "version": "2.1.23", 4 | "description": "Mrm task that adds GitHub Actions workflow that runs Node.js tests", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "https://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-ci", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "node", 24 | "node.js", 25 | "ci", 26 | "continious integration", 27 | "test" 28 | ], 29 | "dependencies": { 30 | "git-default-branch": "^1.0.0", 31 | "got": "^11.8.0", 32 | "lodash": "^4.17.20", 33 | "mrm-core": "^7.1.23", 34 | "package-repo-url": "^1.0.3", 35 | "semver-utils": "^1.1.4" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/mrm-task-codecov/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-codecov/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-codecov 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds [Codecov](https://codecov.io/) as a GitHub Actions workflow and a Readme badge. 6 | 7 | ## What it does 8 | 9 | - Creates GitHub Actions workflow file 10 | - Adds a satus badge to the Readme 11 | 12 | ## Usage 13 | 14 | ``` 15 | npx mrm codecov 16 | ``` 17 | 18 | ## Options 19 | 20 | See [Mrm docs](../../docs/Getting_started.md) for more details. 21 | 22 | ### `workflowFile` (default: `.github/workflows/node.js.yml`) 23 | 24 | Location of the GitHub Actions workflow file. 25 | 26 | ### `readmeFile` (default: `Readme.md`) 27 | 28 | Name of the Readme file. 29 | 30 | ## Changelog 31 | 32 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 33 | 34 | ## Contributing 35 | 36 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 37 | 38 | ## Authors and license 39 | 40 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 41 | 42 | MIT License, see the included [License.md](License.md) file. 43 | -------------------------------------------------------------------------------- /packages/mrm-task-codecov/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add CodeCov 1`] = ` 4 | Object { 5 | "/.github/workflows/coverage.yml": "name: Codecov 6 | on: 7 | push: 8 | branches: 9 | - \\"\\" 10 | pull_request: 11 | branches: 12 | - \\"\\" 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v2 18 | - uses: actions/setup-node@v1 19 | - run: npm ci 20 | - run: npm run test:coverage 21 | - uses: codecov/codecov-action@v1 22 | ", 23 | "/Readme.md": "# Unicorn 24 | 25 | [![Codecov](https://codecov.io/gh/mrm/unicorn/graph/badge.svg)](https://codecov.io/gh/mrm/unicorn)", 26 | "/package.json": "{ 27 | \\"name\\": \\"unicorn\\", 28 | \\"scripts\\": { 29 | \\"test:coverage\\": \\"jest --coverage\\" 30 | } 31 | }", 32 | } 33 | `; 34 | -------------------------------------------------------------------------------- /packages/mrm-task-codecov/index.js: -------------------------------------------------------------------------------- 1 | const packageRepoUrl = require('package-repo-url'); 2 | const gitDefaultBranch = require('git-default-branch'); 3 | const { MrmError, yaml, markdown, packageJson } = require('mrm-core'); 4 | 5 | const coverageScript = 'test:coverage'; 6 | 7 | module.exports = function task({ workflowFile, readmeFile }) { 8 | const pkg = packageJson(); 9 | 10 | // Require coverage npm script 11 | if (!pkg.getScript(coverageScript)) { 12 | throw new MrmError( 13 | `${coverageScript} npm script not found. To add Jest run: 14 | 15 | mrm jest` 16 | ); 17 | } 18 | 19 | const defaultBranch = gitDefaultBranch(); 20 | 21 | // Workflow file 22 | yaml(workflowFile) 23 | .set({ 24 | name: 'Codecov', 25 | on: { 26 | push: { branches: [defaultBranch] }, 27 | pull_request: { branches: [defaultBranch] }, 28 | }, 29 | jobs: { 30 | build: { 31 | 'runs-on': 'ubuntu-latest', 32 | steps: [ 33 | { 34 | uses: 'actions/checkout@v2', 35 | }, 36 | { 37 | uses: 'actions/setup-node@v1', 38 | }, 39 | { 40 | run: 'npm ci', 41 | }, 42 | { 43 | run: `npm run ${coverageScript}`, 44 | }, 45 | { 46 | uses: 'codecov/codecov-action@v1', 47 | }, 48 | ], 49 | }, 50 | }, 51 | }) 52 | .save(); 53 | 54 | // Add Codecov badge to Readme 55 | const github = packageRepoUrl().replace('https://github.com/', ''); 56 | const url = `https://codecov.io/gh/${github}`; 57 | const readme = markdown(readmeFile); 58 | if (readme.exists()) { 59 | readme.addBadge(`${url}/graph/badge.svg`, url, 'Codecov').save(); 60 | } 61 | }; 62 | 63 | module.exports.description = 'Adds Codecov'; 64 | module.exports.parameters = { 65 | workflowFile: { 66 | type: 'input', 67 | message: 'Enter location of GitHub Actions workflow file', 68 | default: '.github/workflows/coverage.yml', 69 | }, 70 | readmeFile: { 71 | type: 'input', 72 | message: 'Enter filename for the readme', 73 | default: 'Readme.md', 74 | }, 75 | }; 76 | -------------------------------------------------------------------------------- /packages/mrm-task-codecov/index.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('fs'); 2 | jest.mock('git-username'); 3 | jest.mock('mrm-core/src/util/log', () => ({ 4 | added: jest.fn(), 5 | })); 6 | 7 | const { getTaskOptions } = require('mrm'); 8 | const vol = require('memfs').vol; 9 | const task = require('./index'); 10 | 11 | const stringify = o => JSON.stringify(o, null, ' '); 12 | 13 | const packageJson = stringify({ 14 | name: 'unicorn', 15 | scripts: { 16 | 'test:coverage': 'jest --coverage', 17 | }, 18 | }); 19 | const readmeMd = '# Unicorn'; 20 | 21 | afterEach(() => vol.reset()); 22 | 23 | it('should add CodeCov', async () => { 24 | vol.fromJSON({ 25 | '/package.json': packageJson, 26 | '/Readme.md': readmeMd, 27 | }); 28 | 29 | task(await getTaskOptions(task)); 30 | 31 | expect(vol.toJSON()).toMatchSnapshot(); 32 | }); 33 | 34 | it('should throw when coverage script not found', async () => { 35 | vol.fromJSON({ 36 | '/package.json': stringify({ 37 | name: 'unicorn', 38 | }), 39 | '/Readme.md': readmeMd, 40 | }); 41 | 42 | const options = await getTaskOptions(task); 43 | const fn = () => task(options); 44 | 45 | expect(fn).toThrowError('npm script not found'); 46 | }); 47 | 48 | it('should not throw when readme file not found', async () => { 49 | vol.fromJSON({ 50 | '/package.json': packageJson, 51 | }); 52 | 53 | const options = await getTaskOptions(task); 54 | const fn = () => task(options); 55 | 56 | expect(fn).not.toThrowError(); 57 | }); 58 | -------------------------------------------------------------------------------- /packages/mrm-task-codecov/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-codecov", 3 | "version": "5.1.23", 4 | "description": "Mrm task that adds Codecov to Travis CI config", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "https://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-codecov", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "codecov", 24 | "travis", 25 | "coverage" 26 | ], 27 | "dependencies": { 28 | "git-default-branch": "^1.0.0", 29 | "mrm-core": "^7.1.23", 30 | "package-repo-url": "^1.0.3" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/mrm-task-contributing/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-contributing/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-contributing 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds contributing guidelines. 6 | 7 | ## What it does 8 | 9 | - Creates a contributing guidelines file 10 | 11 | ## Usage 12 | 13 | ``` 14 | npx mrm contributing 15 | ``` 16 | 17 | ## Options 18 | 19 | See [Mrm docs](../../docs/Getting_started.md) for more details. 20 | 21 | ### `github` (default: extracted from `.git/config` file) 22 | 23 | Your GitHub user name. 24 | 25 | ### `contributingFile` (default: `Contributing.md`) 26 | 27 | Name of the contributing guidelines file. 28 | 29 | ### `packageName` (default: `name` field in `package.json`) 30 | 31 | Package name. 32 | 33 | ## Changelog 34 | 35 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 36 | 37 | ## Contributing 38 | 39 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 40 | 41 | ## Authors and license 42 | 43 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 44 | 45 | MIT License, see the included [License.md](License.md) file. 46 | -------------------------------------------------------------------------------- /packages/mrm-task-contributing/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add a Contributing.md file 1`] = ` 4 | Object { 5 | "/Contributing.md": "# How to contribute 6 | 7 | We love pull requests. And following this guidelines will make your pull request easier to merge. 8 | 9 | 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). 10 | 11 | _[Use GitHub interface](https://blog.sapegin.me/all/open-source-for-everyone/) for simple documentation changes, otherwise follow the steps below._ 12 | 13 | ## Prerequisites 14 | 15 | - If it’s your first pull request, watch [this amazing course](http://makeapullrequest.com/) by [Kent C. Dodds](https://twitter.com/kentcdodds). 16 | - Install [EditorConfig](https://editorconfig.org/) plugin for your code editor to make sure it uses correct settings. 17 | - Fork the repository and clone your fork. 18 | - Install dependencies: \`npm install\`. 19 | 20 | ## Development workflow 21 | 22 | Run linters and tests: 23 | 24 | \`\`\`bash 25 | npm test 26 | \`\`\` 27 | 28 | Or run tests in watch mode: 29 | 30 | \`\`\`bash 31 | npm run test:watch 32 | \`\`\` 33 | 34 | **Don’t forget to add tests and update documentation for your changes.** 35 | 36 | **Please update npm lock file (\`package-lock.json\`) if you add or update dependencies.** 37 | 38 | ## Other notes 39 | 40 | - 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. 41 | - We’re using [Prettier](https://github.com/prettier/prettier) to format code, so don’t worry much about code formatting. 42 | - Don’t commit generated files, like minified JavaScript. 43 | - Don’t change version number and changelog. 44 | 45 | ## Need help? 46 | 47 | 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. 48 | ", 49 | "/package.json": "{ 50 | \\"name\\": \\"unicorn\\" 51 | }", 52 | } 53 | `; 54 | -------------------------------------------------------------------------------- /packages/mrm-task-contributing/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const gitUsername = require('git-username'); 3 | const { template, packageJson } = require('mrm-core'); 4 | 5 | module.exports = function task({ contributingFile, github, packageName }) { 6 | // Create Contributing.md (no update) 7 | const contributing = template( 8 | contributingFile, 9 | path.join(__dirname, 'templates/Contributing.md') 10 | ); 11 | if (!contributing.exists()) { 12 | contributing 13 | .apply({ 14 | github, 15 | contributingFile, 16 | packageName, 17 | }) 18 | .save(); 19 | } 20 | }; 21 | 22 | module.exports.description = 'Adds contributing guidelines'; 23 | module.exports.parameters = { 24 | contributingFile: { 25 | type: 'input', 26 | message: 'Enter filename for contributing guidelines', 27 | default: 'Contributing.md', 28 | }, 29 | github: { 30 | type: 'input', 31 | message: 'Enter your GitHub username', 32 | default: gitUsername(), 33 | validate(value) { 34 | return value ? true : 'GitHub username is required'; 35 | }, 36 | }, 37 | packageName: { 38 | type: 'input', 39 | message: 'Enter package name', 40 | default: () => packageJson().get('name'), 41 | validate(value) { 42 | return value ? true : 'Package name is required'; 43 | }, 44 | }, 45 | }; 46 | -------------------------------------------------------------------------------- /packages/mrm-task-contributing/index.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('fs'); 2 | jest.mock('git-username'); 3 | jest.mock('mrm-core/src/util/log', () => ({ 4 | added: jest.fn(), 5 | })); 6 | 7 | const fs = jest.requireActual('fs'); 8 | const path = require('path'); 9 | const { omitBy } = require('lodash'); 10 | const { getTaskOptions } = require('mrm'); 11 | const vol = require('memfs').vol; 12 | const task = require('./index'); 13 | 14 | const stringify = o => JSON.stringify(o, null, ' '); 15 | 16 | afterEach(() => vol.reset()); 17 | 18 | it('should add a Contributing.md file', async () => { 19 | vol.fromJSON({ 20 | [`${__dirname}/templates/Contributing.md`]: fs 21 | .readFileSync(path.join(__dirname, 'templates/Contributing.md')) 22 | .toString(), 23 | '/package.json': stringify({ 24 | name: 'unicorn', 25 | }), 26 | }); 27 | 28 | task( 29 | await getTaskOptions(task, false, { 30 | github: 'gendalf', 31 | }) 32 | ); 33 | 34 | expect( 35 | omitBy(vol.toJSON(), (v, k) => k.startsWith(__dirname)) 36 | ).toMatchSnapshot(); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/mrm-task-contributing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-contributing", 3 | "version": "4.1.23", 4 | "description": "Mrm task that adds contributing guidelines", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-contributing", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js", 18 | "templates" 19 | ], 20 | "scripts": {}, 21 | "keywords": [ 22 | "mrm", 23 | "mrm-task", 24 | "contributing" 25 | ], 26 | "dependencies": { 27 | "git-username": "^1.0.0", 28 | "mrm-core": "^7.1.23" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/mrm-task-contributing/templates/Contributing.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We love pull requests. And following this guidelines will make your pull request easier to merge. 4 | 5 | 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). 6 | 7 | _[Use GitHub interface](https://blog.sapegin.me/all/open-source-for-everyone/) for simple documentation changes, otherwise follow the steps below._ 8 | 9 | ## Prerequisites 10 | 11 | - If it’s your first pull request, watch [this amazing course](http://makeapullrequest.com/) by [Kent C. Dodds](https://twitter.com/kentcdodds). 12 | - Install [EditorConfig](https://editorconfig.org/) plugin for your code editor to make sure it uses correct settings. 13 | - Fork the repository and clone your fork. 14 | - Install dependencies: `npm install`. 15 | 16 | ## Development workflow 17 | 18 | Run linters and tests: 19 | 20 | ```bash 21 | npm test 22 | ``` 23 | 24 | Or run tests in watch mode: 25 | 26 | ```bash 27 | npm run test:watch 28 | ``` 29 | 30 | **Don’t forget to add tests and update documentation for your changes.** 31 | 32 | **Please update npm lock file (`package-lock.json`) if you add or update dependencies.** 33 | 34 | ## Other notes 35 | 36 | - 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. 37 | - We’re using [Prettier](https://github.com/prettier/prettier) to format code, so don’t worry much about code formatting. 38 | - Don’t commit generated files, like minified JavaScript. 39 | - Don’t change version number and changelog. 40 | 41 | ## Need help? 42 | 43 | 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. 44 | -------------------------------------------------------------------------------- /packages/mrm-task-dependabot/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2020 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-dependabot/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # [DEPRECATED] mrm-task-dependabot 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds GitHub Actions workflow to automerge [Dependabot](https://dependabot.com/) pull requests. 6 | 7 | ## What it does 8 | 9 | - Creates a workflow file 10 | 11 | ## Usage 12 | 13 | ``` 14 | npx mrm dependabot 15 | ``` 16 | 17 | ## Options 18 | 19 | See [Mrm docs](../../docs/Getting_started.md) for more details. 20 | 21 | ### `workflowFile` (default: `.github/workflows/dependabot.yml`) 22 | 23 | Location of GitHub Actions workflow file 24 | 25 | ## Changelog 26 | 27 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 28 | 29 | ## Contributing 30 | 31 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 32 | 33 | ## Authors and license 34 | 35 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 36 | 37 | MIT License, see the included [License.md](License.md) file. 38 | -------------------------------------------------------------------------------- /packages/mrm-task-dependabot/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add a workflow file 1`] = ` 4 | Object { 5 | "/.github/workflows/dependabot.yml": "name: Dependabot Automerge 6 | on: pull_request 7 | jobs: 8 | worker: 9 | runs-on: ubuntu-latest 10 | if: github.actor == 'dependabot[bot]' 11 | steps: 12 | - uses: actions/github-script@v3 13 | with: 14 | script: |- 15 | github.pulls.createReview({ 16 | owner: context.payload.repository.owner.login, 17 | repo: context.payload.repository.name, 18 | pull_number: context.payload.pull_request.number, 19 | event: 'APPROVE' 20 | }) 21 | github.pulls.merge({ 22 | owner: context.payload.repository.owner.login, 23 | repo: context.payload.repository.name, 24 | pull_number: context.payload.pull_request.number, 25 | merge_method: 'squash' 26 | }) 27 | ", 28 | } 29 | `; 30 | -------------------------------------------------------------------------------- /packages/mrm-task-dependabot/index.js: -------------------------------------------------------------------------------- 1 | const { yaml } = require('mrm-core'); 2 | 3 | module.exports = function task({ workflowFile }) { 4 | // Create workflow file (no update) 5 | const workflowYml = yaml(workflowFile); 6 | if (!workflowYml.exists()) { 7 | workflowYml 8 | .merge({ 9 | name: 'Dependabot Automerge', 10 | on: 'pull_request', 11 | jobs: { 12 | worker: { 13 | 'runs-on': 'ubuntu-latest', 14 | if: `github.actor == 'dependabot[bot]'`, 15 | steps: [ 16 | { 17 | uses: 'actions/github-script@v3', 18 | with: { 19 | script: `github.pulls.createReview({ 20 | owner: context.payload.repository.owner.login, 21 | repo: context.payload.repository.name, 22 | pull_number: context.payload.pull_request.number, 23 | event: 'APPROVE' 24 | }) 25 | github.pulls.merge({ 26 | owner: context.payload.repository.owner.login, 27 | repo: context.payload.repository.name, 28 | pull_number: context.payload.pull_request.number, 29 | merge_method: 'squash' 30 | })`, 31 | }, 32 | }, 33 | ], 34 | }, 35 | }, 36 | }) 37 | .save(); 38 | } 39 | }; 40 | 41 | module.exports.description = 42 | 'Adds GitHub Actions workflow to automerge Dependabot pull requests'; 43 | module.exports.parameters = { 44 | workflowFile: { 45 | type: 'input', 46 | message: 'Enter location of GitHub Actions workflow file', 47 | default: '.github/workflows/dependabot.yml', 48 | }, 49 | }; 50 | -------------------------------------------------------------------------------- /packages/mrm-task-dependabot/index.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('fs'); 2 | jest.mock('git-username'); 3 | jest.mock('mrm-core/src/util/log', () => ({ 4 | added: jest.fn(), 5 | })); 6 | 7 | const { getTaskOptions } = require('mrm'); 8 | const vol = require('memfs').vol; 9 | const task = require('./index'); 10 | 11 | afterEach(() => vol.reset()); 12 | 13 | it('should add a workflow file', async () => { 14 | task(await getTaskOptions(task)); 15 | 16 | expect(vol.toJSON()).toMatchSnapshot(); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/mrm-task-dependabot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-dependabot", 3 | "version": "3.1.23", 4 | "private": true, 5 | "description": "Mrm task that adds GitHub Actions workflow to automerge Dependabot pull requests", 6 | "author": { 7 | "name": "Artem Sapegin", 8 | "url": "https://sapegin.me" 9 | }, 10 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-dependabot", 11 | "repository": "sapegin/mrm", 12 | "license": "MIT", 13 | "engines": { 14 | "node": ">=10.13" 15 | }, 16 | "main": "index.js", 17 | "files": [ 18 | "index.js" 19 | ], 20 | "scripts": {}, 21 | "keywords": [ 22 | "mrm", 23 | "mrm-task", 24 | "dependabot" 25 | ], 26 | "dependencies": { 27 | "mrm-core": "^7.1.23" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/mrm-task-editorconfig/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-editorconfig/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-editorconfig 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds [EditorConfig](http://editorconfig.org/). 6 | 7 | ## What it does 8 | 9 | - Creates `.editorconfig`. 10 | 11 | ## Usage 12 | 13 | ``` 14 | npx mrm editorconfig 15 | ``` 16 | 17 | ## Options 18 | 19 | See [Mrm docs](../../docs/Getting_started.md) for more details. 20 | 21 | ### `indent` (default: `tab`) 22 | 23 | Indentation, `tab` or number of spaces. 24 | 25 | ## Changelog 26 | 27 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 28 | 29 | ## Contributing 30 | 31 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 32 | 33 | ## Authors and license 34 | 35 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 36 | 37 | MIT License, see the included [License.md](License.md) file. 38 | -------------------------------------------------------------------------------- /packages/mrm-task-editorconfig/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add EditorConfig 1`] = ` 4 | Object { 5 | "/.editorconfig": "# https://editorconfig.org 6 | root = true 7 | 8 | [*] 9 | indent_style = tab 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | [*.{json,yml,md,babelrc,remarkrc,prettierrc}] 16 | indent_style = space 17 | indent_size = 2 18 | ", 19 | } 20 | `; 21 | 22 | exports[`should add a single section when indent=2 1`] = ` 23 | Object { 24 | "/.editorconfig": "# https://editorconfig.org 25 | root = true 26 | 27 | [*] 28 | indent_style = space 29 | indent_size = 2 30 | end_of_line = lf 31 | charset = utf-8 32 | trim_trailing_whitespace = true 33 | insert_final_newline = true 34 | ", 35 | } 36 | `; 37 | 38 | exports[`should update JSON section 1`] = ` 39 | Object { 40 | "/.editorconfig": "# https://editorconfig.org 41 | root = true 42 | 43 | [*] 44 | indent_style = tab 45 | end_of_line = lf 46 | charset = utf-8 47 | trim_trailing_whitespace = true 48 | insert_final_newline = true 49 | 50 | [*.{json,yml,md,babelrc,remarkrc,prettierrc}] 51 | indent_style = space 52 | indent_size = 2", 53 | } 54 | `; 55 | -------------------------------------------------------------------------------- /packages/mrm-task-editorconfig/index.js: -------------------------------------------------------------------------------- 1 | const { ini } = require('mrm-core'); 2 | 3 | const jsonRules = { 4 | indent_style: 'space', 5 | indent_size: 2, 6 | }; 7 | const jsonExtensions = [ 8 | 'json', 9 | 'yml', 10 | 'md', 11 | 'babelrc', 12 | 'remarkrc', 13 | 'prettierrc', 14 | ]; 15 | 16 | module.exports = function task({ indent }) { 17 | const generalRules = Object.assign( 18 | indent === 'tab' 19 | ? { 20 | indent_style: 'tab', 21 | } 22 | : { 23 | indent_style: 'space', 24 | indent_size: indent, 25 | }, 26 | { 27 | end_of_line: 'lf', 28 | charset: 'utf-8', 29 | trim_trailing_whitespace: true, 30 | insert_final_newline: true, 31 | } 32 | ); 33 | 34 | // .editorconfig 35 | const editorconfig = ini('.editorconfig', 'https://editorconfig.org'); 36 | editorconfig.set('_global', { root: true }).set('*', generalRules); 37 | 38 | // Set/update JSON-like section 39 | const jsonSection = editorconfig.get().find(section => /json/.test(section)); 40 | if (jsonSection) { 41 | editorconfig.unset(jsonSection); 42 | } 43 | 44 | if (indent !== jsonRules.indent_size) { 45 | editorconfig.set('*.{' + jsonExtensions.join(',') + '}', jsonRules); 46 | } 47 | 48 | editorconfig.save(); 49 | }; 50 | 51 | module.exports.description = 'Adds EditorConfig'; 52 | module.exports.parameters = { 53 | indent: { 54 | type: 'input', 55 | message: 'Choose indentation style (tabs or number of spaces)', 56 | default: 'tab', 57 | choices: ['tab', 2, 4, 8], 58 | }, 59 | }; 60 | -------------------------------------------------------------------------------- /packages/mrm-task-editorconfig/index.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('fs'); 2 | jest.mock('mrm-core/src/util/log', () => ({ 3 | added: jest.fn(), 4 | })); 5 | 6 | const { getTaskOptions } = require('mrm'); 7 | const vol = require('memfs').vol; 8 | const task = require('./index'); 9 | 10 | afterEach(() => vol.reset()); 11 | 12 | it('should add EditorConfig', async () => { 13 | vol.fromJSON(); 14 | 15 | task(await getTaskOptions(task)); 16 | 17 | expect(vol.toJSON()).toMatchSnapshot(); 18 | }); 19 | 20 | it('should add a single section when indent=2', async () => { 21 | vol.fromJSON(); 22 | 23 | task(await getTaskOptions(task, false, { indent: 2 })); 24 | 25 | expect(vol.toJSON()).toMatchSnapshot(); 26 | }); 27 | 28 | it('should update JSON section', async () => { 29 | vol.fromJSON({ 30 | '/.editorconfig': `[*.{json,yml}] 31 | indent_style = tab`, 32 | }); 33 | 34 | task(await getTaskOptions(task)); 35 | 36 | expect(vol.toJSON()).toMatchSnapshot(); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/mrm-task-editorconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-editorconfig", 3 | "version": "4.1.23", 4 | "description": "Mrm task that adds EditorConfig", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-editorconfig", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "editorconfig" 24 | ], 25 | "dependencies": { 26 | "mrm-core": "^7.1.23" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/mrm-task-eslint/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-eslint/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-eslint 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds [ESLint](https://eslint.org/). 6 | 7 | Supports JavaScript and TypeScript. 8 | 9 | ## What it does 10 | 11 | - Creates `.eslintrc.json` 12 | - Adds an npm script to run ESLint before tests 13 | - Installs dependencies 14 | 15 | ## Usage 16 | 17 | ``` 18 | npx mrm eslint 19 | ``` 20 | 21 | ## Options 22 | 23 | See [Mrm docs](../../docs/Getting_started.md) for more details. 24 | 25 | ### `eslintPreset` (default: `eslint:recommended`) 26 | 27 | ESLint preset name (e.g. `airbnb` or `eslint-config-airbnb`). 28 | 29 | ### `eslintPeerDependencies` (optional) 30 | 31 | Additional dependencies to install (e.g. `['prettier', 'eslint-plugin-prettier']`). 32 | 33 | ### `eslintObsoleteDependencies` (optional) 34 | 35 | Dependencies that should be removed (e.g. `['eslint-plugin-prettier']`). 36 | 37 | ### `eslintRules` (optional) 38 | 39 | Additional rules (e.g. `{ 'no-undef': 0 }`). 40 | 41 | ## Changelog 42 | 43 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 44 | 45 | ## Contributing 46 | 47 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 48 | 49 | ## Authors and license 50 | 51 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 52 | 53 | MIT License, see the included [License.md](License.md) file. 54 | -------------------------------------------------------------------------------- /packages/mrm-task-eslint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-eslint", 3 | "version": "4.1.23", 4 | "description": "Mrm task that adds ESLint", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-eslint", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "eslint", 24 | "lint", 25 | "javascript" 26 | ], 27 | "dependencies": { 28 | "lodash": "^4.17.15", 29 | "mrm-core": "^7.1.23" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/mrm-task-gitignore/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-gitignore/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-gitignore 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds a `.gitignore` file. 6 | 7 | ## What it does 8 | 9 | - Creates `.gitignore`. 10 | 11 | ## Usage 12 | 13 | ``` 14 | npx mrm gitignore 15 | ``` 16 | 17 | ## Changelog 18 | 19 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 20 | 21 | ## Contributing 22 | 23 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 24 | 25 | ## Authors and license 26 | 27 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 28 | 29 | MIT License, see the included [License.md](License.md) file. 30 | -------------------------------------------------------------------------------- /packages/mrm-task-gitignore/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add .gitignore 1`] = ` 4 | Object { 5 | "/.gitignore": "node_modules/ 6 | .DS_Store 7 | Thumbs.db 8 | .idea/ 9 | .vscode/ 10 | *.sublime-project 11 | *.sublime-workspace 12 | *.log", 13 | } 14 | `; 15 | 16 | exports[`should add package-lock.json and pnpm-lock.yaml, if yarn.lock exists 1`] = ` 17 | Object { 18 | "/.gitignore": "node_modules/ 19 | .DS_Store 20 | Thumbs.db 21 | .idea/ 22 | .vscode/ 23 | *.sublime-project 24 | *.sublime-workspace 25 | *.log 26 | package-lock.json 27 | pnpm-lock.yaml", 28 | "/yarn.lock": "", 29 | } 30 | `; 31 | 32 | exports[`should add yarn.lock and pnpm-lock.yaml, if package-lock.json exists 1`] = ` 33 | Object { 34 | "/.gitignore": "node_modules/ 35 | .DS_Store 36 | Thumbs.db 37 | .idea/ 38 | .vscode/ 39 | *.sublime-project 40 | *.sublime-workspace 41 | *.log 42 | yarn.lock 43 | pnpm-lock.yaml", 44 | "/package-lock.json": "", 45 | } 46 | `; 47 | 48 | exports[`should add package-lock.json and yarn.lock, if pnpm-lock.yaml exists 1`] = ` 49 | Object { 50 | "/.gitignore": "node_modules/ 51 | .DS_Store 52 | Thumbs.db 53 | .idea/ 54 | .vscode/ 55 | *.sublime-project 56 | *.sublime-workspace 57 | *.log 58 | yarn.lock 59 | package-lock.json", 60 | "/pnpm-lock.yaml": "", 61 | } 62 | `; 63 | -------------------------------------------------------------------------------- /packages/mrm-task-gitignore/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const { lines } = require('mrm-core'); 3 | 4 | module.exports = function task() { 5 | const remove = ['node_modules']; 6 | const add = [ 7 | 'node_modules/', 8 | '.DS_Store', 9 | 'Thumbs.db', 10 | '.idea/', 11 | '.vscode/', 12 | '*.sublime-project', 13 | '*.sublime-workspace', 14 | '*.log', 15 | ]; 16 | 17 | // If project uses npm, ignore yarn.lock and pnpm-lock.yaml 18 | if (fs.existsSync('package-lock.json')) { 19 | add.push('yarn.lock'); 20 | add.push('pnpm-lock.yaml'); 21 | remove.push('package-lock.json'); 22 | } 23 | 24 | // If project uses Yarn, ignore package-lock.json and pnpm-lock.yaml 25 | if (fs.existsSync('yarn.lock')) { 26 | remove.push('yarn.lock'); 27 | add.push('package-lock.json'); 28 | add.push('pnpm-lock.yaml'); 29 | } 30 | 31 | // If project uses pnpm, ignore package-lock.json and yarn.lock 32 | if (fs.existsSync('pnpm-lock.yaml')) { 33 | remove.push('pnpm-lock.yaml'); 34 | add.push('yarn.lock'); 35 | add.push('package-lock.json'); 36 | } 37 | 38 | // .gitignore 39 | lines('.gitignore') 40 | .remove(remove) 41 | .add(add) 42 | .save(); 43 | }; 44 | 45 | module.exports.description = 'Adds .gitignore'; 46 | -------------------------------------------------------------------------------- /packages/mrm-task-gitignore/index.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('fs'); 2 | jest.mock('mrm-core/src/util/log', () => ({ 3 | added: jest.fn(), 4 | })); 5 | 6 | const { getTaskOptions } = require('mrm'); 7 | const vol = require('memfs').vol; 8 | const task = require('./index'); 9 | 10 | afterEach(() => vol.reset()); 11 | 12 | it('should add .gitignore', async () => { 13 | vol.fromJSON(); 14 | 15 | task(await getTaskOptions(task, false, {})); 16 | 17 | expect(vol.toJSON()).toMatchSnapshot(); 18 | }); 19 | 20 | it('should add package-lock.json and pnpm-lock.yaml, if yarn.lock exists', async () => { 21 | vol.fromJSON({ 22 | '/yarn.lock': '', 23 | }); 24 | 25 | task(await getTaskOptions(task, false, {})); 26 | 27 | expect(vol.toJSON()).toMatchSnapshot(); 28 | }); 29 | 30 | it('should add yarn.lock and pnpm-lock.yaml, if package-lock.json exists', async () => { 31 | vol.fromJSON({ 32 | '/package-lock.json': '', 33 | }); 34 | 35 | task(await getTaskOptions(task, false, {})); 36 | 37 | expect(vol.toJSON()).toMatchSnapshot(); 38 | }); 39 | 40 | it('should add package-lock.json and yarn.lock, if pnpm-lock.yaml exists', async () => { 41 | vol.fromJSON({ 42 | '/pnpm-lock.yaml': '', 43 | }); 44 | 45 | task(await getTaskOptions(task, false, {})); 46 | 47 | expect(vol.toJSON()).toMatchSnapshot(); 48 | }); 49 | -------------------------------------------------------------------------------- /packages/mrm-task-gitignore/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-gitignore", 3 | "version": "4.1.23", 4 | "description": "Mrm task that adds .gitignore", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-gitignore", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "git", 24 | "gitignore" 25 | ], 26 | "dependencies": { 27 | "mrm-core": "^7.1.23" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/mrm-task-gitter/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-gitter/Readme.md: -------------------------------------------------------------------------------- 1 | # [DEPRECATED] mrm-task-gitter 2 | 3 | [Mrm](https://github.com/sapegin/mrm) task that adds [Gitter](https://gitter.im/) badge to the readme. 4 | 5 | ## Usage 6 | 7 | ``` 8 | npx mrm gitter 9 | ``` 10 | 11 | ## Options 12 | 13 | See [Mrm docs](../../docs/Getting_started.md) for more details. 14 | 15 | ### `packageName` (default: `name` field in `package.json`) 16 | 17 | Gitter channel name. 18 | 19 | ## Changelog 20 | 21 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 22 | 23 | ## Contributing 24 | 25 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 26 | 27 | ## Authors and license 28 | 29 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 30 | 31 | MIT License, see the included [License.md](License.md) file. 32 | -------------------------------------------------------------------------------- /packages/mrm-task-gitter/index.js: -------------------------------------------------------------------------------- 1 | const { markdown, packageJson } = require('mrm-core'); 2 | 3 | module.exports = function task({ packageName, readme }) { 4 | const url = `https://gitter.im/${packageName}`; 5 | const badge = `https://badges.gitter.im/${packageName}.svg`; 6 | markdown(readme) 7 | .addBadge(badge, url, 'Gitter chat') 8 | .save(); 9 | }; 10 | 11 | module.exports.description = 'Adds Gitter badge to the readme'; 12 | module.exports.parameters = { 13 | packageName: { 14 | type: 'input', 15 | message: 'Enter package name', 16 | default: () => packageJson().get('name'), 17 | validate(value) { 18 | return value ? true : 'Package name is required'; 19 | }, 20 | }, 21 | readme: { 22 | type: 'input', 23 | message: 'Enter filename for the readme', 24 | default: 'Readme.md', 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /packages/mrm-task-gitter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-gitter", 3 | "version": "4.1.23", 4 | "private": true, 5 | "description": "Mrm task that adds Gitter badge to the readme", 6 | "author": { 7 | "name": "Artem Sapegin", 8 | "url": "http://sapegin.me" 9 | }, 10 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-gitter", 11 | "repository": "sapegin/mrm", 12 | "license": "MIT", 13 | "engines": { 14 | "node": ">=10.13" 15 | }, 16 | "main": "index.js", 17 | "files": [ 18 | "index.js" 19 | ], 20 | "scripts": {}, 21 | "keywords": [ 22 | "mrm", 23 | "mrm-task", 24 | "gitter", 25 | "readme", 26 | "badge" 27 | ], 28 | "dependencies": { 29 | "mrm-core": "^7.1.23" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/mrm-task-jest/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-jest/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-jest 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds [Jest](https://facebook.github.io/jest/). 6 | 7 | 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)). 8 | 9 | ## What it does 10 | 11 | - Adds npm scripts 12 | - Updates `.gitignore`, `.npmignore`, `.eslintignore` with common patterns 13 | - Creates a sample test file, `test.js`, when the project has `index.js` in the root folder 14 | - Tries to get rid of Mocha and AVA configs and dependencies 15 | - Installs dependencies 16 | 17 | ## Usage 18 | 19 | ``` 20 | npx mrm jest 21 | ``` 22 | 23 | ## Changelog 24 | 25 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 26 | 27 | ## Contributing 28 | 29 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 30 | 31 | ## Authors and license 32 | 33 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 34 | 35 | MIT License, see the included [License.md](License.md) file. 36 | -------------------------------------------------------------------------------- /packages/mrm-task-jest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-jest", 3 | "version": "4.1.23", 4 | "description": "Mrm task that adds Jest", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-jest", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js", 18 | "templates" 19 | ], 20 | "scripts": {}, 21 | "keywords": [ 22 | "mrm", 23 | "mrm-task", 24 | "jest", 25 | "testing" 26 | ], 27 | "dependencies": { 28 | "lodash": "^4.17.15", 29 | "mrm-core": "^7.1.23" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/mrm-task-jest/templates/index.js: -------------------------------------------------------------------------------- 1 | function pizza(num) { 2 | return num * 2; 3 | } 4 | 5 | module.exports = pizza; 6 | -------------------------------------------------------------------------------- /packages/mrm-task-jest/templates/jestsetup.js: -------------------------------------------------------------------------------- 1 | import Enzyme from 'enzyme'; 2 | import Adapter from 'enzyme-adapter-react-16'; 3 | 4 | Enzyme.configure({ adapter: new Adapter() }); 5 | -------------------------------------------------------------------------------- /packages/mrm-task-jest/templates/test.js: -------------------------------------------------------------------------------- 1 | const ${func} = require('./index'); 2 | 3 | test('${func}', () => { 4 | const result = ${func}(); 5 | expect(result).toBeTruthy(); 6 | }); 7 | -------------------------------------------------------------------------------- /packages/mrm-task-license/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-license/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-license 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds license file based on `license` field in `package.json`. 6 | 7 | ## What it does 8 | 9 | - Creates a license file. 10 | 11 | ## Usage 12 | 13 | ``` 14 | npx mrm license 15 | ``` 16 | 17 | ## Options 18 | 19 | See [Mrm docs](../../docs/Getting_started.md) for more details. 20 | 21 | ### `license` (default: taken from `package.json`, if not found `MIT` is used) 22 | 23 | License name (like `MIT`, `Unlicense`). For full list of supported values see: [`/templates`](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-license/templates). 24 | 25 | ### `licenseFile` (default: `License.md`) 26 | 27 | File name. May use `${license}` within the string to insert the value of `license` dynamically into the name (to maintain this general template independently from the license type, while non-redundant with it). 28 | 29 | ### `name` (default: will try to read from your npm or Git config) 30 | 31 | Your name. 32 | 33 | ### `email` (default: will try to read from your npm or Git config) 34 | 35 | Your email. 36 | 37 | ## Changelog 38 | 39 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 40 | 41 | ## Contributing 42 | 43 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 44 | 45 | ## Authors and license 46 | 47 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 48 | 49 | MIT License, see the included [License.md](License.md) file. 50 | -------------------------------------------------------------------------------- /packages/mrm-task-license/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const meta = require('user-meta'); 4 | const parseAuthor = require('parse-author'); 5 | const { template, packageJson } = require('mrm-core'); 6 | const { template: smplTemplate } = require('smpltmpl'); 7 | 8 | function getAuthorName(pkg) { 9 | const rawName = pkg.get('author.name') || pkg.get('author') || ''; 10 | return parseAuthor(rawName).name; 11 | } 12 | 13 | function task({ license, name, email, licenseFile }) { 14 | const templateFile = path.join(__dirname, `templates/${license}.md`); 15 | 16 | if (!fs.existsSync(templateFile)) { 17 | console.log(`No template for the “${license}” license found, skipping`); 18 | return; 19 | } 20 | 21 | template( 22 | smplTemplate(licenseFile, { 23 | license, 24 | }), 25 | templateFile 26 | ) 27 | .apply({ 28 | name, 29 | email, 30 | year: new Date().getFullYear(), 31 | }) 32 | .save(); 33 | 34 | packageJson() 35 | .set('license', license) 36 | .save(); 37 | } 38 | 39 | module.exports = task; 40 | module.exports.description = 'Adds license file'; 41 | module.exports.getAuthorName = getAuthorName; 42 | 43 | module.exports.parameters = { 44 | license: { 45 | type: 'input', 46 | message: 'Choose a license', 47 | default: () => packageJson().get('license', 'MIT'), 48 | choices: ['Apache-2.0', 'BSD-2-Clause', 'BSD-3-Clause', 'MIT', 'Unlicense'], 49 | }, 50 | name: { 51 | type: 'input', 52 | message: 'Enter author name', 53 | default: () => getAuthorName(packageJson()) || meta.name, 54 | validate(value) { 55 | return value ? true : 'Author name is required'; 56 | }, 57 | }, 58 | email: { 59 | type: 'input', 60 | message: 'Enter author email', 61 | default: meta.email, 62 | validate(value) { 63 | return value ? true : 'Email is required'; 64 | }, 65 | }, 66 | licenseFile: { 67 | type: 'input', 68 | message: 'Enter filename for the license', 69 | default: 'License.md', 70 | }, 71 | }; 72 | -------------------------------------------------------------------------------- /packages/mrm-task-license/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-license", 3 | "version": "5.1.23", 4 | "description": "Mrm task that adds a license file", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "https://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-license", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js", 18 | "templates" 19 | ], 20 | "scripts": {}, 21 | "keywords": [ 22 | "mrm", 23 | "mrm-task", 24 | "license" 25 | ], 26 | "dependencies": { 27 | "mrm-core": "^7.1.23", 28 | "parse-author": "^2.0.0", 29 | "smpltmpl": "^1.0.2", 30 | "user-meta": "^1.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/mrm-task-license/templates/Apache-2.0.md: -------------------------------------------------------------------------------- 1 | # Apache License, Version 2.0 (Apache-2.0) 2 | 3 | Copyright ${year} ${name}, contributors 4 | 5 | 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 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-license/templates/BSD-2-Clause.md: -------------------------------------------------------------------------------- 1 | # The 2-Clause BSD License (BSD-2-Clause) 2 | 3 | Copyright ${year} ${name}, contributors 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 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. 10 | 11 | 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. 12 | -------------------------------------------------------------------------------- /packages/mrm-task-license/templates/BSD-3-Clause.md: -------------------------------------------------------------------------------- 1 | # The 3-Clause BSD License (BSD-3-Clause) 2 | 3 | Copyright ${year} ${name}, contributors 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 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. 10 | 11 | 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. 12 | 13 | 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. 14 | -------------------------------------------------------------------------------- /packages/mrm-task-license/templates/MIT.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright ${year} ${name}, contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-license/templates/Unlicense.md: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | 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. 4 | 5 | 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. 6 | 7 | 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. 8 | 9 | For more information, please refer to 10 | -------------------------------------------------------------------------------- /packages/mrm-task-lint-staged/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-lint-staged/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-lint-staged 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds [lint-staged](https://github.com/okonet/lint-staged). 6 | 7 | **Note:** supports only Prettier, ESLint and Stylelint now, pull requests are welcome. 8 | 9 | ## What it does 10 | 11 | - Creates a config in `package.json` 12 | - Sets up a pre-commit Git hook 13 | - Installs dependencies 14 | 15 | 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. 16 | 17 | ## Usage 18 | 19 | ``` 20 | npx mrm lint-staged 21 | ``` 22 | 23 | ## Options 24 | 25 | See [Mrm docs](../../docs/Getting_started.md) and [lint-staged docs](https://github.com/okonet/lint-staged/blob/master/README.md#-lint-staged---) for more details. 26 | 27 | ### `lintStagedRules` (default: infer) 28 | 29 | Overrides and custom rules. By default will try to infer by project dependencies. 30 | 31 | For example, a custom extension: 32 | 33 | ```json 34 | { 35 | "lintStagedRules": { 36 | "eslint": { 37 | "extensions": ["js", "jsx", "mjs"] 38 | } 39 | } 40 | } 41 | ``` 42 | 43 | Or a custom command: 44 | 45 | ```json 46 | { 47 | "lintStagedRules": { 48 | "eslint": { 49 | "command": "eslint --fix" 50 | } 51 | } 52 | } 53 | ``` 54 | 55 | Or you can disable one of the default rules: 56 | 57 | ```json 58 | { 59 | "lintStagedRules": { 60 | "prettier": { 61 | "enabled": false 62 | } 63 | } 64 | } 65 | ``` 66 | 67 | Or add a custom rule: 68 | 69 | ```json 70 | { 71 | "lintStagedRules": { 72 | "jest": { 73 | "extensions": ["js"], 74 | "command": "jest --bail --findRelatedTests" 75 | } 76 | } 77 | } 78 | ``` 79 | 80 | Available rules are `prettier`, `eslint` and `stylelint`. 81 | 82 | ## Changelog 83 | 84 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 85 | 86 | ## Contributing 87 | 88 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 89 | 90 | ## Authors and license 91 | 92 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 93 | 94 | MIT License, see the included [License.md](License.md) file. 95 | -------------------------------------------------------------------------------- /packages/mrm-task-lint-staged/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-lint-staged", 3 | "version": "7.1.23", 4 | "description": "Mrm task that adds lint-staged", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-lint-staged", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "lint-staged", 24 | "lint" 25 | ], 26 | "dependencies": { 27 | "husky": "^7.0.4", 28 | "lodash": "^4.17.15", 29 | "mrm-core": "^7.1.23" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/mrm-task-package/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-package/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-package 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds `package.json`. 6 | 7 | ## What it does 8 | 9 | - Creates `package.json` 10 | 11 | ## Usage 12 | 13 | ``` 14 | npx mrm package 15 | ``` 16 | 17 | ## Options 18 | 19 | See [Mrm docs](../../docs/Getting_started.md) for more details. 20 | 21 | ### `github` (default: extracted from `.git/config` file) 22 | 23 | Your GitHub user name. 24 | 25 | ### `name` (default: will try to read from your npm or Git config) 26 | 27 | Your name. 28 | 29 | ### `url` (default: will try to read from your npm or Git config) 30 | 31 | Your site URL. 32 | 33 | ### `minNode` (default: 10) 34 | 35 | Minimum required Node.js version. 36 | 37 | ### `license` (default: MIT) 38 | 39 | License. 40 | 41 | ## Changelog 42 | 43 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 44 | 45 | ## Contributing 46 | 47 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 48 | 49 | ## Authors and license 50 | 51 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 52 | 53 | MIT License, see the included [License.md](License.md) file. 54 | -------------------------------------------------------------------------------- /packages/mrm-task-package/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add package.json 1`] = ` 4 | "{ 5 | \\"name\\": \\"mrm-task-package\\", 6 | \\"version\\": \\"1.0.0\\", 7 | \\"description\\": \\"\\", 8 | \\"author\\": { 9 | \\"name\\": \\"Gendalf\\", 10 | \\"url\\": \\"https://middleearth.com\\" 11 | }, 12 | \\"contributors\\": [], 13 | \\"homepage\\": \\"https://github.com/gendalf/mrm-task-package\\", 14 | \\"bugs\\": \\"https://github.com/gendalf/mrm-task-package/issues\\", 15 | \\"repository\\": \\"https://github.com/gendalf/mrm-task-package\\", 16 | \\"license\\": \\"MIT\\", 17 | \\"engines\\": { 18 | \\"node\\": \\">=10\\" 19 | }, 20 | \\"main\\": \\"index.js\\", 21 | \\"files\\": [ 22 | \\"index.js\\" 23 | ], 24 | \\"scripts\\": {}, 25 | \\"keywords\\": [], 26 | \\"dependencies\\": {}, 27 | \\"devDependencies\\": {} 28 | }" 29 | `; 30 | 31 | exports[`should set custom Node.js version 1`] = ` 32 | "{ 33 | \\"name\\": \\"\\", 34 | \\"version\\": \\"1.0.0\\", 35 | \\"description\\": \\"\\", 36 | \\"author\\": { 37 | \\"name\\": \\"Gendalf\\", 38 | \\"url\\": \\"https://middleearth.com\\" 39 | }, 40 | \\"contributors\\": [], 41 | \\"homepage\\": \\"https://github.com/gendalf/\\", 42 | \\"bugs\\": \\"https://github.com/gendalf//issues\\", 43 | \\"repository\\": \\"https://github.com/gendalf/\\", 44 | \\"license\\": \\"MIT\\", 45 | \\"engines\\": { 46 | \\"node\\": \\">=9.1\\" 47 | }, 48 | \\"main\\": \\"index.js\\", 49 | \\"files\\": [ 50 | \\"index.js\\" 51 | ], 52 | \\"scripts\\": {}, 53 | \\"keywords\\": [], 54 | \\"dependencies\\": {}, 55 | \\"devDependencies\\": {} 56 | }" 57 | `; 58 | 59 | exports[`should set custom license 1`] = ` 60 | "{ 61 | \\"name\\": \\"\\", 62 | \\"version\\": \\"1.0.0\\", 63 | \\"description\\": \\"\\", 64 | \\"author\\": { 65 | \\"name\\": \\"Gendalf\\", 66 | \\"url\\": \\"https://middleearth.com\\" 67 | }, 68 | \\"contributors\\": [], 69 | \\"homepage\\": \\"https://github.com/gendalf/\\", 70 | \\"bugs\\": \\"https://github.com/gendalf//issues\\", 71 | \\"repository\\": \\"https://github.com/gendalf/\\", 72 | \\"license\\": \\"BSD\\", 73 | \\"engines\\": { 74 | \\"node\\": \\">=10\\" 75 | }, 76 | \\"main\\": \\"index.js\\", 77 | \\"files\\": [ 78 | \\"index.js\\" 79 | ], 80 | \\"scripts\\": {}, 81 | \\"keywords\\": [], 82 | \\"dependencies\\": {}, 83 | \\"devDependencies\\": {} 84 | }" 85 | `; 86 | -------------------------------------------------------------------------------- /packages/mrm-task-package/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-package", 3 | "version": "4.1.23", 4 | "description": "Mrm task that adds package.json file", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-package", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "package", 24 | "package.json", 25 | "npm" 26 | ], 27 | "dependencies": { 28 | "git-username": "^1.0.0", 29 | "mrm-core": "^7.1.23", 30 | "rc": "^1.2.8", 31 | "user-meta": "^1.0.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/mrm-task-prettier/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-prettier/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-prettier 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds [Prettier](https://prettier.io/). 6 | 7 | ## What it does 8 | 9 | - Creates `.prettierrc` 10 | - Adds an npm script to run Prettier after tests 11 | - Installs dependencies 12 | 13 | ## Usage 14 | 15 | ``` 16 | npx mrm prettier 17 | ``` 18 | 19 | Now run: 20 | 21 | ``` 22 | npm run format 23 | ``` 24 | 25 | ## Options 26 | 27 | See [Mrm docs](../../docs/Getting_started.md) for more details. 28 | 29 | ### `indent` (default: `tab`) 30 | 31 | Indentation, `tab` or number of spaces. Will be overwritten by options from EditorConfig. 32 | 33 | ### `prettierOptions` 34 | 35 | Prettier options, by default will try to infer options from EditorConfig. 36 | 37 | ### `prettierOverrides` 38 | 39 | [Prettier overrides](https://prettier.io/docs/en/configuration.html#configuration-overrides), by default will use overrides for Markdown to improve documentation readability. 40 | 41 | ### `prettierPattern` (default: auto based on your dependencies) 42 | 43 | Glob pattern to match file that should be formatted, for example `**/*.{ts,tsx}`. 44 | 45 | ## Changelog 46 | 47 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 48 | 49 | ## Contributing 50 | 51 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 52 | 53 | ## Authors and license 54 | 55 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 56 | 57 | MIT License, see the included [License.md](License.md) file. 58 | -------------------------------------------------------------------------------- /packages/mrm-task-prettier/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-prettier", 3 | "version": "5.1.23", 4 | "description": "Mrm task that adds Prettier", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-prettier", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "prettier", 24 | "format", 25 | "formatting", 26 | "javascript", 27 | "css", 28 | "markdown" 29 | ], 30 | "dependencies": { 31 | "editorconfig-to-prettier": "0.1.1", 32 | "lodash": "^4.17.15", 33 | "mrm-core": "^7.1.23" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/mrm-task-readme/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-readme/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-readme 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds a Readme file. 6 | 7 | ## What it does 8 | 9 | - Creates a Readme file 10 | 11 | ## Usage 12 | 13 | ``` 14 | npx mrm readme 15 | ``` 16 | 17 | ## Options 18 | 19 | See [Mrm docs](../../docs/Getting_started.md) for more details. 20 | 21 | ### `packageName` (default: `name` field in `package.json`) 22 | 23 | Package name. 24 | 25 | ### `name` (default: will try to read from your `package.json`, npm or Git config) 26 | 27 | Your name. 28 | 29 | ### `url` (default: will try to read from your npm or Git config) 30 | 31 | Your site URL. 32 | 33 | ### `readmeFile` (default: `"Readme.md"`) 34 | 35 | Name of the Readme file. 36 | 37 | ### `license` (default: taken from `package.json`, if not found `"MIT"` is used) 38 | 39 | License name (like `MIT`, `Unlicense`). For full list of supported values see: [`/templates`](https://github.com/sapegin/mrm/tree/master/packages/mrm-task-license/templates). 40 | 41 | This is only needed if `licenseFile` is used. 42 | 43 | ### `licenseFile` (default: `"License.md"`) 44 | 45 | Name of the license file. May use `${license}` within the string to insert the value of `license` dynamically into the name (to maintain this general template independently from the license type, while non-redundant with it). 46 | 47 | ### `contributingFile` (default: `"Contributing.md"`) 48 | 49 | Name of the Contributing file. 50 | 51 | ### `includeContributing` (default: `true`) 52 | 53 | Whether to include the Contributing section. 54 | 55 | ## Changelog 56 | 57 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 58 | 59 | ## Contributing 60 | 61 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 62 | 63 | ## Authors and license 64 | 65 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 66 | 67 | MIT License, see the included [License.md](License.md) file. 68 | -------------------------------------------------------------------------------- /packages/mrm-task-readme/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add a readme 1`] = ` 4 | Object { 5 | "/Readme.md": "# unicorn 6 | 7 | ... 8 | 9 | ## Changelog 10 | 11 | The changelog can be found on the [Releases page](https://github.com/gandalf/unicorn/releases). 12 | 13 | ## Contributing 14 | 15 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](Contributing.md). 16 | 17 | ## Authors and license 18 | 19 | [Gandalf](https://middleearth.com) and [contributors](https://github.com/gandalf/unicorn/graphs/contributors). 20 | 21 | MIT License, see the included [License.md](License.md) file. 22 | ", 23 | "/package.json": "{ 24 | \\"name\\": \\"unicorn\\", 25 | \\"repository\\": \\"gandalf/unicorn\\" 26 | }", 27 | } 28 | `; 29 | 30 | exports[`should add a readme without contributing 1`] = ` 31 | Object { 32 | "/Readme.md": "# unicorn 33 | 34 | ... 35 | 36 | ## Changelog 37 | 38 | The changelog can be found on the [Releases page](https://github.com/gandalf/unicorn/releases). 39 | 40 | ## Authors and license 41 | 42 | [Gandalf](https://middleearth.com) and [contributors](https://github.com/gandalf/unicorn/graphs/contributors). 43 | 44 | MIT License, see the included [License.md](License.md) file. 45 | ", 46 | "/package.json": "{ 47 | \\"name\\": \\"unicorn\\", 48 | \\"repository\\": \\"gandalf/unicorn\\" 49 | }", 50 | } 51 | `; 52 | 53 | exports[`should add a readme with custom contributing 1`] = ` 54 | Object { 55 | "/Readme.md": "# unicorn 56 | 57 | ... 58 | 59 | ## Changelog 60 | 61 | The changelog can be found on the [Releases page](https://github.com/gandalf/unicorn/releases). 62 | 63 | ## Contributing 64 | 65 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](CONTRIBUTIONS.md). 66 | 67 | ## Authors and license 68 | 69 | [Gandalf](https://middleearth.com) and [contributors](https://github.com/gandalf/unicorn/graphs/contributors). 70 | 71 | MIT License, see the included [License.md](License.md) file. 72 | ", 73 | "/package.json": "{ 74 | \\"name\\": \\"unicorn\\", 75 | \\"repository\\": \\"gandalf/unicorn\\" 76 | }", 77 | } 78 | `; 79 | -------------------------------------------------------------------------------- /packages/mrm-task-readme/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-readme", 3 | "version": "4.1.23", 4 | "description": "Mrm task that adds a readme file", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "https://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-readme", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js", 18 | "templates" 19 | ], 20 | "scripts": {}, 21 | "keywords": [ 22 | "mrm", 23 | "mrm-task", 24 | "readme" 25 | ], 26 | "dependencies": { 27 | "git-username": "^1.0.0", 28 | "mrm-core": "^7.1.23", 29 | "package-repo-url": "^1.0.3", 30 | "parse-author": "^2.0.0", 31 | "smpltmpl": "^1.0.2", 32 | "user-meta": "^1.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/mrm-task-readme/templates/Contributing.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](${contributingFile}). 4 | -------------------------------------------------------------------------------- /packages/mrm-task-readme/templates/Readme.md: -------------------------------------------------------------------------------- 1 | # ${package} 2 | 3 | ... 4 | 5 | ## Changelog 6 | 7 | The changelog can be found on the [Releases page](${github}/releases). 8 | ${contributing && '\n' + contributing} 9 | ## Authors and license 10 | 11 | [${name}](${url}) and [contributors](${github}/graphs/contributors). 12 | 13 | MIT License, see the included [${license}](${license}) file. 14 | -------------------------------------------------------------------------------- /packages/mrm-task-semantic-release/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-semantic-release/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-semantic-release 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds [semantic-release](https://github.com/semantic-release/semantic-release). 6 | 7 | ## What it does 8 | 9 | - Runs semantic-release using GitHub Action 10 | - Adds an npm version badge to the Readme 11 | 12 | ## Usage 13 | 14 | ``` 15 | npx mrm semantic-release 16 | ``` 17 | 18 | ## Options 19 | 20 | See [Mrm docs](../../docs/Getting_started.md) for more details. 21 | 22 | ### `workflowFile` (default: `.github/workflows/release.yml`) 23 | 24 | Name of the GitHub Actions workflow file. 25 | 26 | ### `readmeFile` (default: `Readme.md`) 27 | 28 | Name of the Readme file. 29 | 30 | ## Changelog 31 | 32 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 33 | 34 | ## Contributing 35 | 36 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 37 | 38 | ## Authors and license 39 | 40 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 41 | 42 | MIT License, see the included [License.md](License.md) file. 43 | -------------------------------------------------------------------------------- /packages/mrm-task-semantic-release/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add semantic-release 1`] = ` 4 | Object { 5 | "/.github/workflows/release.yml": "name: Semantic Release 6 | on: 7 | push: 8 | branches: 9 | - master 10 | jobs: 11 | release: 12 | name: Release 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | - uses: actions/setup-node@v2 17 | with: 18 | node-version: lts/* 19 | - run: npm ci 20 | - env: 21 | GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} 22 | NPM_TOKEN: \${{ secrets.NPM_TOKEN }} 23 | run: npx semantic-release 24 | ", 25 | "/Readme.md": "# Unicorn 26 | 27 | [![npm](https://img.shields.io/npm/v/unicorn.svg)](https://www.npmjs.com/package/unicorn)", 28 | "/package.json": "{ 29 | \\"name\\": \\"unicorn\\", 30 | \\"scripts\\": {} 31 | }", 32 | } 33 | `; 34 | 35 | exports[`should remove custom config from package.json 1`] = ` 36 | "{ 37 | \\"name\\": \\"unicorn\\", 38 | \\"scripts\\": {} 39 | }" 40 | `; 41 | 42 | exports[`should remove semantic-release runner from Travis CI config 1`] = ` 43 | "language: node_js 44 | node_js: 45 | - 8 46 | after_success: 47 | - bash <(curl -s https://codecov.io/bash) 48 | " 49 | `; 50 | -------------------------------------------------------------------------------- /packages/mrm-task-semantic-release/index.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('fs'); 2 | jest.mock('git-username'); 3 | jest.mock('mrm-core/src/util/log', () => ({ 4 | added: jest.fn(), 5 | })); 6 | jest.mock('mrm-core/src/npm', () => ({ 7 | uninstall: jest.fn(), 8 | })); 9 | 10 | const { uninstall } = require('mrm-core'); 11 | const { getTaskOptions } = require('mrm'); 12 | const vol = require('memfs').vol; 13 | const task = require('./index'); 14 | 15 | const console$log = console.log; 16 | 17 | const stringify = o => JSON.stringify(o, null, ' '); 18 | 19 | const packageJson = stringify({ 20 | name: 'unicorn', 21 | scripts: { 22 | 'semantic-release': 'semantic-release', 23 | }, 24 | }); 25 | const readmeMd = '# Unicorn'; 26 | 27 | beforeEach(() => { 28 | console.log = jest.fn(); 29 | }); 30 | 31 | afterEach(() => { 32 | vol.reset(); 33 | uninstall.mockClear(); 34 | console.log = console$log; 35 | }); 36 | 37 | it('should add semantic-release', async () => { 38 | vol.fromJSON({ 39 | '/package.json': packageJson, 40 | '/Readme.md': readmeMd, 41 | }); 42 | 43 | task(await getTaskOptions(task, false, {})); 44 | 45 | expect(vol.toJSON()).toMatchSnapshot(); 46 | }); 47 | 48 | it('should remove custom config from package.json', async () => { 49 | vol.fromJSON({ 50 | '/package.json': stringify({ 51 | name: 'unicorn', 52 | scripts: { 53 | 'semantic-release': 'semantic-release', 54 | }, 55 | release: { 56 | analyzeCommits: 'semantic-release-tamia/analyzeCommits', 57 | }, 58 | }), 59 | }); 60 | 61 | task(await getTaskOptions(task, false, {})); 62 | 63 | expect(vol.toJSON()['/package.json']).toMatchSnapshot(); 64 | }); 65 | 66 | it('should remove semantic-release runner from Travis CI config', async () => { 67 | vol.fromJSON({ 68 | '/.travis.yml': `language: node_js 69 | node_js: 70 | - 8 71 | after_success: 72 | - bash <(curl -s https://codecov.io/bash) 73 | - npm run semantic-release 74 | - npx semantic-release 75 | `, 76 | '/package.json': packageJson, 77 | }); 78 | 79 | task(await getTaskOptions(task, false, {})); 80 | 81 | expect(vol.toJSON()['/.travis.yml']).toMatchSnapshot(); 82 | expect(uninstall).toBeCalledWith(['semantic-release', 'travis-deploy-once']); 83 | }); 84 | -------------------------------------------------------------------------------- /packages/mrm-task-semantic-release/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-semantic-release", 3 | "version": "6.1.23", 4 | "description": "Mrm task that adds semantic-release", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "https://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-semantic-release", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "semantic-release" 24 | ], 25 | "dependencies": { 26 | "mrm-core": "^7.1.23", 27 | "package-repo-url": "^1.0.4" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/mrm-task-styleguidist/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-styleguidist/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-styleguidist 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds [React Styleguidist](https://react-styleguidist.js.org/). 6 | 7 | ## What it does 8 | 9 | - Creates a style guide config 10 | - Installs dependencies 11 | 12 | ## Usage 13 | 14 | ``` 15 | npx mrm styleguidist 16 | ``` 17 | 18 | ## Changelog 19 | 20 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 21 | 22 | ## Contributing 23 | 24 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 25 | 26 | ## Authors and license 27 | 28 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 29 | 30 | MIT License, see the included [License.md](License.md) file. 31 | -------------------------------------------------------------------------------- /packages/mrm-task-styleguidist/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add React Styleguidist 1`] = ` 4 | Object { 5 | "/package.json": "{ 6 | \\"name\\": \\"unicorn\\", 7 | \\"scripts\\": { 8 | \\"styleguide\\": \\"styleguidist server\\", 9 | \\"styleguide:build\\": \\"styleguidist build\\", 10 | \\"start\\": \\"styleguidist server\\" 11 | } 12 | }", 13 | "/styleguide.config.js": "module.exports = { 14 | components: 'src/components/**/[A-Z]*.js', 15 | }; 16 | ", 17 | } 18 | `; 19 | 20 | exports[`should use a TypeScript template for a TypeScript project 1`] = ` 21 | "module.exports = { 22 | components: 'src/components/**/[A-Z]*.tsx', 23 | propsParser: require('react-docgen-typescript').parse, 24 | }; 25 | " 26 | `; 27 | -------------------------------------------------------------------------------- /packages/mrm-task-styleguidist/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { packageJson, template, install } = require('mrm-core'); 3 | 4 | const configFile = 'styleguide.config.js'; 5 | 6 | function task() { 7 | const prodPackages = ['react', 'react-dom']; 8 | const packages = ['react-styleguidist']; 9 | let templateFile = configFile; 10 | 11 | const pkg = packageJson(); 12 | const isCra = pkg.get('dependencies.react-scripts'); 13 | 14 | // Create React App has its own webpack 15 | if (!isCra) { 16 | packages.push('webpack'); 17 | } 18 | 19 | // TypeScript 20 | if (pkg.get('devDependencies.typescript')) { 21 | packages.push('react-docgen-typescript'); 22 | templateFile = 'styleguide.config.typescript.js'; 23 | } 24 | 25 | // Style guide config 26 | if (!isCra) { 27 | template(configFile, path.join(__dirname, 'templates', templateFile)) 28 | .apply() 29 | .save(); 30 | } 31 | 32 | // package.json 33 | pkg 34 | .appendScript('styleguide', 'styleguidist server') 35 | .appendScript('styleguide:build', 'styleguidist build'); 36 | 37 | if (!pkg.getScript('start')) { 38 | pkg.setScript('start', 'styleguidist server'); 39 | } 40 | 41 | pkg.save(); 42 | 43 | // Dependencies 44 | install(prodPackages, { dev: false }); 45 | install(packages); 46 | } 47 | 48 | task.description = 'Adds React Styleguidist'; 49 | module.exports = task; 50 | -------------------------------------------------------------------------------- /packages/mrm-task-styleguidist/index.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('fs'); 2 | jest.mock('mrm-core/src/util/log', () => ({ 3 | added: jest.fn(), 4 | })); 5 | jest.mock('mrm-core/src/npm', () => ({ 6 | install: jest.fn(), 7 | })); 8 | 9 | const fs = jest.requireActual('fs'); 10 | const path = require('path'); 11 | const { install } = require('mrm-core'); 12 | const { omitBy } = require('lodash'); 13 | const vol = require('memfs').vol; 14 | const task = require('./index'); 15 | 16 | const stringify = o => JSON.stringify(o, null, ' '); 17 | 18 | afterEach(() => { 19 | vol.reset(); 20 | install.mockClear(); 21 | }); 22 | 23 | it('should add React Styleguidist', () => { 24 | vol.fromJSON({ 25 | [`${__dirname}/templates/styleguide.config.js`]: fs 26 | .readFileSync(path.join(__dirname, 'templates/styleguide.config.js')) 27 | .toString(), 28 | '/package.json': stringify({ 29 | name: 'unicorn', 30 | }), 31 | }); 32 | 33 | task({}); 34 | 35 | expect( 36 | omitBy(vol.toJSON(), (v, k) => k.startsWith(__dirname)) 37 | ).toMatchSnapshot(); 38 | expect(install.mock.calls).toEqual([ 39 | [['react', 'react-dom'], { dev: false }], 40 | [['react-styleguidist', 'webpack']], 41 | ]); 42 | }); 43 | 44 | it('should use a TypeScript template for a TypeScript project', () => { 45 | vol.fromJSON({ 46 | [`${__dirname}/templates/styleguide.config.typescript.js`]: fs 47 | .readFileSync( 48 | path.join(__dirname, 'templates/styleguide.config.typescript.js') 49 | ) 50 | .toString(), 51 | '/package.json': stringify({ 52 | name: 'unicorn', 53 | devDependencies: { 54 | typescript: '*', 55 | }, 56 | }), 57 | }); 58 | 59 | task({}); 60 | 61 | expect(vol.toJSON()['/styleguide.config.js']).toMatchSnapshot(); 62 | }); 63 | 64 | it('should not install webpack when used with CRA', () => { 65 | vol.fromJSON({ 66 | [`${__dirname}/templates/styleguide.config.js`]: fs 67 | .readFileSync(path.join(__dirname, 'templates/styleguide.config.js')) 68 | .toString(), 69 | '/package.json': stringify({ 70 | name: 'unicorn', 71 | dependencies: { 72 | 'react-scripts': '*', 73 | }, 74 | }), 75 | }); 76 | 77 | task({}); 78 | 79 | expect(install.mock.calls).toEqual([ 80 | [['react', 'react-dom'], { dev: false }], 81 | [['react-styleguidist']], 82 | ]); 83 | }); 84 | -------------------------------------------------------------------------------- /packages/mrm-task-styleguidist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-styleguidist", 3 | "version": "4.1.23", 4 | "description": "Mrm task that adds React Styleguidist", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-styleguidist", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js", 18 | "templates" 19 | ], 20 | "scripts": {}, 21 | "keywords": [ 22 | "mrm", 23 | "mrm-task", 24 | "styleguidist", 25 | "react" 26 | ], 27 | "dependencies": { 28 | "mrm-core": "^7.1.23" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/mrm-task-styleguidist/templates/styleguide.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | components: 'src/components/**/[A-Z]*.js', 3 | }; 4 | -------------------------------------------------------------------------------- /packages/mrm-task-styleguidist/templates/styleguide.config.typescript.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | components: 'src/components/**/[A-Z]*.tsx', 3 | propsParser: require('react-docgen-typescript').parse, 4 | }; 5 | -------------------------------------------------------------------------------- /packages/mrm-task-stylelint/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-stylelint/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-stylelint 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds [stylelint](https://stylelint.io/). 6 | 7 | ## What it does 8 | 9 | - Creates `.stylelintrc` 10 | - Adds npm script to run stylelint before tests 11 | - Installs dependencies 12 | 13 | ## Usage 14 | 15 | ``` 16 | npx mrm stylelint 17 | ``` 18 | 19 | ## Options 20 | 21 | See [Mrm docs](../../docs/Getting_started.md) and [stylelint docs](https://stylelint.io/user-guide/configuration/) for more details. 22 | 23 | ### `stylelintPreset` (default: `stylelint-config-standard`) 24 | 25 | Stylelint preset name. 26 | 27 | ### `stylelintRules` 28 | 29 | Stylelint rules. 30 | 31 | ### `stylelintExtensions` (default: `.css`) 32 | 33 | File extensions to lint. 34 | 35 | ## Changelog 36 | 37 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 38 | 39 | ## Contributing 40 | 41 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 42 | 43 | ## Authors and license 44 | 45 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 46 | 47 | MIT License, see the included [License.md](License.md) file. 48 | -------------------------------------------------------------------------------- /packages/mrm-task-stylelint/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add custom rules 1`] = ` 4 | "{ 5 | \\"rules\\": { 6 | \\"max-empty-lines\\": 2 7 | } 8 | }" 9 | `; 10 | 11 | exports[`should add stylelint 1`] = ` 12 | Object { 13 | "/.stylelintrc": "{ 14 | \\"extends\\": \\"stylelint-config-standard\\" 15 | }", 16 | "/package.json": "{ 17 | \\"name\\": \\"unicorn\\", 18 | \\"scripts\\": { 19 | \\"pretest\\": \\"npm run lint:css\\", 20 | \\"test\\": \\"jest\\", 21 | \\"lint:css\\": \\"stylelint '**/*.css'\\" 22 | } 23 | }", 24 | } 25 | `; 26 | 27 | exports[`should install a custom preset 1`] = ` 28 | "{ 29 | \\"extends\\": \\"stylelint-config-pizza\\" 30 | }" 31 | `; 32 | 33 | exports[`should use custom extension 1`] = ` 34 | "{ 35 | \\"name\\": \\"unicorn\\", 36 | \\"scripts\\": { 37 | \\"pretest\\": \\"npm run lint:css\\", 38 | \\"test\\": \\"jest\\", 39 | \\"lint:css\\": \\"stylelint '**/*.sass'\\" 40 | } 41 | }" 42 | `; 43 | -------------------------------------------------------------------------------- /packages/mrm-task-stylelint/index.js: -------------------------------------------------------------------------------- 1 | const { json, packageJson, install } = require('mrm-core'); 2 | 3 | module.exports = function task({ 4 | stylelintRules, 5 | stylelintPreset, 6 | stylelintExtensions, 7 | }) { 8 | const packages = ['stylelint']; 9 | 10 | if (stylelintPreset) { 11 | packages.push(stylelintPreset); 12 | } 13 | 14 | // .stylelintrc 15 | const stylelintrc = json('.stylelintrc'); 16 | 17 | if (stylelintPreset) { 18 | stylelintrc.merge({ 19 | extends: stylelintPreset, 20 | }); 21 | } 22 | 23 | if (stylelintRules) { 24 | stylelintrc.merge({ 25 | rules: stylelintRules, 26 | }); 27 | } 28 | 29 | stylelintrc.save(); 30 | 31 | // package.json 32 | const pkg = packageJson(); 33 | 34 | pkg 35 | // Add lint script 36 | .setScript('lint:css', `stylelint '**/*${stylelintExtensions}'`) 37 | // Add pretest script 38 | .prependScript('pretest', 'npm run lint:css') 39 | .save(); 40 | 41 | // Dependencies 42 | install(packages); 43 | }; 44 | 45 | module.exports.description = 'Adds Stylelint'; 46 | module.exports.parameters = { 47 | stylelintExtensions: { 48 | type: 'input', 49 | message: 'Enter file extensions to lint', 50 | default: '.css', 51 | }, 52 | stylelintPreset: { 53 | type: 'input', 54 | message: 'Enter Stylelint preset name', 55 | default: 'stylelint-config-standard', 56 | }, 57 | stylelintRules: { 58 | type: 'config', 59 | }, 60 | }; 61 | -------------------------------------------------------------------------------- /packages/mrm-task-stylelint/index.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('fs'); 2 | jest.mock('mrm-core/src/util/log', () => ({ 3 | added: jest.fn(), 4 | })); 5 | jest.mock('mrm-core/src/npm', () => ({ 6 | install: jest.fn(), 7 | })); 8 | 9 | const { install } = require('mrm-core'); 10 | const { getTaskOptions } = require('mrm'); 11 | const vol = require('memfs').vol; 12 | const task = require('./index'); 13 | 14 | const stringify = o => JSON.stringify(o, null, ' '); 15 | 16 | const packageJson = stringify({ 17 | name: 'unicorn', 18 | scripts: { 19 | test: 'jest', 20 | }, 21 | }); 22 | 23 | afterEach(() => { 24 | vol.reset(); 25 | install.mockClear(); 26 | }); 27 | 28 | it('should add stylelint', async () => { 29 | vol.fromJSON({ 30 | '/package.json': packageJson, 31 | }); 32 | 33 | task(await getTaskOptions(task, false, {})); 34 | 35 | expect(vol.toJSON()).toMatchSnapshot(); 36 | expect(install).toBeCalledWith(['stylelint', 'stylelint-config-standard']); 37 | }); 38 | 39 | it('should install a custom preset', async () => { 40 | vol.fromJSON({ 41 | '/package.json': packageJson, 42 | }); 43 | 44 | task( 45 | await getTaskOptions(task, false, { 46 | stylelintPreset: 'stylelint-config-pizza', 47 | }) 48 | ); 49 | 50 | expect(vol.toJSON()['/.stylelintrc']).toMatchSnapshot(); 51 | expect(install).toBeCalledWith(['stylelint', 'stylelint-config-pizza']); 52 | }); 53 | 54 | it('should add custom rules', async () => { 55 | vol.fromJSON({ 56 | '/package.json': packageJson, 57 | }); 58 | 59 | task( 60 | await getTaskOptions(task, false, { 61 | stylelintPreset: '', 62 | stylelintRules: { 'max-empty-lines': 2 }, 63 | }) 64 | ); 65 | 66 | expect(vol.toJSON()['/.stylelintrc']).toMatchSnapshot(); 67 | }); 68 | 69 | it('should use custom extension', async () => { 70 | vol.fromJSON({ 71 | '/package.json': packageJson, 72 | }); 73 | 74 | task(await getTaskOptions(task, false, { stylelintExtensions: '.sass' })); 75 | 76 | expect(vol.toJSON()['/package.json']).toMatchSnapshot(); 77 | }); 78 | -------------------------------------------------------------------------------- /packages/mrm-task-stylelint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-stylelint", 3 | "version": "5.1.23", 4 | "description": "Mrm task that adds stylelint", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-stylelint", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "stylelint", 24 | "css", 25 | "lint" 26 | ], 27 | "dependencies": { 28 | "mrm-core": "^7.1.23" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/mrm-task-travis/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-travis/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # [DEPRECATED] mrm-task-travis 4 | 5 | **Use the [ci](../ci/Readme.md) task instead.** 6 | 7 | [Mrm](https://github.com/sapegin/mrm) task that adds [Travis CI](https://travis-ci.org/). 8 | 9 | ## What it does 10 | 11 | - Creates `.travis.yml` 12 | - Adds Travis CI badge to the Readme 13 | 14 | ## Usage 15 | 16 | ``` 17 | npx mrm travis 18 | ``` 19 | 20 | ## Options 21 | 22 | See [Mrm docs](../../docs/Getting_started.md) for more details. 23 | 24 | ### `readmeFile` (default: `Readme.md`) 25 | 26 | Name of the Readme file. 27 | 28 | ### `maxNode` (default: 9) 29 | 30 | Maximum Node.js version to run tests. Minimum version will be taken from `engines.node` field of you `package.json`. 31 | 32 | ## Changelog 33 | 34 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 35 | 36 | ## Contributing 37 | 38 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 39 | 40 | ## Authors and license 41 | 42 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 43 | 44 | MIT License, see the included [License.md](License.md) file. 45 | -------------------------------------------------------------------------------- /packages/mrm-task-travis/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add Travis CI 1`] = ` 4 | Object { 5 | "/.travis.yml": "language: node_js 6 | cache: 7 | directories: 8 | - node_modules 9 | node_js: 10 | - 4 11 | - 6 12 | - 8 13 | - 10 14 | - 12 15 | ", 16 | "/package.json": "{ 17 | \\"name\\": \\"unicorn\\", 18 | \\"engines\\": { 19 | \\"node\\": 4 20 | }, 21 | \\"scripts\\": { 22 | \\"test\\": \\"jest\\" 23 | } 24 | }", 25 | } 26 | `; 27 | 28 | exports[`should add a badge to the Readme 1`] = ` 29 | "# Unicorn 30 | 31 | [![Build Status](https://travis-ci.org/mrm/unicorn/unicorn.svg)](https://travis-ci.org/mrm/unicorn/unicorn)" 32 | `; 33 | 34 | exports[`should add latest Node version if engines field is not defined 1`] = ` 35 | "language: node_js 36 | cache: 37 | directories: 38 | - node_modules 39 | node_js: 40 | - 12 41 | " 42 | `; 43 | 44 | exports[`should add latest Node version if engines field is not defined 2`] = ` 45 | "language: node_js 46 | cache: 47 | directories: 48 | - node_modules 49 | node_js: 50 | - 4 51 | - 6 52 | - 8 53 | - 10 54 | - 12 55 | - 14 56 | " 57 | `; 58 | -------------------------------------------------------------------------------- /packages/mrm-task-travis/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const { range } = require('lodash'); 3 | const semverUtils = require('semver-utils'); 4 | const packageRepoUrl = require('package-repo-url'); 5 | const { yaml, json, markdown } = require('mrm-core'); 6 | 7 | module.exports = function task({ readmeFile, maxNode }) { 8 | const pkg = json('package.json'); 9 | 10 | // .travis.yml 11 | const travisYml = yaml('.travis.yml'); 12 | 13 | travisYml.merge({ 14 | language: 'node_js', 15 | cache: { 16 | directories: ['node_modules'], 17 | }, 18 | }); 19 | 20 | // Enable caching for Yarn 21 | if (fs.existsSync('yarn.lock')) { 22 | travisYml.set('cache.yarn', true); 23 | } 24 | 25 | // Node versions range 26 | const requireNodeVersion = pkg.get('engines.node'); 27 | const minNodeVersion = requireNodeVersion 28 | ? semverUtils.parseRange(requireNodeVersion)[0].major 29 | : maxNode; 30 | 31 | // Only LTS or latest 32 | const nodeVersions = range(minNodeVersion, maxNode + 1).filter( 33 | ver => ver % 2 === 0 || ver === maxNode 34 | ); 35 | travisYml.set('node_js', nodeVersions); 36 | 37 | travisYml.save(); 38 | 39 | // Add Travis package badge to Readme 40 | const github = packageRepoUrl().replace('https://github.com/', ''); 41 | const url = `https://travis-ci.org/${github}/${pkg.get('name')}`; 42 | const readme = markdown(readmeFile); 43 | if (readme.exists()) { 44 | readme.addBadge(`${url}.svg`, url, 'Build Status').save(); 45 | } 46 | 47 | console.log(` 48 | 1. Activate your repository on Travis CI: 49 | ${url} 50 | 51 | 2. Commit and push your changes 52 | `); 53 | }; 54 | 55 | module.exports.description = 'Adds Travis CI'; 56 | module.exports.parameters = { 57 | readmeFile: { 58 | type: 'input', 59 | message: 'Enter filename for the readme', 60 | default: 'Readme.md', 61 | }, 62 | maxNode: { 63 | type: 'input', 64 | message: 'Enter the maximum Node.js versions to run tests on', 65 | default: 12, 66 | }, 67 | }; 68 | -------------------------------------------------------------------------------- /packages/mrm-task-travis/index.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('fs'); 2 | jest.mock('git-username'); 3 | jest.mock('mrm-core/src/util/log', () => ({ 4 | added: jest.fn(), 5 | })); 6 | 7 | const { getTaskOptions } = require('mrm'); 8 | const vol = require('memfs').vol; 9 | const task = require('./index'); 10 | 11 | const console$log = console.log; 12 | 13 | const stringify = o => JSON.stringify(o, null, ' '); 14 | 15 | const packageJson = stringify({ 16 | name: 'unicorn', 17 | engines: { 18 | node: 4, 19 | }, 20 | scripts: { 21 | test: 'jest', 22 | }, 23 | }); 24 | 25 | beforeEach(() => { 26 | console.log = jest.fn(); 27 | }); 28 | 29 | afterEach(() => { 30 | vol.reset(); 31 | console.log = console$log; 32 | }); 33 | 34 | it('should add Travis CI', async () => { 35 | vol.fromJSON({ 36 | '/package.json': packageJson, 37 | }); 38 | 39 | task(await getTaskOptions(task)); 40 | 41 | expect(vol.toJSON()).toMatchSnapshot(); 42 | }); 43 | 44 | it('should add latest Node version if engines field is not defined', async () => { 45 | vol.fromJSON({ 46 | '/package.json': stringify({ 47 | name: 'unicorn', 48 | scripts: { 49 | test: 'jest', 50 | }, 51 | }), 52 | }); 53 | 54 | task(await getTaskOptions(task)); 55 | 56 | expect(vol.toJSON()['/.travis.yml']).toMatchSnapshot(); 57 | }); 58 | 59 | it('should add latest Node version if engines field is not defined', async () => { 60 | vol.fromJSON({ 61 | '/package.json': packageJson, 62 | }); 63 | 64 | task(await getTaskOptions(task, false, { maxNode: 14 })); 65 | 66 | expect(vol.toJSON()['/.travis.yml']).toMatchSnapshot(); 67 | }); 68 | 69 | it('should add a badge to the Readme', async () => { 70 | vol.fromJSON({ 71 | '/package.json': packageJson, 72 | '/Readme.md': '# Unicorn', 73 | }); 74 | 75 | task(await getTaskOptions(task)); 76 | 77 | expect(vol.toJSON()['/Readme.md']).toMatchSnapshot(); 78 | }); 79 | -------------------------------------------------------------------------------- /packages/mrm-task-travis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-travis", 3 | "version": "4.1.23", 4 | "private": true, 5 | "description": "Mrm task that adds Travis CI", 6 | "author": { 7 | "name": "Artem Sapegin", 8 | "url": "https://sapegin.me" 9 | }, 10 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-travis", 11 | "repository": "sapegin/mrm", 12 | "license": "MIT", 13 | "engines": { 14 | "node": ">=10.13" 15 | }, 16 | "main": "index.js", 17 | "files": [ 18 | "index.js" 19 | ], 20 | "scripts": {}, 21 | "keywords": [ 22 | "mrm", 23 | "mrm-task", 24 | "travis ci" 25 | ], 26 | "dependencies": { 27 | "lodash": "^4.17.15", 28 | "mrm-core": "^7.1.23", 29 | "package-repo-url": "^1.0.3", 30 | "semver-utils": "^1.1.4" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/mrm-task-typescript/License.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright 2017 Artem Sapegin (http://sapegin.me), contributors 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /packages/mrm-task-typescript/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # mrm-task-typescript 4 | 5 | [Mrm](https://github.com/sapegin/mrm) task that adds [TypeScript](https://www.typescriptlang.org/). 6 | 7 | ## What it does 8 | 9 | - Creates `tsconfig.json` 10 | - Adds an npm script to run type check before tests 11 | - Installs dependencies 12 | 13 | ## Usage 14 | 15 | ``` 16 | npx mrm typescript 17 | ``` 18 | 19 | ## Changelog 20 | 21 | The changelog can be found in [CHANGELOG.md](CHANGELOG.md). 22 | 23 | ## Contributing 24 | 25 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 26 | 27 | ## Authors and license 28 | 29 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 30 | 31 | MIT License, see the included [License.md](License.md) file. 32 | -------------------------------------------------------------------------------- /packages/mrm-task-typescript/__snapshots__/index.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should add TypeScript 1`] = ` 4 | Object { 5 | "/package.json": "{ 6 | \\"name\\": \\"unicorn\\", 7 | \\"scripts\\": { 8 | \\"pretest\\": \\"tsc --noEmit\\", 9 | \\"test\\": \\"jest\\" 10 | } 11 | }", 12 | "/tsconfig.json": "{ 13 | \\"compilerOptions\\": { 14 | \\"target\\": \\"es6\\", 15 | \\"module\\": \\"commonjs\\", 16 | \\"moduleResolution\\": \\"node\\", 17 | \\"strict\\": true, 18 | \\"experimentalDecorators\\": true, 19 | \\"emitDecoratorMetadata\\": true, 20 | \\"noUnusedLocals\\": true, 21 | \\"pretty\\": true, 22 | \\"lib\\": [ 23 | \\"esnext\\" 24 | ] 25 | } 26 | }", 27 | } 28 | `; 29 | -------------------------------------------------------------------------------- /packages/mrm-task-typescript/index.js: -------------------------------------------------------------------------------- 1 | const { json, packageJson, install } = require('mrm-core'); 2 | 3 | const packages = ['typescript']; 4 | 5 | function task() { 6 | // tsconfig.json 7 | json('tsconfig.json') 8 | .merge({ 9 | compilerOptions: { 10 | target: 'es6', 11 | module: 'commonjs', 12 | moduleResolution: 'node', 13 | strict: true, 14 | experimentalDecorators: true, 15 | emitDecoratorMetadata: true, 16 | noUnusedLocals: true, 17 | pretty: true, 18 | lib: ['esnext'], 19 | }, 20 | }) 21 | .save(); 22 | 23 | // package.json 24 | packageJson() 25 | .appendScript('pretest', 'tsc --noEmit') 26 | .save(); 27 | 28 | // Dependencies 29 | install(packages); 30 | } 31 | task.description = 'Adds TypeScript'; 32 | 33 | module.exports = task; 34 | -------------------------------------------------------------------------------- /packages/mrm-task-typescript/index.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('fs'); 2 | jest.mock('mrm-core/src/util/log', () => ({ 3 | added: jest.fn(), 4 | })); 5 | jest.mock('mrm-core/src/npm', () => ({ 6 | install: jest.fn(), 7 | })); 8 | 9 | const vol = require('memfs').vol; 10 | const task = require('./index'); 11 | 12 | const stringify = o => JSON.stringify(o, null, ' '); 13 | 14 | const packageJson = stringify({ 15 | name: 'unicorn', 16 | scripts: { 17 | test: 'jest', 18 | }, 19 | }); 20 | 21 | afterEach(() => vol.reset()); 22 | 23 | it('should add TypeScript', () => { 24 | vol.fromJSON({ 25 | '/package.json': packageJson, 26 | }); 27 | 28 | task({}); 29 | 30 | expect(vol.toJSON()).toMatchSnapshot(); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/mrm-task-typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm-task-typescript", 3 | "version": "4.1.23", 4 | "description": "Mrm task that adds TypeScript", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm/tree/master/packages/mrm-task-typescript", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=10.13" 14 | }, 15 | "main": "index.js", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "scripts": {}, 20 | "keywords": [ 21 | "mrm", 22 | "mrm-task", 23 | "typescript" 24 | ], 25 | "dependencies": { 26 | "mrm-core": "^7.1.23" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/mrm/Readme.md: -------------------------------------------------------------------------------- 1 | # Mrm 2 | 3 | [![npm](https://img.shields.io/npm/v/mrm.svg)](https://www.npmjs.com/package/mrm) 4 | 5 | Command line tool to help you keep configuration (`package.json`, `.gitignore`, `.eslintrc`, etc.) of your open source projects in sync. 6 | 7 | See [documentation](https://mrm.js.org/docs/getting-started). 8 | 9 | ## Changelog 10 | 11 | The changelog can be found on the [Releases page](https://github.com/sapegin/mrm/releases). 12 | 13 | ## Contributing 14 | 15 | Everyone is welcome to contribute. Please take a moment to review the [contributing guidelines](../../Contributing.md). 16 | 17 | ## Authors and license 18 | 19 | [Artem Sapegin](https://sapegin.me) and [contributors](https://github.com/sapegin/mrm/graphs/contributors). 20 | 21 | MIT License, see the included [License.md](License.md) file. 22 | -------------------------------------------------------------------------------- /packages/mrm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mrm", 3 | "version": "4.1.23", 4 | "description": "Codemods for your project config files", 5 | "author": { 6 | "name": "Artem Sapegin", 7 | "url": "http://sapegin.me" 8 | }, 9 | "homepage": "https://github.com/sapegin/mrm", 10 | "repository": "sapegin/mrm", 11 | "license": "MIT", 12 | "main": "src/index.js", 13 | "bin": "bin/mrm.js", 14 | "engines": { 15 | "node": ">=10.13" 16 | }, 17 | "files": [ 18 | "bin", 19 | "src" 20 | ], 21 | "dependencies": { 22 | "git-username": "^1.0.0", 23 | "glob": "^7.1.6", 24 | "inquirer": "^7.0.4", 25 | "is-directory": "^0.3.1", 26 | "kleur": "^3.0.3", 27 | "libnpx": "^10.2.4", 28 | "listify": "^1.0.0", 29 | "lodash": "^4.17.15", 30 | "longest": "^2.0.1", 31 | "middleearth-names": "^1.1.0", 32 | "minimist": "^1.2.0", 33 | "mrm-core": "^7.1.23", 34 | "semver-utils": "^1.1.4", 35 | "update-notifier": "^4.1.0", 36 | "user-home": "^2.0.0", 37 | "user-meta": "^1.0.0", 38 | "which": "^2.0.2" 39 | }, 40 | "keywords": [ 41 | "boilerplate", 42 | "cli", 43 | "codemod", 44 | "command line", 45 | "generate", 46 | "generator", 47 | "ini", 48 | "json", 49 | "markdown", 50 | "runner", 51 | "scaffold", 52 | "task", 53 | "template", 54 | "tool", 55 | "yaml" 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /packages/mrm/src/errors.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | class MrmUnknownTask extends Error { 4 | constructor(message, extra) { 5 | super(message); 6 | Object.defineProperty(this, 'name', { 7 | value: this.constructor.name, 8 | }); 9 | Object.defineProperty(this, 'extra', { 10 | value: extra, 11 | }); 12 | } 13 | } 14 | 15 | class MrmInvalidTask extends Error { 16 | constructor(message, extra) { 17 | super(message); 18 | Object.defineProperty(this, 'name', { 19 | value: this.constructor.name, 20 | }); 21 | Object.defineProperty(this, 'extra', { 22 | value: extra, 23 | }); 24 | } 25 | } 26 | 27 | class MrmUnknownAlias extends Error { 28 | constructor(message) { 29 | super(message); 30 | Object.defineProperty(this, 'name', { 31 | value: this.constructor.name, 32 | }); 33 | } 34 | } 35 | 36 | class MrmUndefinedOption extends Error { 37 | constructor(message, extra) { 38 | super(message); 39 | Object.defineProperty(this, 'name', { 40 | value: this.constructor.name, 41 | }); 42 | Object.defineProperty(this, 'extra', { 43 | value: extra, 44 | }); 45 | } 46 | } 47 | 48 | module.exports = { 49 | MrmUnknownTask, 50 | MrmInvalidTask, 51 | MrmUnknownAlias, 52 | MrmUndefinedOption, 53 | }; 54 | -------------------------------------------------------------------------------- /packages/mrm/test/dir1/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "pizza": "salami", 3 | "aliases": { 4 | "alias1": ["task1", "task3"] 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/mrm/test/dir1/task1/index.js: -------------------------------------------------------------------------------- 1 | module.exports = jest.fn(); 2 | module.exports.description = 'Taks 1.1'; 3 | -------------------------------------------------------------------------------- /packages/mrm/test/dir1/task2/index.js: -------------------------------------------------------------------------------- 1 | module.exports = jest.fn(); 2 | module.exports.description = 'Taks 1.2'; 3 | -------------------------------------------------------------------------------- /packages/mrm/test/dir2/task2/index.js: -------------------------------------------------------------------------------- 1 | module.exports = jest.fn(); 2 | module.exports.description = 'Taks 2.2'; 3 | -------------------------------------------------------------------------------- /packages/mrm/test/dir2/task3/index.js: -------------------------------------------------------------------------------- 1 | module.exports = jest.fn(); 2 | module.exports.description = 'Taks 2.3'; 3 | -------------------------------------------------------------------------------- /packages/mrm/test/dir2/task4/index.js: -------------------------------------------------------------------------------- 1 | module.exports = jest.fn((options, params) => { 2 | return new Promise(resolve => { 3 | setTimeout(() => { 4 | params.stack.push('Task 2.4'); 5 | resolve(); 6 | }, 10); 7 | }); 8 | }); 9 | module.exports.description = 'Taks 2.4'; 10 | -------------------------------------------------------------------------------- /packages/mrm/test/dir2/task5/index.js: -------------------------------------------------------------------------------- 1 | module.exports = jest.fn((options, params) => { 2 | return new Promise(resolve => { 3 | setTimeout(() => { 4 | params.stack.push('Task 2.5'); 5 | resolve(); 6 | }); 7 | }); 8 | }); 9 | module.exports.description = 'Taks 2.5'; 10 | -------------------------------------------------------------------------------- /packages/mrm/test/dir3/task6/index.js: -------------------------------------------------------------------------------- 1 | module.exports = jest.fn(); 2 | module.exports.description = 'Taks 3.6'; 3 | module.exports.parameters = { 4 | 'first-config': { 5 | type: 'input', 6 | message: 'Please, fulfil this first interactive input', 7 | }, 8 | 'second-config': { 9 | type: 'input', 10 | message: 'Please, fulfil this second interactive input', 11 | default: 'default value', 12 | }, 13 | 'third-config': { 14 | type: 'input', 15 | message: 'Please, fulfil this third interactive input', 16 | default: jest.fn( 17 | values => 18 | values['second-config'] && 19 | values['second-config'] 20 | .split('') 21 | .reverse() 22 | .join('') 23 | ), 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /packages/mrm/test/dir4/task7/index.js: -------------------------------------------------------------------------------- 1 | module.exports = 'invalid'; 2 | -------------------------------------------------------------------------------- /packages/mrm/test/dir5/task8/index.js: -------------------------------------------------------------------------------- 1 | module.exports = jest.fn(); 2 | module.exports.description = 'Taks 5.8'; 3 | module.exports.parameters = { 4 | 'interactive-config': { 5 | type: 'input', 6 | message: 'Please, fulfil this first interactive input', 7 | validate: value => (value === 'pizza' ? true : 'Invalid!'), 8 | }, 9 | 'static-config': { 10 | type: 'config', 11 | default: 'default value', 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /packages/mrm/test/dir6/task1/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../dir1/task1'); 2 | -------------------------------------------------------------------------------- /site/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | docs 11 | 12 | # Misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /site/Readme.md: -------------------------------------------------------------------------------- 1 | # [Mrm site](https://mrm.js.org/) 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/fc0ecb8b-3ab1-406d-be20-ea357f4889ab/deploy-status)](https://app.netlify.com/sites/mrmjs/deploys) 4 | 5 | This site is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static site generator. 6 | 7 | ### Installation 8 | 9 | ``` 10 | npm install 11 | ``` 12 | 13 | ### Local Development 14 | 15 | ``` 16 | npm start 17 | ``` 18 | 19 | This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. 20 | 21 | ### Build 22 | 23 | ``` 24 | npm run build 25 | ``` 26 | 27 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 28 | -------------------------------------------------------------------------------- /site/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'Mrm', 3 | tagline: 'Codemods for your project config files', 4 | url: 'https://mrm.js.org', 5 | baseUrl: '/', 6 | favicon: 'img/favicon.png', 7 | organizationName: 'sapegin', 8 | projectName: 'mrm', 9 | themeConfig: { 10 | colorMode: { 11 | disableSwitch: true, 12 | }, 13 | prism: { 14 | theme: require('prism-react-renderer/themes/nightOwlLight'), 15 | }, 16 | navbar: { 17 | hideOnScroll: false, 18 | title: 'Mrm', 19 | items: [ 20 | { 21 | to: 'docs/getting-started', 22 | activeBasePath: 'docs', 23 | label: 'Docs', 24 | position: 'left', 25 | }, 26 | { 27 | to: 'docs/mrm-task-ci', 28 | activeBasePath: 'docs', 29 | label: 'Tasks', 30 | position: 'left', 31 | }, 32 | { 33 | href: 'https://github.com/sapegin/mrm', 34 | label: 'GitHub', 35 | position: 'right', 36 | }, 37 | ], 38 | }, 39 | footer: { 40 | style: 'dark', 41 | links: [ 42 | { 43 | title: 'Docs', 44 | items: [ 45 | { 46 | label: 'Changelog', 47 | href: 'https://github.com/sapegin/mrm/releases', 48 | }, 49 | { 50 | label: 'Contributing', 51 | href: 52 | 'https://github.com/sapegin/mrm/blob/master/Contributing.md', 53 | }, 54 | ], 55 | }, 56 | { 57 | title: 'Social', 58 | items: [ 59 | { 60 | label: 'Twitter', 61 | href: 'https://twitter.com/iamsapegin', 62 | }, 63 | { 64 | label: 'GitHub', 65 | href: 'https://github.com/sapegin/mrm', 66 | }, 67 | ], 68 | }, 69 | { 70 | title: 'Sponsor', 71 | items: [ 72 | { 73 | label: 'Buy me a coffee', 74 | href: 'https://www.buymeacoffee.com/sapegin', 75 | }, 76 | ], 77 | }, 78 | ], 79 | copyright: `Made with coffee in Berlin by Artem Sapegin and contributors`, 80 | }, 81 | }, 82 | plugins: [require.resolve('./src/plugins/goatcounter-plugin.js')], 83 | presets: [ 84 | [ 85 | '@docusaurus/preset-classic', 86 | { 87 | debug: false, 88 | docs: { 89 | includeCurrentVersion: true, 90 | sidebarPath: require.resolve('./sidebars.js'), 91 | remarkPlugins: require('./remark'), 92 | }, 93 | theme: { 94 | customCss: require.resolve('./src/css/custom.css'), 95 | }, 96 | }, 97 | ], 98 | ], 99 | }; 100 | -------------------------------------------------------------------------------- /site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "site", 3 | "version": "0.0.4", 4 | "private": true, 5 | "scripts": { 6 | "start": "docusaurus start", 7 | "build": "docusaurus build", 8 | "swizzle": "docusaurus swizzle", 9 | "deploy": "docusaurus deploy", 10 | "sync": "node scripts/sync.js" 11 | }, 12 | "dependencies": { 13 | "@docusaurus/core": "2.0.0-alpha.65", 14 | "@docusaurus/preset-classic": "2.0.0-alpha.65", 15 | "clsx": "^1.1.1", 16 | "fs-extra": "^9.0.1", 17 | "glob": "^7.1.6", 18 | "lodash": "^4.17.15", 19 | "react": "^16.13.1", 20 | "react-dom": "^16.13.1", 21 | "unist-util-visit": "^2.0.2" 22 | }, 23 | "browserslist": { 24 | "production": [ 25 | ">0.2%", 26 | "not dead", 27 | "not op_mini all" 28 | ], 29 | "development": [ 30 | "last 1 chrome version", 31 | "last 1 firefox version", 32 | "last 1 safari version" 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /site/remark.js: -------------------------------------------------------------------------------- 1 | const visit = require('unist-util-visit'); 2 | const { kebabCase } = require('lodash'); 3 | 4 | const IGNORES = [ 5 | 'https://github.com/sapegin/mrm/tree/master/packages/mrm-task-license/templates', 6 | ]; 7 | const REPLACEMENTS = { 8 | 'https://github.com/sapegin/mrm': 'https://mrm.js.org/', 9 | '../Readme.md#tasks': '/docs/mrm-task-codecov', 10 | }; 11 | const PACKAGES_URL_PREFIX = 12 | 'https://github.com/sapegin/mrm/tree/master/packages/'; 13 | 14 | const getDocUrl = url => 15 | url 16 | .replace(/(\w+)(?:\.md)/, (_, $1) => kebabCase($1)) 17 | .replace(/^\.\.\/\.\.\/docs\//, '/docs/') 18 | .replace(/^\.\//, '/docs/'); 19 | 20 | const getPacakgeUrl = url => `/docs/${url.replace(PACKAGES_URL_PREFIX, '')}`; 21 | 22 | /* 23 | * Fix links: 24 | * Getting_started.md -> /docs/getting-started 25 | * https://github.com/sapegin/mrm/tree/master/packages/mrm-task-eslint -> /docs/mrm-task-eslint 26 | */ 27 | function link() { 28 | return ast => 29 | visit(ast, 'link', node => { 30 | if (IGNORES.includes(node.url)) { 31 | return; 32 | } 33 | if (REPLACEMENTS[node.url]) { 34 | node.url = REPLACEMENTS[node.url]; 35 | } else if (node.url.endsWith('.md') || node.url.includes('.md#')) { 36 | node.url = getDocUrl(node.url); 37 | } else if (node.url.startsWith(PACKAGES_URL_PREFIX)) { 38 | node.url = getPacakgeUrl(node.url); 39 | } 40 | }); 41 | } 42 | 43 | module.exports = [link]; 44 | -------------------------------------------------------------------------------- /site/scripts/sync.js: -------------------------------------------------------------------------------- 1 | // Get docs from the docs folder and each preset and task 2 | 3 | const { readFileSync, writeFileSync, emptyDirSync } = require('fs-extra'); 4 | const glob = require('glob'); 5 | const { kebabCase } = require('lodash'); 6 | 7 | const DEST_DIR = 'docs'; 8 | 9 | const read = file => readFileSync(file, 'utf8'); 10 | const write = (file, contents) => 11 | writeFileSync(`${DEST_DIR}/${file}.md`, contents); 12 | 13 | const getTitle = contents => contents.match(/^#\s*(.*?)$/m) || []; 14 | const getSidebarTitle = contents => contents.match(/^/) || []; 15 | const stripTitle = contents => contents.replace(/^#.*?$/m, ''); 16 | const getEditUrl = relativePath => 17 | `https://github.com/sapegin/mrm/edit/master/${relativePath.replace( 18 | '../', 19 | '' 20 | )}`; 21 | 22 | const template = ({ id, title, sidebarLabel, editUrl, contents }) => `--- 23 | id: ${id} 24 | title: "${title}" 25 | sidebar_label: "${sidebarLabel}" 26 | custom_edit_url: ${getEditUrl(editUrl)} 27 | --- 28 | 29 | ${stripTitle(contents)}`; 30 | 31 | emptyDirSync(DEST_DIR); 32 | 33 | console.log('Syncing docs...'); 34 | 35 | const docs = glob.sync('../docs/*.md'); 36 | docs.forEach(filepath => { 37 | console.log(`👉 ${filepath}`); 38 | const contents = read(filepath); 39 | const [, title] = getTitle(contents); 40 | const [, sidebarLabel = title] = getSidebarTitle(contents); 41 | const id = kebabCase(sidebarLabel); 42 | write( 43 | id, 44 | template({ 45 | id, 46 | title, 47 | sidebarLabel, 48 | editUrl: filepath, 49 | contents, 50 | }) 51 | ); 52 | }); 53 | 54 | console.log('\nSyncing packages...'); 55 | 56 | const packages = glob.sync('../packages/*/Readme.md'); 57 | packages.forEach(filepath => { 58 | console.log(`👉 ${filepath}`); 59 | const contents = read(filepath); 60 | const [, package] = getTitle(contents); 61 | const title = package.replace('mrm-taks-', '').replace('mrm-preset-', ''); 62 | const [, sidebarLabel = title] = getSidebarTitle(contents); 63 | 64 | if (title.startsWith('[DEPRECATED]')) { 65 | return; 66 | } 67 | 68 | const id = kebabCase(package); 69 | write( 70 | id, 71 | template({ 72 | id, 73 | title: package, 74 | sidebarLabel, 75 | editUrl: filepath, 76 | contents: contents.split('## Changelog')[0], 77 | }) 78 | ); 79 | }); 80 | -------------------------------------------------------------------------------- /site/sidebars.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | someSidebar: { 3 | Docs: [ 4 | 'getting-started', 5 | 'making-tasks', 6 | 'sharing-tasks', 7 | 'making-presets', 8 | 'mrm-core', 9 | 'faq', 10 | ], 11 | Tasks: [ 12 | 'mrm-task-ci', 13 | 'mrm-task-codecov', 14 | 'mrm-task-contributing', 15 | 'mrm-task-editorconfig', 16 | 'mrm-task-eslint', 17 | 'mrm-task-gitignore', 18 | 'mrm-task-license', 19 | 'mrm-task-lint-staged', 20 | 'mrm-task-package', 21 | 'mrm-task-prettier', 22 | 'mrm-task-readme', 23 | 'mrm-task-semantic-release', 24 | 'mrm-task-styleguidist', 25 | 'mrm-task-typescript', 26 | ], 27 | }, 28 | }; 29 | -------------------------------------------------------------------------------- /site/src/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "tamia/react" 4 | } 5 | -------------------------------------------------------------------------------- /site/src/components/CarbonAds.js: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect } from 'react'; 2 | import styles from './CarbonAds.module.css'; 3 | 4 | const CARBON_URL = 5 | 'https://cdn.carbonads.com/carbon.js?serve=CEBIVK3W&placement=mrmjsorg'; 6 | 7 | export const CarbonAds = React.memo(() => { 8 | const ref = useRef(); 9 | 10 | useEffect(() => { 11 | const container = ref.current; 12 | // Add a tiny delay because Docusaurus rerenders the sidebar twice 13 | // on first page load 14 | const timeout = setTimeout(() => { 15 | const script = document.createElement('script'); 16 | script.src = CARBON_URL; 17 | script.async = true; 18 | script.id = '_carbonads_js'; 19 | container.appendChild(script); 20 | }, 100); 21 | 22 | return () => clearTimeout(timeout); 23 | }, [ref]); 24 | 25 | return
; 26 | }); 27 | -------------------------------------------------------------------------------- /site/src/components/CarbonAds.module.css: -------------------------------------------------------------------------------- 1 | :global #carbonads { 2 | position: relative; 3 | max-width: 40rem; 4 | margin: 0 auto; 5 | padding: 0.25rem; 6 | outline: 1px solid var(--ifm-color-emphasis-300); 7 | } 8 | 9 | :global #carbonads:focus-within { 10 | outline: 2px solid var(--ifm-color-primary); 11 | } 12 | 13 | .carbon :global a { 14 | color: inherit; 15 | text-decoration: none; 16 | } 17 | 18 | .carbon :global a:hover, 19 | .carbon :global a:active, 20 | .carbon :global a:focus { 21 | outline: 0; 22 | color: var(--ifm-color-primary); 23 | } 24 | 25 | .carbon :global span { 26 | position: relative; 27 | display: block; 28 | overflow: hidden; 29 | } 30 | 31 | .carbon :global(.carbon-wrap) { 32 | display: flex; 33 | line-height: 1.3; 34 | } 35 | 36 | .carbon :global(.carbon-img) { 37 | display: block; 38 | margin-right: 1rem; 39 | line-height: 1; 40 | } 41 | 42 | .carbon :global(.carbon-img) img { 43 | display: block; 44 | } 45 | 46 | .carbon :global(.carbon-text) { 47 | display: block; 48 | padding-bottom: 1.5rem; 49 | font-size: 90%; 50 | text-align: left; 51 | } 52 | 53 | .carbon :global(.carbon-poweredby) { 54 | position: absolute; 55 | right: 0.25rem; 56 | bottom: 0.25rem; 57 | text-transform: uppercase; 58 | letter-spacing: 0.1ch; 59 | font-weight: 600; 60 | font-size: 65%; 61 | line-height: 1; 62 | } 63 | 64 | @media (min-width: 997px) { 65 | .carbon :global(.carbon-wrap) { 66 | display: block; 67 | } 68 | 69 | .carbon :global(.carbon-img) { 70 | margin-left: 0; 71 | margin-bottom: 0.5rem; 72 | } 73 | 74 | .carbon :global(.carbon-text) { 75 | padding-bottom: 0; 76 | } 77 | 78 | .carbon :global(.carbon-poweredby) { 79 | position: static; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /site/src/components/Terminal.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import styles from './Terminal.module.css'; 4 | 5 | export const Terminal = ({ children, ...rest }) => ( 6 |
7 | {children} 8 |
9 | ); 10 | 11 | Terminal.propTypes = { 12 | children: PropTypes.node, 13 | }; 14 | 15 | export const TerminalText = ({ children, color, ...rest }) => ( 16 | 17 | {children} 18 | 19 | ); 20 | 21 | TerminalText.propTypes = { 22 | children: PropTypes.node.isRequired, 23 | color: PropTypes.string.isRequired, 24 | }; 25 | -------------------------------------------------------------------------------- /site/src/components/Terminal.module.css: -------------------------------------------------------------------------------- 1 | .terminal { 2 | position: relative; 3 | padding: 3rem 1rem 1rem; 4 | color: #c4a48a; 5 | background-color: #2f251d; 6 | border-radius: calc(var(--ifm-global-radius) * 1.5) 7 | calc(var(--ifm-global-radius) * 1.5) var(--ifm-global-radius) 8 | var(--ifm-global-radius); 9 | font-weight: bold; 10 | font-family: var(--ifm-font-family-monospace); 11 | line-height: var(--ifm-pre-line-height); 12 | font-size: 1.1rem; 13 | white-space: pre; 14 | } 15 | 16 | .terminal::before { 17 | content: ''; 18 | position: absolute; 19 | top: 0; 20 | right: 0; 21 | left: 0; 22 | height: 2rem; 23 | background-color: #d2d2d2; 24 | border-radius: var(--ifm-global-radius) var(--ifm-global-radius) 0 0; 25 | } 26 | 27 | .terminal::after { 28 | content: ''; 29 | position: absolute; 30 | top: 0.5rem; 31 | left: 0.5rem; 32 | width: 1rem; 33 | height: 1rem; 34 | background-color: #f95955; 35 | border-radius: 99999rem; 36 | box-shadow: 1.6rem 0 0 #fcbe40, 3.2rem 0 0 #44cc4b; 37 | } 38 | 39 | .text__white { 40 | color: #f3ebd4; 41 | } 42 | 43 | .text__cyan { 44 | color: #3ab9c2; 45 | } 46 | 47 | .text__green { 48 | color: #36a822; 49 | } 50 | -------------------------------------------------------------------------------- /site/src/components/VisuallyHidden.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import styles from './VisuallyHidden.module.css'; 4 | 5 | export const VisuallyHidden = ({ 6 | children, 7 | as: Component = 'span', 8 | ...rest 9 | }) => ( 10 | 11 | {children} 12 | 13 | ); 14 | 15 | VisuallyHidden.propTypes = { 16 | children: PropTypes.node.isRequired, 17 | as: PropTypes.string, 18 | }; 19 | -------------------------------------------------------------------------------- /site/src/components/VisuallyHidden.module.css: -------------------------------------------------------------------------------- 1 | .visuallyHidden { 2 | border: 0; 3 | clip: rect(0 0 0 0); 4 | height: 1px; 5 | margin: -1px; 6 | overflow: hidden; 7 | padding: 0; 8 | position: absolute; 9 | width: 1px; 10 | white-space: nowrap; 11 | word-wrap: normal; 12 | } 13 | -------------------------------------------------------------------------------- /site/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | /** 3 | * Any CSS included here will be global. The classic template 4 | * bundles Infima by default. Infima is a CSS framework designed to 5 | * work well for content-centric websites. 6 | */ 7 | 8 | /* You can override the default Infima variables here. */ 9 | :root { 10 | --ifm-color-primary: #538000; 11 | --ifm-color-primary-dark: #4b7300; 12 | --ifm-color-primary-darker: #476d00; 13 | --ifm-color-primary-darkest: #3a5a00; 14 | --ifm-color-primary-light: #5b8d00; 15 | --ifm-color-primary-lighter: #5f9300; 16 | --ifm-color-primary-lightest: #6ca600; 17 | --ifm-font-color-base: #333; 18 | --ifm-button-color: #333; 19 | --ifm-button-background-color: #fff; 20 | --ifm-link-decoration: underline; 21 | --ifm-footer-background-color: #2f430a; 22 | } 23 | 24 | a:focus { 25 | outline: solid 2px; 26 | outline-offset: 2px; 27 | } 28 | 29 | .docusaurus-highlight-code-line { 30 | background-color: rgb(72, 77, 91); 31 | display: block; 32 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 33 | padding: 0 var(--ifm-pre-padding); 34 | } 35 | 36 | .button:focus { 37 | box-shadow: 0 0 0 2px var(--ifm-color-primary), 38 | 0 0 0 4px var(--ifm-button-background-color); 39 | } 40 | -------------------------------------------------------------------------------- /site/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | .heroBanner { 2 | --ifm-heading-line-height: 1; 3 | padding: 3rem 0; 4 | text-align: center; 5 | } 6 | 7 | @media screen and (max-width: 966px) { 8 | .heroBanner { 9 | padding: 2rem; 10 | } 11 | } 12 | 13 | .main { 14 | padding: 3rem 0; 15 | } 16 | 17 | .section + .section { 18 | margin-top: 2rem; 19 | } 20 | -------------------------------------------------------------------------------- /site/src/plugins/goatcounter-plugin.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'goatcounter-plugin', 4 | injectHtmlTags() { 5 | return { 6 | headTags: [ 7 | ``, 26 | { 27 | tagName: 'script', 28 | attributes: { 29 | 'data-goatcounter': 'https://mrm.goatcounter.com/count', 30 | async: true, 31 | src: '//gc.zgo.at/count.js', 32 | }, 33 | }, 34 | ], 35 | }; 36 | }, 37 | }; 38 | }; 39 | -------------------------------------------------------------------------------- /site/src/theme/DocSidebar/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import DocSidebarBase from '@theme-original/DocSidebar'; 4 | import { CarbonAds } from '../../components/CarbonAds'; 5 | import styles from './styles.module.css'; 6 | 7 | function Extra() { 8 | return ( 9 |
10 | 11 |
12 | ); 13 | } 14 | 15 | function DocSidebar({ showExtra, ...props }) { 16 | return ( 17 |
18 | {showExtra && } 19 | 20 |
21 | ); 22 | } 23 | 24 | DocSidebar.propTypes = { 25 | path: PropTypes.string.isRequired, 26 | showExtra: PropTypes.bool, 27 | }; 28 | 29 | DocSidebar.defaultProps = { 30 | showExtra: true, 31 | }; 32 | 33 | export default DocSidebar; 34 | -------------------------------------------------------------------------------- /site/src/theme/DocSidebar/styles.module.css: -------------------------------------------------------------------------------- 1 | /* Styles below are mostly copy of the default theme styles. We need to move 2 | the sidebar container styles to our own container that contains both: 3 | the original sidebar (with styles on the root element removed) and CodeFund 4 | container */ 5 | 6 | .extra { 7 | min-height: 9rem; 8 | padding: 1rem 1.5rem; 9 | } 10 | 11 | /* HACK: Horizontal Carbon Ads layout */ 12 | @media (max-width: 996px) { 13 | [class*='docSidebarContainer'] { 14 | --ifm-toc-border-color: transparent; 15 | width: auto !important; 16 | } 17 | } 18 | 19 | @media (min-width: 997px) { 20 | .sidebar { 21 | height: 100vh; 22 | overflow-y: auto; 23 | position: sticky; 24 | top: 0; 25 | } 26 | 27 | /* HACK: Remove styles from the theme sidebar container */ 28 | .sidebar > *:first-child + * { 29 | height: initial; 30 | overflow: initial; 31 | position: initial; 32 | top: initial; 33 | padding-top: initial; 34 | } 35 | 36 | .sidebar::-webkit-scrollbar { 37 | width: 7px; 38 | } 39 | 40 | .sidebar::-webkit-scrollbar-track { 41 | background: #f1f1f1; 42 | border-radius: 10px; 43 | } 44 | 45 | .sidebar::-webkit-scrollbar-thumb { 46 | background: #888; 47 | border-radius: 10px; 48 | } 49 | 50 | .sidebar::-webkit-scrollbar-thumb:hover { 51 | background: #555; 52 | } 53 | 54 | .extra { 55 | min-height: 17.2rem; 56 | padding: 0.5rem; 57 | padding-top: calc(0.5rem + var(--ifm-navbar-height)); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /site/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sapegin/mrm/7cf2eb7562696a6881330d001c5d9fdb610bf1ef/site/static/img/favicon.png -------------------------------------------------------------------------------- /site/static/img/mrm-article.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sapegin/mrm/7cf2eb7562696a6881330d001c5d9fdb610bf1ef/site/static/img/mrm-article.png -------------------------------------------------------------------------------- /site/static/img/mrm-video.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sapegin/mrm/7cf2eb7562696a6881330d001c5d9fdb610bf1ef/site/static/img/mrm-video.jpg -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "packages/*/types/*.ts" 4 | ] 5 | } 6 | --------------------------------------------------------------------------------