diff --git a/BuildServer/app.js b/BuildServer/app.js index d4fdd88..cc65956 100644 --- a/BuildServer/app.js +++ b/BuildServer/app.js @@ -20,8 +20,7 @@ const settings = require("./settings"); const app = express(); -// All environments -app.set("port", process.env.PORT || settings.port); +app.set("port", process.env.PORT || settings.port); // eslint-disable-line no-process-env app.set("views", path.join(__dirname, "views")); app.set("view engine", "jade"); app.set("gitpath", settings.gitpath); diff --git a/BuildServer/lib/builder.js b/BuildServer/lib/builder.js index e13ceb4..120bd78 100644 --- a/BuildServer/lib/builder.js +++ b/BuildServer/lib/builder.js @@ -62,6 +62,14 @@ const wrapGitLoader = (skipGitLoader) => { return (gitLoaderOptions, gitLoaderCallback) => process.nextTick(gitLoaderCallback); }; +const safeParseJson = (data) => { + try { + return { "parsed": JSON.parse(data) }; + } catch (err) { + return { err }; + } +}; + const build = (options, buildCallback) => { const url = options.url; const owner = options.owner; @@ -179,17 +187,15 @@ const build = (options, buildCallback) => { return done(readErr, "MBSUnableToRead"); } - let task = null; + const { parsed, err } = safeParseJson(data); - try { - task = JSON.parse(data); - } catch (ex) { + if (err) { console.log(`Malformed data: ${data}`); - return done(ex, "MBSMalformed"); + return done(err, "MBSMalformed"); } - return processor.processTask(task, { + return processor.processTask(parsed, { branch, exported, owner, diff --git a/BuildServer/lib/commenter.js b/BuildServer/lib/commenter.js index f6adc12..90a9483 100644 --- a/BuildServer/lib/commenter.js +++ b/BuildServer/lib/commenter.js @@ -1,5 +1,6 @@ "use strict"; +const _ = require("underscore"); const reportProcessor = require("./report-processor"); const settings = require("../settings"); @@ -135,9 +136,9 @@ const checkPullRequest = (options, callback) => { }); }; -exports.commentOnPullRequest = (options, callback) => { - options.github = settings.createGithub(options.baseRepoOptions.owner); - options.headRepoOptions.onTenthAttempt = () => writeComment(options, "Waiting for build to finish..."); +exports.commentOnPullRequest = (originalOptions, callback) => { + const optionsGithub = _.extend(originalOptions, { "github": settings.createGithub(originalOptions.baseRepoOptions.owner) }); + const options = _.extend(optionsGithub, { "onTenthAttempt": () => writeComment(optionsGithub, "Waiting for build to finish...") }); return checkPullRequest(options, () => reportProcessor.getStatusMessageFromRelease(options.app, options.headRepoOptions, (statusMessageErr, statusSuccessMessage) => { const escapedErr = String(statusMessageErr || "").substring(0, maxCommentLength) diff --git a/BuildServer/lib/git/copy.js b/BuildServer/lib/git/copy.js index 0ac1aa3..27fafe3 100644 --- a/BuildServer/lib/git/copy.js +++ b/BuildServer/lib/git/copy.js @@ -1,11 +1,19 @@ "use strict"; -const EventEmitter = require("events").EventEmitter; +const EventEmitter = require("events").EventEmitter; // eslint-disable-line fp/no-events const path = require("path"); const fs = require("fs"); const async = require("async"); const Copier = require("recursive-tree-copy").Copier; +const safeGetEntries = (tree) => { + try { + return { "entries": tree.gitTree.entries() }; + } catch (err) { + return { err }; + } +}; + const gitToFsCopier = new Copier({ "concurrency": 4, "copyLeaf": (entry, targetDir, callback) => { @@ -36,19 +44,17 @@ const gitToFsCopier = new Copier({ const emitter = new EventEmitter(); process.nextTick(() => { - let entries = null; + const { entries, err } = safeGetEntries(tree); - try { - entries = tree.gitTree.entries(); - } catch (err) { + if (err) { return emitter.emit("error", err); } return async.parallel(entries.map((entry) => (callback) => { if (entry.isTree()) { - return entry.getTree((err, subTree) => { - if (err) { - return callback(err); + return entry.getTree((getTreeErr, subTree) => { + if (getTreeErr) { + return callback(getTreeErr); } emitter.emit("tree", { @@ -67,9 +73,9 @@ const gitToFsCopier = new Copier({ } return callback(); - }), (err) => { - if (err) { - return emitter.emit("error", err); + }), (parallelErr) => { + if (parallelErr) { + return emitter.emit("error", parallelErr); } return emitter.emit("done"); diff --git a/BuildServer/lib/git/loader.js b/BuildServer/lib/git/loader.js index 587d87e..1cdea6a 100644 --- a/BuildServer/lib/git/loader.js +++ b/BuildServer/lib/git/loader.js @@ -3,13 +3,23 @@ const nodegit = require("nodegit"); const fse = require("fs-extra"); const gitToFs = require("./copy").gitToFs; + const mkdirs = (path) => { fse.mkdirsSync(path); // eslint-disable-line no-sync }; + const removedirs = (path) => { fse.removeSync(path); // eslint-disable-line no-sync }; +const fixUrl = (url) => { + if (!url.startsWith("https://")) { + return url; + } + + return `git://${url.substr("https://".length)}`; +}; + /* Example: options = { "remote": "https://github.com/visionmedia/express.git", @@ -21,17 +31,13 @@ options = { */ module.exports = (options, globalCallback) => { - let url = options.remote; + const url = fixUrl(options.remote); const path = `${options.local}/${options.hash}`; const exported = options.exported; removedirs(path); mkdirs(path); - if (url.startsWith("https://")) { - url = `git://${url.substr("https://".length)}`; - } - console.log(`Cloning ${url} to ${path}`); nodegit.Repository.init(path, 1) diff --git a/BuildServer/lib/report-processor.js b/BuildServer/lib/report-processor.js index 1c84902..5152713 100644 --- a/BuildServer/lib/report-processor.js +++ b/BuildServer/lib/report-processor.js @@ -88,8 +88,6 @@ exports.loadReport = (app, options, callback) => { const reportFile = path.join(releaseDir, reportFilename); - options.files = files; - return fs.exists(reportFile, (exists) => { if (!exists) { return callback("ReportFileNotFound", options); @@ -97,23 +95,23 @@ exports.loadReport = (app, options, callback) => { return readReport(releaseDir, (readErr, report) => { if (readErr) { - return callback(readErr, options); + return callback(readErr, _.extend(options, { files })); } - options.report = report; - - return callback(null, options); + return callback(null, _.extend(options, { + files, + report + })); }); }); }); }; -exports.getStatusMessageFromRelease = (app, options, callback) => { +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); - options.attemptsGetReport = (Number(options.attemptsGetReport) || Number()) + 1; - fs.exists(reportFile, (exists) => { if (!exists) { return setTimeout(() => fs.exists(releaseDir, (dirExists) => { diff --git a/BuildServer/lib/status-processor.js b/BuildServer/lib/status-processor.js index e545124..f9ce9f5 100644 --- a/BuildServer/lib/status-processor.js +++ b/BuildServer/lib/status-processor.js @@ -2,7 +2,7 @@ const path = require("path"); const fs = require("fs"); - +const _ = require("underscore"); const reportProcessor = require("./report-processor"); const addBranchInfo = (app, options, callback) => { @@ -17,10 +17,15 @@ const addBranchInfo = (app, options, callback) => { if (err) { return callback(err, options); } - options.branch = data.toString(); - options.branchName = options.branch.split("/").pop(); - return callback(null, options); + const branch = data.toString(); + const branchParts = branch.split("/"); + const branchName = branchParts[branchParts.length - 1]; + + return callback(null, _.extend(options, { + branch, + branchName + })); }); }); }; @@ -37,39 +42,38 @@ const addRevInfo = (app, options, callback) => { if (err) { return callback(err, options); } - options.rev = data.toString(); - return callback(null, options); + const rev = data.toString(); + + return callback(null, _.extend(options, { rev })); }); }); }; const parseOptions = (app, options, callback) => { + if (options.rev && !(/^[\da-f]{40}$/i).test(options.rev)) { + return callback(`Wrong rev format: ${options.rev}`, options); + } + const result = { "owner": options.owner, "reponame": options.reponame }; - if (options.rev && !(/^[\da-f]{40}$/i).test(options.rev)) { - return callback(`Wrong rev format: ${options.rev}`, options); - } - if (options.rev) { - result.rev = options.rev; - - return addBranchInfo(app, result, callback); + return addBranchInfo(app, _.extend(result, { "rev": options.rev }), callback); } if (/^[\da-f]{40}$/i.test(options.branchName)) { - result.rev = options.branchName; - - return addBranchInfo(app, result, callback); + return addBranchInfo(app, _.extend(result, { "rev": options.branchName }), callback); } - result.branchName = options.branchName || "master"; - result.branch = `refs/heads/${result.branchName}`; + const branchName = options.branchName || "master"; - return addRevInfo(app, result, callback); + return addRevInfo(app, _.extend(result, { + "branch": `refs/heads/${branchName}`, + branchName + }), callback); }; exports.getReport = (app, options, callback) => parseOptions(app, options, (err, result) => { diff --git a/BuildServer/lib/task-processor.js b/BuildServer/lib/task-processor.js index 0b71aab..fd92a9d 100644 --- a/BuildServer/lib/task-processor.js +++ b/BuildServer/lib/task-processor.js @@ -1,5 +1,6 @@ "use strict"; +const _ = require("underscore"); const tasks = require("./tasks"); // TaskProcessor does not look like EventEmitter, so no need to extend EventEmitter and use `emit' here. @@ -9,9 +10,9 @@ const TaskProcessor = function (task, outerProcessor, callback) { } const that = this; - let taskWorker = null; + const createTaskWorker = () => tasks[task.type](task.params || {}, that); const errors = []; - const process = () => taskWorker.process(); + const process = () => createTaskWorker().process(); const getOuterPrefix = (prefix) => { if (task.name && prefix) { return `${task.name}/${prefix}`; @@ -39,43 +40,48 @@ const TaskProcessor = function (task, outerProcessor, callback) { that.processTask = processTask; that.done = done; that.context = outerProcessor.context; - - const taskImpl = tasks[task.type]; - - taskWorker = taskImpl(task.params || {}, that); - - return this; }; -const pushMessage = (list, message, prefix) => { - const parts = prefix.split("/"); - let innerList = list; +const pushMessage = (list, message, parts, index) => { + if (!index) { + list.$allMessages = list.$allMessages || []; // eslint-disable-line fp/no-mutation + list.$allMessages.push({ // eslint-disable-line fp/no-mutating-methods + message, + "prefix": parts.join("/") + }); + } - parts.forEach((part) => { - innerList = innerList[part] = innerList[part] || {}; - }); + list.$messages = list.$messages || []; // eslint-disable-line fp/no-mutation + if (index === parts.length) { + return list.$messages.push(message); // eslint-disable-line fp/no-mutating-methods + } - innerList.$messages = innerList.$messages || []; - innerList.$messages.push(message); + return pushMessage(list, message, parts, index + 1); +}; - list.$allMessages = list.$allMessages || []; - list.$allMessages.push({ - message, - prefix - }); +const addFlag = (flags) => (flagName) => { + flags[flagName] = true; // eslint-disable-line fp/no-mutation }; +const containsFlag = (flags) => (flagName) => flags[flagName]; + exports.processTask = (task, context, callback) => { const errors = {}; const warns = {}; const infos = {}; const messages = {}; const messageProcessor = (list) => (message, prefix) => { - pushMessage(list, message, prefix); - pushMessage(messages, message, prefix); + const parts = prefix.split("/"); + + pushMessage(list, message, parts, 0); + pushMessage(messages, message, parts, 0); }; + const flags = {}; const processor = new TaskProcessor(task, { - context, + "context": _.extend(context, { + "addFlag": addFlag(flags), + "containsFlag": containsFlag(flags) + }), "onError": messageProcessor(errors), "onInfo": messageProcessor(infos), "onWarn": messageProcessor(warns) diff --git a/BuildServer/lib/tasks/cssnanoall.js b/BuildServer/lib/tasks/cssnanoall.js index 35dc307..92a8437 100644 --- a/BuildServer/lib/tasks/cssnanoall.js +++ b/BuildServer/lib/tasks/cssnanoall.js @@ -1,14 +1,15 @@ "use strict"; const glob = require("glob"); +const flagDoneName = "cssnanoallDone"; module.exports = (params, processor) => ({ "process": () => { - if (processor.context.cssnanoallDone) { + if (processor.context.containsFlag(flagDoneName)) { processor.onWarn("cssnanoall task is executed more than once; this is probably a bug in your mbs.json"); } - processor.context.cssnanoallDone = true; + processor.context.addFlag(flagDoneName); glob("**/*.css", { "cwd": processor.context.exported, diff --git a/BuildServer/lib/tasks/dotnetbuilderwrapper.js b/BuildServer/lib/tasks/dotnetbuilderwrapper.js index 070c68a..7feb445 100644 --- a/BuildServer/lib/tasks/dotnetbuilderwrapper.js +++ b/BuildServer/lib/tasks/dotnetbuilderwrapper.js @@ -1,28 +1,37 @@ "use strict"; const spawn = require("child_process").spawn; +const streamBuffers = require("stream-buffers"); const settings = require("../../settings"); +const wrapBuilder = (builder, input, onExit) => { + const resultBuffer = new streamBuffers.WritableStreamBuffer(); + const errorBuffer = new streamBuffers.WritableStreamBuffer(); + + builder.stdout.on("data", (data) => { + resultBuffer.write(data); + }); + + builder.stderr.on("data", (data) => { + errorBuffer.write(data); + }); + + builder.on("exit", (code) => onExit(code, resultBuffer.getContentsAsString(), errorBuffer.getContentsAsString())); + + builder.stdin.write(input); + builder.stdin.end(); +}; + module.exports = (params, processor) => ({ "process": () => { - let result = ""; - let error = ""; + const input = JSON.stringify(params); const builder = spawn(settings.builderExecutable, [params.command]); - processor.onInfo(`DotNetBuilderWrapper processing (at ${new Date().toISOString()}): ${JSON.stringify(params, null, " ")}`); + processor.onInfo(`DotNetBuilderWrapper processing (at ${new Date().toISOString()}): ${input}`); - builder.stdout.on("data", (data) => { - result += data; - }); - - builder.stderr.on("data", (data) => { - error += data; - }); - - builder.on("exit", (code) => { + wrapBuilder(builder, input, (code, result, error) => { if (code) { - error = `Return code is ${code}\r\n${error}`; - processor.onError(error); + processor.onError(`Return code is ${code}\r\n${error}`); return processor.done(); } @@ -49,8 +58,5 @@ module.exports = (params, processor) => ({ return processor.done(); }); - - builder.stdin.write(JSON.stringify(params)); - builder.stdin.end(); } }); diff --git a/BuildServer/lib/tasks/dotnetbuildwithoutcleanup.js b/BuildServer/lib/tasks/dotnetbuildwithoutcleanup.js index 20c4cae..b5ed97e 100644 --- a/BuildServer/lib/tasks/dotnetbuildwithoutcleanup.js +++ b/BuildServer/lib/tasks/dotnetbuildwithoutcleanup.js @@ -2,29 +2,27 @@ const sequential = require("./sequential"); -module.exports = (params, processor) => { - const tasks = []; - +const createTasks = function *(params) { if (!params.skipMbsCheckStyle) { - tasks.push({ + yield { params, "type": "dotnetcheckstyle" - }); + }; } - tasks.push({ + yield { params, "type": "dotnetrewrite" - }); + }; if (!params.skipNugetRestore) { - tasks.push({ + yield { params, "type": "dotnetnugetrestore" - }); + }; } - tasks.push({ + yield { "params": { "configuration": params.configuration, "forceCodeAnalysis": params.forceCodeAnalysis, @@ -34,7 +32,11 @@ module.exports = (params, processor) => { "target": "Rebuild" }, "type": "dotnetcompile" - }); + }; +}; + +module.exports = (params, processor) => { + const tasks = Array.from(createTasks(params)); return sequential({ tasks }, processor); }; diff --git a/BuildServer/lib/tasks/dotnetcheckstyle.js b/BuildServer/lib/tasks/dotnetcheckstyle.js index edcd414..502787a 100644 --- a/BuildServer/lib/tasks/dotnetcheckstyle.js +++ b/BuildServer/lib/tasks/dotnetcheckstyle.js @@ -9,13 +9,15 @@ const autoGeneratedMarker = "//------------------------------------------------------------------------------\n" + "// "; +const flagDoneName = "dotnetcheckerDone"; + module.exports = (params, processor) => ({ "process": () => { - if (processor.context.dotnetcheckerDone) { + if (processor.context.containsFlag(flagDoneName)) { return processor.done(); } - processor.context.dotnetcheckerDone = true; + processor.context.addFlag(flagDoneName); return glob("**/*.cs", { "cwd": processor.context.exported }, (globErr, files) => { if (globErr) { diff --git a/BuildServer/lib/tasks/dotnetcompile.js b/BuildServer/lib/tasks/dotnetcompile.js index d95a270..bbf360f 100644 --- a/BuildServer/lib/tasks/dotnetcompile.js +++ b/BuildServer/lib/tasks/dotnetcompile.js @@ -1,35 +1,37 @@ "use strict"; const path = require("path"); +const _ = require("underscore"); const settings = require("../../settings"); const dotnetbuilderwrapper = require("./dotnetbuilderwrapper"); module.exports = (params, processor) => { - const compileParams = { - "Configuration": params.configuration, - "OutputDirectory": params.overrideOutputDirectory, - "SolutionPath": path.join(processor.context.exported, params.solution), - "Target": params.target, - "command": "compile" - }; - - if (!settings.skipCodeSigning && !params.skipCodeSigning) { - compileParams.SigningKey = settings.codeSigningKeyFile; - } - if (settings.isCodeAnalysisUnsupported && params.forceCodeAnalysis) { processor.onError("Code analysis is not supported"); return processor.done(); } - if ( - settings.isCodeAnalysisUnsupported + const getAdditionalSigningParameters = () => { + if (settings.skipCodeSigning || params.skipCodeSigning) { + return {}; + } + + return { "SigningKey": settings.codeSigningKeyFile }; + }; + + const skipCodeAnalysis = settings.isCodeAnalysisUnsupported || params.ignoreCodeAnalysis - || (settings.ignoreCodeAnalysisByDefault && !params.forceCodeAnalysis) - ) { - compileParams.SkipCodeAnalysis = true; - } + || (settings.ignoreCodeAnalysisByDefault && !params.forceCodeAnalysis); + + const compileParams = { + "Configuration": params.configuration, + "OutputDirectory": params.overrideOutputDirectory, + "SkipCodeAnalysis": skipCodeAnalysis, + "SolutionPath": path.join(processor.context.exported, params.solution), + "Target": params.target, + "command": "compile" + }; - return dotnetbuilderwrapper(compileParams, processor); + return dotnetbuilderwrapper(_.extend(compileParams, getAdditionalSigningParameters()), processor); }; diff --git a/BuildServer/lib/tasks/dotnetnunitall.js b/BuildServer/lib/tasks/dotnetnunitall.js index daa76b9..f4340c3 100644 --- a/BuildServer/lib/tasks/dotnetnunitall.js +++ b/BuildServer/lib/tasks/dotnetnunitall.js @@ -1,14 +1,15 @@ "use strict"; const glob = require("glob"); +const flagDoneName = "dotnetnunitallDone"; module.exports = (params, processor) => ({ "process": () => { - if (processor.context.dotnetnunitallDone) { + if (processor.context.containsFlag(flagDoneName)) { processor.onWarn("dotnetnunitall task is executed more than once; this is probably a bug in your mbs.json"); } - processor.context.dotnetnunitallDone = true; + processor.context.addFlag(flagDoneName); glob("**/{bin,build}/**/*.{Tests,Test,UnitTests}.dll", { "cwd": processor.context.exported, diff --git a/BuildServer/lib/tasks/dotnetrewrite.js b/BuildServer/lib/tasks/dotnetrewrite.js index 49e69c1..c6db85c 100644 --- a/BuildServer/lib/tasks/dotnetrewrite.js +++ b/BuildServer/lib/tasks/dotnetrewrite.js @@ -6,30 +6,38 @@ const async = require("async"); const glob = require("glob"); const settings = require("../../settings"); +const flagDoneName = "dotnetrewriterDone"; + const processAssemblyInfo = (params, processor, appendInformationalVersion) => (originalContent, cb) => { - let content = originalContent; + const processInternalsVisible = (content) => { + if (params.skipCodeSigning || settings.skipCodeSigning) { + return content; + } - if (!params.skipCodeSigning && !settings.skipCodeSigning) { - content = content.replace( + return content.replace( /InternalsVisibleTo\s*\(\s*"([\w.]+)"\s*\)/g, (match, p1) => `InternalsVisibleTo("${p1},PublicKey=${settings.codeSigningPublicKey}")` ); - } + }; - if (appendInformationalVersion) { - content = `${content}\n[assembly: System.Reflection.AssemblyInformationalVersion("${processor.context.versionInfo}")]\n`; - } + const processInformationalVersion = (content) => { + if (!appendInformationalVersion) { + return content; + } + + return `${content}\n[assembly: System.Reflection.AssemblyInformationalVersion("${processor.context.versionInfo}")]\n`; + }; - return cb(null, content); + return cb(null, processInformationalVersion(processInternalsVisible(originalContent))); }; module.exports = (params, processor) => ({ "process": () => { - if (processor.context.dotnetrewriterDone) { + if (processor.context.containsFlag(flagDoneName)) { return processor.done(); } - processor.context.dotnetrewriterDone = true; + processor.context.addFlag(flagDoneName); return glob("**/{InternalsVisible,AssemblyInfo}*.cs", { "cwd": processor.context.exported }, (globErr, files) => { if (globErr) { diff --git a/BuildServer/lib/tasks/eslintbrowserall.js b/BuildServer/lib/tasks/eslintbrowserall.js index 2cbee42..82d253c 100644 --- a/BuildServer/lib/tasks/eslintbrowserall.js +++ b/BuildServer/lib/tasks/eslintbrowserall.js @@ -1,14 +1,15 @@ "use strict"; const glob = require("glob"); +const flagDoneName = "eslintbrowserallDone"; module.exports = (params, processor) => ({ "process": () => { - if (processor.context.eslintbrowserallDone) { + if (processor.context.containsFlag(flagDoneName)) { processor.onWarn("eslintbrowserall task is executed more than once; this is probably a bug in your mbs.json"); } - processor.context.eslintbrowserallDone = true; + processor.context.addFlag(flagDoneName); const excludeFiles = params.excludeFiles || []; diff --git a/BuildServer/lib/tasks/uglifyjsall.js b/BuildServer/lib/tasks/uglifyjsall.js index 1190c9d..0af6ef1 100644 --- a/BuildServer/lib/tasks/uglifyjsall.js +++ b/BuildServer/lib/tasks/uglifyjsall.js @@ -2,13 +2,15 @@ const glob = require("glob"); +const doneFlagName = "uglifyjsallDone"; + module.exports = (params, processor) => ({ "process": () => { - if (processor.context.uglifyjsallDone) { + if (processor.context.containsFlag(doneFlagName)) { processor.onWarn("dotnetnunitall task is executed more than once; this is probably a bug in your mbs.json"); } - processor.context.uglifyjsallDone = true; + processor.context.addFlag(doneFlagName); glob("**/*.js", { "cwd": processor.context.exported, diff --git a/BuildServer/package.json b/BuildServer/package.json index ccaabb3..8327619 100644 --- a/BuildServer/package.json +++ b/BuildServer/package.json @@ -3,7 +3,8 @@ "version": "0.0.1", "private": true, "scripts": { - "start": "forever -c node app.js" + "start": "forever -c node app.js", + "test": "./node_modules/.bin/eslint ." }, "dependencies": { "archiver": "^1.3.0", @@ -37,8 +38,23 @@ "parserOptions": { "ecmaVersion": 6 }, - "extends": "eslint:all", + "plugins": [ + "fp" + ], + "extends": [ + "eslint:all", + "plugin:fp/recommended" + ], "rules": { + "fp/no-unused-expression": "off", + "fp/no-nil": "off", + "fp/no-mutation": [ + "error", + { + "commonjs": true + } + ], + "prefer-destructuring": "off", "quotes": [ "warn", "double" @@ -112,5 +128,9 @@ } ] } + }, + "devDependencies": { + "eslint": "^3.15.0", + "eslint-plugin-fp": "^2.3.0" } } diff --git a/BuildServer/routes/manual.js b/BuildServer/routes/manual.js index a9ee5e8..b14dd9f 100644 --- a/BuildServer/routes/manual.js +++ b/BuildServer/routes/manual.js @@ -1,14 +1,15 @@ "use strict"; +const _ = require("underscore"); const builder = require("../lib/builder"); exports.get = (req, res) => res.render("manual"); exports.post = (req, res) => { - const options = req.body; - - options.url = `https://pos-github.payonline.ru/${options.owner}/${options.reponame}`; - options.app = req.app; + const options = _.extend(req.body, { + "app": req.app, + "url": `https://pos-github.payonline.ru/${req.body.owner}/${req.body.reponame}` + }); builder.build(options, (err, result) => { console.log("Done processing manual request"); diff --git a/BuildServer/routes/status.js b/BuildServer/routes/status.js index d461524..4aa859e 100644 --- a/BuildServer/routes/status.js +++ b/BuildServer/routes/status.js @@ -1,58 +1,92 @@ "use strict"; const url = require("url"); +const _ = require("underscore"); const statusProcessor = require("../lib/status-processor"); const parseOptionsFromReferer = (path, callback) => { const pathParts = path.split("/").filter((value) => value); - const result = {}; const [, secondPart, thirdPart] = pathParts; if (!secondPart) { - return callback("BadRequest", result); + return callback("BadRequest", {}); } if (thirdPart === "tree") { - [result.owner, result.reponame, , result.branchName, result.rev] = pathParts; - } else { - [result.owner, result.reponame, result.branchName, result.rev] = pathParts; + const [owner, reponame, , branchName, rev] = pathParts; + + return callback(null, { + branchName, + owner, + reponame, + rev + }); } - return callback(null, result); + const [owner, reponame, branchName, rev] = pathParts; + + return callback(null, { + branchName, + owner, + reponame, + rev + }); }; const createShowReport = (res) => (err, inputOptions) => { - const options = inputOptions || {}; + const options = _.extendOwn(inputOptions || {}, { err }); - options.err = err; res.render("status", options); }; exports.image = (req, res) => { - const handle = (err, options) => { + const getAdditionalOptions = (err, options) => { if (err === "ReportFileNotFound") { - options.status = "Building"; - } else if (err) { - options.status = "StatusError"; - options.message = err; - } else if (options.report.result === "MBSNotFound") { - options.status = "MBSNotUsed"; - } else if (options.report.err) { - options.status = "Error"; - options.message = options.report.err; - } else if ((options.report.result.warns.$allMessages || []).length) { + return { "status": "Building" }; + } + + if (err) { + return { + "message": err, + "status": "StatusError" + }; + } + + if (options.report.result === "MBSNotFound") { + return { "status": "MBSNotUsed" }; + } + + if (options.report.err) { + return { + "message": options.report.err, + "status": "Error" + }; + } + + if ((options.report.result.warns.$allMessages || []).length) { const [firstWarn] = options.report.result.warns.$allMessages; - options.status = "Warning"; - options.message = firstWarn.message; - } else { - options.status = "OK"; - if ((options.report.result.infos.$allMessages || []).length) { - options.message = options.report.result.infos.$allMessages[options.report.result.infos.$allMessages.length - 1].message; - } + return { + "message": firstWarn.message, + "status": "Warning" + }; + } + + const allInfos = options.report.result.infos.$allMessages || []; + + if (allInfos.length) { + return { + "message": allInfos[allInfos.length - 1].message, + "status": "OK" + }; } + + return { "status": "OK" }; + }; + + const handle = (err, options) => { res.setHeader("Content-Type", "image/svg+xml"); - res.render("status-image", options); + res.render("status-image", _.extend(options, getAdditionalOptions(err, options))); }; parseOptionsFromReferer(url.parse(req.headers.referer || "").pathname || "", (err, options) => {