Add `createMinimalGraph` for a tiny git graph (#689)
This implements the approach suggested in [1]. Instead of forking the git plugin entirely, we'll fork the createGraph method and the pluginAdapter so that we have instances that produce a lightweight git graph. createMinimalGraph is a fork of createGraph that only adds commit nodes and has_parent edges. New unit tests ensure that only the whitelisted nodes and edges appear. Supersedes #683 and #684. Test plan: `yarn test` [1]: https://github.com/sourcecred/sourcecred/issues/627#issuecomment-413623784
This commit is contained in:
parent
ae6e269d9d
commit
a460704ea8
|
@ -0,0 +1,148 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`plugins/git/createMinimalGraph createMinimalGraph processes a simple repository 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"type": "sourcecred/graph",
|
||||
"version": "0.4.0",
|
||||
},
|
||||
Object {
|
||||
"edges": Array [
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"HAS_PARENT",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"3715ddfb8d4c4fd2a6f6af75488c82f84c92ec2f",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"69c5aad50eec8f2a0a07c988c3b283a6490eb45b",
|
||||
],
|
||||
"dstIndex": 1,
|
||||
"srcIndex": 0,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"HAS_PARENT",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"69c5aad50eec8f2a0a07c988c3b283a6490eb45b",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"e8b7a8f19701cd5a25e4a097d513ead60e5f8bcc",
|
||||
],
|
||||
"dstIndex": 6,
|
||||
"srcIndex": 1,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"HAS_PARENT",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"8d287c3bfbf8455ef30187bf5153ffc1b6eef268",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"c08ee3a4edea384d5291ffcbf06724a13ed72325",
|
||||
],
|
||||
"dstIndex": 3,
|
||||
"srcIndex": 2,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"HAS_PARENT",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"c08ee3a4edea384d5291ffcbf06724a13ed72325",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"c2b51945e7457546912a8ce158ed9d294558d294",
|
||||
],
|
||||
"dstIndex": 4,
|
||||
"srcIndex": 3,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"HAS_PARENT",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"d160cca97611e9dfed642522ad44408d0292e8ea",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"8d287c3bfbf8455ef30187bf5153ffc1b6eef268",
|
||||
],
|
||||
"dstIndex": 2,
|
||||
"srcIndex": 5,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"HAS_PARENT",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"e8b7a8f19701cd5a25e4a097d513ead60e5f8bcc",
|
||||
"2",
|
||||
"COMMIT",
|
||||
"d160cca97611e9dfed642522ad44408d0292e8ea",
|
||||
],
|
||||
"dstIndex": 5,
|
||||
"srcIndex": 6,
|
||||
},
|
||||
],
|
||||
"nodes": Array [
|
||||
Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"COMMIT",
|
||||
"3715ddfb8d4c4fd2a6f6af75488c82f84c92ec2f",
|
||||
],
|
||||
Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"COMMIT",
|
||||
"69c5aad50eec8f2a0a07c988c3b283a6490eb45b",
|
||||
],
|
||||
Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"COMMIT",
|
||||
"8d287c3bfbf8455ef30187bf5153ffc1b6eef268",
|
||||
],
|
||||
Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"COMMIT",
|
||||
"c08ee3a4edea384d5291ffcbf06724a13ed72325",
|
||||
],
|
||||
Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"COMMIT",
|
||||
"c2b51945e7457546912a8ce158ed9d294558d294",
|
||||
],
|
||||
Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"COMMIT",
|
||||
"d160cca97611e9dfed642522ad44408d0292e8ea",
|
||||
],
|
||||
Array [
|
||||
"sourcecred",
|
||||
"git",
|
||||
"COMMIT",
|
||||
"e8b7a8f19701cd5a25e4a097d513ead60e5f8bcc",
|
||||
],
|
||||
],
|
||||
},
|
||||
]
|
||||
`;
|
|
@ -0,0 +1,41 @@
|
|||
// @flow
|
||||
|
||||
import {Graph} from "../../core/graph";
|
||||
|
||||
import * as GT from "./types";
|
||||
import * as GN from "./nodes";
|
||||
import * as GE from "./edges";
|
||||
|
||||
export function createMinimalGraph(repository: GT.Repository): Graph {
|
||||
const creator = new MinimalGraphCreator();
|
||||
creator.addRepository(repository);
|
||||
return creator.graph;
|
||||
}
|
||||
|
||||
class MinimalGraphCreator {
|
||||
+graph: Graph;
|
||||
|
||||
constructor() {
|
||||
this.graph = new Graph();
|
||||
}
|
||||
|
||||
addNode(a: GN.StructuredAddress) {
|
||||
this.graph.addNode(GN.toRaw(a));
|
||||
}
|
||||
|
||||
addRepository(repository: GT.Repository) {
|
||||
for (const commitHash of Object.keys(repository.commits)) {
|
||||
this.addCommit(repository.commits[commitHash]);
|
||||
}
|
||||
}
|
||||
|
||||
addCommit(commit: GT.Commit) {
|
||||
const node: GN.CommitAddress = {type: GN.COMMIT_TYPE, hash: commit.hash};
|
||||
this.graph.addNode(GN.toRaw(node));
|
||||
for (const parentHash of commit.parentHashes) {
|
||||
const parent: GN.CommitAddress = {type: GN.COMMIT_TYPE, hash: parentHash};
|
||||
this.graph.addNode(GN.toRaw(parent));
|
||||
this.graph.addEdge(GE.createEdge.hasParent(node, parent));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// @flow
|
||||
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
|
||||
import {createMinimalGraph} from "./createMinimalGraph";
|
||||
import {GraphView} from "./graphView";
|
||||
import {_Prefix as NodePrefix} from "./nodes";
|
||||
import {_Prefix as EdgePrefix} from "./edges";
|
||||
import {NodeAddress, EdgeAddress} from "../../core/graph";
|
||||
|
||||
const makeData = () => cloneDeep(require("./example/example-git"));
|
||||
|
||||
describe("plugins/git/createMinimalGraph", () => {
|
||||
describe("createMinimalGraph", () => {
|
||||
it("processes a simple repository", () => {
|
||||
expect(createMinimalGraph(makeData())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("satisfies the GraphView invariants", () => {
|
||||
const graph = createMinimalGraph(makeData());
|
||||
expect(() => new GraphView(graph)).not.toThrow();
|
||||
});
|
||||
|
||||
it("only has commit nodes and has_parent edges", () => {
|
||||
const graph = createMinimalGraph(makeData());
|
||||
for (const n of graph.nodes()) {
|
||||
if (!NodeAddress.hasPrefix(n, NodePrefix.commit)) {
|
||||
throw new Error("Found non-commit node");
|
||||
}
|
||||
}
|
||||
for (const {address} of graph.edges()) {
|
||||
if (!EdgeAddress.hasPrefix(address, EdgePrefix.hasParent)) {
|
||||
throw new Error("Found non-has-parent edge");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue