diff --git a/CHANGELOG.md b/CHANGELOG.md index 69ec6ad..490a66d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## [Unreleased] +- Display short hash + summary for commits (#879) - Hyperlink to GitHub entities (#860) - Add GitHub reactions to the graph (#846) - Detect references to commits (#833) diff --git a/src/plugins/git/__snapshots__/render.test.js.snap b/src/plugins/git/__snapshots__/render.test.js.snap index b8f2bb6..d362096 100644 --- a/src/plugins/git/__snapshots__/render.test.js.snap +++ b/src/plugins/git/__snapshots__/render.test.js.snap @@ -1,3 +1,3 @@ // 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"`; diff --git a/src/plugins/git/pluginAdapter.js b/src/plugins/git/pluginAdapter.js index 4b34c78..a50581f 100644 --- a/src/plugins/git/pluginAdapter.js +++ b/src/plugins/git/pluginAdapter.js @@ -9,6 +9,7 @@ import * as E from "./edges"; import {description} from "./render"; import type {Assets} from "../../app/assets"; import type {Repo} from "../../core/repo"; +import type {Repository} from "./types"; export class StaticPluginAdapter implements IStaticPluginAdapter { name() { @@ -42,23 +43,38 @@ export class StaticPluginAdapter implements IStaticPluginAdapter { ]; } async load(assets: Assets, repo: Repo): Promise { - const url = assets.resolve( - `/api/v1/data/data/${repo.owner}/${repo.name}/git/graph.json` - ); - const response = await fetch(url); - if (!response.ok) { - return Promise.reject(response); + const baseUrl = `/api/v1/data/data/${repo.owner}/${repo.name}/git/`; + async function loadGraph() { + const url = assets.resolve(baseUrl + "graph.json"); + const response = await fetch(url); + if (!response.ok) { + return Promise.reject(response); + } + const json = await response.json(); + return Graph.fromJSON(json); } - const json = await response.json(); - const graph = Graph.fromJSON(json); - return new DynamicPluginAdapter(graph); + async function loadRepository(): Promise { + const url = assets.resolve(baseUrl + "repository.json"); + 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 { +_graph: Graph; - constructor(graph: Graph) { + +_repository: Repository; + constructor(graph: Graph, repository: Repository) { this._graph = graph; + this._repository = repository; } 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 // silent failures or cause problems down the road. const address = N.fromRaw((node: any)); - return description(address); + return description(address, this._repository); } static() { return new StaticPluginAdapter(); diff --git a/src/plugins/git/render.js b/src/plugins/git/render.js index 04f0bee..161fc2c 100644 --- a/src/plugins/git/render.js +++ b/src/plugins/git/render.js @@ -1,19 +1,23 @@ // @flow 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) { - case "COMMIT": - return `commit ${address.hash}`; - case "TREE": - return `tree ${address.hash}`; - case "BLOB": - return `blob ${address.hash}`; - case "TREE_ENTRY": - return `entry ${JSON.stringify(address.name)} in tree ${ - address.treeHash - }`; + case "COMMIT": { + const hash = address.hash; + const commit = repository.commits[hash]; + if (commit == null) { + console.error(`Unable to find data for commit ${hash}`); + return hash; + } + const {shortHash, summary} = commit; + return `${shortHash}: ${summary}`; + } default: throw new Error(`unknown type: ${(address.type: empty)}`); } diff --git a/src/plugins/git/render.test.js b/src/plugins/git/render.test.js index 93b61ae..ff1ece3 100644 --- a/src/plugins/git/render.test.js +++ b/src/plugins/git/render.test.js @@ -2,15 +2,35 @@ import * as GN from "./nodes"; import {description} from "./render"; +import type {Repository} from "./types"; describe("plugins/git/render", () => { - const examples = { - commit: (): GN.CommitAddress => ({ - type: GN.COMMIT_TYPE, - hash: "3715ddfb8d4c4fd2a6f6af75488c82f84c92ec2f", - }), - }; + const exampleHash = "3715ddfb8d4c4fd2a6f6af75488c82f84c92ec2f"; + const exampleCommit: GN.CommitAddress = Object.freeze({ + type: GN.COMMIT_TYPE, + 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", () => { - 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" + ); }); });