# automutate

> Applies waves of mutations provided by other tools, such as linters.

Latest version **0.9.0** (published 2022-07-25) · MIT license · 0 weekly downloads

## Install

```sh
npm install automutate
pnpm add automutate
yarn add automutate
bun add automutate
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.9.0 |
| Published | 2022-07-25 |
| First published | 2016-11-24 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 126.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 17 |
| Author | joshuakgoldberg@outlook.com |
| Maintainers | joshuakgoldberg |
| Keywords | lint, autolint, linter, clean, code, quality, tslint, lesshint, eslint |

## Links

- npm: https://www.npmjs.com/package/automutate
- Repository: https://github.com/automutate/automutate
- Homepage: https://github.com/automutate/automutate#readme
- Issues: https://github.com/automutate/automutate/issues
- npm.io page: https://npm.io/package/automutate

## Alternatives

- [eslint-plugin-sonarjs](https://npm.io/package/eslint-plugin-sonarjs.md) — 2.9M weekly downloads
- [eslint-config-expo](https://npm.io/package/eslint-config-expo.md) — 1.5M weekly downloads
- [@matter/protocol](https://npm.io/package/@matter/protocol.md) — 63.5K weekly downloads
- [@eventcatalog/linter](https://npm.io/package/@eventcatalog/linter.md) — 24.8K weekly downloads
- [@inrupt/eslint-config-base](https://npm.io/package/@inrupt/eslint-config-base.md) — 4.5K weekly downloads

## Recent versions

- 0.9.0 (latest) — 2022-07-25
- 0.8.1 — 2021-11-07
- 0.8.0 — 2021-11-07
- 0.7.3 — 2019-05-05
- 0.7.2 — 2019-01-09
- 0.7.1 — 2018-12-15
- 0.7.0 — 2018-12-15
- 0.6.2 — 2018-12-13
- 0.6.1 — 2018-12-12
- 0.6.0 — 2018-11-18
- 0.5.3 — 2018-03-26
- 0.5.2 — 2018-03-26
- 0.5.1 — 2017-02-25
- 0.5.0 — 2017-02-14
- 0.3.3 — 2017-01-06
- … 5 more at https://npm.io/package/automutate/versions

## README

# automutate

[![Build Status](https://travis-ci.org/automutate/automutate.svg?branch=master)](https://travis-ci.org/automutate/automutate)
[![npm](https://img.shields.io/npm/v/automutate.svg)](https://www.npmjs.com/package/automutate)

Applies waves of mutations provided by other tools, such as linters or codemods.

There are [many](https://github.com/eslint/eslint) [linters](https://github.com/stylelint/stylelint) [out](https://github.com/lesshint/lesshint) [there](https://github.com/sasstools/sass-lint) and most include ways to `--fix` rule failures automatically.
This is great but hard to do for a couple of reasons:

- **Overlapping mutations** - The possibility of mutations applying to overlapping sets of characters requires logic to handle applying one, then re-running linting, and so on.
- **Code bloat verses duplication** - Most linters either provide hooks to apply fixes themselves (which can result in code bloat) or have an external project (which duplicates logic for finding rules).

`automutate` proposes that linters only propose **how** to fix rules, via a standardized JSON format.

Having a standardized source-agnostic project to apply mutations brings a couple of benefits:

- **Reduced overhead** - Projects no longer need to do this work themselves.
- **Standardized base** - Ramp-up time to switch between projects using `automutate` is reduced with common code.

In general, _detecting_ rule failures is a separate concern from _fixing_ them.
Linters need to run quickly over a read-only set of files, often during built processes, while fixers typically run slowly and modify files on user request.

## How it works

The main `automutate` algorithm is started in [`autoMutator.ts`](../src/autoMutator.ts) and mostly applied in [`mutationsApplier.ts`](../src/mutationsApplier.ts):

```swift
while mutationsWave = getMutationsWave():
    for (file, fileMutations) of groupMutationsByFile(mutationsWave):
        for mutation of getNonOverlappingMutationsInReverse(fileMutations):
            applyMutation(file, mutation)
```

1. `getMutationsWave` calls to an external tool, such as a linter, to receive a wave of suggested mutations.
2. `groupMutationsByFile` organizes the suggested mutations by file.
3. `getNonOverlappingMutationsInReverse` removes overlapping mutations that would conflict with each other, and sorts the remainder in reverse order so that later mutations don't interfere with character positions of earlier mutations.
4. `applyMutation` modifies files on disk using the remaining mutations.

## Mutations

A single mutation contains a unique `type` identifier, a range of character position(s) to apply to, and optionally other logic.

The following basic text manipulations are provided out of the box:

- **`multiple`** - Container for multiple mutations. This indicates to `automutate` that these must be applied all at once or not at all, which guarantees consistency with the built-in mutation overlap detection.
- **`text-delete`** - Deletes a range of characters.
- **`text-insert`** - Inserts a string at a point.
- **`text-replace`** - Replaces characters matching a string or regular expression within a range.
- **`text-swap`** - Swaps a range of characters with a new string.

For example:

```json
{
  "ugly-file.txt": [
    {
      "range": {
        "begin": 7,
        "end": 14
      },
      "type": "text-delete"
    },
    {
      "insertion": "inconceivable!",
      "range": {
        "begin": 21
      },
      "type": "text-insert"
    }
  ]
}
```

Linter-specific utilities may define their own mutations.
For example, a language's linter may define a `node-rename` mutation rather than use a `multiple` mutation containing `text-swap` mutations.

See [Mutators](docs/mutators.md) for more on custom mutators.

## Project Onboarding

See [Onboarding](docs/onboarding.md).

`automutate` requires NodeJS >= 14.

---
_Source: https://npm.io/package/automutate · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
