arnaucube
arnaucube/commonroutesServerPublic Self-hosted repository
commonroutesServer/www/platforms/android/cordova/lib/builders/GenericBuilder.js
www/platforms/android/cordova/lib/builders/GenericBuilder.jsRaw
  1/*
  2       Licensed to the Apache Software Foundation (ASF) under one
  3       or more contributor license agreements.  See the NOTICE file
  4       distributed with this work for additional information
  5       regarding copyright ownership.  The ASF licenses this file
  6       to you under the Apache License, Version 2.0 (the
  7       "License"); you may not use this file except in compliance
  8       with the License.  You may obtain a copy of the License at
  9
 10         http://www.apache.org/licenses/LICENSE-2.0
 11
 12       Unless required by applicable law or agreed to in writing,
 13       software distributed under the License is distributed on an
 14       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15       KIND, either express or implied.  See the License for the
 16       specific language governing permissions and limitations
 17       under the License.
 18*/
 19
 20var Q = require('q');
 21var fs = require('fs');
 22var path = require('path');
 23var shell = require('shelljs');
 24var events = require('cordova-common').events;
 25var CordovaError = require('cordova-common').CordovaError;
 26
 27function GenericBuilder (projectDir) {
 28    this.root = projectDir || path.resolve(__dirname, '../../..');
 29    this.binDirs = {
 30        ant: path.join(this.root, hasCustomRules(this.root) ? 'ant-build' : 'bin'),
 31        gradle: path.join(this.root, 'build', 'outputs', 'apk')
 32    };
 33}
 34
 35function hasCustomRules(projectRoot) {
 36    return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
 37}
 38
 39GenericBuilder.prototype.prepEnv = function() {
 40    return Q();
 41};
 42
 43GenericBuilder.prototype.build = function() {
 44    events.emit('log', 'Skipping build...');
 45    return Q(null);
 46};
 47
 48GenericBuilder.prototype.clean = function() {
 49    return Q();
 50};
 51
 52GenericBuilder.prototype.findOutputApks = function(build_type, arch) {
 53    var self = this;
 54    return Object.keys(this.binDirs)
 55    .reduce(function (result, builderName) {
 56        var binDir = self.binDirs[builderName];
 57        return result.concat(findOutputApksHelper(binDir, build_type, builderName === 'ant' ? null : arch));
 58    }, [])
 59    .sort(apkSorter);
 60};
 61
 62GenericBuilder.prototype.readProjectProperties = function () {
 63    function findAllUniq(data, r) {
 64        var s = {};
 65        var m;
 66        while ((m = r.exec(data))) {
 67            s[m[1]] = 1;
 68        }
 69        return Object.keys(s);
 70    }
 71
 72    var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8');
 73    return {
 74        libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg),
 75        gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg),
 76        systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg)
 77    };
 78};
 79
 80GenericBuilder.prototype.extractRealProjectNameFromManifest = function () {
 81    var manifestPath = path.join(this.root, 'AndroidManifest.xml');
 82    var manifestData = fs.readFileSync(manifestPath, 'utf8');
 83    var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
 84    if (!m) {
 85        throw new CordovaError('Could not find package name in ' + manifestPath);
 86    }
 87
 88    var packageName=m[1];
 89    var lastDotIndex = packageName.lastIndexOf('.');
 90    return packageName.substring(lastDotIndex + 1);
 91};
 92
 93module.exports = GenericBuilder;
 94
 95function apkSorter(fileA, fileB) {
 96    // De-prioritize unsigned builds
 97    var unsignedRE = /-unsigned/;
 98    if (unsignedRE.exec(fileA)) {
 99        return 1;
100    } else if (unsignedRE.exec(fileB)) {
101        return -1;
102    }
103
104    var timeDiff = fs.statSync(fileA).mtime - fs.statSync(fileB).mtime;
105    return timeDiff === 0 ? fileA.length - fileB.length : timeDiff;
106}
107
108function findOutputApksHelper(dir, build_type, arch) {
109    var shellSilent = shell.config.silent;
110    shell.config.silent = true;
111
112    var ret = shell.ls(path.join(dir, '*.apk'))
113    .filter(function(candidate) {
114        var apkName = path.basename(candidate);
115        // Need to choose between release and debug .apk.
116        if (build_type === 'debug') {
117            return /-debug/.exec(apkName) && !/-unaligned|-unsigned/.exec(apkName);
118        }
119        if (build_type === 'release') {
120            return /-release/.exec(apkName) && !/-unaligned/.exec(apkName);
121        }
122        return true;
123    })
124    .sort(apkSorter);
125
126    shellSilent = shellSilent;
127
128    if (ret.length === 0) {
129        return ret;
130    }
131    // Assume arch-specific build if newest apk has -x86 or -arm.
132    var archSpecific = !!/-x86|-arm/.exec(path.basename(ret[0]));
133    // And show only arch-specific ones (or non-arch-specific)
134    ret = ret.filter(function(p) {
135        /*jshint -W018 */
136        return !!/-x86|-arm/.exec(path.basename(p)) == archSpecific;
137        /*jshint +W018 */
138    });
139
140    if (archSpecific && ret.length > 1 && arch) {
141        ret = ret.filter(function(p) {
142            return path.basename(p).indexOf('-' + arch) != -1;
143        });
144    }
145
146    return ret;
147}