diff --git a/src/plugins/artifact/artifactPlugin.js b/src/plugins/artifact/artifactPlugin.js index 1bdd6e9..911a17b 100644 --- a/src/plugins/artifact/artifactPlugin.js +++ b/src/plugins/artifact/artifactPlugin.js @@ -1,18 +1,45 @@ // @flow -export type ArtifactNodeID = string; +import type {Address} from "../../core/address"; +import type {Graph} from "../../core/graph"; + +export const ARTIFACT_PLUGIN_NAME = "sourcecred/artifact-beta"; + +export const ARTIFACT_NODE_TYPE = "ARTIFACT"; export type ArtifactNodePayload = {| +name: string, + +description: string, |}; export type NodePayload = ArtifactNodePayload; -export type ArtifactEdgeID = {| - +src: string, - +dst: string, -|}; -export type ArtifactEdgePayload = {| +export const INCLUDES_EDGE_TYPE = "INCLUDES"; +export type IncludesEdgePayload = {| +weight: number, // non-negative |}; -export type EdgePayload = ArtifactEdgePayload; +export type EdgePayload = IncludesEdgePayload; + +const NON_SLUG_CHARACTER: RegExp = /[^a-z]/g; + +export function artifactAddress( + graph: Graph, + repoOwner: string, + repoName: string, + artifactName: string +): Address { + const baseId = artifactName.toLowerCase().replace(NON_SLUG_CHARACTER, "-"); + function address(id) { + return { + repositoryName: `${repoOwner}/${repoName}`, + pluginName: ARTIFACT_PLUGIN_NAME, + id, + type: ARTIFACT_NODE_TYPE, + }; + } + let id = baseId; + for (let i = 0; graph.getNode(address(id)) != null; i++) { + id = baseId + "-" + i; + } + return address(id); +} diff --git a/src/plugins/artifact/artifactPlugin.test.js b/src/plugins/artifact/artifactPlugin.test.js new file mode 100644 index 0000000..5c905db --- /dev/null +++ b/src/plugins/artifact/artifactPlugin.test.js @@ -0,0 +1,51 @@ +// @flow + +import {Graph} from "../../core/graph"; +import {artifactAddress} from "./artifactPlugin"; + +describe("artifactPlugin", () => { + describe("artifactAddress", () => { + it("formats the repository name", () => { + const a = artifactAddress( + new Graph(), + "not-sourcecred", + "not-artifact-plugin", + "Sample artifact!" + ); + expect(a.repositoryName).toEqual("not-sourcecred/not-artifact-plugin"); + }); + + it("slugifies the artifact name", () => { + const a = artifactAddress( + new Graph(), + "not-sourcecred", + "not-artifact-plugin", + "Sample artifact!" + ); + expect(a.id).toEqual("sample-artifact-"); + }); + + it("resolves collisions", () => { + const g = new Graph(); + const ids = []; + for (let i = 0; i < 3; i++) { + const a = artifactAddress( + g, + "not-sourcecred", + "not-artifact-plugin", + "Sample artifact!" + ); + ids.push(a.id); + g.addNode({ + address: a, + payload: {name: "Sample artifact!", description: ""}, + }); + } + expect(ids).toEqual([ + "sample-artifact-", + "sample-artifact--0", + "sample-artifact--1", + ]); + }); + }); +}); diff --git a/src/plugins/artifact/editor/App.js b/src/plugins/artifact/editor/App.js index 1e34d57..04f15a9 100644 --- a/src/plugins/artifact/editor/App.js +++ b/src/plugins/artifact/editor/App.js @@ -34,7 +34,7 @@ function createSampleArtifact(name) { id, type: "artifact", }, - payload: {name}, + payload: {name, description: ""}, }; }