Skip to content

Commit

Permalink
feat(cat-version-history): introduce --graph flag to generate a png f…
Browse files Browse the repository at this point in the history
…ile with the graph (#7377)
  • Loading branch information
davidfirst authored May 8, 2023
1 parent 7acab4d commit 11ffcb4
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 8 deletions.
18 changes: 14 additions & 4 deletions src/api/scope/lib/cat-version-history.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
import { BitId } from '../../../bit-id';
import { loadScope, Scope } from '../../../scope';
import { VersionHistory } from '../../../scope/models';

export async function catVersionHistory(id: string) {
const scope: Scope = await loadScope();
const bitId: BitId = await scope.getParsedId(id);
const component = await scope.getModelComponent(bitId);
const versionHistory = await component.GetVersionHistory(scope.objects);
const versionHistory = await getVersionHistory(id);
const versionHistoryObj = versionHistory.toObject();
versionHistoryObj.hash = versionHistory.hash().toString();
return versionHistoryObj;
}

export async function generateVersionHistoryGraph(id: string) {
const versionHistory = await getVersionHistory(id);
return versionHistory.getGraph();
}

async function getVersionHistory(id: string): Promise<VersionHistory> {
const scope: Scope = await loadScope();
const bitId: BitId = await scope.getParsedId(id);
const component = await scope.getModelComponent(bitId);
return component.GetVersionHistory(scope.objects);
}
20 changes: 18 additions & 2 deletions src/cli/commands/private-cmds/cat-version-history-cmd.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { catVersionHistory } from '../../../api/scope/lib/cat-version-history';
import { catVersionHistory, generateVersionHistoryGraph } from '../../../api/scope/lib/cat-version-history';
import VisualDependencyGraph from '../../../scope/graph/vizgraph';
import { CommandOptions, LegacyCommand } from '../../legacy-command';

const colorPerEdgeType = {
parent: 'green',
unrelated: 'red',
squashed: 'blue',
};

export class CatVersionHistoryCmd implements LegacyCommand {
name = 'cat-version-history [id]';
description = 'cat version-history object by component-id';
Expand All @@ -9,9 +16,18 @@ export class CatVersionHistoryCmd implements LegacyCommand {
opts = [
// json is also the default for this command. it's only needed to suppress the logger.console
['j', 'json', 'json format'],
['g', 'graph', `generate graph image (arrows color: ${JSON.stringify(colorPerEdgeType)})`],
] as CommandOptions;

action([id]: [string]): Promise<any> {
async action([id]: [string], { graph }: { graph: boolean }): Promise<any> {
if (graph) {
const graphHistory = await generateVersionHistoryGraph(id);
const visualDependencyGraph = await VisualDependencyGraph.loadFromClearGraph(graphHistory, {
colorPerEdgeType,
});
const result = await visualDependencyGraph.image();
return `image created at ${result}`;
}
return catVersionHistory(id);
}

Expand Down
46 changes: 44 additions & 2 deletions src/scope/graph/vizgraph.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import execa from 'execa';
import os from 'os';
import fs from 'fs-extra';
import { Graph } from 'graphlib';
import graphviz, { Digraph } from 'graphviz';
import { Graph as ClearGraph } from '@teambit/graph.cleargraph';
import * as path from 'path';

import BitId from '../../bit-id/bit-id';
import BitIds from '../../bit-id/bit-ids';
import logger from '../../logger/logger';
import { getLatestVersionNumber } from '../../utils';
import { generateRandomStr, getLatestVersionNumber } from '../../utils';

// const Graph = GraphLib.Graph;
// const Digraph = graphviz.digraph;
Expand All @@ -23,6 +25,7 @@ type ConfigProps = {
graphVizOptions?: Record<string, any>; // null Custom GraphViz options
graphVizPath?: string; // null Custom GraphViz path
highlightColor?: string;
colorPerEdgeType?: { [edgeType: string]: string };
};

const defaultConfig: ConfigProps = {
Expand Down Expand Up @@ -62,6 +65,18 @@ export default class VisualDependencyGraph {
return new VisualDependencyGraph(graphlib, graph, mergedConfig);
}

static async loadFromClearGraph(
clearGraph: ClearGraph<any, any>,
config: ConfigProps = {}
): Promise<VisualDependencyGraph> {
const mergedConfig = Object.assign({}, defaultConfig, config);
await checkGraphvizInstalled(config.graphVizPath);
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
const graph: Digraph = VisualDependencyGraph.buildDependenciesGraphFromClearGraph(clearGraph, mergedConfig);
// @ts-ignore
return new VisualDependencyGraph(clearGraph, graph, mergedConfig);
}

/**
* Creates the graphviz graph
*/
Expand Down Expand Up @@ -92,6 +107,29 @@ export default class VisualDependencyGraph {
return graph;
}

static buildDependenciesGraphFromClearGraph(clearGraph: ClearGraph<any, any>, config: ConfigProps): Digraph {
const graph = graphviz.digraph('G');

if (config.graphVizPath) {
graph.setGraphVizPath(config.graphVizPath);
}

const nodes = clearGraph.nodes;
const edges = clearGraph.edges;

nodes.forEach((node) => {
graph.addNode(node);
});
edges.forEach((edge) => {
const edgeType = edge.attr;
const vizEdge = graph.addEdge(edge.sourceId, edge.targetId);
const color = config.colorPerEdgeType?.[edgeType] || 'green';
setEdgeColor(vizEdge, color);
});

return graph;
}

getNode(id: BitId) {
if (id.hasVersion()) {
return this.graph.getNode(id.toString());
Expand All @@ -108,12 +146,16 @@ export default class VisualDependencyGraph {
setNodeColor(node, this.config.highlightColor);
}

private getTmpFilename() {
return path.join(os.tmpdir(), `${generateRandomStr()}.png`);
}

/**
* Creates an image from the module dependency graph.
* @param {String} imagePath
* @return {Promise}
*/
async image(imagePath: string): Promise<string> {
async image(imagePath: string = this.getTmpFilename()): Promise<string> {
const options: Record<string, any> = createGraphvizOptions(this.config);
const type: string = path.extname(imagePath).replace('.', '') || 'png';
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
Expand Down

0 comments on commit 11ffcb4

Please sign in to comment.