export function augmentLog()

in src/shared/index.ts [70:142]


export function augmentLog(log: Log, rules?: Map<string, ReportingDescriptor>) {
    if (log._augmented) return;
    log._augmented = true;
    const fileAndUris = [] as [string, string][];
    log.runs?.forEach((run, runIndex) => { // types.d.ts is wrong, per spec `runs` is allowed to be null.
        run._index = runIndex;

        // For `Run`s that lack `tool.driver.rules` we generate a `Rule` object on demand.
        // We intern these objects so they can be conveniently instance comparable elsewhere in the code.
        // If we don't do this, then the same ruleId may generate multiple `Rule` objects.
        // When instance comparing those `Rule` objects, they would appear to be different rules. We don't want that.
        const driverlessRules = rules ?? new Map<string, ReportingDescriptor>();
        function getDriverlessRule(id: string | undefined): ReportingDescriptor | undefined {
            if (!id) return undefined;
            if (!driverlessRules.has(id)) {
                driverlessRules.set(id, { id });
            }
            return driverlessRules.get(id)!;
        }

        let implicitBaseParts = undefined as string[] | undefined;
        run.results?.forEach((result, resultIndex) => {
            result._log = log;
            result._run = run;
            result._id = [log._uri, runIndex, resultIndex];

            const ploc = result.locations?.[0]?.physicalLocation;
            const [uri, uriContents] = parseArtifactLocation(result, ploc?.artifactLocation);
            result._uri = uri;
            result._uriContents = uriContents;
            {
                const parts = uri?.split('/');
                implicitBaseParts = // Base calc (inclusive of dash for now)
                    implicitBaseParts?.slice(0, Array.commonLength(implicitBaseParts, parts ?? []))
                    ?? parts;
                const file = parts?.pop();
                if (file && uri) {
                    fileAndUris.push([file, uri.replace(/^\//, '')]); // Normalize leading slashes.
                }
            }
            result._region = ploc?.region;

            // The toolComponent is either specified in a ToolComponentReference or defaults to driver.
            // We're only supporting index-based lookup at the moment, though the spec also defines using guids.
            const toolComponent
                =  run.tool.extensions?.[result?.rule?.toolComponent?.index ?? -1]
                ?? run.tool.driver

            // We look up the rule in the toolComponent via index. (We're not supporting guid-based lookup at the moment.)
            // Failing the index-based lookup we fall back to searching the rule via id.
            result._rule
                =  toolComponent?.rules?.[result?.rule?.index ?? result?.ruleIndex ?? -1]
                ?? toolComponent?.rules?.find(rule => rule.id === result.ruleId)
                ?? getDriverlessRule(result.ruleId);

            const message = result._rule?.messageStrings?.[result.message.id ?? -1] ?? result.message;
            result._message = format(message.text || result.message?.text, result.message.arguments) ?? '—';
            result._markdown = format(message.markdown || result.message?.markdown, result.message.arguments); // No '—', leave undefined if empty.

            result.level = effectiveLevel(result);
            result.baselineState = result.baselineState ?? 'new';
            result._suppression = !result.suppressions || result.suppressions.every(sup => sup.status === 'rejected')
                ? 'not suppressed'
                : 'suppressed';
        });

        const implicitBase = implicitBaseParts?.join('/')  ?? '';
        run.results?.forEach(result => {
            result._relativeUri = result._uri?.replace(implicitBase , '') ?? ''; // For grouping, Empty works more predictably than undefined
        });
    });
    log._distinct = mapDistinct(fileAndUris);
}