You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
5.2 KiB
164 lines
5.2 KiB
"use strict";
|
|
|
|
const path = require("path");
|
|
const fs = require("fs");
|
|
const zlib = require("zlib");
|
|
const glob = require("glob");
|
|
const streamBuffers = require("stream-buffers");
|
|
const _ = require("underscore");
|
|
|
|
const reportFilename = "report.json.gz";
|
|
const maxAttemptsNumber = 100;
|
|
const attemptsTimeout = 30000;
|
|
const reportReadTimeout = 5000;
|
|
const directoryCheckTimeout = 2000;
|
|
const attemptsDebugFrequency = 10;
|
|
|
|
const readableStreamBufferOptions = {
|
|
"chunkSize": 262144,
|
|
"frequency": 1
|
|
};
|
|
|
|
const getAllErrors = (report) => ((report.result || {}).errors || {}).$allMessages || [];
|
|
const getAllWarns = (report) => ((report.result || {}).warns || {}).$allMessages || [];
|
|
const getAllInfos = (report) => ((report.result || {}).infos || {}).$allMessages || [];
|
|
|
|
const writeReport = (releaseDir, err, result, callback) => {
|
|
const data = JSON.stringify({
|
|
"date": Date.now(),
|
|
err,
|
|
result
|
|
});
|
|
|
|
const readable = new streamBuffers.ReadableStreamBuffer(readableStreamBufferOptions);
|
|
const writeStream = fs.createWriteStream(path.join(releaseDir, reportFilename));
|
|
|
|
readable
|
|
.on("error", callback)
|
|
.pipe(zlib.createGzip())
|
|
.on("error", callback)
|
|
.pipe(writeStream)
|
|
.on("error", callback)
|
|
.on("finish", () => {
|
|
writeStream.end();
|
|
callback();
|
|
});
|
|
|
|
readable.put(data);
|
|
readable.stop();
|
|
};
|
|
|
|
const readReport = (releaseDir, callback) => {
|
|
const readStream = fs.createReadStream(path.join(releaseDir, reportFilename));
|
|
const writable = new streamBuffers.WritableStreamBuffer();
|
|
|
|
readStream
|
|
.on("error", callback)
|
|
.pipe(zlib.createGunzip())
|
|
.on("error", callback)
|
|
.pipe(writable)
|
|
.on("error", callback)
|
|
.on("finish", () => {
|
|
readStream.destroy();
|
|
|
|
const data = writable.getContentsAsString();
|
|
|
|
if (!data) {
|
|
return callback("ReportFileNotFound");
|
|
}
|
|
|
|
return callback(null, JSON.parse(data));
|
|
});
|
|
};
|
|
|
|
exports.readReport = readReport;
|
|
|
|
exports.writeReport = writeReport;
|
|
|
|
exports.loadReport = (app, options, callback) => {
|
|
const releaseDir = path.join(app.get("releasepath"), options.owner, options.reponame, options.branch, options.rev);
|
|
|
|
glob("**", {
|
|
"cwd": releaseDir,
|
|
"mark": true
|
|
}, (err, files) => {
|
|
if (err) {
|
|
return callback(err, options);
|
|
}
|
|
|
|
const reportFile = path.join(releaseDir, reportFilename);
|
|
|
|
return fs.exists(reportFile, (exists) => {
|
|
if (!exists) {
|
|
return callback("ReportFileNotFound", options);
|
|
}
|
|
|
|
return readReport(releaseDir, (readErr, report) => {
|
|
if (readErr) {
|
|
return callback(readErr, _.extend(options, { files }));
|
|
}
|
|
|
|
return callback(null, _.extend(options, {
|
|
files,
|
|
report
|
|
}));
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
exports.getStatusMessageFromRelease = (app, originalOptions, callback) => {
|
|
const options = _.extend(originalOptions, { "attemptsGetReport": (Number(originalOptions.attemptsGetReport) || Number()) + 1 });
|
|
const releaseDir = path.join(app.get("releasepath"), options.owner, options.reponame, options.branch, options.rev);
|
|
const reportFile = path.join(releaseDir, reportFilename);
|
|
|
|
fs.exists(reportFile, (exists) => {
|
|
if (!exists) {
|
|
return setTimeout(() => fs.exists(releaseDir, (dirExists) => {
|
|
if (!dirExists) {
|
|
return callback("Release directory not found. Probably repository hooks are not configured");
|
|
}
|
|
|
|
if (options.attemptsGetReport > maxAttemptsNumber) {
|
|
return callback("Report file not found");
|
|
}
|
|
|
|
// Maybe it is building right now
|
|
if (!(options.attemptsGetReport % attemptsDebugFrequency) && options.onTenthAttempt) {
|
|
options.onTenthAttempt();
|
|
}
|
|
|
|
return setTimeout(() => exports.getStatusMessageFromRelease(app, options, callback), attemptsTimeout);
|
|
}), directoryCheckTimeout);
|
|
}
|
|
|
|
return setTimeout(() => readReport(releaseDir, (readErr, report) => {
|
|
if (readErr) {
|
|
return callback(readErr);
|
|
}
|
|
|
|
if (report.result === "MBSNotFound") {
|
|
return callback("mbs.json is not found");
|
|
}
|
|
|
|
const errors = getAllErrors(report);
|
|
const warns = getAllWarns(report);
|
|
const infos = getAllInfos(report);
|
|
|
|
if (errors.length + warns.length) {
|
|
return callback(_.map(
|
|
errors, (message) => `ERR: ${message.message}`
|
|
).concat(_.map(
|
|
warns, (message) => `WARN: ${message.message}`
|
|
))
|
|
.join("\r\n"));
|
|
}
|
|
|
|
if (!report.result || report.err) {
|
|
return callback(`CRITICAL ERROR: ${report.err}`);
|
|
}
|
|
|
|
return callback(null, (infos[infos.length - 1] || { "message": "OK" }).message);
|
|
}), reportReadTimeout);
|
|
});
|
|
};
|
|
|