@broadcom/endevor-bridge-for-git-for-zowe-cli
Version:
Endevor Bridge for Git plug-in for Zowe CLI
252 lines • 13.3 kB
JavaScript
;
/*
* Copyright (c) 2019 Broadcom. All Rights Reserved. The term
* "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
*
* This software and all information contained therein is
* confidential and proprietary and shall not be duplicated,
* used, disclosed, or disseminated in any way except as
* authorized by the applicable license agreement, without the
* express written permission of Broadcom. All authorized
* reproductions must be marked with this language.
*
* EXCEPT AS SET FORTH IN THE APPLICABLE LICENSE AGREEMENT, TO
* THE EXTENT PERMITTED BY APPLICABLE LAW, BROADCOM PROVIDES THIS
* SOFTWARE WITHOUT WARRANTY OF ANY KIND, INCLUDING WITHOUT
* LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL BROADCOM
* BE LIABLE TO THE END USER OR ANY THIRD PARTY FOR ANY LOSS OR
* DAMAGE, DIRECT OR INDIRECT, FROM THE USE OF THIS SOFTWARE,
* INCLUDING WITHOUT LIMITATION, LOST PROFITS, BUSINESS
* INTERRUPTION, GOODWILL, OR LOST DATA, EVEN IF BROADCOM IS
* EXPRESSLY ADVISED OF SUCH LOSS OR DAMAGE.
*/
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 });
const imperative_1 = require("@zowe/imperative");
const object_1 = require("../../../utils/object");
const api_1 = require("@broadcom/endevor-for-zowe-cli/lib/api");
const BuildOptions_1 = require("../../options/BuildOptions");
const api_2 = require("../../../api");
const EndevorOptions_1 = require("../../options/EndevorOptions");
const BaseHandler_1 = require("../../BaseHandler");
const zos_jobs_for_zowe_sdk_1 = require("@zowe/zos-jobs-for-zowe-sdk");
const path = require("path");
const fs = require("fs");
class BuildJobReportHandler extends BaseHandler_1.BaseHandler {
processWithSession() {
return __awaiter(this, void 0, void 0, function* () {
const endevorSession = this.createEndevorSession();
const zosmfSession = this.createZosmfSession();
const instance = this.getOption(EndevorOptions_1.EndevorOptions.ENDEVOR_INSTANCE, true);
const workDir = this.getOption(BuildOptions_1.BuildOptions.OPTION_WORK_DIR);
const listingDir = this.getOption(BuildOptions_1.BuildOptions.OPTION_LISTING_DIR, false);
const listingRC = this.getOption(BuildOptions_1.BuildOptions.OPTION_LISTING_RC, false);
this.validateRequiredOptions();
const task = {
percentComplete: imperative_1.TaskProgress.TEN_PERCENT,
statusMessage: "Getting job details",
stageName: imperative_1.TaskStage.IN_PROGRESS
};
this.progress.startBar({ task });
/**
* Get details from the precedent build job
*/
const gitLocation = path.resolve(workDir);
let currRqbIGBDetails;
try {
const fileContent = fs.readFileSync(path.join(gitLocation, ".git", "endvWrk", "developerBuildDetails.json"), "utf8");
currRqbIGBDetails = JSON.parse(fileContent);
// check if previous submit job was successful
if ((0, object_1.isNil)(currRqbIGBDetails.jobDetails)) {
throw new Error();
}
}
catch (err) {
throw new imperative_1.ImperativeError({
msg: "--work-dir specified is incorrect, or run 'request-build-job' command first to submit the build job.",
});
}
/**
* Precedent job submit detected, checking its job details
*/
const jobDetails = yield zos_jobs_for_zowe_sdk_1.GetJobs.getJob(zosmfSession, currRqbIGBDetails.jobDetails.jobid);
if (jobDetails.status !== "OUTPUT") { // job is still in input or active state
this.console.log("Build job is in progress:" +
"\n jobname: " + jobDetails.jobname +
"\n jobid: " + jobDetails.jobid +
"\n jobstatus: " + jobDetails.status);
return;
}
else if (!jobDetails.retcode.startsWith("CC")) { // job didn't finish with normal return code
throw new imperative_1.ImperativeError({
msg: "Build job failed to finish with normal completion code:" +
"\n jobname: " + jobDetails.jobname +
"\n jobid: " + jobDetails.jobid +
"\n jobstatus: " + jobDetails.status +
"\n returncode: " + jobDetails.retcode
});
}
/**
* job finish as expected, get output from the job to display
*/
// check if download listing is needed.
let downloadListing;
if ((0, object_1.isNotNil)(listingDir)) {
api_2.EndevorService.mkdirSyncRecursive(listingDir);
downloadListing = {
endevorSession,
instance,
listingDir,
listingRC
};
}
// get job output and download listing
yield this.processJobOutputToDisplay(zosmfSession, jobDetails, task, gitLocation, this.params.response, currRqbIGBDetails, downloadListing);
});
}
// tslint:disable:member-ordering
processJobOutputToDisplay(zosmfSession, jobDetails, task, gitLocation, commandResponse, currRqbIGBDetails, downloadListing) {
return __awaiter(this, void 0, void 0, function* () {
const endvReportsDir = api_2.EBGConstants.getEndevorReportsDir(gitLocation);
api_2.EndevorService.mkdirSyncRecursive(endvReportsDir);
/**
* job finished, check if c1 c2 msg exist
*/
let c1msgID = -1;
let c2msgID = -1;
const jobFileDetails = yield zos_jobs_for_zowe_sdk_1.GetJobs.getSpoolFiles(zosmfSession, jobDetails.jobname, jobDetails.jobid);
for (const jobFileDetail of jobFileDetails) {
if (jobFileDetail.ddname === "C1MSGS1") {
c1msgID = jobFileDetail.id;
}
if (jobFileDetail.ddname === "C1MSGS2") {
c2msgID = jobFileDetail.id;
}
if ((c1msgID !== -1) && (c2msgID !== -1)) {
break;
}
}
if ((c1msgID === -1) || (c2msgID === -1)) {
throw new imperative_1.ImperativeError({
msg: "Unable to find C1MSG1/C1MSG2 message from spool. Job details:" +
"\n jobname: " + jobDetails.jobname + "\n jobid: " + jobDetails.jobid +
"\n jobstatus: " + jobDetails.status,
});
}
/**
* download c1 c2 msg and write to file
*/
task.statusMessage = "Downloading C1MSG1 message";
task.percentComplete = imperative_1.TaskProgress.THIRTY_PERCENT;
const now = new Date();
const fileDateTime = api_1.EndevorUtils.formatDate(now, false) + "-" + api_1.EndevorUtils.formatTime(now, true, "");
const genC1MSGFileName = path.join(endvReportsDir, "Generate-C1MSG1-" + fileDateTime + ".txt");
const c1msgContent = yield zos_jobs_for_zowe_sdk_1.GetJobs.getSpoolContentById(zosmfSession, jobDetails.jobname, jobDetails.jobid, c1msgID);
api_1.EndevorUtils.generalWriteFile(genC1MSGFileName, c1msgContent);
task.statusMessage = "Downloading C1MSG2 message";
task.percentComplete = imperative_1.TaskProgress.FIFTY_PERCENT;
const genC2MSGFileName = path.join(endvReportsDir, "Generate-C1MSG2-" + fileDateTime + ".txt");
const c2msgContent = yield zos_jobs_for_zowe_sdk_1.GetJobs.getSpoolContentById(zosmfSession, jobDetails.jobname, jobDetails.jobid, c2msgID);
api_1.EndevorUtils.generalWriteFile(genC2MSGFileName, c2msgContent);
/**
* process each line of c2msglines into output IDisplayGeneratedElement object
*/
if ((0, object_1.isNotNil)(downloadListing)) {
task.statusMessage = "Downloading C1MSG2 message and build output";
}
else {
task.statusMessage = "Downloading C1MSG2 message";
}
task.percentComplete = imperative_1.TaskProgress.EIGHTY_PERCENT;
const generatedElms = [];
const c2msglines = api_1.ElementUtils.parseElementC1MSGS2reports(c2msgContent);
if ((0, object_1.isNotNil)(c2msglines)) {
if (c2msglines.length === 1 && c2msglines[0].elementName.trim() === "*") {
task.statusMessage = "Complete";
task.percentComplete = imperative_1.TaskProgress.ONE_HUNDRED_PERCENT;
task.stageName = 1;
commandResponse.console.log("No element generated");
}
else {
for (const line of c2msglines) {
const toDisplay = this.createDisplayGeneratedElement(currRqbIGBDetails, line);
// download listing
if ((0, object_1.isNotNil)(downloadListing)) {
if (line.processorRC.length > 0) {
toDisplay.listingFile = yield api_2.BuildUtils.downloadListings(downloadListing.endevorSession, downloadListing.instance, line, downloadListing.listingDir, downloadListing.listingRC, endvReportsDir);
}
else {
toDisplay.listingFile = "N/A";
}
}
generatedElms.push(toDisplay);
}
task.statusMessage = "Complete";
task.percentComplete = imperative_1.TaskProgress.ONE_HUNDRED_PERCENT;
task.stageName = 1;
commandResponse.format.output({
output: generatedElms,
format: "table",
header: true
});
}
}
commandResponse.console.log("\nBuild Report:");
commandResponse.console.log("\tC1MSG1: " + genC1MSGFileName);
commandResponse.console.log("\tC1MSG2: " + genC2MSGFileName);
});
}
static findFileExtByType(gitLocation, type) {
const gitBridgeExt = JSON.parse(fs.readFileSync(path.join(gitLocation, ".git", "endvWrk", "gitBridgeFileExt.json"), "utf8"));
const fileExt = gitBridgeExt[type.toUpperCase()];
if ((0, object_1.isNil)(fileExt)) { // only check for types with file extension defined
return "";
}
else {
return `.${fileExt}`;
}
}
findElementInWorkArea(currRqbIGBDetails, elementLine) {
const system = currRqbIGBDetails.workArea.systems.find(s => s.to === elementLine.system);
const subsystem = system.subsystems.find(s => s.to === elementLine.subsystem);
return currRqbIGBDetails.elmsInWorkArea.find(e => e.fromSys === system.from &&
e.fromSubsys === subsystem.from &&
e.type === elementLine.type &&
e.name === elementLine.elementName);
}
createDisplayGeneratedElement(currRqbIGBDetails, line) {
let status = "OK";
if (line.endevorRC !== "0000") {
status = `RC=${line.endevorRC}/${line.processorRC}`;
}
let partialFilepath = `${line.type}${path.sep}${line.elementName}${BuildJobReportHandler.findFileExtByType(currRqbIGBDetails.gitLocation, line.type)}`;
if (line.action.trim() === "GEN-AUTO") {
partialFilepath = partialFilepath + " (AUTO-GEN)";
}
const element = this.findElementInWorkArea(currRqbIGBDetails, line);
// TODO: The element will be undefined only in unexpected cases. Maybe this will not be necessary in the future
if ((0, object_1.isNil)(element)) {
return {
filename: partialFilepath,
status
};
}
else {
return {
filename: `${element.fromSys}${path.sep}${element.fromSubsys}${path.sep}${partialFilepath}`,
status
};
}
}
}
exports.default = BuildJobReportHandler;
//# sourceMappingURL=BuildJobReport.handler.js.map