/* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ var Q = require('q'); var fs = require('fs'); var util = require('util'); var path = require('path'); var shell = require('shelljs'); var superspawn = require('cordova-common').superspawn; var CordovaError = require('cordova-common').CordovaError; var events = require('cordova-common').events; var check_reqs = require('../check_reqs'); var GenericBuilder = require('./GenericBuilder'); var MARKER = 'YOUR CHANGES WILL BE ERASED!'; var SIGNING_PROPERTIES = '-signing.properties'; var TEMPLATE = '# This file is automatically generated.\n' + '# Do not modify this file -- ' + MARKER + '\n'; function GradleBuilder (projectRoot) { GenericBuilder.call(this, projectRoot); this.binDirs = { gradle: this.binDirs.gradle }; } util.inherits(GradleBuilder, GenericBuilder); GradleBuilder.prototype.getArgs = function (cmd, opts) { if (cmd === 'release') { cmd = 'cdvBuildRelease'; } else if (cmd === 'debug') { cmd = 'cdvBuildDebug'; } var args = [cmd, '-b', path.join(this.root, 'build.gradle')]; if (opts.arch) { args.push('-PcdvBuildArch=' + opts.arch); } // 10 seconds -> 6 seconds args.push('-Dorg.gradle.daemon=true'); // to allow dex in process args.push('-Dorg.gradle.jvmargs=-Xmx2048m'); // allow NDK to be used - required by Gradle 1.5 plugin args.push('-Pandroid.useDeprecatedNdk=true'); args.push.apply(args, opts.extraArgs); // Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet): // args.push('-Dorg.gradle.parallel=true'); return args; }; /* * This returns a promise */ GradleBuilder.prototype.runGradleWrapper = function (gradle_cmd, gradle_file) { var gradlePath = path.join(this.root, 'gradlew'); gradle_file = path.join(this.root, (gradle_file || 'wrapper.gradle')); if (fs.existsSync(gradlePath)) { // Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows } else { return superspawn.spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', gradle_file], { stdio: 'pipe' }) .progress(function (stdio) { suppressJavaOptionsInfo(stdio); }); } }; /* * We need to kill this in a fire. */ GradleBuilder.prototype.readProjectProperties = function () { function findAllUniq (data, r) { var s = {}; var m; while ((m = r.exec(data))) { s[m[1]] = 1; } return Object.keys(s); } var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8'); return { libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg), gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg), systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg) }; }; GradleBuilder.prototype.extractRealProjectNameFromManifest = function () { var manifestPath = path.join(this.root, 'AndroidManifest.xml'); var manifestData = fs.readFileSync(manifestPath, 'utf8'); var m = /= 0) { return check_reqs.check_android_target(error).then(function () { // If due to some odd reason - check_android_target succeeds // we should still fail here. return Q.reject(error); }); } return Q.reject(error); }); }; GradleBuilder.prototype.clean = function (opts) { var builder = this; var wrapper = path.join(this.root, 'gradlew'); var args = builder.getArgs('clean', opts); return Q().then(function () { return superspawn.spawn(wrapper, args, { stdio: 'inherit' }); }).then(function () { shell.rm('-rf', path.join(builder.root, 'out')); ['debug', 'release'].forEach(function (config) { var propertiesFilePath = path.join(builder.root, config + SIGNING_PROPERTIES); if (isAutoGenerated(propertiesFilePath)) { shell.rm('-f', propertiesFilePath); } }); }); }; module.exports = GradleBuilder; function suppressJavaOptionsInfo (stdio) { if (stdio.stderr) { /* * Workaround for 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. */ var suppressThisLine = /^Picked up _JAVA_OPTIONS: /i.test(stdio.stderr.toString()); if (suppressThisLine) { return; } process.stderr.write(stdio.stderr); } else { process.stdout.write(stdio.stdout); } } function isAutoGenerated (file) { return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0; }