# core/producers/tool.ruff.producer.ts

> 47 lines of code and 12 definitions.

Tree: GovLab Quality
Language: typescript
Layer: application
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-producers-tool-ruff-producer-ts
Source text: https://banes-lab.com/source/quality/core/producers/tool.ruff.producer.ts.txt

Listed in [core/producers](https://banes-lab.com/api/source/quality/core/producers.md), after [core/producers/tool.rubocop.producer.ts](https://banes-lab.com/source/quality/core/producers/tool.rubocop.producer.ts.md) and before [core/producers/tool.scalastyle.producer.ts](https://banes-lab.com/source/quality/core/producers/tool.scalastyle.producer.ts.md).

## Definitions

- `orNull` (lexical_declaration, line 12)
- `ruleOf` (lexical_declaration, line 16)
- `TOOL` (lexical_declaration, line 8)
- `DOCS` (lexical_declaration, line 9)
- `NOT_AVAILABLE` (lexical_declaration, line 10)
- `name` (lexical_declaration, line 17)
- `fix` (lexical_declaration, line 18)
- `produce` (lexical_declaration, line 34)
- `version` (lexical_declaration, line 35)
- `parsed` (lexical_declaration, line 36)
- `rules` (lexical_declaration, line 37)
- `summary` (lexical_declaration, line 41)

## Contained in

- [core/producers](https://banes-lab.com/anatomy/quality/folder-quality-core-producers.md)

## Linked from

- [core/producers](https://banes-lab.com/anatomy/quality/folder-quality-core-producers.md)

## Source

```typescript
import type { CatalogProduct, CatalogRule } from "#types/catalog.types";
import { commandOutput, commandVersion } from "#core/adapters/invocation.adapter";
import { isRecord, stringField } from "#core/selectors/record.selector";
import { byRuleId } from "#core/comparators/rule.comparator";
import { defineProducer } from "#core/registries/producer.registry";
import { tallyBy } from "#core/aggregators/catalog.aggregator";

const TOOL = "ruff";
const DOCS = "https://docs.astral.sh/ruff/rules";
const NOT_AVAILABLE = "not available";

const orNull = function orNull(value: string): string | null {
    return value === "" ? null : value;
};

const ruleOf = function ruleOf(entry: Record<string, unknown>, version: string): CatalogRule {
    const name = orNull(stringField(entry, "name"));
    const fix = stringField(entry, "fix");
    return {
        canonical: null,
        category: orNull(stringField(entry, "linter")),
        description: orNull(stringField(entry, "summary")),
        ecosystem: "python",
        fixable: fix !== "" && !fix.toLowerCase().includes(NOT_AVAILABLE),
        name,
        preview: entry["preview"] === true,
        ruleId: stringField(entry, "code"),
        tool: TOOL,
        toolVersion: version,
        url: name === null ? null : `${DOCS}/${name}`,
    };
};

const produce = async function produce(): Promise<CatalogProduct[]> {
    const version = commandVersion(TOOL, ["--version"]);
    const parsed: unknown = JSON.parse(commandOutput(TOOL, ["rule", "--all", "--output-format", "json"]));
    const rules = (Array.isArray(parsed) ? parsed : [])
        .filter(isRecord)
        .map((entry) => ruleOf(entry, version))
        .toSorted(byRuleId);
    const summary = {
        byCategory: tallyBy(rules, "category"),
        fixable: rules.filter((rule) => rule["fixable"] === true).length,
        preview: rules.filter((rule) => rule["preview"] === true).length,
        tool: TOOL,
        toolVersion: version,
        total: rules.length,
    };
    return [{ rules, source: TOOL, summary }];
};

defineProducer({ name: TOOL, produce, refresh: "manual" });
```
