remove sourcecred export-graph

Now that the graph is saved by default as a part of load, users who need
the graph can grab it directly from the `$SOURCECRED_DIRECTORY`. If we
really need a command line util for grabbing it, we should rewrite that
command to just grab the graph from that spot rather than re-computing
it.

Test plan: `yarn test`
This commit is contained in:
Dandelion Mané 2019-06-13 22:31:55 +03:00
parent a348747aed
commit 3179ba841b
6 changed files with 0 additions and 271 deletions

View File

@ -1,121 +0,0 @@
// @flow
// Implementation of `sourcecred export-graph`.
import {repoIdToString, stringToRepoId, type RepoId} from "../core/repoId";
import dedent from "../util/dedent";
import type {Command} from "./command";
import * as Common from "./common";
import stringify from "json-stable-stringify";
import {loadGraph, type LoadGraphResult} from "../analysis/loadGraph";
import {BackendAdapterLoader as GithubAdapterLoader} from "../plugins/github/analysisAdapter";
import {BackendAdapterLoader as GitAdapterLoader} from "../plugins/git/analysisAdapter";
function usage(print: (string) => void): void {
print(
dedent`\
usage: sourcecred export-graph REPO_ID [--help]
Print a combined SourceCred graph for a given REPO_ID.
Data must already be loaded for the given REPO_ID, using
'sourcecred load REPO_ID'
REPO_ID refers to a GitHub repository in the form OWNER/NAME: for
example, torvalds/linux. The REPO_ID may be a "combined" repo as
created by the --output flag to sourcecred load.
Arguments:
REPO_ID
Already-loaded repository for which to load data.
--help
Show this help message and exit, as 'sourcecred help export-graph'.
Environment Variables:
SOURCECRED_DIRECTORY
Directory owned by SourceCred, in which data, caches,
registries, etc. are stored. Optional: defaults to a
directory 'sourcecred' under your OS's temporary directory;
namely:
${Common.defaultSourcecredDirectory()}
`.trimRight()
);
}
function die(std, message) {
std.err("fatal: " + message);
std.err("fatal: run 'sourcecred help export-graph' for help");
return 1;
}
export function makeExportGraph(
loader: (RepoId) => Promise<LoadGraphResult>
): Command {
return async function exportGraph(args, std) {
let repoId: RepoId | null = null;
for (let i = 0; i < args.length; i++) {
switch (args[i]) {
case "--help": {
usage(std.out);
return 0;
}
default: {
if (repoId != null)
return die(std, "multiple repository IDs provided");
// Should be a repository.
repoId = stringToRepoId(args[i]);
break;
}
}
}
if (repoId == null) {
return die(std, "no repository ID provided");
}
const result: LoadGraphResult = await loader(repoId);
switch (result.status) {
case "REPO_NOT_LOADED": {
const repoIdStr = repoIdToString(repoId);
std.err(`fatal: repository ID ${repoIdStr} not loaded`);
std.err(`Try running \`sourcecred load ${repoIdStr}\` first.`);
return 1;
}
case "PLUGIN_FAILURE": {
std.err(
`fatal: plugin "${result.pluginName}" errored: ${
result.error.message
}`
);
return 1;
}
case "SUCCESS": {
const graphJSON = result.graph.toJSON();
std.out(stringify(graphJSON));
return 0;
}
// istanbul ignore next: unreachable per Flow
default: {
std.err(`Unexpected status: ${(result.status: empty)}`);
return 1;
}
}
};
}
const defaultLoaders = [new GithubAdapterLoader(), new GitAdapterLoader()];
const defaultLoadGraph = (r: RepoId) =>
loadGraph(Common.sourcecredDirectory(), defaultLoaders, r);
export const exportGraph = makeExportGraph(defaultLoadGraph);
export const help: Command = async (args, std) => {
if (args.length === 0) {
usage(std.out);
return 0;
} else {
usage(std.err);
return 1;
}
};
export default exportGraph;

View File

@ -1,123 +0,0 @@
// @flow
import {run} from "./testUtil";
import {help, makeExportGraph} from "./exportGraph";
import {Graph} from "../core/graph";
import {node} from "../core/graphTestUtil";
import stringify from "json-stable-stringify";
import {makeRepoId} from "../core/repoId";
describe("cli/exportGraph", () => {
describe("'help' command", () => {
it("prints usage when given no arguments", async () => {
expect(await run(help, [])).toEqual({
exitCode: 0,
stdout: expect.arrayContaining([
expect.stringMatching(/^usage: sourcecred export-graph/),
]),
stderr: [],
});
});
it("fails when given arguments", async () => {
expect(await run(help, ["foo/bar"])).toEqual({
exitCode: 1,
stdout: [],
stderr: expect.arrayContaining([
expect.stringMatching(/^usage: sourcecred export-graph/),
]),
});
});
});
describe("'exportGraph' command", () => {
it("prints usage with '--help'", async () => {
const exportGraph = makeExportGraph(jest.fn());
expect(await run(exportGraph, ["--help"])).toEqual({
exitCode: 0,
stdout: expect.arrayContaining([
expect.stringMatching(/^usage: sourcecred export-graph/),
]),
stderr: [],
});
});
it("errors if no repoId is provided", async () => {
const exportGraph = makeExportGraph(jest.fn());
expect(await run(exportGraph, [])).toEqual({
exitCode: 1,
stdout: [],
stderr: expect.arrayContaining([
"fatal: no repository ID provided",
"fatal: run 'sourcecred help export-graph' for help",
]),
});
});
it("attempts to load the repoId provided", async () => {
const mockFn = jest.fn();
const exportGraph = makeExportGraph(mockFn);
await run(exportGraph, ["foo/bar"]);
expect(mockFn).toHaveBeenCalledWith(makeRepoId("foo", "bar"));
});
it("on load success, prints the stringified graph to stdout", async () => {
const graph = new Graph().addNode(node("n"));
const loadGraphResult = {status: "SUCCESS", graph};
const exportGraph = makeExportGraph(
(_unused_repoId) => new Promise((resolve) => resolve(loadGraphResult))
);
const result = run(exportGraph, ["foo/bar"]);
expect(await result).toEqual({
exitCode: 0,
stdout: [stringify(graph.toJSON())],
stderr: [],
});
});
it("errors if multiple repos are provided", async () => {
const exportGraph = makeExportGraph(jest.fn());
expect(await run(exportGraph, ["foo/bar", "zod/zoink"])).toEqual({
exitCode: 1,
stdout: [],
stderr: [
"fatal: multiple repository IDs provided",
"fatal: run 'sourcecred help export-graph' for help",
],
});
});
it("errors if the repoId was not loaded first", async () => {
const loadGraphResult = {status: "REPO_NOT_LOADED"};
const exportGraph = makeExportGraph(
(_unused_repoId) => new Promise((resolve) => resolve(loadGraphResult))
);
const result = run(exportGraph, ["zod/zoink"]);
expect(await result).toEqual({
exitCode: 1,
stdout: [],
stderr: [
"fatal: repository ID zod/zoink not loaded",
"Try running `sourcecred load zod/zoink` first.",
],
});
});
it("reports the failing plugin when a plugin rejects", async () => {
const loadGraphResult = {
status: "PLUGIN_FAILURE",
pluginName: "badPlugin",
error: new Error("MockPluginFailure"),
};
const exportGraph = makeExportGraph(
(_unused_repoId) => new Promise((resolve) => resolve(loadGraphResult))
);
const result = await run(exportGraph, ["foo/bar"]);
expect(result).toEqual({
exitCode: 1,
stdout: [],
stderr: ['fatal: plugin "badPlugin" errored: MockPluginFailure'],
});
});
});
});

View File

@ -7,7 +7,6 @@ import dedent from "../util/dedent";
import {help as loadHelp} from "./load"; import {help as loadHelp} from "./load";
import {help as analyzeHelp} from "./analyze"; import {help as analyzeHelp} from "./analyze";
import {help as pagerankHelp} from "./pagerank"; import {help as pagerankHelp} from "./pagerank";
import {help as exportGraphHelp} from "./exportGraph";
import {help as clearHelp} from "./clear"; import {help as clearHelp} from "./clear";
const help: Command = async (args, std) => { const help: Command = async (args, std) => {
@ -22,7 +21,6 @@ const help: Command = async (args, std) => {
analyze: analyzeHelp, analyze: analyzeHelp,
pagerank: pagerankHelp, pagerank: pagerankHelp,
clear: clearHelp, clear: clearHelp,
"export-graph": exportGraphHelp,
}; };
if (subHelps[command] !== undefined) { if (subHelps[command] !== undefined) {
return subHelps[command](args.slice(1), std); return subHelps[command](args.slice(1), std);
@ -43,7 +41,6 @@ function usage(print: (string) => void): void {
Commands: Commands:
load load repository data into SourceCred load load repository data into SourceCred
analyze analyze cred for a loaded repository analyze analyze cred for a loaded repository
export-graph print a raw SourceCred graph
pagerank recompute cred scores pagerank recompute cred scores
clear clear SoucrceCred data clear clear SoucrceCred data
help show this help message help show this help message

View File

@ -45,16 +45,6 @@ describe("cli/help", () => {
}); });
}); });
it("prints help about 'sourcecred export-graph'", async () => {
expect(await run(help, ["export-graph"])).toEqual({
exitCode: 0,
stdout: expect.arrayContaining([
expect.stringMatching(/^usage: sourcecred export-graph/),
]),
stderr: [],
});
});
it("prints help about 'sourcecred clear'", async () => { it("prints help about 'sourcecred clear'", async () => {
expect(await run(help, ["clear"])).toEqual({ expect(await run(help, ["clear"])).toEqual({
exitCode: 0, exitCode: 0,

View File

@ -8,7 +8,6 @@ import {VERSION_SHORT} from "../core/version";
import help from "./help"; import help from "./help";
import load from "./load"; import load from "./load";
import analyze from "./analyze"; import analyze from "./analyze";
import exportGraph from "./exportGraph";
import pagerank from "./pagerank"; import pagerank from "./pagerank";
import clear from "./clear"; import clear from "./clear";
@ -30,8 +29,6 @@ const sourcecred: Command = async (args, std) => {
return analyze(args.slice(1), std); return analyze(args.slice(1), std);
case "clear": case "clear":
return clear(args.slice(1), std); return clear(args.slice(1), std);
case "export-graph":
return exportGraph(args.slice(1), std);
case "pagerank": case "pagerank":
return pagerank(args.slice(1), std); return pagerank(args.slice(1), std);
default: default:

View File

@ -14,7 +14,6 @@ function mockCommand(name) {
jest.mock("./help", () => mockCommand("help")); jest.mock("./help", () => mockCommand("help"));
jest.mock("./load", () => mockCommand("load")); jest.mock("./load", () => mockCommand("load"));
jest.mock("./analyze", () => mockCommand("analyze")); jest.mock("./analyze", () => mockCommand("analyze"));
jest.mock("./exportGraph", () => mockCommand("export-graph"));
jest.mock("./pagerank", () => mockCommand("pagerank")); jest.mock("./pagerank", () => mockCommand("pagerank"));
jest.mock("./clear", () => mockCommand("clear")); jest.mock("./clear", () => mockCommand("clear"));
@ -67,16 +66,6 @@ describe("cli/sourcecred", () => {
}); });
}); });
it("responds to 'export-graph'", async () => {
expect(
await run(sourcecred, ["export-graph", "foo/bar", "foo/baz"])
).toEqual({
exitCode: 2,
stdout: ['out(export-graph): ["foo/bar","foo/baz"]'],
stderr: ["err(export-graph)"],
});
});
it("responds to 'pagerank'", async () => { it("responds to 'pagerank'", async () => {
expect(await run(sourcecred, ["pagerank", "foo/bar", "foo/baz"])).toEqual({ expect(await run(sourcecred, ["pagerank", "foo/bar", "foo/baz"])).toEqual({
exitCode: 2, exitCode: 2,