mirror of
https://github.com/status-im/sourcecred.git
synced 2025-02-11 03:56:41 +00:00
Backend: implement PluginLoaders.contractPluginGraphs (#1619)
Note: this doesn't include a WeightedGraph.overrideWeights step. Because overriding weights isn't related to plugins, this will be handled as a separate feature, later in the load pipeline.
This commit is contained in:
parent
ffd6c38e4c
commit
5fd43bf62d
@ -3,6 +3,7 @@
|
|||||||
import {TaskReporter} from "../util/taskReporter";
|
import {TaskReporter} from "../util/taskReporter";
|
||||||
import {type Project} from "../core/project";
|
import {type Project} from "../core/project";
|
||||||
import {type WeightedGraph as WeightedGraphT} from "../core/weightedGraph";
|
import {type WeightedGraph as WeightedGraphT} from "../core/weightedGraph";
|
||||||
|
import * as WeightedGraph from "../core/weightedGraph";
|
||||||
import {type PluginDeclaration} from "../analysis/pluginDeclaration";
|
import {type PluginDeclaration} from "../analysis/pluginDeclaration";
|
||||||
import {type CacheProvider} from "./cache";
|
import {type CacheProvider} from "./cache";
|
||||||
import {type GithubToken} from "../plugins/github/token";
|
import {type GithubToken} from "../plugins/github/token";
|
||||||
@ -123,3 +124,26 @@ export async function createPluginGraphs(
|
|||||||
cachedProject: {cache, project},
|
cachedProject: {cache, project},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes PluginGraphs and merges it into a WeightedGraph with identities contracted.
|
||||||
|
*/
|
||||||
|
export async function contractPluginGraphs(
|
||||||
|
{identity}: PluginLoaders,
|
||||||
|
{graphs, cachedProject}: PluginGraphs
|
||||||
|
): Promise<WeightedGraphT> {
|
||||||
|
const {project} = cachedProject;
|
||||||
|
const mergedGraph = WeightedGraph.merge(graphs);
|
||||||
|
|
||||||
|
// Don't contract when there's no identities. This will prevent unnecessary copying.
|
||||||
|
if (!project.identities.length) {
|
||||||
|
return mergedGraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
const discourseServer = project.discourseServer || {serverUrl: null};
|
||||||
|
const identitySpec = {
|
||||||
|
identities: project.identities,
|
||||||
|
discourseServerUrl: discourseServer.serverUrl,
|
||||||
|
};
|
||||||
|
return identity.contractIdentities(mergedGraph, identitySpec);
|
||||||
|
}
|
||||||
|
@ -10,6 +10,7 @@ import * as PluginLoaders from "./pluginLoaders";
|
|||||||
|
|
||||||
const githubSentinel = graphNode("github-sentinel");
|
const githubSentinel = graphNode("github-sentinel");
|
||||||
const discourseSentinel = graphNode("discourse-sentinel");
|
const discourseSentinel = graphNode("discourse-sentinel");
|
||||||
|
const identitySentinel = graphNode("identity-sentinel");
|
||||||
|
|
||||||
const mockGithubGraph = () => {
|
const mockGithubGraph = () => {
|
||||||
const wg = WeightedGraph.empty();
|
const wg = WeightedGraph.empty();
|
||||||
@ -23,6 +24,12 @@ const mockDiscourseGraph = () => {
|
|||||||
return wg;
|
return wg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mockContractedGraph = () => {
|
||||||
|
const wg = WeightedGraph.empty();
|
||||||
|
wg.graph.addNode(identitySentinel);
|
||||||
|
return wg;
|
||||||
|
};
|
||||||
|
|
||||||
const mockCacheProvider = () => ({
|
const mockCacheProvider = () => ({
|
||||||
database: jest.fn(),
|
database: jest.fn(),
|
||||||
});
|
});
|
||||||
@ -44,6 +51,7 @@ const mockPluginLoaders = () => ({
|
|||||||
},
|
},
|
||||||
identity: {
|
identity: {
|
||||||
declaration: jest.fn().mockReturnValue(fakeIdentityDec),
|
declaration: jest.fn().mockReturnValue(fakeIdentityDec),
|
||||||
|
contractIdentities: jest.fn().mockReturnValue(mockContractedGraph()),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -269,4 +277,69 @@ describe("src/backend/pluginLoaders", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("contractPluginGraphs", () => {
|
||||||
|
it("should only merge graphs when no identities are defined", async () => {
|
||||||
|
// Given
|
||||||
|
const loaders = mockPluginLoaders();
|
||||||
|
const cache = mockCacheProvider();
|
||||||
|
const project = createProject({
|
||||||
|
id: "has-github-and-discourse",
|
||||||
|
discourseServer: {serverUrl: "http://foo.bar"},
|
||||||
|
repoIds: [exampleRepoId],
|
||||||
|
});
|
||||||
|
const pluginGraphs = ({
|
||||||
|
graphs: [mockGithubGraph(), mockDiscourseGraph()],
|
||||||
|
cachedProject: {project, cache},
|
||||||
|
}: any);
|
||||||
|
|
||||||
|
// When
|
||||||
|
const graph = await PluginLoaders.contractPluginGraphs(
|
||||||
|
loaders,
|
||||||
|
pluginGraphs
|
||||||
|
);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
const expectedGraph = WeightedGraph.merge([
|
||||||
|
mockGithubGraph(),
|
||||||
|
mockDiscourseGraph(),
|
||||||
|
]);
|
||||||
|
expect(graph).toEqual(expectedGraph);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should contract identities when they are defined", async () => {
|
||||||
|
// Given
|
||||||
|
const loaders = mockPluginLoaders();
|
||||||
|
const cache = mockCacheProvider();
|
||||||
|
const project = createProject({
|
||||||
|
id: "has-github-and-discourse-and-identity",
|
||||||
|
identities: [{username: "foo", aliases: ["github/foo"]}],
|
||||||
|
discourseServer: {serverUrl: "http://foo.bar"},
|
||||||
|
repoIds: [exampleRepoId],
|
||||||
|
});
|
||||||
|
const pluginGraphs = ({
|
||||||
|
graphs: [mockGithubGraph(), mockDiscourseGraph()],
|
||||||
|
cachedProject: {project, cache},
|
||||||
|
}: any);
|
||||||
|
|
||||||
|
// When
|
||||||
|
const graph = await PluginLoaders.contractPluginGraphs(
|
||||||
|
loaders,
|
||||||
|
pluginGraphs
|
||||||
|
);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
const {identity} = loaders;
|
||||||
|
const expectedGraph = WeightedGraph.merge([
|
||||||
|
mockGithubGraph(),
|
||||||
|
mockDiscourseGraph(),
|
||||||
|
]);
|
||||||
|
expect(graph).toEqual(mockContractedGraph());
|
||||||
|
expect(identity.contractIdentities).toBeCalledTimes(1);
|
||||||
|
expect(identity.contractIdentities).toBeCalledWith(expectedGraph, {
|
||||||
|
identities: project.identities,
|
||||||
|
discourseServerUrl: (project.discourseServer: any).serverUrl,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import {type PluginDeclaration} from "../../analysis/pluginDeclaration";
|
import {type PluginDeclaration} from "../../analysis/pluginDeclaration";
|
||||||
|
import {type WeightedGraph} from "../../core/weightedGraph";
|
||||||
|
import {type IdentitySpec} from "./identity";
|
||||||
|
import {contractIdentities} from "./contractIdentities";
|
||||||
import {declaration} from "./declaration";
|
import {declaration} from "./declaration";
|
||||||
|
|
||||||
export interface Loader {
|
export interface Loader {
|
||||||
declaration(): PluginDeclaration;
|
declaration(): PluginDeclaration;
|
||||||
|
contractIdentities(
|
||||||
|
weightedGraph: WeightedGraph,
|
||||||
|
identitySpec: IdentitySpec
|
||||||
|
): WeightedGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ({
|
export default ({
|
||||||
declaration: () => declaration,
|
declaration: () => declaration,
|
||||||
|
contractIdentities,
|
||||||
}: Loader);
|
}: Loader);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user