Source: out/parser/DotParser.js

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DotParser = void 0;
const typescript_map_1 = require("typescript-map");
const constants_1 = require("../support/constants");
const helpers_1 = require("../support/helpers");
const Link_1 = require("./Link");
const Node_1 = require("./Node");
const recipe_parser_1 = require("./recipe_parser");
/**
 * Class used for parsing BitBake generated .dot files.
 */
class DotParser {
    /**
     * Initialize DotParser class instance.
     * @param dotPath Path to the .dot file.
     */
    constructor(dotPath) {
        this.dotPath = dotPath;
    }
    /**
     * Parse a .dot file based on given parameters.
     * @param type Type of the BitBake task that will be parsed.
     * @param mode Mode of graph analysis.
     * @returns JSON string with data for visualization.
     */
    parseDotFile(type, mode) {
        var graphString;
        if (type === constants_1.DEFAULT_TYPE) {
            graphString = this.parseDotFileDefault(mode);
        }
        else {
            graphString = this.parseDotFileTaskType(type, mode);
        }
        return graphString;
    }
    /**
     * Parse .dot file if "default" BitBake task type was selected (uses ".do_prepare_recipe_sysroot" on the left side and ".do_populate_sysroot" on the right side).
     * @param mode Mode of graph analysis.
     * @returns JSON string with data for visualization.
     */
    parseDotFileDefault(mode) {
        var index = 1;
        var data = (0, helpers_1.loadFile)(this.dotPath);
        var nodes = [];
        var links = [];
        data === null || data === void 0 ? void 0 : data.forEach(line => {
            var lineData = line.split(" -> ");
            if (lineData[0].includes("do_prepare_recipe_sysroot") && !lineData[0].includes("label=") && lineData[1].includes("do_populate_sysroot")) {
                const recipeName = lineData[0].replace(".do_prepare_recipe_sysroot", "").replace('"', "").replace('"', "").trim();
                const dependentRecipeName = lineData[1].replace(".do_populate_sysroot", "").replace('"', "").replace('"', "").trim();
                if (dependentRecipeName !== recipeName) {
                    index = this.addGraphData(nodes, links, recipeName, dependentRecipeName, index);
                }
            }
            else if (lineData[0].includes("label=")) {
                lineData = line.split(" ");
                const recipeNameData = lineData[0].split(".");
                const recipeName = recipeNameData[0].replace('"', "").replace('"', "").trim();
                index = this.setNodeRecipe(nodes, lineData[2], recipeName, index, mode);
            }
        });
        return this.generateGraphJSON(nodes, links);
    }
    /**
     * Parse BitBake .dot file. Uses only lines that have the specified type on the left side.
     * @param type Type of the BitBake task that will be parsed.
     * @param mode Mode of graph analysis.
     * @returns JSON string with data for visualization.
     */
    parseDotFileTaskType(type, mode) {
        var index = 1;
        var data = (0, helpers_1.loadFile)(this.dotPath);
        var nodes = [];
        var links = [];
        data === null || data === void 0 ? void 0 : data.forEach(line => {
            var lineData = line.split(" -> ");
            if (lineData[0].includes(type) && !lineData[0].includes("label=")) {
                const recipeName = lineData[0].replace("." + type, "").replace('"', "").replace('"', "").trim();
                const dependentRecipeName = lineData[1].split(".")[0].replace('"', "").replace('"', "").trim();
                if (dependentRecipeName !== recipeName) {
                    index = this.addGraphData(nodes, links, recipeName, dependentRecipeName, index);
                }
            }
            else if (lineData[0].includes("label=")) {
                lineData = line.split(" ");
                const recipeNameData = lineData[0].split(".");
                const recipeName = recipeNameData[0].replace('"', "").replace('"', "").trim();
                index = this.setNodeRecipe(nodes, lineData[2], recipeName, index, mode);
            }
        });
        return this.generateGraphJSON(nodes, links);
    }
    /**
     * Add new nodes and links to the list of nodes and links.
     * @param nodes List of nodes.
     * @param links List of links.
     * @param recipeName Name of the first recipe.
     * @param dependentRecipeName Name of the second recipe.
     * @param index Index of the node in the list of nodes.
     * @returns New index.
     */
    addGraphData(nodes, links, recipeName, dependentRecipeName, index) {
        var source;
        var target;
        if (!nodes.some(rn => rn.getName() == recipeName)) {
            nodes.push(new Node_1.Node(index, recipeName));
            source = index;
            index++;
        }
        else {
            source = nodes.find(rn => rn.getName() == recipeName).getId();
        }
        if (!nodes.some(rn => rn.getName() == dependentRecipeName)) {
            nodes.push(new Node_1.Node(index, dependentRecipeName));
            target = index;
            index++;
        }
        else {
            target = nodes.find(rn => rn.getName() == dependentRecipeName).getId();
        }
        const link = new Link_1.Link(source, target);
        links.push(link);
        return index;
    }
    /**
     * Assing a path to the recipe file for a specified node or for a newly created one.
     * @param nodes List of nodes.
     * @param labelSource Label string.
     * @param recipeName Name of the recipe.
     * @param index Index of the node in the list of nodes.
     * @param mode Mode of graph analysis.
     * @returns New index.
     */
    setNodeRecipe(nodes, labelSource, recipeName, index, mode) {
        var label = labelSource.replace("[", "").replace("]", "").replace("label=", "").replace('"', "").replace('"', "").trim();
        var labelData = label.split(/\\n|:/);
        var recipePath = labelData[labelData.length - 1];
        if (!nodes.some(rn => rn.getName() == recipeName)) {
            const node = new Node_1.Node(index, recipeName);
            node.setRecipe(recipePath);
            if (mode === "licenses") {
                node.setLicense((0, recipe_parser_1.parseRecipe)((0, helpers_1.getRecipePath)(recipePath)).license);
            }
            nodes.push(node);
            index++;
        }
        else {
            const node = nodes.find(rn => rn.getName() == recipeName);
            node.setRecipe(recipePath);
            if (mode === "licenses") {
                node.setLicense((0, recipe_parser_1.parseRecipe)((0, helpers_1.getRecipePath)(recipePath)).license);
            }
        }
        return index;
    }
    /**
     * Generate a JSON string containing list of nodes and list of links.
     * @param nodes List of nodes.
     * @param links List of links.
     * @returns JSON string with data for visualization.
     */
    generateGraphJSON(nodes, links) {
        var graph = new typescript_map_1.TSMap();
        graph.set("nodes", nodes);
        graph.set("links", links);
        return JSON.stringify(graph.toJSON());
    }
}
exports.DotParser = DotParser;
//# sourceMappingURL=DotParser.js.map