oneuptime/Copilot/Utils/ServiceRepository.ts

155 lines
5.1 KiB
TypeScript

import ServiceFileTypesUtil from "./FileTypes";
import Dictionary from "Common/Types/Dictionary";
import BadDataException from "Common/Types/Exception/BadDataException";
import TechStack from "Common/Types/ServiceCatalog/TechStack";
import CodeRepositoryCommonServerUtil from "Common/Server/Utils/CodeRepository/CodeRepository";
import CodeRepositoryFile from "Common/Server/Utils/CodeRepository/CodeRepositoryFile";
import LocalFile from "Common/Server/Utils/LocalFile";
import ServiceCopilotCodeRepository from "Common/Models/DatabaseModels/ServiceCopilotCodeRepository";
import ServiceLanguageUtil from "Common/Utils/TechStack";
import CodeRepositoryUtil, {
CodeRepositoryResult,
ServiceToImproveResult,
} from "./CodeRepository";
import PullRequestUtil from "./PullRequest";
import CopilotPullRequest from "Common/Models/DatabaseModels/CopilotPullRequest";
import logger from "Common/Server/Utils/Logger";
import ProcessUtil from "./Process";
import ObjectID from "Common/Types/ObjectID";
export default class ServiceRepositoryUtil {
public static codeRepositoryResult: CodeRepositoryResult | null = null;
public static servicesToImprove: Array<ServiceCopilotCodeRepository> | null =
null;
public static setCodeRepositoryResult(data: {
codeRepositoryResult: CodeRepositoryResult;
}): void {
ServiceRepositoryUtil.codeRepositoryResult = data.codeRepositoryResult;
}
public static async getServicesToImprove(): Promise<
Array<ServiceCopilotCodeRepository>
> {
if (this.servicesToImprove) {
return this.servicesToImprove;
}
const codeRepositoryResult: CodeRepositoryResult =
ServiceRepositoryUtil.codeRepositoryResult!;
if (!codeRepositoryResult) {
throw new BadDataException("Code repository result is not set");
}
// before cloning the repo, check if there are any services to improve.
const openPullRequests: Array<CopilotPullRequest> =
await PullRequestUtil.getOpenPRs();
const servicesToImproveResult: Array<ServiceToImproveResult> =
await CodeRepositoryUtil.getServicesToImproveCode({
codeRepository: codeRepositoryResult.codeRepository,
serviceRepositories: codeRepositoryResult.serviceRepositories,
openPullRequests: openPullRequests,
});
const servicesToImprove: Array<ServiceCopilotCodeRepository> =
servicesToImproveResult.map(
(serviceToImproveResult: ServiceToImproveResult) => {
return serviceToImproveResult.serviceRepository;
},
);
if (servicesToImprove.length === 0) {
logger.info("No services to improve. Exiting.");
ProcessUtil.haltProcessWithSuccess();
}
this.servicesToImprove = servicesToImprove;
return servicesToImprove;
}
public static async getFileLanguage(data: {
filePath: string;
}): Promise<TechStack> {
const fileExtention: string = LocalFile.getFileExtension(data.filePath);
const techStack: TechStack = ServiceLanguageUtil.getLanguageByFileExtension(
{
fileExtension: fileExtention,
},
);
return techStack;
}
public static async getFileContent(data: {
filePath: string;
}): Promise<string> {
const { filePath } = data;
const fileContent: string =
await CodeRepositoryCommonServerUtil.getFileContent({
repoPath: CodeRepositoryUtil.getLocalRepositoryPath(),
filePath: filePath,
});
return fileContent;
}
public static async getFilesByServiceCatalogId(data: {
serviceCatalogId: ObjectID;
}): Promise<Dictionary<CodeRepositoryFile>> {
const { serviceCatalogId } = data;
const serviceRepository: ServiceCopilotCodeRepository | undefined = (
await ServiceRepositoryUtil.getServicesToImprove()
).find((serviceRepository: ServiceCopilotCodeRepository) => {
return (
serviceRepository.serviceCatalog!.id?.toString() ===
serviceCatalogId.toString()
);
});
if (!serviceRepository) {
throw new BadDataException("Service repository not found");
}
const allFiles: Dictionary<CodeRepositoryFile> =
await ServiceRepositoryUtil.getFilesInServiceDirectory({
serviceRepository,
});
return allFiles;
}
public static async getFilesInServiceDirectory(data: {
serviceRepository: ServiceCopilotCodeRepository;
}): Promise<Dictionary<CodeRepositoryFile>> {
const { serviceRepository } = data;
if (!serviceRepository.serviceCatalog?.techStack) {
throw new BadDataException(
"Service language is not defined in the service catalog",
);
}
const allFiles: Dictionary<CodeRepositoryFile> =
await CodeRepositoryCommonServerUtil.getFilesInDirectoryRecursive({
repoPath: CodeRepositoryUtil.getLocalRepositoryPath(),
directoryPath: serviceRepository.servicePathInRepository || ".",
acceptedFileExtensions:
ServiceFileTypesUtil.getFileExtentionsByTechStack(
serviceRepository.serviceCatalog!.techStack!,
),
ignoreFilesOrDirectories:
ServiceFileTypesUtil.getCommonFilesToIgnoreByTechStack(
serviceRepository.serviceCatalog!.techStack!,
),
});
return allFiles;
}
}