We use many tools, like linters, test runners and continuous integration, to make our life as developers easier. But maintaining configuration for these tools is far from easy, especially if you want up-to-date configs in all your projects. Mrm tries to solve this problem.
Slightly different files. Photo by yours truly.
The only thing that many times was preventing me from extracting some generic function to a separate package is a need to copy and modify a dozen of config files — all that .somethingrc
s — just to publish a 50-line function.
These support files are usually only slightly different in all your projects. For example, a .gitignore
file has node_modules
and editor artifacts that you want to share between all your projects, but some projects have extra lines there that you don’t want in other projects. We need a way to keep in sync the common parts but allow per-project customizations.
Template-based tools, like Yeoman, are good for initial project bootstrapping but don’t work well for updates: they would overwrite a file with a new version and you’ll lose your customizations.
Mrm takes a different approach. It works similar to codemods: instead of a template that would overwrite everything, you’re describing in code how to modify or create files to achieve the desired state of the file.
Mrm tries to do minimal changes by inferring indentation style or reading it from the EditorConfig, and keeping comments in JSON files.
It has minimal required configuration: it’ll use values from the project itself or from the environment, like reading your name and email from your Git or npm configs.
Mrm has utilities to work with popular config file formats: JSON, YAML, INI and new line separated text files; install npm packages; and file operations.
This allows you to create smart tasks, so the result depends on your project needs.
Mrm has many tasks out of the box: CodeCov, EditorConfig, ESLint, .gitignore, Jest, lint-staged, Prettier, semantic-release, React Styleguidist, stylelint, Travis CI, TypeScript, package.json, contributing guidelines, license and readme file. You can create your own task or combine multiple tasks using aliases.
For example, the Jest task:
package.json
if needed;.gitignore
, .npmignore
, .eslintignore
with common patterns;babel-jest
, ts-jest
or Enzyme if needed;jest-codemods
if projects used other test frameworks.
Or the gitignore task that will add new lines to the .gitignore
file but won’t remove per-project customizations:
Install Mrm from npm:
npm install -g mrm
And run like this:
mrm gitignoremrm license --config:licenseFile
Or run Mrm via npx without installation:
npx mrm gitignorenpx mrm license --config:licenseFile
Optionally, create a config file at ~/.mrm/config.json
or ~/dotfiles/mrm/config.json
instead of passing values via command line:
{ "github": "sapegin", "eslintPreset": "airbnb", "aliases": { // Aliases to run multiple tasks at once "node": ["license", "readme", "editorconfig", "gitignore"] }}
See more usage examples and options in the docs.
The real power of Mrm is in custom tasks and mrm-core library that gives you tools to work with config files, dependencies, file operations, etc.
The simplest task could look like this:
// Mrm module to work with new line separated text filesconst { lines } = require('mrm-core');function task() { // Read .gitignore if it exists lines('.gitignore') // Add lines that do not exist in a file yet, // but keep all existing lines .add(['node_modules/', '.DS_Store']) // Update or create a file .save();}task.description = 'Adds .gitignore';module.exports = task;
See more examples in the docs.
You can save your tasks locally, publish them on npm or combine multiple tasks in a preset.
If you have many projects with a similar stack or a big multi-repository project, Mrm may be a good way to manage their configuration and could save your time.
Start with default tasks and then write your own or create a preset for your project or organization.
The project is still young — let me know what you think in comments or GitHub issues.
P.S. Check out our new book on JavaScript projects maintenance.
Thanks to Anna Gerus, Karl Horky, Andrey Okonetchnikov, Oleg Slobodskoi, Olga Sylenko, Juho Vepsäläinen.