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

> 42 lines of code and 13 definitions.

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

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

## Definitions

- `TOOL` (lexical_declaration, line 8)
- `VERSION` (lexical_declaration, line 9)
- `SOURCE` (lexical_declaration, line 10)
- `DOCS` (lexical_declaration, line 11)
- `MIN_CODE_DIGITS` (lexical_declaration, line 12)
- `NAME_MAX` (lexical_declaration, line 13)
- `NAME_TRUNC` (lexical_declaration, line 14)
- `ruleOf` (lexical_declaration, line 16)
- `end` (lexical_declaration, line 17)
- `description` (lexical_declaration, line 21)
- `code` (lexical_declaration, line 25)
- `produce` (lexical_declaration, line 41)
- `rules` (lexical_declaration, line 42)

## Contained in

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

## Source

```typescript
import type { CatalogProduct, CatalogRule } from "#types/catalog.types";
import { byRuleId } from "#core/comparators/rule.comparator";
import { defineProducer } from "#core/registries/producer.registry";
import { distinctRules } from "#core/selectors/catalog.selector";
import { isDigit } from "@govlab/constants";
import { remoteText } from "#core/adapters/remote.adapter";

const TOOL = "luacheck";
const VERSION = "master";
const SOURCE = "https://raw.githubusercontent.com/lunarmodules/luacheck/master/docsrc/warnings.rst";
const DOCS = "https://luacheck.readthedocs.io/en/stable/warnings.html";
const MIN_CODE_DIGITS = 2;
const NAME_MAX = 60;
const NAME_TRUNC = 57;

const ruleOf = function ruleOf(raw: string): CatalogRule[] {
    let end = 0;
    while (end < raw.length && isDigit(raw[end] ?? "")) {
        end += 1;
    }
    const description = raw.slice(end).trim();
    if (end < MIN_CODE_DIGITS || raw[end] !== " " || description === "") {
        return [];
    }
    const code = raw.slice(0, end);
    return [
        {
            canonical: null,
            category: code.startsWith("0") ? "error" : "warning",
            description,
            ecosystem: "lua",
            name: description.length > NAME_MAX ? `${description.slice(0, NAME_TRUNC)}...` : description,
            ruleId: code,
            tool: TOOL,
            toolVersion: VERSION,
            url: DOCS,
        },
    ];
};

const produce = async function produce(): Promise<CatalogProduct[]> {
    const rules = distinctRules(((await remoteText(SOURCE)) ?? "").split("\n").flatMap(ruleOf)).toSorted(byRuleId);
    return [{ rules, source: TOOL, summary: { tool: TOOL, toolVersion: VERSION, total: rules.length } }];
};

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