From c30eeee5d8f5dc849a082db648a55de4796f95ca Mon Sep 17 00:00:00 2001 From: Vladimir Kotikov Date: Fri, 20 Nov 2015 11:55:15 +0300 Subject: [PATCH] CB-9971 Suppress gradlew _JAVA_OPTIONS output during build --- .../cordova/lib/builders/GradleBuilder.js | 66 ++++++++++++++++++- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/bin/templates/cordova/lib/builders/GradleBuilder.js b/bin/templates/cordova/lib/builders/GradleBuilder.js index 0f613cc5..8dea4bfc 100644 --- a/bin/templates/cordova/lib/builders/GradleBuilder.js +++ b/bin/templates/cordova/lib/builders/GradleBuilder.js @@ -22,6 +22,7 @@ var fs = require('fs'); var util = require('util'); var path = require('path'); var shell = require('shelljs'); +var child_process = require('child_process'); var spawn = require('cordova-common').superspawn.spawn; var CordovaError = require('cordova-common').CordovaError; var check_reqs = require('../check_reqs'); @@ -182,9 +183,7 @@ GradleBuilder.prototype.prepEnv = function(opts) { GradleBuilder.prototype.build = function(opts) { var wrapper = path.join(this.root, 'gradlew'); var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts); - return Q().then(function() { - return spawn(wrapper, args, {stdio: 'inherit'}); - }); + return spawnAndSuppressJavaOptions(wrapper, args); }; GradleBuilder.prototype.clean = function(opts) { @@ -211,3 +210,64 @@ module.exports = GradleBuilder; function isAutoGenerated(file) { return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0; } + +/** + * A special superspawn-like implementation, required to workaround the issue + * with Java printing some unwanted information to stderr instead of stdout. + * This function suppresses 'Picked up _JAVA_OPTIONS' message from being + * printed to stderr. See https://issues.apache.org/jira/browse/CB-9971 for + * explanation. + * + * This function needed because superspawn does not provide a way to get and + * manage spawned process output streams. There is a CB-10052 which describes + * an improvements for superspawn, needed to get rid of this. + * TODO: Once this improvement added to cordova-common, we could remove this functionality. + * + * @param {String} cmd A command to spawn + * @param {String[]} args Command arguments. Note that on Windows arguments + * will be concatenated into string and passed to 'cmd.exe' along with '/s' + * and '/c' switches for proper space-in-path handling + * + * @return {Promise} A promise, rejected with error message if + * underlying command exits with nonzero exit code, fulfilled otherwise + */ +function spawnAndSuppressJavaOptions(cmd, args) { + var opts = { stdio: 'pipe' }; + + if (process.platform === 'win32') { + // Work around spawn not being able to find .bat files. + var joinedArgs = [cmd] + .concat(args) + .map(function(a){ + // Add quotes to arguments which contains whitespaces + if (/^[^"].* .*[^"]/.test(a)) return '"' + a + '"'; + return a; + }).join(' '); + + args = ['/s', '/c'].concat('"' + joinedArgs + '"'); + cmd = 'cmd'; + opts.windowsVerbatimArguments = true; + } + + return Q.Promise(function (resolve, reject) { + var proc = child_process.spawn(cmd, args, opts); + + proc.stdout.on('data', process.stdout.write.bind(process.stdout)); + proc.stderr.on('data', function (data) { + var suppressThisLine = /^Picked up _JAVA_OPTIONS: /i.test(data.toString()); + if (suppressThisLine) { + return; + } + + process.stderr.write(data); + }); + + proc.on('exit', function(code) { + if (code) { + reject('Error code ' + code + ' for command: ' + cmd + ' with args: ' + args); + } else { + resolve(); + } + }); + }); +}