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

> 48 lines of code and 18 definitions.

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

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

## Definitions

- `cell` (lexical_declaration, line 17)
- `ruleOf` (lexical_declaration, line 21)
- `TOOL` (lexical_declaration, line 7)
- `VERSION` (lexical_declaration, line 8)
- `SOURCE` (lexical_declaration, line 9)
- `DOCS` (lexical_declaration, line 10)
- `ID_COL` (lexical_declaration, line 11)
- `CAT_COL` (lexical_declaration, line 12)
- `DESC_COL` (lexical_declaration, line 13)
- `ROW_MARKERS` (lexical_declaration, line 14)
- `ID_PREFIXES` (lexical_declaration, line 15)
- `cols` (lexical_declaration, line 25)
- `idCell` (lexical_declaration, line 26)
- `open` (lexical_declaration, line 27)
- `close` (lexical_declaration, line 28)
- `id` (lexical_declaration, line 29)
- `produce` (lexical_declaration, line 48)
- `rules` (lexical_declaration, line 49)

## 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 { byRuleId } from "#core/comparators/rule.comparator";
import { defineProducer } from "#core/registries/producer.registry";
import { distinctRules } from "#core/selectors/catalog.selector";
import { remoteText } from "#core/adapters/remote.adapter";

const TOOL = "hadolint";
const VERSION = "readme";
const SOURCE = "https://raw.githubusercontent.com/hadolint/hadolint/master/README.md";
const DOCS = "https://github.com/hadolint/hadolint/wiki";
const ID_COL = 1;
const CAT_COL = 2;
const DESC_COL = 3;
const ROW_MARKERS = ["| [DL", "| [SC"];
const ID_PREFIXES = ["DL", "SC"];

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

const ruleOf = function ruleOf(line: string): CatalogRule[] {
    if (!ROW_MARKERS.some((marker) => line.includes(marker))) {
        return [];
    }
    const cols = line.split("|").map((col) => col.trim());
    const idCell = cols[ID_COL] ?? "";
    const open = idCell.indexOf("[");
    const close = idCell.indexOf("]");
    const id = open === -1 || close === -1 ? "" : idCell.slice(open + 1, close);
    if (!ID_PREFIXES.some((prefix) => id.startsWith(prefix))) {
        return [];
    }
    return [
        {
            canonical: null,
            category: cell(cols[CAT_COL]),
            description: cell(cols[DESC_COL]),
            ecosystem: "dockerfile",
            name: id,
            ruleId: id,
            tool: TOOL,
            toolVersion: VERSION,
            url: `${DOCS}/${id}`,
        },
    ];
};

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" });
```
