core/producers/tool.scalastyle.producer.ts

core/producers/tool.scalastyle.producer.ts is a file in GovLab Quality. 73 lines of code and 24 definitions.

import type { CatalogProduct, CatalogRule, KnobEntry } from "#types/catalog.types";
import { INTEGER_TYPE } from "#configuration/constants/knob.constants";
import { byRuleId } from "#core/comparators/rule.comparator";
import { defineProducer } from "#core/registries/producer.registry";
import { distinctRules } from "#core/selectors/catalog.selector";
import { isDigitsOnly } from "#core/parsers/knob.parser";
import { remoteText } from "#core/adapters/remote.adapter";

const TOOL = "scalastyle";
const VERSION = "master";
const SOURCE =
    "https://raw.githubusercontent.com/scalastyle/scalastyle/master/src/main/resources/scalastyle_definition.xml";
const DOCS = "https://www.scalastyle.org/rules-dev.html";
const CHECKER = "<checker";
const CHECKER_CLOSE = "</checker>";
const SEGMENT_WINDOW = 600;

const attr = function attr(text: string, name: string): string | null {
    const key = `${name}="`;
    const at = text.indexOf(key);
    const end = at === -1 ? -1 : text.indexOf('"', at + key.length);
    return end === -1 ? null : text.slice(at + key.length, end);
};

const checkers = function checkers(text: string): { segment: string; tag: string }[] {
    const found: { segment: string; tag: string }[] = [];
    let at = text.indexOf(CHECKER);
    while (at !== -1) {
        const tagEnd = text.indexOf(">", at);
        const close = text.indexOf(CHECKER_CLOSE, at);
        found.push({
            segment: text.slice(at, close === -1 ? at + SEGMENT_WINDOW : close),
            tag: text.slice(at, tagEnd === -1 ? text.length : tagEnd),
        });
        at = text.indexOf(CHECKER, at + CHECKER.length);
    }
    return found;
};

const ruleOf = function ruleOf(tag: string): CatalogRule[] {
    const id = attr(tag, "id");
    const className = attr(tag, "class");
    const level = attr(tag, "defaultLevel");
    return id === null
        ? []
        : [
              {
                  canonical: null,
                  category: "checker",
                  defaultLevel: level === "" ? null : level,
                  description: null,
                  ecosystem: "scala",
                  name: className === null || className === "" ? id : className.slice(className.lastIndexOf(".") + 1),
                  ruleId: id,
                  tool: TOOL,
                  toolVersion: VERSION,
                  url: DOCS,
              },
          ];
};

const source = async function source(): Promise<string> {
    return (await remoteText(SOURCE)) ?? "";
};

const produce = async function produce(): Promise<CatalogProduct[]> {
    const rules = distinctRules(checkers(await source()).flatMap(({ tag }) => ruleOf(tag))).toSorted(byRuleId);
    return [{ rules, source: TOOL, summary: { tool: TOOL, toolVersion: VERSION, total: rules.length } }];
};

const knobs = async function knobs(): Promise<KnobEntry[]> {
    return checkers(await source()).flatMap(({ segment, tag }): KnobEntry[] => {
        const id = attr(tag, "id");
        const fallback = (attr(segment, "default") ?? "").trim();
        return id !== null && isDigitsOnly(fallback)
            ? [[TOOL, id, { default: Number(fallback), knob: "value", threshold: true, type: INTEGER_TYPE }]]
            : [];
    });
};

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