Cred explorer: display commit short hash + summary (#879)

This modifies how commits are displayed in the cred explorer. Rather
than printing the full hash, we now print a short hash followed by the
summary.

Test plan:
Snapshot is updated, also I tested it by running SourceCred on a real
repository.
This commit is contained in:
Dandelion Mané 2018-09-21 13:24:28 -07:00 committed by GitHub
parent 09ed51ed6e
commit 1e5f728e29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 30 deletions

View File

@ -1,6 +1,7 @@
# Changelog # Changelog
## [Unreleased] ## [Unreleased]
- Display short hash + summary for commits (#879)
- Hyperlink to GitHub entities (#860) - Hyperlink to GitHub entities (#860)
- Add GitHub reactions to the graph (#846) - Add GitHub reactions to the graph (#846)
- Detect references to commits (#833) - Detect references to commits (#833)

View File

@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`plugins/git/render commit snapshots as expected 1`] = `"commit 3715ddfb8d4c4fd2a6f6af75488c82f84c92ec2f"`; exports[`plugins/git/render commit snapshots as expected 1`] = `"3715ddf: This is an example commit"`;

View File

@ -9,6 +9,7 @@ import * as E from "./edges";
import {description} from "./render"; import {description} from "./render";
import type {Assets} from "../../app/assets"; import type {Assets} from "../../app/assets";
import type {Repo} from "../../core/repo"; import type {Repo} from "../../core/repo";
import type {Repository} from "./types";
export class StaticPluginAdapter implements IStaticPluginAdapter { export class StaticPluginAdapter implements IStaticPluginAdapter {
name() { name() {
@ -42,23 +43,38 @@ export class StaticPluginAdapter implements IStaticPluginAdapter {
]; ];
} }
async load(assets: Assets, repo: Repo): Promise<IDynamicPluginAdapter> { async load(assets: Assets, repo: Repo): Promise<IDynamicPluginAdapter> {
const url = assets.resolve( const baseUrl = `/api/v1/data/data/${repo.owner}/${repo.name}/git/`;
`/api/v1/data/data/${repo.owner}/${repo.name}/git/graph.json` async function loadGraph() {
); const url = assets.resolve(baseUrl + "graph.json");
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) { if (!response.ok) {
return Promise.reject(response); return Promise.reject(response);
}
const json = await response.json();
return Graph.fromJSON(json);
} }
const json = await response.json(); async function loadRepository(): Promise<Repository> {
const graph = Graph.fromJSON(json); const url = assets.resolve(baseUrl + "repository.json");
return new DynamicPluginAdapter(graph); const response = await fetch(url);
if (!response.ok) {
return Promise.reject(response);
}
return await response.json();
}
const [graph, repository] = await Promise.all([
loadGraph(),
loadRepository(),
]);
return new DynamicPluginAdapter(graph, repository);
} }
} }
class DynamicPluginAdapter implements IDynamicPluginAdapter { class DynamicPluginAdapter implements IDynamicPluginAdapter {
+_graph: Graph; +_graph: Graph;
constructor(graph: Graph) { +_repository: Repository;
constructor(graph: Graph, repository: Repository) {
this._graph = graph; this._graph = graph;
this._repository = repository;
} }
graph() { graph() {
return this._graph; return this._graph;
@ -67,7 +83,7 @@ class DynamicPluginAdapter implements IDynamicPluginAdapter {
// This cast is unsound, and might throw at runtime, but won't have // This cast is unsound, and might throw at runtime, but won't have
// silent failures or cause problems down the road. // silent failures or cause problems down the road.
const address = N.fromRaw((node: any)); const address = N.fromRaw((node: any));
return description(address); return description(address, this._repository);
} }
static() { static() {
return new StaticPluginAdapter(); return new StaticPluginAdapter();

View File

@ -1,19 +1,23 @@
// @flow // @flow
import * as N from "./nodes"; import * as N from "./nodes";
import type {Repository} from "./types";
export function description(address: N.StructuredAddress) { export function description(
address: N.StructuredAddress,
repository: Repository
) {
switch (address.type) { switch (address.type) {
case "COMMIT": case "COMMIT": {
return `commit ${address.hash}`; const hash = address.hash;
case "TREE": const commit = repository.commits[hash];
return `tree ${address.hash}`; if (commit == null) {
case "BLOB": console.error(`Unable to find data for commit ${hash}`);
return `blob ${address.hash}`; return hash;
case "TREE_ENTRY": }
return `entry ${JSON.stringify(address.name)} in tree ${ const {shortHash, summary} = commit;
address.treeHash return `${shortHash}: ${summary}`;
}`; }
default: default:
throw new Error(`unknown type: ${(address.type: empty)}`); throw new Error(`unknown type: ${(address.type: empty)}`);
} }

View File

@ -2,15 +2,35 @@
import * as GN from "./nodes"; import * as GN from "./nodes";
import {description} from "./render"; import {description} from "./render";
import type {Repository} from "./types";
describe("plugins/git/render", () => { describe("plugins/git/render", () => {
const examples = { const exampleHash = "3715ddfb8d4c4fd2a6f6af75488c82f84c92ec2f";
commit: (): GN.CommitAddress => ({ const exampleCommit: GN.CommitAddress = Object.freeze({
type: GN.COMMIT_TYPE, type: GN.COMMIT_TYPE,
hash: "3715ddfb8d4c4fd2a6f6af75488c82f84c92ec2f", hash: exampleHash,
}), });
}; const exampleRepository: Repository = Object.freeze({
commits: {
[exampleHash]: {
hash: exampleHash,
shortHash: exampleHash.slice(0, 7),
summary: "This is an example commit",
parentHashes: [],
},
},
});
it("commit snapshots as expected", () => { it("commit snapshots as expected", () => {
expect(description(examples.commit())).toMatchSnapshot(); expect(description(exampleCommit, exampleRepository)).toMatchSnapshot();
});
it("logs an error for a commit not in the repository", () => {
const badCommit = {type: GN.COMMIT_TYPE, hash: "1234"};
// $ExpectFlowError
console.error = jest.fn();
expect(description(badCommit, exampleRepository)).toBe("1234");
expect(console.error).toHaveBeenCalledWith(
"Unable to find data for commit 1234"
);
}); });
}); });