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

View File

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

View File

@ -14,7 +14,6 @@ function mockCommand(name) {
jest.mock("./help", () => mockCommand("help"));
jest.mock("./load", () => mockCommand("load"));
jest.mock("./analyze", () => mockCommand("analyze"));
jest.mock("./exportGraph", () => mockCommand("export-graph"));
jest.mock("./pagerank", () => mockCommand("pagerank"));
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 () => {
expect(await run(sourcecred, ["pagerank", "foo/bar", "foo/baz"])).toEqual({
exitCode: 2,