UNPKG

@broadcom/endevor-for-zowe-cli

Version:

Endevor Plug-in for Zowe CLI

890 lines (889 loc) 133 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkspaceUtils = void 0; const fs = require("fs"); const lodash_1 = require("lodash"); const __1 = require(".."); const HashUtils_1 = require("./HashUtils"); const path = require("path"); const imperative_1 = require("@zowe/imperative"); const WorkspaceOptions_1 = require("../../cli/WorkspaceOptions"); const CacheUtils_1 = require("./CacheUtils"); const EndevorWorkspaceFilter_1 = require("./EndevorWorkspaceFilter"); const EndevorSyncActionRetrieve_1 = require("./actions/EndevorSyncActionRetrieve"); const IEndevorWorkspaceEnums_1 = require("./doc/IEndevorWorkspaceEnums"); class WorkspaceUtils { static isWorkspace(workspaceDir) { if (!fs.existsSync(workspaceDir + "/.endevor")) return false; const stats = fs.statSync(workspaceDir + "/.endevor"); return stats.isDirectory(); } static findWorkspace(workspaceDir) { if (this.isWorkspace(workspaceDir)) return workspaceDir; const dirname = path.dirname(workspaceDir); if (dirname == workspaceDir) return ""; else return this.findWorkspace(dirname); } static getLocalState(workspaceDir, filter) { return __awaiter(this, void 0, void 0, function* () { const state = yield this.readMetadata(workspaceDir, true, filter); for (const stageKey in state.environments) { const stage = state.environments[stageKey]; for (const systemKey in stage.systems) { const system = stage.systems[systemKey]; for (const subsystemKey in system.subsystems) { const subsystem = system.subsystems[subsystemKey]; for (const elementKey in subsystem.elements) { const element = subsystem.elements[elementKey]; const type = system.types[element.type]; try { element.localStatus = yield this.getLocalElementVersionStatus(element, WorkspaceUtils.getEndOfLineChars(type)); } catch (err) { state.errorMessages.push("Failed to determine local file changes because of error: " + err); element.localStatus = __1.ElementVersionStatus.NEW; } } } } } return state; }); } static getLocalElementVersionStatus(element, endOfLine) { return __awaiter(this, void 0, void 0, function* () { if (!fs.existsSync(element.localFile)) { if (element.localFileVersion.sha1) { return __1.ElementVersionStatus.DELETED; } else { return __1.ElementVersionStatus.MISSING; } } if (element.localStatus == __1.ElementVersionStatus.CONFLICT_RESOLUTION) return __1.ElementVersionStatus.CONFLICT_RESOLUTION; const localFileSha1 = yield HashUtils_1.HashUtils.getFileHash(element.localFile); if (element.localFileVersion.sha1 == localFileSha1 && element.syncFingerprint == undefined) return __1.ElementVersionStatus.INSYNC; const localLines = fs.readFileSync(element.localFile).toString().split(endOfLine); const cacheLines = CacheUtils_1.CacheUtils.readSha1File(element.localFileVersion).toString().split(endOfLine); if (localLines.length != cacheLines.length) return __1.ElementVersionStatus.CHANGED; for (let i = 0; i < localLines.length; i++) { if (localLines[i].trimEnd() != cacheLines[i].trimEnd()) { return __1.ElementVersionStatus.CHANGED; } } element.localFileVersion.sha1 = localFileSha1; return __1.ElementVersionStatus.INSYNC; }); } static isWorkspaceFile(file) { if (!fs.existsSync(file)) return false; const parsedPath = path.parse(fs.realpathSync(file)); const typeDir = parsedPath.dir; const subsystemDir = path.dirname(typeDir); if (subsystemDir == typeDir) return false; const systemDir = path.dirname(subsystemDir); if (systemDir == subsystemDir) return false; const stageDir = path.dirname(systemDir); if (stageDir == systemDir) return false; const envDir = path.dirname(stageDir); if (envDir == stageDir) return false; const workspaceDir = path.dirname(envDir); if (workspaceDir == envDir) return false; if (this.isWorkspace(workspaceDir)) { return true; } return false; } static getWorkspaceFileState(file) { return __awaiter(this, void 0, void 0, function* () { const realPath = fs.realpathSync(file); const parsedPath = path.parse(realPath); const element = parsedPath.name; const typeDir = parsedPath.dir; const type = path.basename(typeDir); const subsystemDir = path.dirname(typeDir); const subsystem = path.basename(subsystemDir); const systemDir = path.dirname(subsystemDir); const system = path.basename(systemDir); const stageDir = path.dirname(systemDir); const stageNumber = path.basename(stageDir); const envDir = path.dirname(stageDir); const envName = path.basename(envDir); const workspaceDir = path.dirname(envDir); const location = { environment: envName, stageNumber: stageNumber, system: system, subsystem: subsystem, type: type, element: element }; const state = this.getLocalState(workspaceDir, new EndevorWorkspaceFilter_1.EndevorWorkspaceFilter().addLocation(location)); return state; }); } static detectNewLocalFiles(state, progressApi) { return __awaiter(this, void 0, void 0, function* () { const progressTask = { percentComplete: 0, statusMessage: "Detecting local changes..", stageName: imperative_1.TaskStage.IN_PROGRESS }; progressApi === null || progressApi === void 0 ? void 0 : progressApi.startBar({ task: progressTask }); for (const stageKey in state.environments) { const stage = state.environments[stageKey]; for (const systemKey in stage.systems) { const system = stage.systems[systemKey]; for (const subsystemKey in system.subsystems) { const subsystem = system.subsystems[subsystemKey]; this.detectNewLocalFilesInSubsystem(stage.envName, stage.stageNumber, system.name, subsystem.name, system.types, subsystem.elements, state, state.filter); } } } progressApi === null || progressApi === void 0 ? void 0 : progressApi.endBar(); return state; }); } static removeAllLocalFiles(state, inclMetadata) { return __awaiter(this, void 0, void 0, function* () { for (const stageKey in state.environments) { const stage = state.environments[stageKey]; const environmentDir = stage.envName; const stageDir = `${state.workspaceDir}/${environmentDir}/${stage.stageNumber}`; for (const systemKey in stage.systems) { const system = stage.systems[systemKey]; const systemDir = stageDir + "/" + systemKey; for (const subsystemKey in system.subsystems) { const subsystem = system.subsystems[subsystemKey]; const subsystemDir = systemDir + "/" + subsystemKey; for (const elementKey in subsystem.elements) { const element = subsystem.elements[elementKey]; try { if (fs.existsSync(element.localFile)) { fs.unlinkSync(element.localFile); } if (inclMetadata) { CacheUtils_1.CacheUtils.removeSha1File(element.localFileVersion); delete subsystem.elements[elementKey]; } } catch (err) { state.errorMessages.push(`${err}`); } } for (const typeKey in system.types) { const typeDir = subsystemDir + "/" + typeKey; if (fs.existsSync(typeDir) && fs.readdirSync(typeDir).length == 0) { try { fs.rmdirSync(typeDir); this.cleanupParentDirs(typeDir); } catch (err) { state.errorMessages.push(`${err}`); } } } } } } return state; }); } static saveState(currentState) { return __awaiter(this, void 0, void 0, function* () { const savedState = yield this.readMetadata(currentState.workspaceDir, false); savedState.workspaceDir = currentState.workspaceDir; savedState.fileEncoding = currentState.fileEncoding; savedState.nodeEncoding = currentState.nodeEncoding; savedState.codepageConfig = currentState.codepageConfig; savedState.codepageValue = currentState.codepageValue; savedState.fileExtensionResolution = currentState.fileExtensionResolution; const filter = currentState.filter; for (const stageKey in savedState.environments) { const stage = savedState.environments[stageKey]; if (filter.matchStage(stage.envName, stage.stageNumber) && currentState.environments[stageKey] == undefined) { delete savedState.environments[stageKey]; } } for (const stageKey in currentState.environments) { savedState.environments[stageKey] = this.updateEnvStgMetadata(savedState.workspaceDir, currentState.environments[stageKey], savedState.environments[stageKey], currentState.filter); } fs.writeFileSync(savedState.workspaceDir + "/.endevor/metadata.json", JSON.stringify(savedState)); }); } static checkEntryStage(state, optDryRun, optNoUpdate) { let allowed = true; for (const stageKey in state.environments) { const stage = state.environments[stageKey]; if (!stage.entry) { if (optDryRun) { state.infoMessages.push(`Stage ${stage.stageNumber} (${stage.stageName}) is not the entry stage of environment ${stage.envName}, sync allowed to continue because '--${WorkspaceOptions_1.WorkspaceOptions.optDryRun.name}' option was specified.`); } else if (optNoUpdate) { state.infoMessages.push(`Stage ${stage.stageNumber} (${stage.stageName}) is not the entry stage of environment ${stage.envName}, sync allowed to continue because '--${WorkspaceOptions_1.WorkspaceOptions.optNoUpdate.name}' option was specified.`); } else { state.errorMessages.push(`Stage ${stage.stageNumber} (${stage.stageName}) is not the entry stage of environment ${stage.envName}, sync can only be executed as '--${WorkspaceOptions_1.WorkspaceOptions.optDryRun.name}' or '--${WorkspaceOptions_1.WorkspaceOptions.optNoUpdate.name}'.`); allowed = false; } } } return allowed; } static ccidAndCommentCheck(state, ccidProvided, commentProvided, optSignout, optNoUpdate, optDryRun) { if (ccidProvided && commentProvided) return true; if (optNoUpdate && !optSignout) return true; if (optDryRun) return true; let ccidRequired = false; let commentRequired = false; const relevantActions = []; relevantActions.push(...state.updateActions); relevantActions.push(...state.conflictActions); relevantActions.push(...state.deleteActions); if (optSignout) { relevantActions.push(...state.retrieveActions); relevantActions.push(...state.mergeActions); } relevantActions.some((action) => { const envKey = `${action.location.environment}-${action.location.stageNumber}`; const system = state.environments[envKey].systems[action.location.system]; if (system.ccidRequired) ccidRequired = true; if (system.commentRequired) commentRequired = true; if (!ccidProvided && system.ccidRequired) { if (!commentProvided && system.commentRequired) action.statusDetailed = IEndevorWorkspaceEnums_1.EndevorActionStatusDetailed.NOT_RUN_CCID_COMMENT_REQUIRED; else action.statusDetailed = IEndevorWorkspaceEnums_1.EndevorActionStatusDetailed.NOT_RUN_CCID_REQUIRED; } else if (!commentProvided && system.commentRequired) action.statusDetailed = IEndevorWorkspaceEnums_1.EndevorActionStatusDetailed.NOT_RUN_COMMENT_REQUIRED; }); if (ccidRequired && !ccidProvided) { state.errorMessages.push("CCID is required by at least 1 affected Endevor system and the --ccid parameter wasn't provided."); } if (commentRequired && !commentProvided) { state.errorMessages.push("Comment is required by at least 1 affected Endevor system and the --comment parameter wasn't provided."); } return (!ccidRequired || ccidProvided) && (!commentRequired || commentProvided); } static getServerConfig(session, instanceName) { return __awaiter(this, void 0, void 0, function* () { try { const restResponse = yield __1.EndevorRestClient.getInstances(session); const listinstanceResult = restResponse.body.data; let result = undefined; if (listinstanceResult === null || listinstanceResult === undefined || listinstanceResult.length == 0) { return Promise.reject(); } else { listinstanceResult.forEach((instance) => { if (instance.name == instanceName) { result = instance; } }); } if (result == undefined) return Promise.reject(`Configuration ${instanceName} not found.`); return result; } catch (err) { return Promise.reject(err); } }); } static updateInventoryState(state, session, instance, maxConcurrentRequests, serverConfig, progressApi) { return __awaiter(this, void 0, void 0, function* () { const listOptions = { path: "PHY", return: "ALL", search: "NO" }; const filter = state.filter; const listData = filter.getInventoryListData(); const progressTask = { percentComplete: 0, statusMessage: "Reading inventory data..", stageName: imperative_1.TaskStage.IN_PROGRESS }; progressApi === null || progressApi === void 0 ? void 0 : progressApi.startBar({ task: progressTask }); const restResponseStages = yield __1.ListInventories.listStage(session, instance, listData, listOptions); progressApi === null || progressApi === void 0 ? void 0 : progressApi.endBar(); if (!restResponseStages.isResponseJSON) { state.errorMessages.push("Failed to retrieve inventory information: HTTP status code " + (restResponseStages.body == null ? "unknown" : restResponseStages.body.statusCode)); return false; } if (restResponseStages.body.returnCode > 8 || restResponseStages.body.statusCode > 200) { state.errorMessages.push("Failed to retrieve inventory information: "); restResponseStages.body.messages.forEach((msg) => state.errorMessages.push(msg)); return false; } const requests = [__1.ListInventories.listSystem, __1.ListInventories.listSubsystem, __1.ListInventories.listType]; const restResponses = yield __1.AsyncUtils.pooledParallelExec(requests, (query) => __awaiter(this, void 0, void 0, function* () { return query(session, instance, listData, listOptions); }), maxConcurrentRequests, "Reading inventory data..", progressApi).catch((err) => { state.errorMessages.push("Failed to retrieve inventory information: " + err); return []; }); if (restResponses.length < 3) { return false; } const restResponseSystems = restResponses[0]; const restResponseSubsystems = restResponses[1]; const restResponseTypes = restResponses[2]; if (!restResponseStages.isResponseJSON || restResponseStages.body.returnCode > 8) { state.errorMessages.push("Failed to read stage information."); restResponseStages.body.messages.forEach((msg) => state.errorMessages.push(msg)); return false; } if (__1.ListInventories.isNoMatch(restResponseStages.body.returnCode, restResponseStages.body.data, restResponseStages.body.messages)) { if (state.elementCount == 0) { state.errorMessages.push(`Environment '${listData.environment}' stage number '${listData.stageNumber}' not found.`); return false; } else { state.warningMessages.push(`Environment '${listData.environment}' stage number '${listData.stageNumber}' not found in Endevor. Matching workspace files without local changes will be deleted. Attempts to push local changes to Endevor will fail.`); return true; } } for (const stage of restResponseStages.body.data) { if (stage.envName == undefined) throw new Error(`envName undefined in list type response`); if (stage.stgName == undefined) throw new Error(`stgName undefined in list type response`); if (stage.stgNum == undefined) throw new Error(`stgNum undefined in list type response`); if (stage.stgId == undefined) throw new Error(`stgId undefined in list type response`); if (stage.nextEnv == undefined) stage.nextEnv = ""; if (stage.nextStgNum == undefined) stage.nextStgNum = ""; if (stage.entryStg == undefined) throw new Error(`entryStg undefined in list type response`); WorkspaceUtils.addStageToState(state, stage.envName, stage.stgName, stage.stgNum, stage.stgId, stage.nextEnv, stage.nextStgNum, stage.entryStg); } if (!restResponseSystems.isResponseJSON || restResponseSystems.body.returnCode > 8) { state.errorMessages.push("[ERROR] Failed to read system information."); restResponseStages.body.messages.forEach((msg) => state.errorMessages.push(msg)); return false; } if (__1.ListInventories.isNoMatch(restResponseSystems.body.returnCode, restResponseSystems.body.data, restResponseSystems.body.messages)) { if (state.elementCount == 0) { state.errorMessages.push(`System ${listData.system} not found in environment '${listData.environment}' stage number '${listData.stageNumber}'.`); return false; } else { state.warningMessages.push(`System ${listData.system} in environment '${listData.environment}' stage number '${listData.stageNumber}' not found in Endevor. Matching workspace files without local changes will be deleted. Attempts to push local changes to Endevor will fail.`); return true; } } for (const system of restResponseSystems.body.data) { if (system.envName == undefined) throw new Error(`envName undefined in list type response`); if (system.stgId == undefined) throw new Error(`stgId undefined in list type response`); if (system.sysName == undefined) throw new Error(`sysName undefined in list type response`); if (system.nextSys == undefined) throw new Error(`nextSys undefined in list type response`); if (system.ccidReq == undefined) system.ccidReq = false; if (system.commentReq == undefined) system.commentReq = false; WorkspaceUtils.addSystemToState(state, system.envName, system.stgId, system.sysName, system.nextSys, system.ccidReq, system.commentReq); } if (!restResponseSubsystems.isResponseJSON || restResponseSubsystems.body.returnCode > 8) { state.errorMessages.push("Failed to read subsystem information."); restResponseStages.body.messages.forEach((msg) => state.errorMessages.push(msg)); return false; } if (__1.ListInventories.isNoMatch(restResponseSubsystems.body.returnCode, restResponseSubsystems.body.data, restResponseSubsystems.body.messages)) { if (state.elementCount == 0) { state.errorMessages.push(`Subsystem ${listData.subsystem} not found in environment '${listData.environment}' stage number '${listData.stageNumber}' system '${listData.system}'.`); return false; } else { state.warningMessages.push(`Subsystem ${listData.subsystem} in environment '${listData.environment}' stage number '${listData.stageNumber}' system '${listData.system}' not found in Endevor. Matching workspace files without local changes will be deleted. Attempts to push local changes to Endevor will fail.`); return true; } } for (const subsys of restResponseSubsystems.body.data) { if (subsys.envName == undefined) throw new Error(`envName undefined in list type response`); if (subsys.stgId == undefined) throw new Error(`stgId undefined in list type response`); if (subsys.sysName == undefined) throw new Error(`sysName undefined in list type response`); if (subsys.sbsName == undefined) throw new Error(`sbsName undefined in list type response`); if (subsys.nextSbs == undefined) throw new Error(`nextSbs undefined in list type response`); WorkspaceUtils.addSubsystemToState(state, subsys.envName, subsys.stgId, subsys.sysName, subsys.sbsName, subsys.nextSbs); } if (!restResponseTypes.isResponseJSON || restResponseTypes.body.returnCode > 8) { state.errorMessages.push("Failed to read type information."); restResponseStages.body.messages.forEach((msg) => state.errorMessages.push(msg)); return false; } if (__1.ListInventories.isNoMatch(restResponseTypes.body.returnCode, restResponseTypes.body.data, restResponseTypes.body.messages)) { state.errorMessages.push(`Type ${listData.type} not found in environment '${listData.environment}' stage number '${listData.stageNumber}' system '${listData.system}'.`); if (state.elementCount == 0) { state.errorMessages.push(`Type ${listData.type} not found in environment '${listData.environment}' stage number '${listData.stageNumber}' system '${listData.system}'.`); return false; } else { state.warningMessages.push(`Type ${listData.type} in environment '${listData.environment}' stage number '${listData.stageNumber}' system '${listData.system}' not found in Endevor. Matching workspace files without local changes will be deleted. Attempts to push local changes to Endevor will fail.`); return true; } } for (const type of restResponseTypes.body.data) { if (type.envName == undefined) throw new Error(`envName undefined in list type response`); if (type.stgId == undefined) throw new Error(`stgId undefined in list type response`); if (type.sysName == undefined) throw new Error(`sysName undefined in list type response`); if (type.typeName == undefined) throw new Error(`typeName undefined in list type response`); if (type.dataFm == undefined) type.dataFm = "T"; if (type.srcLgt == undefined) type.srcLgt = ""; if (type.ussDlim == undefined) type.ussDlim = "NL"; if (type.fileExt == undefined) type.fileExt = ""; WorkspaceUtils.addTypeToState(state, type.envName, type.stgId, type.sysName, type.typeName, type.dataFm == "B", type.srcLgt, type.ussDlim, type.fileExt); } try { __1.EndevorRestClient.checkRestVersion(restResponseStages.headers, __1.ApiConstants.API_VERSION_WITH_MULTI_CODEPAGES); const restResponseCodepages = yield __1.ListCodePageConfig.listCodePageConfig(session, instance); if (restResponseCodepages != undefined && restResponseCodepages.default) { state.codepageConfig = restResponseCodepages; } else { state.codepageConfig = undefined; } } catch (error) { } if (serverConfig.codepage) { state.codepageValue = serverConfig.codepage; } else { state.codepageValue = undefined; } return true; }); } static updateElementState(state, session, instance, maxConcurrentRequests, progressApi) { return __awaiter(this, void 0, void 0, function* () { for (const stageKey in state.environments) { const stage = state.environments[stageKey]; for (const systemKey in stage.systems) { const system = stage.systems[systemKey]; for (const subsystemKey in system.subsystems) { const subsystem = system.subsystems[subsystemKey]; for (const elementKey in subsystem.elements) { const element = subsystem.elements[elementKey]; element.remoteStatus = __1.ElementVersionStatus.MISSING; element.remoteElmVersion = { fingerprint: "", vvll: "", userId: "", ccid: "", comment: "", date: "" }; } } } } const elementLists = yield __1.AsyncUtils.pooledParallelExec(state.filter.getElementListData(), (listData) => __awaiter(this, void 0, void 0, function* () { return yield WorkspaceUtils.listElement(state, session, instance, listData, false, false, false); }), maxConcurrentRequests, "Reading element data from Endevor..", progressApi).catch((err) => { state.errorMessages.push("Failed to retrieve element information: " + err); return []; }); if (elementLists.length == 0) return false; elementLists.forEach((elementList) => { if (elementList == null) return; for (const ele of elementList) { if (ele.nosource != "Y") { if (ele.envName == undefined) throw new Error(`envName undefined in list element response`); if (ele.stgNum == undefined) throw new Error(`stgNum undefined in list element response`); if (ele.sysName == undefined) throw new Error(`sysName undefined in list element response`); if (ele.sbsName == undefined) throw new Error(`sbsName undefined in list element response`); if (ele.stgNum == undefined) throw new Error(`stgNum undefined in list element response`); if (ele.typeName == undefined) throw new Error(`typeName undefined in list element response`); if (ele.elmName == undefined) throw new Error(`elmName undefined in list element response`); if (ele.fullElmName == undefined) ele.fullElmName = ele.elmName; if (ele.fingerprint == undefined) throw new Error(`fingerprint undefined in list element response`); if (ele.elmVVLL == undefined) ele.elmVVLL = ""; if (ele.elmLastLLUsrid == undefined) ele.elmLastLLUsrid = ""; if (ele.elmLastLLCcid == undefined) ele.elmLastLLCcid = ""; if (ele.elmLastLLComment == undefined) ele.elmLastLLComment = ""; if (ele.elmLastLLDate == undefined) ele.elmLastLLDate = ""; WorkspaceUtils.updateElementRemoteState(state, ele.envName, ele.stgNum, ele.sysName, ele.sbsName, ele.typeName, ele.elmName, ele.fullElmName, ele.fingerprint, ele.elmVVLL, ele.elmLastLLUsrid, ele.elmLastLLCcid, ele.elmLastLLComment, ele.elmLastLLDate); } } }); return true; }); } static listElement(state_1, session_1, instance_1, location_1, searchMap_1, returnFirst_1, logicalPath_1) { return __awaiter(this, arguments, void 0, function* (state, session, instance, location, searchMap, returnFirst, logicalPath, reportErrors = true) { const listOptions = { path: logicalPath ? "log" : "phy", return: returnFirst ? "fir" : "all", search: searchMap ? "yes" : "no" }; try { const restResponse = yield __1.ListElement.listElement(session, instance, location, listOptions); if (restResponse.isResponseJSON && restResponse.body.returnCode <= 8) { let stcShortage = false; __1.EndevorUtils.removeMessageTimestamps(restResponse.body.messages).forEach((message) => { if (message.startsWith("EWS1111E")) { stcShortage = true; } }); if (stcShortage) { if (reportErrors) { state.errorMessages.push(`Failed to list elements ${location.element}.${location.type} at ${location.environment}/${location.stageNumber}/${location.system}/${location.subsystem}`); state.errorMessages.push(...restResponse.body.messages); return null; } } if (restResponse.body.data == null) { if (reportErrors) { state.errorMessages.push(`Failed to list elements ${location.element}.${location.type} at ${location.environment}/${location.stageNumber}/${location.system}/${location.subsystem}`); state.errorMessages.push(...restResponse.body.messages); } return null; } return restResponse.body.data; } else { if (reportErrors) { state.errorMessages.push(`Failed to list elements ${location.element}.${location.type} at ${location.environment}/${location.stageNumber}/${location.system}/${location.subsystem}`); } state.errorMessages.push(...restResponse.body.messages); return null; } } catch (err) { if (reportErrors) { state.errorMessages.push(`Failed to list elements ${location.element}.${location.type} at ${location.environment}/${location.stageNumber}/${location.system}/${location.subsystem}`); state.errorMessages.push(`${err}`); } return null; } }); } static composeActionsSummaryMsgs(state) { EndevorSyncActionRetrieve_1.EndevorSyncActionRetrieve.composeActionsSummaryMsg(state, state.retrieveActions); __1.EndevorSyncActionUpdate.composeActionsSummaryMsg(state, state.updateActions); __1.EndevorSyncActionDelete.composeActionsSummaryMsg(state, state.deleteActions); __1.EndevorSyncActionUntrack.composeActionsSummaryMsg(state, state.untrackActions); __1.EndevorSyncActionConflict.composeActionsSummaryMsg(state, state.conflictActions); __1.EndevorSyncActionMerge.composeActionsSummaryMsg(state, state.mergeActions); } static readMetadata(workspaceDir, includeElements, filter) { return __awaiter(this, void 0, void 0, function* () { if (filter == undefined) { filter = new EndevorWorkspaceFilter_1.EndevorWorkspaceFilter(); } if (fs.existsSync(workspaceDir + "/.endevor/metadata.json")) { const buffer = fs.readFileSync(workspaceDir + "/.endevor/metadata.json"); const json = buffer.toString(); const state = JSON.parse(json); if (state.renameActions == undefined) state.renameActions = []; if (state.retrieveActions == undefined) state.retrieveActions = []; if (state.updateActions == undefined) state.updateActions = []; if (state.deleteActions == undefined) state.deleteActions = []; if (state.untrackActions == undefined) state.untrackActions = []; if (state.conflictActions == undefined) state.conflictActions = []; if (state.mergeActions == undefined) state.mergeActions = []; if (state.actions != undefined) delete state.actions; state.filter = filter; if (state.caseSensitiveFS == undefined) state.caseSensitiveFS = WorkspaceUtils.isFSCaseSensitive(workspaceDir); if (state.errorMessages == undefined) state.errorMessages = []; if (state.warningMessages == undefined) state.warningMessages = []; if (state.infoMessages == undefined) state.infoMessages = []; if (state.messages != undefined) delete state.messages; if (state.fileExtensionResolution == undefined) state.fileExtensionResolution = IEndevorWorkspaceEnums_1.FileExtensionResolution.MIXED; for (const stageKey in state.environments) { const stage = state.environments[stageKey]; if (!filter.matchStage(stage.envName, stage.stageNumber)) { delete state.environments[stageKey]; } else { for (const systemKey in stage.systems) { if (!filter.matchSystem(stage.envName, stage.stageNumber, systemKey)) { delete stage.systems[systemKey]; } else { const system = stage.systems[systemKey]; if (system.nextSystem == undefined) { system.nextSystem = system.name; } for (const typeKey in system.types) { if (!filter.matchType(stage.envName, stage.stageNumber, systemKey, typeKey)) { delete system.types[typeKey]; } } for (const subsystemKey in system.subsystems) { if (!filter.matchSubsystem(stage.envName, stage.stageNumber, systemKey, subsystemKey)) { delete system.subsystems[subsystemKey]; } else { const subsystem = system.subsystems[subsystemKey]; if (subsystem.nextSubsystem == undefined) { subsystem.nextSubsystem = subsystem.name; } if (includeElements) { subsystem.elements = this.readElementMetadata(workspaceDir, stage.envName, stage.stageNumber, systemKey, subsystemKey, filter); state.elementCount += (0, lodash_1.keysIn)(subsystem.elements).length; } } } } } } } return state; } return { filter: filter, workspaceDir: workspaceDir, environments: {}, errorMessages: [], warningMessages: [], infoMessages: [], mkDirs: [], renameActions: [], retrieveActions: [], updateActions: [], deleteActions: [], untrackActions: [], conflictActions: [], mergeActions: [], inSync: false, unresolvedMergeConflicts: false, signoutOverrideNeeded: false, fileEncoding: "", nodeEncoding: "utf-8", caseSensitiveFS: WorkspaceUtils.isFSCaseSensitive(workspaceDir), elementCount: 0, fileExtensionResolution: IEndevorWorkspaceEnums_1.FileExtensionResolution.MIXED }; }); } static readElementMetadata(workspaceDir, environment, stageNumber, system, subsystem, filter) { const dir = `${workspaceDir}/.endevor/${environment}/${stageNumber}/${system}/${subsystem}`; const fileName = dir + "/metadata.json"; if (fs.existsSync(fileName)) { const buffer = fs.readFileSync(fileName); const json = buffer.toString(); const elements = JSON.parse(json); for (const elementKey in elements) { const element = elements[elementKey]; if (filter != undefined && !filter.matchElement(environment, stageNumber, system, subsystem, element.type, element.fullName)) { delete elements[elementKey]; } if (element.fileExtensionResolution == undefined) { element.fileExtensionResolution = IEndevorWorkspaceEnums_1.FileExtensionResolution.MIXED; } } return elements; } return {}; } static updateEnvStgMetadata(workspaceDir, currentStage, savedStage, filter) { if (savedStage == undefined) { savedStage = (0, lodash_1.cloneDeep)(currentStage); } else { savedStage.entry = currentStage.entry; savedStage.envName = currentStage.envName; savedStage.stageId = currentStage.stageId; savedStage.stageName = currentStage.stageName; savedStage.stageNumber = currentStage.stageNumber; } for (const systemKey in savedStage.systems) { if (filter.matchSystem(currentStage.envName, currentStage.stageNumber, systemKey) && currentStage.systems[systemKey] == undefined) { delete savedStage.systems[systemKey]; } } for (const systemKey in currentStage.systems) { savedStage.systems[systemKey] = this.updateSystemMetadata(workspaceDir, currentStage.systems[systemKey], savedStage.systems[systemKey], currentStage.envName, currentStage.stageNumber, filter); } return savedStage; } static updateSystemMetadata(workspaceDir, currentSystem, savedSystem, environment, stageNumber, filter) { if (savedSystem == undefined) { savedSystem = (0, lodash_1.cloneDeep)(currentSystem); } else { savedSystem.name = currentSystem.name; savedSystem.ccidRequired = currentSystem.ccidRequired; savedSystem.commentRequired = currentSystem.commentRequired; } for (const typeKey in savedSystem.types) { if (filter.matchType(environment, stageNumber, currentSystem.name, typeKey) && currentSystem.types[typeKey] == undefined) { delete savedSystem.types[typeKey]; } } for (const typeKey in currentSystem.types) { savedSystem.types[typeKey] = currentSystem.types[typeKey]; } for (const subsystemKey in savedSystem.subsystems) { if (filter.matchSubsystem(environment, stageNumber, currentSystem.name, subsystemKey) && currentSystem.subsystems[subsystemKey] == undefined) { delete savedSystem.subsystems[subsystemKey]; } } for (const subsystemKey in currentSystem.subsystems) { savedSystem.subsystems[subsystemKey] = this.updateSubsystemMetadata(workspaceDir, currentSystem.subsystems[subsystemKey], savedSystem.subsystems[subsystemKey], environment, stageNumber, savedSystem.name, filter); } return savedSystem; } static updateSubsystemMetadata(workspaceDir, currentSubsystem, savedSubsystem, environment, stageNumber, system, filter) { if (savedSubsystem == undefined) { savedSubsystem = (0, lodash_1.cloneDeep)(currentSubsystem); } savedSubsystem.elements = this.readElementMetadata(workspaceDir, environment, stageNumber, system, savedSubsystem.name); for (const elementKey in savedSubsystem.elements) { const savedElement = savedSubsystem.elements[elementKey]; if (filter.matchElement(environment, stageNumber, system, currentSubsystem.name, savedElement.type, savedElement.fullName)) { if (currentSubsystem.elements[elementKey] == undefined) { delete savedSubsystem.elements[elementKey]; } } } for (const elementKey in currentSubsystem.elements) { const currentElement = currentSubsystem.elements[elementKey]; if (currentElement.localStatus == __1.ElementVersionStatus.MISSING) { delete savedSubsystem.elements[elementKey]; } else if (currentElement.localStatus == __1.ElementVersionStatus.NEW && currentElement.remoteStatus == __1.ElementVersionStatus.MISSING) { delete savedSubsystem.elements[elementKey]; } else { savedSubsystem.elements[elementKey] = currentElement; } } this.saveElementMetadata(workspaceDir, environment, stageNumber, system, savedSubsystem.name, savedSubsystem.elements); savedSubsystem.elements = {}; return savedSubsystem; } static saveElementMetadata(workspaceDir, environment, stageNumber, system, subsystem, elements) { const dir = `${workspaceDir}/.endevor/${environment}/${stageNumber}/${system}/${subsystem}`; const fileName = dir + "/metadata.json"; if ((0, lodash_1.keysIn)(elements).length == 0) { if (fs.existsSync(fileName)) { fs.unlinkSync(fileName); this.cleanupParentDirs(fileName); } } else { this.ensureDirectoryExistence(fileName); fs.writeFileSync(fileName, JSON.stringify(elements)); } } static detectNewLocalFilesInSubsystem(environment, stageNumber, system, subsystem, types, elements, state, filter) { return __awaiter(this, void 0, void 0, function* () { const subsystemDir = `${state.workspaceDir}/${environment}/${stageNumber}/${system}/${subsystem}`; if (!fs.existsSync(subsystemDir)) return; const typeSubdirs = fs.readdirSync(subsystemDir); typeSubdirs.forEach((typeDir) => __awaiter(this, void 0, void 0, function* () { const type = types[typeDir]; const fullTypeDir = `${subsystemDir}/${typeDir}`; if (type != undefined && filter.matchType(environment, stageNumber, system, type.name) && fs.statSync(fullTypeDir).isDirectory()) { const files = fs.readdirSync(fullTypeDir); files.forEach((fileName) => __awaiter(this, void 0, void 0, function* () { const fullFileName = `${fullTypeDir}/${fileName}`; if (fs.statSync(fullFileName).isFile()) { if (this.findElementByFileName(fullFileName, elements, true) == null) { const fileSuffix = this.getFileSuffix(type.name, type.fileext, state.fileExtensionResolution); if (fileSuffix == "" || fileName.endsWith(fileSuffix)) { const elmName = fileName.substr(0, fileName.length - fileSuffix.length); if (filter.matchElement(environment, stageNumber, system, subsystem, type.name, elmName)) { elements[`${elmName}.${type.name}`] = { name: "", fullName: elmName, type: type.name, localFile: fullFileName, localStatus: __1.ElementVersionStatus.NEW, localFileVersion: { sha1: "", sha1File: "" }, localElmVersion: { fingerprint: "", vvll: "",