Add params field to Project type (#1801)
* Add params field to Project type This will allow SourceCred instances to override the default alpha and interval decay parameters by adding an optional "params" field in their project.json file. If they don't include any of the fields, it will just fallback to use the default params. Test Plan: Add params field in project.json file and see if the resulting SourceCred instance correctly picks up the custom alpha value. * Rename params field in project to timelineCredParams Makes the field more descriptive and allows it to be nullable Test Plan: Ensure all usages of Project type are updated to use timelineCredParams field instead of params * Update Snapshots Update snapshots for new project version file Test Plan: Ensure sharness tests pass in CI
This commit is contained in:
parent
a8a83c4a86
commit
1abed5f0ed
|
@ -1 +1 @@
|
|||
[{"type":"sourcecred/project","version":"0.5.0"},{"discourseServer":null,"id":"sourcecred-test/example-github","identities":[],"initiatives":null,"repoIds":[{"name":"example-github","owner":"sourcecred-test"}]}]
|
||||
[{"type":"sourcecred/project","version":"0.5.1"},{"discourseServer":null,"id":"sourcecred-test/example-github","identities":[],"initiatives":null,"repoIds":[{"name":"example-github","owner":"sourcecred-test"}],"timelineCredParams":null}]
|
|
@ -62,7 +62,7 @@ export function defaultParams(): TimelineCredParameters {
|
|||
* Fill in default values for timeline cred parameters.
|
||||
*/
|
||||
export function partialParams(
|
||||
partial: $Shape<TimelineCredParameters>
|
||||
partial: $Shape<TimelineCredParameters> | null
|
||||
): TimelineCredParameters {
|
||||
return {...defaultParams(), ...partial};
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import {LoggingTaskReporter} from "../util/taskReporter";
|
|||
import type {Command} from "./command";
|
||||
import * as Common from "./common";
|
||||
import * as Weights from "../core/weights";
|
||||
import {projectFromJSON} from "../core/project";
|
||||
import {projectFromJSON, type Project} from "../core/project";
|
||||
import {load} from "../api/load";
|
||||
import {specToProject} from "../plugins/github/specToProject";
|
||||
import fs from "fs-extra";
|
||||
|
@ -14,7 +14,7 @@ import {type PluginDeclaration} from "../analysis/pluginDeclaration";
|
|||
import {declaration as discourseDeclaration} from "../plugins/discourse/declaration";
|
||||
import {declaration as githubDeclaration} from "../plugins/github/declaration";
|
||||
import {declaration as identityDeclaration} from "../plugins/identity/declaration";
|
||||
import {defaultParams} from "../analysis/timeline/params";
|
||||
import {partialParams} from "../analysis/timeline/params";
|
||||
|
||||
function usage(print: (string) => void): void {
|
||||
print(
|
||||
|
@ -126,7 +126,7 @@ const loadCommand: Command = async (args, std) => {
|
|||
|
||||
const taskReporter = new LoggingTaskReporter();
|
||||
|
||||
const specProjects = await Promise.all(
|
||||
const specProjects: $ReadOnlyArray<Project> = await Promise.all(
|
||||
projectSpecs.map((s) => specToProject(s, githubToken))
|
||||
);
|
||||
const manualProjects = await Promise.all(projectPaths.map(loadProject));
|
||||
|
@ -142,9 +142,11 @@ const loadCommand: Command = async (args, std) => {
|
|||
if (project.identities.length) {
|
||||
plugins.push(identityDeclaration);
|
||||
}
|
||||
const params = partialParams(project.timelineCredParams);
|
||||
|
||||
return {
|
||||
project,
|
||||
params: defaultParams(),
|
||||
params,
|
||||
weightsOverrides: weights,
|
||||
plugins,
|
||||
sourcecredDirectory: Common.sourcecredDirectory(),
|
||||
|
|
|
@ -6,6 +6,7 @@ import {toCompat, fromCompat, type Compatible} from "../util/compat";
|
|||
import {type ProjectParameters as Initiatives} from "../plugins/initiatives/params";
|
||||
import {type Identity} from "../plugins/identity/identity";
|
||||
import {type DiscourseServer} from "../plugins/discourse/server";
|
||||
import type {TimelineCredParameters} from "../analysis/timeline/params";
|
||||
|
||||
export type ProjectId = string;
|
||||
|
||||
|
@ -25,22 +26,24 @@ export type ProjectId = string;
|
|||
* the future (e.g. showing the last update time for each of the project's data
|
||||
* dependencies).
|
||||
*/
|
||||
export type Project = ProjectV050;
|
||||
export type Project = ProjectV051;
|
||||
export type SupportedProject =
|
||||
| ProjectV030
|
||||
| ProjectV031
|
||||
| ProjectV040
|
||||
| ProjectV051
|
||||
| ProjectV050;
|
||||
|
||||
export type ProjectV050 = {|
|
||||
export type ProjectV051 = {|
|
||||
+id: ProjectId,
|
||||
+initiatives: Initiatives | null,
|
||||
+repoIds: $ReadOnlyArray<RepoId>,
|
||||
+discourseServer: DiscourseServer | null,
|
||||
+identities: $ReadOnlyArray<Identity>,
|
||||
+timelineCredParams: $Shape<TimelineCredParameters> | null,
|
||||
|};
|
||||
|
||||
const COMPAT_INFO = {type: "sourcecred/project", version: "0.5.0"};
|
||||
const COMPAT_INFO = {type: "sourcecred/project", version: "0.5.1"};
|
||||
|
||||
/**
|
||||
* Creates a new Project instance with default values.
|
||||
|
@ -57,6 +60,7 @@ export function createProject(p: $Shape<Project>): Project {
|
|||
identities: [],
|
||||
discourseServer: null,
|
||||
initiatives: null,
|
||||
timelineCredParams: null,
|
||||
...p,
|
||||
};
|
||||
}
|
||||
|
@ -79,11 +83,25 @@ export function encodeProjectId(id: ProjectId): string {
|
|||
return base64url.encode(id);
|
||||
}
|
||||
|
||||
const upgradeFrom040 = (p: ProjectV040): ProjectV050 => ({
|
||||
const upgradeFrom050 = (p: ProjectV050): ProjectV051 => ({
|
||||
...p,
|
||||
initiatives: null,
|
||||
timelineCredParams: {},
|
||||
});
|
||||
|
||||
export type ProjectV050 = {|
|
||||
+id: ProjectId,
|
||||
+initiatives: Initiatives | null,
|
||||
+repoIds: $ReadOnlyArray<RepoId>,
|
||||
+discourseServer: DiscourseServer | null,
|
||||
+identities: $ReadOnlyArray<Identity>,
|
||||
|};
|
||||
|
||||
const upgradeFrom040 = (p: ProjectV040) =>
|
||||
upgradeFrom050({
|
||||
...p,
|
||||
initiatives: null,
|
||||
});
|
||||
|
||||
export type ProjectV040 = {|
|
||||
+id: ProjectId,
|
||||
+repoIds: $ReadOnlyArray<RepoId>,
|
||||
|
@ -124,4 +142,5 @@ const upgrades = {
|
|||
"0.3.0": upgradeFrom030,
|
||||
"0.3.1": upgradeFrom030,
|
||||
"0.4.0": upgradeFrom040,
|
||||
"0.5.0": upgradeFrom050,
|
||||
};
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
|
||||
import {makeRepoId} from "../plugins/github/repoId";
|
||||
import {toCompat} from "../util/compat";
|
||||
import type {ProjectV050} from "./project";
|
||||
|
||||
describe("core/project", () => {
|
||||
const foobar = deepFreeze(makeRepoId("foo", "bar"));
|
||||
|
@ -25,6 +26,7 @@ describe("core/project", () => {
|
|||
discourseServer: null,
|
||||
initiatives: null,
|
||||
identities: [],
|
||||
timelineCredParams: null,
|
||||
});
|
||||
const p2: Project = deepFreeze({
|
||||
id: "@foo",
|
||||
|
@ -37,6 +39,7 @@ describe("core/project", () => {
|
|||
aliases: ["github/example"],
|
||||
},
|
||||
],
|
||||
timelineCredParams: null,
|
||||
});
|
||||
describe("to/from JSON", () => {
|
||||
it("round trip is identity", () => {
|
||||
|
@ -74,6 +77,7 @@ describe("core/project", () => {
|
|||
// It should strip the apiUsername field, keeping just serverUrl.
|
||||
discourseServer: {serverUrl: "https://example.com"},
|
||||
initiatives: null,
|
||||
timelineCredParams: {},
|
||||
}: Project)
|
||||
);
|
||||
});
|
||||
|
@ -103,6 +107,7 @@ describe("core/project", () => {
|
|||
// It should strip the apiUsername field, keeping just serverUrl.
|
||||
discourseServer: {serverUrl: "https://example.com"},
|
||||
initiatives: null,
|
||||
timelineCredParams: {},
|
||||
}: Project)
|
||||
);
|
||||
});
|
||||
|
@ -128,6 +133,33 @@ describe("core/project", () => {
|
|||
...body,
|
||||
// It should add a default initiatives field.
|
||||
initiatives: null,
|
||||
timelineCredParams: {},
|
||||
}: Project)
|
||||
);
|
||||
});
|
||||
it("should upgrade from 0.5.0 formatting", () => {
|
||||
// Given
|
||||
const body: ProjectV050 = {
|
||||
id: "example-050",
|
||||
repoIds: [foobar, foozod],
|
||||
discourseServer: {serverUrl: "https://example.com"},
|
||||
identities: [],
|
||||
initiatives: null,
|
||||
};
|
||||
const compat = toCompat(
|
||||
{type: "sourcecred/project", version: "0.5.0"},
|
||||
body
|
||||
);
|
||||
|
||||
// When
|
||||
const project = projectFromJSON(compat);
|
||||
|
||||
// Then
|
||||
expect(project).toEqual(
|
||||
({
|
||||
...body,
|
||||
// It should add default params field.
|
||||
timelineCredParams: {},
|
||||
}: Project)
|
||||
);
|
||||
});
|
||||
|
@ -169,6 +201,7 @@ describe("core/project", () => {
|
|||
initiatives: null,
|
||||
repoIds: [],
|
||||
identities: [],
|
||||
timelineCredParams: null,
|
||||
});
|
||||
});
|
||||
it("treats input shape as overrides", () => {
|
||||
|
@ -185,6 +218,7 @@ describe("core/project", () => {
|
|||
aliases: ["github/example"],
|
||||
},
|
||||
],
|
||||
timelineCredParams: {alpha: 0.2, intervalDecay: 0.5},
|
||||
};
|
||||
|
||||
// When
|
||||
|
|
|
@ -38,6 +38,7 @@ describe("core/project_io", () => {
|
|||
discourseServer: {serverUrl: "https://example.com"},
|
||||
identities: [{username: "foo", aliases: ["github/foo", "discourse/foo"]}],
|
||||
initiatives: {remoteUrl: "https://example.com/initiatives"},
|
||||
timelineCredParams: {alpha: 0.2, intervalDecay: 0.5},
|
||||
});
|
||||
|
||||
it("setupProjectDirectory results in a loadable project", async () => {
|
||||
|
|
Loading…
Reference in New Issue