Merge pull request #2270 from github/nora/model-repo-states

Repo States: new data model and mapping
This commit is contained in:
Nora
2023-04-06 15:26:26 +02:00
committed by GitHub
6 changed files with 138 additions and 20 deletions

View File

@@ -0,0 +1,12 @@
export interface VariantAnalysisScannedRepositoryStateData {
repositoryId: number;
downloadStatus: VariantAnalysisScannedRepositoryDownloadData;
downloadPercentage?: number;
}
export enum VariantAnalysisScannedRepositoryDownloadData {
Pending = "pending",
InProgress = "inProgress",
Succeeded = "succeeded",
Failed = "failed",
}

View File

@@ -1,17 +1,44 @@
import { outputJson, readJson } from "fs-extra";
import { VariantAnalysisScannedRepositoryState } from "../shared/variant-analysis";
import { VariantAnalysisScannedRepositoryStateData } from "./repo-states-data-types";
import { mapRepoStateToData } from "./repo-states-to-data-mapper";
import { mapRepoStateToDomain } from "./repo-states-to-domain-mapper";
export const REPO_STATES_FILENAME = "repo_states.json";
export async function writeRepoStates(
storagePath: string,
repoStates: Record<number, VariantAnalysisScannedRepositoryState> | undefined,
repoStates: Record<number, VariantAnalysisScannedRepositoryState>,
): Promise<void> {
return await outputJson(storagePath, repoStates);
// Map from repoStates Domain type to the repoStates Data type
const repoStatesData = Object.fromEntries(
Object.entries(repoStates).map(([key, value]) => {
return [key, mapRepoStateToData(value)];
}),
);
return await outputJson(storagePath, repoStatesData);
}
export async function readRepoStates(
storagePath: string,
): Promise<Record<number, VariantAnalysisScannedRepositoryState>> {
return await readJson(storagePath);
): Promise<Record<number, VariantAnalysisScannedRepositoryState> | undefined> {
try {
const repoStatesData: Record<
number,
VariantAnalysisScannedRepositoryStateData
> = await readJson(storagePath);
// Map from repoStates Data type to the repoStates Domain type
const repoStates = Object.fromEntries(
Object.entries(repoStatesData).map(([key, value]) => {
return [key, mapRepoStateToDomain(value)];
}),
);
return repoStates;
} catch (e) {
// Ignore this error, we simply might not have downloaded anything yet
return undefined;
}
}

View File

@@ -0,0 +1,36 @@
import { assertNever } from "../../pure/helpers-pure";
import {
VariantAnalysisScannedRepositoryDownloadStatus,
VariantAnalysisScannedRepositoryState,
} from "../shared/variant-analysis";
import {
VariantAnalysisScannedRepositoryDownloadData,
VariantAnalysisScannedRepositoryStateData,
} from "./repo-states-data-types";
export function mapRepoStateToData(
repoState: VariantAnalysisScannedRepositoryState,
): VariantAnalysisScannedRepositoryStateData {
return {
repositoryId: repoState.repositoryId,
downloadStatus: processDownloadStatus(repoState.downloadStatus),
downloadPercentage: repoState.downloadPercentage,
};
}
function processDownloadStatus(
downloadedStatus: VariantAnalysisScannedRepositoryDownloadStatus,
) {
switch (downloadedStatus) {
case VariantAnalysisScannedRepositoryDownloadStatus.Pending:
return VariantAnalysisScannedRepositoryDownloadData.Pending;
case VariantAnalysisScannedRepositoryDownloadStatus.InProgress:
return VariantAnalysisScannedRepositoryDownloadData.InProgress;
case VariantAnalysisScannedRepositoryDownloadStatus.Succeeded:
return VariantAnalysisScannedRepositoryDownloadData.Succeeded;
case VariantAnalysisScannedRepositoryDownloadStatus.Failed:
return VariantAnalysisScannedRepositoryDownloadData.Failed;
default:
assertNever(downloadedStatus);
}
}

View File

@@ -0,0 +1,36 @@
import { assertNever } from "../../pure/helpers-pure";
import {
VariantAnalysisScannedRepositoryState,
VariantAnalysisScannedRepositoryDownloadStatus,
} from "../shared/variant-analysis";
import {
VariantAnalysisScannedRepositoryStateData,
VariantAnalysisScannedRepositoryDownloadData,
} from "./repo-states-data-types";
export function mapRepoStateToDomain(
repoState: VariantAnalysisScannedRepositoryStateData,
): VariantAnalysisScannedRepositoryState {
return {
repositoryId: repoState.repositoryId,
downloadStatus: processDownloadStatus(repoState.downloadStatus),
downloadPercentage: repoState.downloadPercentage,
};
}
function processDownloadStatus(
downloadedStatus: VariantAnalysisScannedRepositoryDownloadData,
) {
switch (downloadedStatus) {
case VariantAnalysisScannedRepositoryDownloadData.Pending:
return VariantAnalysisScannedRepositoryDownloadStatus.Pending;
case VariantAnalysisScannedRepositoryDownloadData.InProgress:
return VariantAnalysisScannedRepositoryDownloadStatus.InProgress;
case VariantAnalysisScannedRepositoryDownloadData.Succeeded:
return VariantAnalysisScannedRepositoryDownloadStatus.Succeeded;
case VariantAnalysisScannedRepositoryDownloadData.Failed:
return VariantAnalysisScannedRepositoryDownloadStatus.Failed;
default:
assertNever(downloadedStatus);
}
}

View File

@@ -264,15 +264,11 @@ export class VariantAnalysisManager
} else {
await this.setVariantAnalysis(variantAnalysis);
try {
const repoStates = await readRepoStates(
this.getRepoStatesStoragePath(variantAnalysis.id),
);
this.repoStates.set(variantAnalysis.id, repoStates);
} catch (e) {
// Ignore this error, we simply might not have downloaded anything yet
this.repoStates.set(variantAnalysis.id, {});
}
const repoStatesFromDisk = await readRepoStates(
this.getRepoStatesStoragePath(variantAnalysis.id),
);
this.repoStates.set(variantAnalysis.id, repoStatesFromDisk || {});
if (
!(await isVariantAnalysisComplete(
@@ -598,10 +594,13 @@ export class VariantAnalysisManager
VariantAnalysisScannedRepositoryDownloadStatus.Succeeded;
await this.onRepoStateUpdated(variantAnalysis.id, repoState);
await writeRepoStates(
this.getRepoStatesStoragePath(variantAnalysis.id),
this.repoStates.get(variantAnalysis.id),
);
const repoStates = this.repoStates.get(variantAnalysis.id);
if (repoStates) {
await writeRepoStates(
this.getRepoStatesStoragePath(variantAnalysis.id),
repoStates,
);
}
}
public async enqueueDownload(

View File

@@ -45,6 +45,10 @@ import { App } from "../../../../src/common/app";
import { ExtensionApp } from "../../../../src/common/vscode/vscode-app";
import { DbConfigStore } from "../../../../src/databases/config/db-config-store";
import { mockedObject } from "../../utils/mocking.helpers";
import {
REPO_STATES_FILENAME,
writeRepoStates,
} from "../../../../src/variant-analysis/store/repo-states-store";
// up to 3 minutes per test
jest.setTimeout(3 * 60 * 1000);
@@ -119,8 +123,12 @@ describe("Variant Analysis Manager", () => {
});
it("should read in the repo states if it exists", async () => {
await fs.writeJson(
join(storagePath, variantAnalysis.id.toString(), "repo_states.json"),
await writeRepoStates(
join(
storagePath,
variantAnalysis.id.toString(),
REPO_STATES_FILENAME,
),
{
[scannedRepos[0].repository.id]: {
repositoryId: scannedRepos[0].repository.id,
@@ -177,7 +185,7 @@ describe("Variant Analysis Manager", () => {
repoStatesPath = join(
storagePath,
variantAnalysis.id.toString(),
"repo_states.json",
REPO_STATES_FILENAME,
);
});