mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-26 03:53:09 +08:00
Merge branch 'master' into StudioProjectCompat
This will have to be linted
This commit is contained in:
commit
e456175a81
10
.eslintrc.yml
Normal file
10
.eslintrc.yml
Normal file
@ -0,0 +1,10 @@
|
||||
root: true
|
||||
extends: semistandard
|
||||
rules:
|
||||
indent:
|
||||
- error
|
||||
- 4
|
||||
camelcase: off
|
||||
padded-blocks: off
|
||||
operator-linebreak: off
|
||||
no-throw-literal: off
|
@ -15,7 +15,7 @@ android:
|
||||
- tools
|
||||
- tools
|
||||
script:
|
||||
- npm run jshint
|
||||
- npm run eslint
|
||||
- npm run cover
|
||||
- npm run test-build
|
||||
after_script:
|
||||
|
@ -19,12 +19,12 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var shell = require('shelljs'),
|
||||
Q = require('q'),
|
||||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
check_reqs = require('./../templates/cordova/lib/check_reqs'),
|
||||
ROOT = path.join(__dirname, '..', '..');
|
||||
var shell = require('shelljs');
|
||||
var Q = require('q');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var check_reqs = require('./../templates/cordova/lib/check_reqs');
|
||||
var ROOT = path.join(__dirname, '..', '..');
|
||||
|
||||
var MIN_SDK_VERSION = 19;
|
||||
|
||||
@ -62,9 +62,9 @@ function copyJsAndLibrary(projectPath, shared, projectName, isLegacy) {
|
||||
// We need these files to build cordova.js if using browserify method.
|
||||
shell.cp('-rf', path.join(ROOT, 'cordova-js-src'), path.join(projectPath, 'platform_www'));
|
||||
|
||||
// Don't fail if there are no old jars, because there hasn't been cordova JARs for years!
|
||||
// Don't fail if there are no old jars.
|
||||
setShellFatal(false, function () {
|
||||
shell.ls(path.join(app_path, 'libs', 'cordova-*.jar')).forEach(function(oldJar) {
|
||||
shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function (oldJar) {
|
||||
console.log('Deleting ' + oldJar);
|
||||
shell.rm('-f', oldJar);
|
||||
});
|
||||
@ -116,9 +116,8 @@ function writeProjectProperties(projectPath, target_api) {
|
||||
var subProjects = extractSubProjectPaths(data);
|
||||
subProjects = subProjects.filter(function (p) {
|
||||
return !(/^CordovaLib$/m.exec(p) ||
|
||||
/[\\\/]cordova-android[\\\/]framework$/m.exec(p) ||
|
||||
/^(\.\.[\\\/])+framework$/m.exec(p)
|
||||
);
|
||||
/[\\/]cordova-android[\\/]framework$/m.exec(p) ||
|
||||
/^(\.\.[\\/])+framework$/m.exec(p));
|
||||
});
|
||||
subProjects.unshift('CordovaLib');
|
||||
data = data.replace(/^\s*android\.library\.reference\.\d+=.*\n/mg, '');
|
||||
@ -326,7 +325,7 @@ exports.create = function(project_path, config, options, events) {
|
||||
|
||||
function generateDoneMessage (type, link) {
|
||||
var pkg = require('../../package');
|
||||
var msg = 'Android project ' + (type == 'update' ? 'updated ' : 'created ') + 'with ' + pkg.name + '@' + pkg.version;
|
||||
var msg = 'Android project ' + (type === 'update' ? 'updated ' : 'created ') + 'with ' + pkg.name + '@' + pkg.version;
|
||||
if (link) {
|
||||
msg += ' and has a linked CordovaLib';
|
||||
}
|
||||
@ -372,7 +371,6 @@ exports.update = function(projectPath, options, events) {
|
||||
}).thenResolve(projectPath);
|
||||
};
|
||||
|
||||
|
||||
// For testing
|
||||
exports.validatePackageName = validatePackageName;
|
||||
exports.validateProjectName = validateProjectName;
|
||||
|
47
bin/templates/cordova/Api.js
vendored
47
bin/templates/cordova/Api.js
vendored
@ -29,7 +29,6 @@ var selfEvents = require('cordova-common').events;
|
||||
|
||||
var PLATFORM = 'android';
|
||||
|
||||
|
||||
function setupEvents (externalEventEmitter) {
|
||||
if (externalEventEmitter) {
|
||||
// This will make the platform internal events visible outside
|
||||
@ -43,7 +42,6 @@ function setupEvents(externalEventEmitter) {
|
||||
return selfEvents;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class, that acts as abstraction over particular platform. Encapsulates the
|
||||
* platform's properties and methods.
|
||||
@ -117,14 +115,11 @@ Api.createPlatform = function (destination, config, options, events) {
|
||||
events = setupEvents(events);
|
||||
var result;
|
||||
try {
|
||||
result = require('../../lib/create')
|
||||
.create(destination, config, options, events)
|
||||
.then(function (destination) {
|
||||
result = require('../../lib/create').create(destination, config, options, events).then(function (destination) {
|
||||
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
||||
return new PlatformApi(PLATFORM, destination, events);
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
events.emit('error', 'createPlatform is not callable from the android project API.');
|
||||
throw (e);
|
||||
}
|
||||
@ -151,14 +146,11 @@ Api.updatePlatform = function (destination, options, events) {
|
||||
events = setupEvents(events);
|
||||
var result;
|
||||
try {
|
||||
result = require('../../lib/create')
|
||||
.update(destination, options, events)
|
||||
.then(function (destination) {
|
||||
result = require('../../lib/create').update(destination, options, events).then(function (destination) {
|
||||
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
||||
return new PlatformApi('android', destination, events);
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
events.emit('error', 'updatePlatform is not callable from the android project API, you will need to do this manually.');
|
||||
throw (e);
|
||||
}
|
||||
@ -235,12 +227,10 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
|
||||
installOptions.android_studio = true;
|
||||
}
|
||||
|
||||
return Q()
|
||||
.then(function () {
|
||||
return Q().then(function () {
|
||||
// CB-11964: Do a clean when installing the plugin code to get around
|
||||
// the Gradle bug introduced by the Android Gradle Plugin Version 2.2
|
||||
// TODO: Delete when the next version of Android Gradle plugin comes out
|
||||
|
||||
// Since clean doesn't just clean the build, it also wipes out www, we need
|
||||
// to pass additional options.
|
||||
|
||||
@ -253,14 +243,10 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
|
||||
if (!AndroidStudio.isAndroidStudioProject(self.root) && !project.isClean()) {
|
||||
return self.clean(opts);
|
||||
}
|
||||
})
|
||||
.then(function () {
|
||||
return PluginManager.get(self.platform, self.locations, project)
|
||||
.addPlugin(plugin, installOptions);
|
||||
})
|
||||
.then(function () {
|
||||
}).then(function () {
|
||||
return PluginManager.get(self.platform, self.locations, project).addPlugin(plugin, installOptions);
|
||||
}).then(function () {
|
||||
if (plugin.getFrameworks(this.platform).length === 0) return;
|
||||
|
||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||
//This should pick the correct builder, not just get gradle
|
||||
require('./lib/builders/builders').getBuilder(this.builder).prepBuildFiles();
|
||||
@ -351,11 +337,9 @@ Api.prototype.build = function (buildOptions) {
|
||||
var self = this;
|
||||
if(this.android_studio)
|
||||
buildOptions.studio = true;
|
||||
return require('./lib/check_reqs').run()
|
||||
.then(function () {
|
||||
return require('./lib/check_reqs').run() .then(function () {
|
||||
return require('./lib/build').run.call(self, buildOptions);
|
||||
})
|
||||
.then(function (buildResults) {
|
||||
}).then(function (buildResults) {
|
||||
// Cast build result to array of build artifacts
|
||||
return buildResults.apkPaths.map(function (apkPath) {
|
||||
return {
|
||||
@ -382,8 +366,7 @@ Api.prototype.build = function (buildOptions) {
|
||||
*/
|
||||
Api.prototype.run = function (runOptions) {
|
||||
var self = this;
|
||||
return require('./lib/check_reqs').run()
|
||||
.then(function () {
|
||||
return require('./lib/check_reqs').run().then(function () {
|
||||
return require('./lib/run').run.call(self, runOptions);
|
||||
});
|
||||
};
|
||||
@ -397,17 +380,13 @@ Api.prototype.run = function(runOptions) {
|
||||
*/
|
||||
Api.prototype.clean = function (cleanOptions) {
|
||||
var self = this;
|
||||
return require('./lib/check_reqs').run()
|
||||
.then(function () {
|
||||
return require('./lib/check_reqs').run().then(function () {
|
||||
return require('./lib/build').runClean.call(self, cleanOptions);
|
||||
})
|
||||
.then(function () {
|
||||
}).then(function () {
|
||||
return require('./lib/prepare').clean.call(self, cleanOptions);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Performs a requirements check for current platform. Each platform defines its
|
||||
* own set of requirements, which should be resolved before platform can be
|
||||
|
12
bin/templates/cordova/lib/Adb.js
vendored
12
bin/templates/cordova/lib/Adb.js
vendored
@ -44,8 +44,7 @@ function isEmulator(line) {
|
||||
* devices/emulators
|
||||
*/
|
||||
Adb.devices = function (opts) {
|
||||
return spawn('adb', ['devices'], {cwd: os.tmpdir()})
|
||||
.then(function(output) {
|
||||
return spawn('adb', ['devices'], {cwd: os.tmpdir()}).then(function (output) {
|
||||
return output.split('\n').filter(function (line) {
|
||||
// Filter out either real devices or emulators, depending on options
|
||||
return (line && opts && opts.emulators) ? isEmulator(line) : isDevice(line);
|
||||
@ -59,8 +58,7 @@ Adb.install = function (target, packagePath, opts) {
|
||||
events.emit('verbose', 'Installing apk ' + packagePath + ' on target ' + target + '...');
|
||||
var args = ['-s', target, 'install'];
|
||||
if (opts && opts.replace) args.push('-r');
|
||||
return spawn('adb', args.concat(packagePath), {cwd: os.tmpdir()})
|
||||
.then(function(output) {
|
||||
return spawn('adb', args.concat(packagePath), {cwd: os.tmpdir()}).then(function (output) {
|
||||
// 'adb install' seems to always returns no error, even if installation fails
|
||||
// so we catching output to detect installation failure
|
||||
if (output.match(/Failure/)) {
|
||||
@ -86,8 +84,7 @@ Adb.shell = function (target, shellCommand) {
|
||||
events.emit('verbose', 'Running adb shell command "' + shellCommand + '" on target ' + target + '...');
|
||||
var args = ['-s', target, 'shell'];
|
||||
shellCommand = shellCommand.split(/\s+/);
|
||||
return spawn('adb', args.concat(shellCommand), {cwd: os.tmpdir()})
|
||||
.catch(function (output) {
|
||||
return spawn('adb', args.concat(shellCommand), {cwd: os.tmpdir()}).catch(function (output) {
|
||||
return Q.reject(new CordovaError('Failed to execute shell command "' +
|
||||
shellCommand + '"" on device: ' + output));
|
||||
});
|
||||
@ -95,8 +92,7 @@ Adb.shell = function (target, shellCommand) {
|
||||
|
||||
Adb.start = function (target, activityName) {
|
||||
events.emit('verbose', 'Starting application "' + activityName + '" on target ' + target + '...');
|
||||
return Adb.shell(target, 'am start -W -a android.intent.action.MAIN -n' + activityName)
|
||||
.catch(function (output) {
|
||||
return Adb.shell(target, 'am start -W -a android.intent.action.MAIN -n' + activityName).catch(function (output) {
|
||||
return Q.reject(new CordovaError('Failed to start application "' +
|
||||
activityName + '"" on device: ' + output));
|
||||
});
|
||||
|
3
bin/templates/cordova/lib/AndroidManifest.js
vendored
3
bin/templates/cordova/lib/AndroidManifest.js
vendored
@ -102,8 +102,7 @@ AndroidManifest.prototype.getActivity = function() {
|
||||
};
|
||||
};
|
||||
|
||||
['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion']
|
||||
.forEach(function(sdkPrefName) {
|
||||
['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion'].forEach(function (sdkPrefName) {
|
||||
// Copy variable reference to avoid closure issues
|
||||
var prefName = sdkPrefName;
|
||||
|
||||
|
5
bin/templates/cordova/lib/AndroidProject.js
vendored
5
bin/templates/cordova/lib/AndroidProject.js
vendored
@ -28,8 +28,7 @@ var projectFileCache = {};
|
||||
|
||||
function addToPropertyList (projectProperties, key, value) {
|
||||
var i = 1;
|
||||
while (projectProperties.get(key + '.' + i))
|
||||
i++;
|
||||
while (projectProperties.get(key + '.' + i)) { i++; }
|
||||
|
||||
projectProperties.set(key + '.' + i, value);
|
||||
projectProperties.dirty = true;
|
||||
@ -54,7 +53,7 @@ function removeFromPropertyList(projectProperties, key, value) {
|
||||
|
||||
function getRelativeLibraryPath (parentDir, subDir) {
|
||||
var libraryPath = path.relative(parentDir, subDir);
|
||||
return (path.sep == '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath;
|
||||
return (path.sep === '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath;
|
||||
}
|
||||
|
||||
function AndroidProject (projectDir) {
|
||||
|
21
bin/templates/cordova/lib/android_sdk.js
vendored
21
bin/templates/cordova/lib/android_sdk.js
vendored
@ -17,8 +17,8 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var Q = require('q'),
|
||||
superspawn = require('cordova-common').superspawn;
|
||||
var Q = require('q');
|
||||
var superspawn = require('cordova-common').superspawn;
|
||||
|
||||
var suffix_number_regex = /(\d+)$/;
|
||||
// Used for sorting Android targets, example strings to sort:
|
||||
@ -44,8 +44,7 @@ function sort_by_largest_numerical_suffix(a, b) {
|
||||
}
|
||||
|
||||
module.exports.print_newest_available_sdk_target = function () {
|
||||
return module.exports.list_targets()
|
||||
.then(function(targets) {
|
||||
return module.exports.list_targets().then(function (targets) {
|
||||
targets.sort(sort_by_largest_numerical_suffix);
|
||||
console.log(targets[0]);
|
||||
});
|
||||
@ -78,26 +77,22 @@ function parse_targets(output) {
|
||||
}
|
||||
|
||||
module.exports.list_targets_with_android = function () {
|
||||
return superspawn.spawn('android', ['list', 'target'])
|
||||
.then(parse_targets);
|
||||
return superspawn.spawn('android', ['list', 'target']).then(parse_targets);
|
||||
};
|
||||
|
||||
module.exports.list_targets_with_avdmanager = function () {
|
||||
return superspawn.spawn('avdmanager', ['list', 'target'])
|
||||
.then(parse_targets);
|
||||
return superspawn.spawn('avdmanager', ['list', 'target']).then(parse_targets);
|
||||
};
|
||||
|
||||
module.exports.list_targets = function () {
|
||||
return module.exports.list_targets_with_avdmanager()
|
||||
.catch(function(err) {
|
||||
return module.exports.list_targets_with_avdmanager().catch(function (err) {
|
||||
// If there's an error, like avdmanager could not be found, we can try
|
||||
// as a last resort, to run `android`, in case this is a super old
|
||||
// SDK installation.
|
||||
if (err && (err.code == 'ENOENT' || (err.stderr && err.stderr.match(/not recognized/)))) {
|
||||
if (err && (err.code === 'ENOENT' || (err.stderr && err.stderr.match(/not recognized/)))) {
|
||||
return module.exports.list_targets_with_android();
|
||||
} else throw err;
|
||||
})
|
||||
.then(function(targets) {
|
||||
}).then(function (targets) {
|
||||
if (targets.length === 0) {
|
||||
return Q.reject(new Error('No android targets (SDKs) installed!'));
|
||||
}
|
||||
|
50
bin/templates/cordova/lib/build.js
vendored
50
bin/templates/cordova/lib/build.js
vendored
@ -19,10 +19,10 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var Q = require('q'),
|
||||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
nopt = require('nopt');
|
||||
var Q = require('q');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var nopt = require('nopt');
|
||||
|
||||
var Adb = require('./Adb');
|
||||
|
||||
@ -64,11 +64,9 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
||||
|
||||
if (options.nobuild) ret.buildMethod = 'none';
|
||||
|
||||
if (options.argv.versionCode)
|
||||
ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode);
|
||||
if (options.argv.versionCode) { ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode); }
|
||||
|
||||
if (options.argv.minSdkVersion)
|
||||
ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion);
|
||||
if (options.argv.minSdkVersion) { ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion); }
|
||||
|
||||
if (options.argv.gradleArg) {
|
||||
ret.extraArgs = ret.extraArgs.concat(options.argv.gradleArg);
|
||||
@ -76,12 +74,10 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
||||
|
||||
var packageArgs = {};
|
||||
|
||||
if (options.argv.keystore)
|
||||
packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore));
|
||||
if (options.argv.keystore) { packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore)); }
|
||||
|
||||
['alias', 'storePassword', 'password', 'keystoreType'].forEach(function (flagName) {
|
||||
if (options.argv[flagName])
|
||||
packageArgs[flagName] = options.argv[flagName];
|
||||
if (options.argv[flagName]) { packageArgs[flagName] = options.argv[flagName]; }
|
||||
});
|
||||
|
||||
var buildConfig = options.buildConfig;
|
||||
@ -132,8 +128,7 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
||||
module.exports.runClean = function (options) {
|
||||
var opts = parseOpts(options, null, this.root);
|
||||
var builder = builders.getBuilder(opts.buildMethod);
|
||||
return builder.prepEnv(opts)
|
||||
.then(function() {
|
||||
return builder.prepEnv(opts).then(function () {
|
||||
return builder.clean(opts);
|
||||
});
|
||||
};
|
||||
@ -154,14 +149,12 @@ module.exports.run = function(options, optResolvedTarget) {
|
||||
var opts = parseOpts(options, optResolvedTarget, this.root);
|
||||
console.log(opts.buildMethod);
|
||||
var builder = builders.getBuilder(opts.buildMethod);
|
||||
return builder.prepEnv(opts)
|
||||
.then(function() {
|
||||
return builder.prepEnv(opts).then(function () {
|
||||
if (opts.prepEnv) {
|
||||
events.emit('verbose', 'Build file successfully prepared.');
|
||||
return;
|
||||
}
|
||||
return builder.build(opts)
|
||||
.then(function() {
|
||||
return builder.build(opts).then(function () {
|
||||
var apkPaths = builder.findOutputApks(opts.buildType, opts.arch);
|
||||
events.emit('log', 'Built the following apk(s): \n\t' + apkPaths.join('\n\t'));
|
||||
return {
|
||||
@ -179,31 +172,24 @@ module.exports.run = function(options, optResolvedTarget) {
|
||||
*/
|
||||
module.exports.detectArchitecture = function (target) {
|
||||
function helper () {
|
||||
return Adb.shell(target, 'cat /proc/cpuinfo')
|
||||
.then(function(output) {
|
||||
return Adb.shell(target, 'cat /proc/cpuinfo').then(function (output) {
|
||||
return /intel/i.exec(output) ? 'x86' : 'arm';
|
||||
});
|
||||
}
|
||||
// It sometimes happens (at least on OS X), that this command will hang forever.
|
||||
// To fix it, either unplug & replug device, or restart adb server.
|
||||
return helper()
|
||||
.timeout(1000, new CordovaError('Device communication timed out. Try unplugging & replugging the device.'))
|
||||
.then(null, function(err) {
|
||||
return helper().timeout(1000, new CordovaError('Device communication timed out. Try unplugging & replugging the device.')).then(null, function (err) {
|
||||
if (/timed out/.exec('' + err)) {
|
||||
// adb kill-server doesn't seem to do the trick.
|
||||
// Could probably find a x-platform version of killall, but I'm not actually
|
||||
// sure that this scenario even happens on non-OSX machines.
|
||||
events.emit('verbose', 'adb timed out while detecting device/emulator architecture. Killing adb and trying again.');
|
||||
return spawn('killall', ['adb'])
|
||||
.then(function() {
|
||||
return helper()
|
||||
.then(null, function() {
|
||||
return spawn('killall', ['adb']).then(function () {
|
||||
return helper().then(null, function () {
|
||||
// The double kill is sadly often necessary, at least on mac.
|
||||
events.emit('warn', 'adb timed out a second time while detecting device/emulator architecture. Killing adb and trying again.');
|
||||
return spawn('killall', ['adb'])
|
||||
.then(function() {
|
||||
return helper()
|
||||
.then(null, function() {
|
||||
return spawn('killall', ['adb']).then(function () {
|
||||
return helper().then(null, function () {
|
||||
return Q.reject(new CordovaError('adb timed out a third time while detecting device/emulator architecture. Try unplugging & replugging the device.'));
|
||||
});
|
||||
});
|
||||
@ -220,7 +206,7 @@ module.exports.detectArchitecture = function(target) {
|
||||
module.exports.findBestApkForArchitecture = function (buildResults, arch) {
|
||||
var paths = buildResults.apkPaths.filter(function (p) {
|
||||
var apkName = path.basename(p);
|
||||
if (buildResults.buildType == 'debug') {
|
||||
if (buildResults.buildType === 'debug') {
|
||||
return /-debug/.exec(apkName);
|
||||
}
|
||||
return !/-debug/.exec(apkName);
|
||||
|
@ -16,6 +16,8 @@
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
/* eslint no-self-assign: 0 */
|
||||
/* eslint no-unused-vars: 0 */
|
||||
|
||||
var Q = require('q');
|
||||
var fs = require('fs');
|
||||
@ -46,13 +48,11 @@ GenericBuilder.prototype.clean = function() {
|
||||
|
||||
GenericBuilder.prototype.findOutputApks = function (build_type, arch) {
|
||||
var self = this;
|
||||
return Object.keys(this.binDirs)
|
||||
.reduce(function (result, builderName) {
|
||||
return Object.keys(this.binDirs) .reduce(function (result, builderName) {
|
||||
console.log('builderName:'+ builderName);
|
||||
var binDir = self.binDirs[builderName];
|
||||
return result.concat(findOutputApksHelper(binDir, build_type, builderName === 'ant' ? null : arch));
|
||||
}, [])
|
||||
.sort(apkSorter);
|
||||
}, []).sort(apkSorter);
|
||||
};
|
||||
|
||||
module.exports = GenericBuilder;
|
||||
@ -74,8 +74,7 @@ function findOutputApksHelper(dir, build_type, arch) {
|
||||
var shellSilent = shell.config.silent;
|
||||
shell.config.silent = true;
|
||||
|
||||
var ret = shell.ls(path.join(dir, '*.apk'))
|
||||
.filter(function(candidate) {
|
||||
var ret = shell.ls(path.join(dir, '*.apk')).filter(function (candidate) {
|
||||
var apkName = path.basename(candidate);
|
||||
// Need to choose between release and debug .apk.
|
||||
if (build_type === 'debug') {
|
||||
@ -85,8 +84,7 @@ function findOutputApksHelper(dir, build_type, arch) {
|
||||
return /-release/.exec(apkName) && !/-unaligned/.exec(apkName);
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.sort(apkSorter);
|
||||
}).sort(apkSorter);
|
||||
|
||||
shellSilent = shellSilent;
|
||||
|
||||
@ -98,13 +96,13 @@ function findOutputApksHelper(dir, build_type, arch) {
|
||||
// And show only arch-specific ones (or non-arch-specific)
|
||||
ret = ret.filter(function (p) {
|
||||
/* jshint -W018 */
|
||||
return !!/-x86|-arm/.exec(path.basename(p)) == archSpecific;
|
||||
return !!/-x86|-arm/.exec(path.basename(p)) === archSpecific;
|
||||
/* jshint +W018 */
|
||||
});
|
||||
|
||||
if (archSpecific && ret.length > 1 && arch) {
|
||||
ret = ret.filter(function (p) {
|
||||
return path.basename(p).indexOf('-' + arch) != -1;
|
||||
return path.basename(p).indexOf('-' + arch) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -43,9 +43,9 @@ function GradleBuilder (projectRoot) {
|
||||
util.inherits(GradleBuilder, GenericBuilder);
|
||||
|
||||
GradleBuilder.prototype.getArgs = function (cmd, opts) {
|
||||
if (cmd == 'release') {
|
||||
if (cmd === 'release') {
|
||||
cmd = 'cdvBuildRelease';
|
||||
} else if (cmd == 'debug') {
|
||||
} else if (cmd === 'debug') {
|
||||
cmd = 'cdvBuildDebug';
|
||||
}
|
||||
var args = [cmd, '-b', path.join(this.root, 'build.gradle')];
|
||||
@ -150,8 +150,7 @@ GradleBuilder.prototype.prepBuildFiles = function() {
|
||||
var realDir = p.replace(/[/\\]/g, ':');
|
||||
var libName = realDir.replace(name + '-', '');
|
||||
var str = 'include ":' + libName + '"\n';
|
||||
if(realDir.indexOf(name+'-')!==-1)
|
||||
str+='project(":'+libName+'").projectDir = new File("'+p+'")\n';
|
||||
if (realDir.indexOf(name + '-') !== -1) { str += 'project(":' + libName + '").projectDir = new File("' + p + '")\n'; }
|
||||
return str;
|
||||
});
|
||||
|
||||
@ -173,8 +172,7 @@ GradleBuilder.prototype.prepBuildFiles = function() {
|
||||
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
|
||||
if(projectGradleFile.indexOf('CordovaLib') != -1) {
|
||||
depsList += '{\n exclude module:("CordovaLib")\n }\n';
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
depsList += '\n';
|
||||
}
|
||||
};
|
||||
@ -194,7 +192,6 @@ GradleBuilder.prototype.prepBuildFiles = function() {
|
||||
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
|
||||
[/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+']
|
||||
];
|
||||
|
||||
propertiesObj.systemLibs.forEach(function (p) {
|
||||
var mavenRef;
|
||||
// It's already in gradle form if it has two ':'s
|
||||
@ -228,8 +225,7 @@ GradleBuilder.prototype.prepBuildFiles = function() {
|
||||
|
||||
GradleBuilder.prototype.prepEnv = function (opts) {
|
||||
var self = this;
|
||||
return check_reqs.check_gradle()
|
||||
.then(function(gradlePath) {
|
||||
return check_reqs.check_gradle().then(function (gradlePath) {
|
||||
return self.runGradleWrapper(gradlePath);
|
||||
}).then(function () {
|
||||
return self.prepBuildFiles();
|
||||
@ -276,10 +272,9 @@ 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);
|
||||
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
|
||||
|
||||
return superspawn.spawn(wrapper, args, {stdio: 'pipe'})
|
||||
.progress(function (stdio){
|
||||
return superspawn.spawn(wrapper, args, {stdio: 'pipe'}).progress(function (stdio) {
|
||||
if (stdio.stderr) {
|
||||
/*
|
||||
* Workaround for the issue with Java printing some unwanted information to
|
||||
@ -314,8 +309,7 @@ GradleBuilder.prototype.clean = function(opts) {
|
||||
var args = builder.getArgs('clean', opts);
|
||||
return Q().then(function () {
|
||||
return superspawn.spawn(wrapper, args, {stdio: 'inherit'});
|
||||
})
|
||||
.then(function () {
|
||||
}).then(function () {
|
||||
shell.rm('-rf', path.join(builder.root, 'out'));
|
||||
|
||||
['debug', 'release'].forEach(function (config) {
|
||||
|
@ -35,8 +35,7 @@ var knownBuilders = {
|
||||
* @return {Builder} A builder instance for specified build type.
|
||||
*/
|
||||
module.exports.getBuilder = function (builderType, projectRoot) {
|
||||
if (!knownBuilders[builderType])
|
||||
throw new CordovaError('Builder ' + builderType + ' is not supported.');
|
||||
if (!knownBuilders[builderType]) { throw new CordovaError('Builder ' + builderType + ' is not supported.'); }
|
||||
|
||||
try {
|
||||
var Builder = require('./' + knownBuilders[builderType]);
|
||||
|
76
bin/templates/cordova/lib/check_reqs.js
vendored
76
bin/templates/cordova/lib/check_reqs.js
vendored
@ -21,14 +21,14 @@
|
||||
|
||||
/* jshint sub:true */
|
||||
|
||||
var shelljs = require('shelljs'),
|
||||
child_process = require('child_process'),
|
||||
Q = require('q'),
|
||||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
os = require('os'),
|
||||
REPO_ROOT = path.join(__dirname, '..', '..', '..', '..'),
|
||||
PROJECT_ROOT = path.join(__dirname, '..', '..');
|
||||
var shelljs = require('shelljs');
|
||||
var child_process = require('child_process');
|
||||
var Q = require('q');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var os = require('os');
|
||||
var REPO_ROOT = path.join(__dirname, '..', '..', '..', '..');
|
||||
var PROJECT_ROOT = path.join(__dirname, '..', '..');
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var superspawn = require('cordova-common').superspawn;
|
||||
var android_sdk = require('./android_sdk');
|
||||
@ -53,11 +53,11 @@ function tryCommand(cmd, errMsg, catchStderr) {
|
||||
}
|
||||
|
||||
module.exports.isWindows = function () {
|
||||
return (os.platform() == 'win32');
|
||||
return (os.platform() === 'win32');
|
||||
};
|
||||
|
||||
module.exports.isDarwin = function () {
|
||||
return (os.platform() == 'darwin');
|
||||
return (os.platform() === 'darwin');
|
||||
};
|
||||
|
||||
// Get valid target from framework/project.properties if run from this repo
|
||||
@ -84,12 +84,13 @@ module.exports.get_target = function() {
|
||||
|
||||
// Returns a promise. Called only by build and clean commands.
|
||||
module.exports.check_ant = function () {
|
||||
return superspawn.spawn('ant', ['-version'])
|
||||
.then(function(output) {
|
||||
return superspawn.spawn('ant', ['-version']).then(function (output) {
|
||||
// Parse Ant version from command output
|
||||
return /version ((?:\d+\.)+(?:\d+))/i.exec(output)[1];
|
||||
}).catch(function (err) {
|
||||
if (err) {
|
||||
throw new CordovaError('Failed to run `ant -version`. Make sure you have `ant` on your $PATH.');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@ -108,6 +109,12 @@ module.exports.get_gradle_wrapper = function() {
|
||||
} else { ++i; }
|
||||
}
|
||||
} else if (module.exports.isWindows()) {
|
||||
|
||||
var result = child_process.spawnSync(path.join(__dirname, 'getASPath.bat'));
|
||||
// console.log('result.stdout =' + result.stdout.toString());
|
||||
// console.log('result.stderr =' + result.stderr.toString());
|
||||
|
||||
if (result.stderr.toString().length > 0) {
|
||||
var androidPath = path.join(process.env['ProgramFiles'], 'Android') + '/';
|
||||
if (fs.existsSync(androidPath)) {
|
||||
program_dir = fs.readdirSync(androidPath);
|
||||
@ -118,11 +125,17 @@ module.exports.get_gradle_wrapper = function() {
|
||||
} else { ++i; }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// console.log('got android studio path from registry');
|
||||
// remove the (os independent) new line char at the end of stdout
|
||||
// add gradle to match the above.
|
||||
androidStudioPath = path.join(result.stdout.toString().split('\r\n')[0], 'gradle');
|
||||
}
|
||||
}
|
||||
|
||||
if (androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
|
||||
var dirs = fs.readdirSync(androidStudioPath);
|
||||
if(dirs[0].split('-')[0] == 'gradle') {
|
||||
if (dirs[0].split('-')[0] === 'gradle') {
|
||||
return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
|
||||
}
|
||||
} else {
|
||||
@ -135,17 +148,17 @@ module.exports.get_gradle_wrapper = function() {
|
||||
module.exports.check_gradle = function () {
|
||||
var sdkDir = process.env['ANDROID_HOME'];
|
||||
var d = Q.defer();
|
||||
if (!sdkDir)
|
||||
if (!sdkDir) {
|
||||
return Q.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' +
|
||||
'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.'));
|
||||
}
|
||||
|
||||
var gradlePath = module.exports.get_gradle_wrapper();
|
||||
if (gradlePath.length !== 0)
|
||||
d.resolve(gradlePath);
|
||||
else
|
||||
if (gradlePath.length !== 0) { d.resolve(gradlePath); } else {
|
||||
d.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' +
|
||||
'or on your system to install the gradle wrapper. Please include gradle \n' +
|
||||
'in your path, or install Android Studio'));
|
||||
}
|
||||
return d.promise;
|
||||
};
|
||||
|
||||
@ -165,11 +178,12 @@ module.exports.check_java = function() {
|
||||
var find_java = '/usr/libexec/java_home';
|
||||
var default_java_error_msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting setting it manually.';
|
||||
if (fs.existsSync(find_java)) {
|
||||
return superspawn.spawn(find_java)
|
||||
.then(function(stdout) {
|
||||
return superspawn.spawn(find_java).then(function (stdout) {
|
||||
process.env['JAVA_HOME'] = stdout.trim();
|
||||
}).catch(function (err) {
|
||||
if (err) {
|
||||
throw new CordovaError(default_java_error_msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// See if we can derive it from javac's location.
|
||||
@ -209,8 +223,7 @@ module.exports.check_java = function() {
|
||||
}
|
||||
// We use tryCommand with catchStderr = true, because
|
||||
// javac writes version info to stderr instead of stdout
|
||||
return tryCommand('javac -version', msg, true)
|
||||
.then(function (output) {
|
||||
return tryCommand('javac -version', msg, true).then(function (output) {
|
||||
// Let's check for at least Java 8, and keep it future proof so we can support Java 10
|
||||
var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output);
|
||||
return match && match[1];
|
||||
@ -265,7 +278,7 @@ module.exports.check_android = function() {
|
||||
if (androidCmdPath) {
|
||||
parentDir = path.dirname(androidCmdPath);
|
||||
grandParentDir = path.dirname(parentDir);
|
||||
if (path.basename(parentDir) == 'tools' || fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
|
||||
if (path.basename(parentDir) === 'tools' || fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
|
||||
maybeSetAndroidHome(grandParentDir);
|
||||
} else {
|
||||
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
|
||||
@ -276,7 +289,7 @@ module.exports.check_android = function() {
|
||||
if (adbInPath) {
|
||||
parentDir = path.dirname(adbInPath);
|
||||
grandParentDir = path.dirname(parentDir);
|
||||
if (path.basename(parentDir) == 'platform-tools') {
|
||||
if (path.basename(parentDir) === 'platform-tools') {
|
||||
maybeSetAndroidHome(grandParentDir);
|
||||
} else {
|
||||
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
|
||||
@ -287,7 +300,7 @@ module.exports.check_android = function() {
|
||||
if (avdmanagerInPath) {
|
||||
parentDir = path.dirname(avdmanagerInPath);
|
||||
grandParentDir = path.dirname(parentDir);
|
||||
if (path.basename(parentDir) == 'bin' && path.basename(grandParentDir) == 'tools') {
|
||||
if (path.basename(parentDir) === 'bin' && path.basename(grandParentDir) === 'tools') {
|
||||
maybeSetAndroidHome(path.dirname(grandParentDir));
|
||||
} else {
|
||||
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
|
||||
@ -337,8 +350,7 @@ module.exports.check_android_target = function(originalError) {
|
||||
// Google Inc.:Google APIs:20
|
||||
// Google Inc.:Glass Development Kit Preview:20
|
||||
var desired_api_level = module.exports.get_target();
|
||||
return android_sdk.list_targets()
|
||||
.then(function(targets) {
|
||||
return android_sdk.list_targets().then(function (targets) {
|
||||
if (targets.indexOf(desired_api_level) >= 0) {
|
||||
return targets;
|
||||
}
|
||||
@ -358,8 +370,7 @@ module.exports.check_android_target = function(originalError) {
|
||||
|
||||
// Returns a promise.
|
||||
module.exports.run = function () {
|
||||
return Q.all([this.check_java(), this.check_android()])
|
||||
.then(function(values) {
|
||||
return Q.all([this.check_java(), this.check_android()]).then(function (values) {
|
||||
console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']);
|
||||
console.log('JAVA_HOME=' + process.env['JAVA_HOME']);
|
||||
|
||||
@ -373,7 +384,6 @@ module.exports.run = function() {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Object thar represents one of requirements for current platform.
|
||||
* @param {String} id The unique identifier for this requirements.
|
||||
@ -387,7 +397,7 @@ var Requirement = function (id, name, version, installed) {
|
||||
this.name = name;
|
||||
this.installed = installed || false;
|
||||
this.metadata = {
|
||||
version: version,
|
||||
version: version
|
||||
};
|
||||
};
|
||||
|
||||
@ -417,15 +427,13 @@ module.exports.check_all = function() {
|
||||
return checkFns.reduce(function (promise, checkFn, idx) {
|
||||
// Update each requirement with results
|
||||
var requirement = requirements[idx];
|
||||
return promise.then(checkFn)
|
||||
.then(function (version) {
|
||||
return promise.then(checkFn).then(function (version) {
|
||||
requirement.installed = true;
|
||||
requirement.metadata.version = version;
|
||||
}, function (err) {
|
||||
requirement.metadata.reason = err instanceof Error ? err.message : err;
|
||||
});
|
||||
}, Q())
|
||||
.then(function () {
|
||||
}, Q()).then(function () {
|
||||
// When chain is completed, return requirements array to upstream API
|
||||
return requirements;
|
||||
});
|
||||
|
30
bin/templates/cordova/lib/device.js
vendored
30
bin/templates/cordova/lib/device.js
vendored
@ -19,8 +19,8 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var Q = require('q'),
|
||||
build = require('./build');
|
||||
var Q = require('q');
|
||||
var build = require('./build');
|
||||
var path = require('path');
|
||||
var Adb = require('./Adb');
|
||||
var AndroidManifest = require('./AndroidManifest');
|
||||
@ -33,14 +33,12 @@ var events = require('cordova-common').events;
|
||||
* @param lookHarder When true, try restarting adb if no devices are found.
|
||||
*/
|
||||
module.exports.list = function (lookHarder) {
|
||||
return Adb.devices()
|
||||
.then(function(list) {
|
||||
return Adb.devices().then(function (list) {
|
||||
if (list.length === 0 && lookHarder) {
|
||||
// adb kill-server doesn't seem to do the trick.
|
||||
// Could probably find a x-platform version of killall, but I'm not actually
|
||||
// sure that this scenario even happens on non-OSX machines.
|
||||
return spawn('killall', ['adb'])
|
||||
.then(function() {
|
||||
return spawn('killall', ['adb']).then(function () {
|
||||
events.emit('verbose', 'Restarting adb to see if more devices are detected.');
|
||||
return Adb.devices();
|
||||
}, function () {
|
||||
@ -53,8 +51,7 @@ module.exports.list = function(lookHarder) {
|
||||
};
|
||||
|
||||
module.exports.resolveTarget = function (target) {
|
||||
return this.list(true)
|
||||
.then(function(device_list) {
|
||||
return this.list(true).then(function (device_list) {
|
||||
if (!device_list || !device_list.length) {
|
||||
return Q.reject(new CordovaError('Failed to deploy to device, no devices found.'));
|
||||
}
|
||||
@ -65,8 +62,7 @@ module.exports.resolveTarget = function(target) {
|
||||
return Q.reject('ERROR: Unable to find target \'' + target + '\'.');
|
||||
}
|
||||
|
||||
return build.detectArchitecture(target)
|
||||
.then(function(arch) {
|
||||
return build.detectArchitecture(target).then(function (arch) {
|
||||
return { target: target, arch: arch, isEmulator: false };
|
||||
});
|
||||
});
|
||||
@ -79,7 +75,7 @@ module.exports.resolveTarget = function(target) {
|
||||
*/
|
||||
module.exports.install = function (target, buildResults) {
|
||||
return Q().then(function () {
|
||||
if (target && typeof target == 'object') {
|
||||
if (target && typeof target === 'object') {
|
||||
return target;
|
||||
}
|
||||
return module.exports.resolveTarget(target);
|
||||
@ -91,24 +87,20 @@ module.exports.install = function(target, buildResults) {
|
||||
events.emit('log', 'Using apk: ' + apk_path);
|
||||
events.emit('log', 'Package name: ' + pkgName);
|
||||
|
||||
return Adb.install(resolvedTarget.target, apk_path, {replace: true})
|
||||
.catch(function (error) {
|
||||
return Adb.install(resolvedTarget.target, apk_path, {replace: true}).catch(function (error) {
|
||||
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
||||
// is already installed on device was signed w/different certificate
|
||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString()))
|
||||
throw error;
|
||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) { throw error; }
|
||||
|
||||
events.emit('warn', 'Uninstalling app from device and reinstalling it again because the ' +
|
||||
'installed app already signed with different key');
|
||||
|
||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||
// or the app doesn't installed at all, so no error catching needed.
|
||||
return Adb.uninstall(resolvedTarget.target, pkgName)
|
||||
.then(function() {
|
||||
return Adb.uninstall(resolvedTarget.target, pkgName).then(function () {
|
||||
return Adb.install(resolvedTarget.target, apk_path, {replace: true});
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
}).then(function () {
|
||||
// unlock screen
|
||||
return Adb.shell(resolvedTarget.target, 'input keyevent 82');
|
||||
}).then(function () {
|
||||
|
73
bin/templates/cordova/lib/emulator.js
vendored
73
bin/templates/cordova/lib/emulator.js
vendored
@ -55,8 +55,7 @@ function forgivingWhichSync(cmd) {
|
||||
}
|
||||
|
||||
module.exports.list_images_using_avdmanager = function () {
|
||||
return superspawn.spawn('avdmanager', ['list', 'avd'])
|
||||
.then(function(output) {
|
||||
return superspawn.spawn('avdmanager', ['list', 'avd']).then(function (output) {
|
||||
var response = output.split('\n');
|
||||
var emulator_list = [];
|
||||
for (var i = 1; i < response.length; i++) {
|
||||
@ -116,8 +115,7 @@ module.exports.list_images_using_avdmanager = function () {
|
||||
};
|
||||
|
||||
module.exports.list_images_using_android = function () {
|
||||
return superspawn.spawn('android', ['list', 'avd'])
|
||||
.then(function(output) {
|
||||
return superspawn.spawn('android', ['list', 'avd']).then(function (output) {
|
||||
var response = output.split('\n');
|
||||
var emulator_list = [];
|
||||
for (var i = 1; i < response.length; i++) {
|
||||
@ -188,8 +186,7 @@ module.exports.list_images = function() {
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.best_image = function () {
|
||||
return this.list_images()
|
||||
.then(function(images) {
|
||||
return this.list_images().then(function (images) {
|
||||
// Just return undefined if there is no images
|
||||
if (images.length === 0) return;
|
||||
|
||||
@ -200,7 +197,7 @@ module.exports.best_image = function() {
|
||||
var target = images[i].target;
|
||||
if (target) {
|
||||
var num = target.split('(API level ')[1].replace(')', '');
|
||||
if (num == project_target) {
|
||||
if (num === project_target) {
|
||||
return images[i];
|
||||
} else if (project_target - num < closest && project_target > num) {
|
||||
closest = project_target - num;
|
||||
@ -220,8 +217,7 @@ module.exports.list_started = function() {
|
||||
// Returns a promise.
|
||||
// TODO: we should remove this, there's a more robust method under android_sdk.js
|
||||
module.exports.list_targets = function () {
|
||||
return superspawn.spawn('android', ['list', 'targets'], {cwd: os.tmpdir()})
|
||||
.then(function(output) {
|
||||
return superspawn.spawn('android', ['list', 'targets'], {cwd: os.tmpdir()}).then(function (output) {
|
||||
var target_out = output.split('\n');
|
||||
var targets = [];
|
||||
for (var i = target_out.length; i >= 0; i--) {
|
||||
@ -240,8 +236,7 @@ module.exports.list_targets = function() {
|
||||
module.exports.get_available_port = function () {
|
||||
var self = this;
|
||||
|
||||
return self.list_started()
|
||||
.then(function (emulators) {
|
||||
return self.list_started().then(function (emulators) {
|
||||
for (var p = 5584; p >= 5554; p -= 2) {
|
||||
if (emulators.indexOf('emulator-' + p) === -1) {
|
||||
events.emit('verbose', 'Found available port: ' + p);
|
||||
@ -268,8 +263,7 @@ module.exports.start = function(emulator_ID, boot_timeout) {
|
||||
return Q().then(function () {
|
||||
if (emulator_ID) return Q(emulator_ID);
|
||||
|
||||
return self.best_image()
|
||||
.then(function(best) {
|
||||
return self.best_image().then(function (best) {
|
||||
if (best && best.name) {
|
||||
events.emit('warn', 'No emulator specified, defaulting to ' + best.name);
|
||||
return best.name;
|
||||
@ -282,8 +276,7 @@ module.exports.start = function(emulator_ID, boot_timeout) {
|
||||
'HINT: For a faster emulator, use an Intel System Image and install the HAXM device driver\n'));
|
||||
});
|
||||
}).then(function (emulatorId) {
|
||||
return self.get_available_port()
|
||||
.then(function (port) {
|
||||
return self.get_available_port().then(function (port) {
|
||||
// Figure out the directory the emulator binary runs in, and set the cwd to that directory.
|
||||
// Workaround for https://code.google.com/p/android/issues/detail?id=235461
|
||||
var emulator_dir = path.dirname(shelljs.which('emulator'));
|
||||
@ -298,18 +291,15 @@ module.exports.start = function(emulator_ID, boot_timeout) {
|
||||
return self.wait_for_emulator(port);
|
||||
});
|
||||
}).then(function (emulatorId) {
|
||||
if (!emulatorId)
|
||||
return Q.reject(new CordovaError('Failed to start emulator'));
|
||||
if (!emulatorId) { return Q.reject(new CordovaError('Failed to start emulator')); }
|
||||
|
||||
// wait for emulator to boot up
|
||||
process.stdout.write('Waiting for emulator to boot (this may take a while)...');
|
||||
return self.wait_for_boot(emulatorId, boot_timeout)
|
||||
.then(function(success) {
|
||||
return self.wait_for_boot(emulatorId, boot_timeout).then(function (success) {
|
||||
if (success) {
|
||||
events.emit('log', 'BOOT COMPLETE');
|
||||
// unlock screen
|
||||
return Adb.shell(emulatorId, 'input keyevent 82')
|
||||
.then(function() {
|
||||
return Adb.shell(emulatorId, 'input keyevent 82').then(function () {
|
||||
// return the new emulator id for the started emulators
|
||||
return emulatorId;
|
||||
});
|
||||
@ -329,16 +319,15 @@ module.exports.wait_for_emulator = function(port) {
|
||||
var self = this;
|
||||
return Q().then(function () {
|
||||
var emulator_id = 'emulator-' + port;
|
||||
return Adb.shell(emulator_id, 'getprop dev.bootcomplete')
|
||||
.then(function (output) {
|
||||
return Adb.shell(emulator_id, 'getprop dev.bootcomplete').then(function (output) {
|
||||
if (output.indexOf('1') >= 0) {
|
||||
return emulator_id;
|
||||
}
|
||||
return self.wait_for_emulator(port);
|
||||
}, function (error) {
|
||||
if (error && error.message &&
|
||||
(error.message.indexOf('not found') > -1) ||
|
||||
error.message.indexOf('device offline') > -1) {
|
||||
if ((error && error.message &&
|
||||
(error.message.indexOf('not found') > -1)) ||
|
||||
(error.message.indexOf('device offline') > -1)) {
|
||||
// emulator not yet started, continue waiting
|
||||
return self.wait_for_emulator(port);
|
||||
} else {
|
||||
@ -356,8 +345,7 @@ module.exports.wait_for_emulator = function(port) {
|
||||
*/
|
||||
module.exports.wait_for_boot = function (emulator_id, time_remaining) {
|
||||
var self = this;
|
||||
return Adb.shell(emulator_id, 'ps')
|
||||
.then(function(output) {
|
||||
return Adb.shell(emulator_id, 'ps').then(function (output) {
|
||||
if (output.match(/android\.process\.acore/)) {
|
||||
return true;
|
||||
} else if (time_remaining === 0) {
|
||||
@ -382,8 +370,7 @@ module.exports.wait_for_boot = function(emulator_id, time_remaining) {
|
||||
module.exports.create_image = function (name, target) {
|
||||
console.log('Creating new avd named ' + name);
|
||||
if (target) {
|
||||
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', target])
|
||||
.then(null, function(error) {
|
||||
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', target]).then(null, function (error) {
|
||||
console.error('ERROR : Failed to create emulator image : ');
|
||||
console.error(' Do you have the latest android targets including ' + target + '?');
|
||||
console.error(error);
|
||||
@ -391,8 +378,7 @@ module.exports.create_image = function(name, target) {
|
||||
} else {
|
||||
console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
|
||||
// TODO: there's a more robust method for finding targets in android_sdk.js
|
||||
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', this.list_targets()[0]])
|
||||
.then(function() {
|
||||
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', this.list_targets()[0]]).then(function () {
|
||||
// TODO: This seems like another error case, even though it always happens.
|
||||
console.error('ERROR : Unable to create an avd emulator, no targets found.');
|
||||
console.error('Ensure you have targets available by running the "android" command');
|
||||
@ -405,8 +391,7 @@ module.exports.create_image = function(name, target) {
|
||||
};
|
||||
|
||||
module.exports.resolveTarget = function (target) {
|
||||
return this.list_started()
|
||||
.then(function(emulator_list) {
|
||||
return this.list_started().then(function (emulator_list) {
|
||||
if (emulator_list.length < 1) {
|
||||
return Q.reject('No running Android emulators found, please start an emulator before deploying your project.');
|
||||
}
|
||||
@ -417,8 +402,7 @@ module.exports.resolveTarget = function(target) {
|
||||
return Q.reject('Unable to find target \'' + target + '\'. Failed to deploy to emulator.');
|
||||
}
|
||||
|
||||
return build.detectArchitecture(target)
|
||||
.then(function(arch) {
|
||||
return build.detectArchitecture(target).then(function (arch) {
|
||||
return {target: target, arch: arch, isEmulator: true};
|
||||
});
|
||||
});
|
||||
@ -438,7 +422,7 @@ module.exports.install = function(givenTarget, buildResults) {
|
||||
|
||||
// resolve the target emulator
|
||||
return Q().then(function () {
|
||||
if (givenTarget && typeof givenTarget == 'object') {
|
||||
if (givenTarget && typeof givenTarget === 'object') {
|
||||
return givenTarget;
|
||||
} else {
|
||||
return module.exports.resolveTarget(givenTarget);
|
||||
@ -452,8 +436,7 @@ module.exports.install = function(givenTarget, buildResults) {
|
||||
}).then(function () {
|
||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||
// or the app doesn't installed at all, so no error catching needed.
|
||||
return Q.when()
|
||||
.then(function() {
|
||||
return Q.when().then(function () {
|
||||
|
||||
var apk_path = build.findBestApkForArchitecture(buildResults, target.arch);
|
||||
var execOptions = {
|
||||
@ -494,27 +477,23 @@ module.exports.install = function(givenTarget, buildResults) {
|
||||
}
|
||||
|
||||
function installPromise () {
|
||||
return adbInstallWithOptions(target.target, apk_path, execOptions)
|
||||
.catch(function (error) {
|
||||
return adbInstallWithOptions(target.target, apk_path, execOptions).catch(function (error) {
|
||||
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
||||
// is already installed on device was signed w/different certificate
|
||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString()))
|
||||
throw error;
|
||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) { throw error; }
|
||||
|
||||
events.emit('warn', 'Uninstalling app from device and reinstalling it because the ' +
|
||||
'currently installed app was signed with different key');
|
||||
|
||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||
// or the app doesn't installed at all, so no error catching needed.
|
||||
return Adb.uninstall(target.target, pkgName)
|
||||
.then(function() {
|
||||
return Adb.uninstall(target.target, pkgName).then(function () {
|
||||
return adbInstallWithOptions(target.target, apk_path, execOptions);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise)
|
||||
.then(function (output) {
|
||||
return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise).then(function (output) {
|
||||
events.emit('log', 'INSTALL SUCCESS');
|
||||
});
|
||||
});
|
||||
|
3
bin/templates/cordova/lib/getASPath.bat
Normal file
3
bin/templates/cordova/lib/getASPath.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@ECHO OFF
|
||||
for /f "tokens=2*" %%a in ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Android Studio" /v Path') do set "ASPath=%%~b"
|
||||
ECHO %ASPath%
|
10
bin/templates/cordova/lib/log.js
vendored
10
bin/templates/cordova/lib/log.js
vendored
@ -19,11 +19,11 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var path = require('path'),
|
||||
os = require('os'),
|
||||
Q = require('q'),
|
||||
child_process = require('child_process'),
|
||||
ROOT = path.join(__dirname, '..', '..');
|
||||
var path = require('path');
|
||||
var os = require('os');
|
||||
var Q = require('q');
|
||||
var child_process = require('child_process');
|
||||
var ROOT = path.join(__dirname, '..', '..');
|
||||
|
||||
/*
|
||||
* Starts running logcat in the shell.
|
||||
|
20
bin/templates/cordova/lib/pluginHandlers.js
vendored
20
bin/templates/cordova/lib/pluginHandlers.js
vendored
@ -95,9 +95,9 @@ var handlers = {
|
||||
subDir = src;
|
||||
}
|
||||
|
||||
if (obj.type == 'gradleReference') {
|
||||
if (obj.type === 'gradleReference') {
|
||||
project.addGradleReference(parentDir, subDir);
|
||||
} else if (obj.type == 'sys') {
|
||||
} else if (obj.type === 'sys') {
|
||||
project.addSystemLibrary(parentDir, subDir);
|
||||
} else {
|
||||
project.addSubProject(parentDir, subDir);
|
||||
@ -125,9 +125,9 @@ var handlers = {
|
||||
subDir = src;
|
||||
}
|
||||
|
||||
if (obj.type == 'gradleReference') {
|
||||
if (obj.type === 'gradleReference') {
|
||||
project.removeGradleReference(parentDir, subDir);
|
||||
} else if (obj.type == 'sys') {
|
||||
} else if (obj.type === 'sys') {
|
||||
project.removeSystemLibrary(parentDir, subDir);
|
||||
} else {
|
||||
project.removeSubProject(parentDir, subDir);
|
||||
@ -221,14 +221,12 @@ function copyFile (plugin_dir, src, project_dir, dest, link) {
|
||||
// check that src path is inside plugin directory
|
||||
var real_path = fs.realpathSync(src);
|
||||
var real_plugin_path = fs.realpathSync(plugin_dir);
|
||||
if (real_path.indexOf(real_plugin_path) !== 0)
|
||||
throw new CordovaError('File "' + src + '" is located outside the plugin directory "' + plugin_dir + '"');
|
||||
if (real_path.indexOf(real_plugin_path) !== 0) { throw new CordovaError('File "' + src + '" is located outside the plugin directory "' + plugin_dir + '"'); }
|
||||
|
||||
dest = path.resolve(project_dir, dest);
|
||||
|
||||
// check that dest path is located in project directory
|
||||
if (dest.indexOf(project_dir) !== 0)
|
||||
throw new CordovaError('Destination "' + dest + '" for source file "' + src + '" is located outside the project');
|
||||
if (dest.indexOf(project_dir) !== 0) { throw new CordovaError('Destination "' + dest + '" for source file "' + src + '" is located outside the project'); }
|
||||
|
||||
shell.mkdir('-p', path.dirname(dest));
|
||||
if (link) {
|
||||
@ -244,8 +242,7 @@ function copyFile (plugin_dir, src, project_dir, dest, link) {
|
||||
// Same as copy file but throws error if target exists
|
||||
function copyNewFile (plugin_dir, src, project_dir, dest, link) {
|
||||
var target_path = path.resolve(project_dir, dest);
|
||||
if (fs.existsSync(target_path))
|
||||
throw new CordovaError('"' + target_path + '" already exists!');
|
||||
if (fs.existsSync(target_path)) { throw new CordovaError('"' + target_path + '" already exists!'); }
|
||||
|
||||
copyFile(plugin_dir, src, project_dir, dest, !!link);
|
||||
}
|
||||
@ -260,8 +257,7 @@ function symlinkFileOrDirTree(src, dest) {
|
||||
fs.readdirSync(src).forEach(function (entry) {
|
||||
symlinkFileOrDirTree(path.join(src, entry), path.join(dest, entry));
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fs.symlinkSync(path.relative(fs.realpathSync(path.dirname(dest)), src), dest);
|
||||
}
|
||||
}
|
||||
|
20
bin/templates/cordova/lib/prepare.js
vendored
20
bin/templates/cordova/lib/prepare.js
vendored
@ -16,6 +16,7 @@
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
/* eslint no-useless-escape: 0 */
|
||||
|
||||
var Q = require('q');
|
||||
var fs = require('fs');
|
||||
@ -40,17 +41,14 @@ module.exports.prepare = function (cordovaProject, options) {
|
||||
this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations);
|
||||
|
||||
// Update own www dir with project's www assets and plugins' assets and js-files
|
||||
return Q.when(updateWww(cordovaProject, this.locations))
|
||||
.then(function () {
|
||||
return Q.when(updateWww(cordovaProject, this.locations)).then(function () {
|
||||
// update project according to config.xml changes.
|
||||
return updateProjectAccordingTo(self._config, self.locations);
|
||||
})
|
||||
.then(function () {
|
||||
}).then(function () {
|
||||
updateIcons(cordovaProject, path.relative(cordovaProject.root, self.locations.res));
|
||||
updateSplashes(cordovaProject, path.relative(cordovaProject.root, self.locations.res));
|
||||
updateFileResources(cordovaProject, path.relative(cordovaProject.root, self.locations.root));
|
||||
})
|
||||
.then(function () {
|
||||
}).then(function () {
|
||||
events.emit('verbose', 'Prepared android project successfully');
|
||||
});
|
||||
};
|
||||
@ -272,7 +270,7 @@ function updateSplashes(cordovaProject, platformResourcesDir) {
|
||||
if (!resource.density) {
|
||||
return;
|
||||
}
|
||||
if (resource.density == 'mdpi') {
|
||||
if (resource.density === 'mdpi') {
|
||||
hadMdpi = true;
|
||||
}
|
||||
var targetPath = getImageResourcePath(
|
||||
@ -397,15 +395,13 @@ function cleanIcons(projectRoot, projectConfig, platformResourcesDir) {
|
||||
*/
|
||||
function mapImageResources (rootDir, subDir, type, resourceName) {
|
||||
var pathMap = {};
|
||||
shell.ls(path.join(rootDir, subDir, type + '-*'))
|
||||
.forEach(function (drawableFolder) {
|
||||
shell.ls(path.join(rootDir, subDir, type + '-*')).forEach(function (drawableFolder) {
|
||||
var imagePath = path.join(subDir, path.basename(drawableFolder), resourceName);
|
||||
pathMap[imagePath] = null;
|
||||
});
|
||||
return pathMap;
|
||||
}
|
||||
|
||||
|
||||
function updateFileResources (cordovaProject, platformDir) {
|
||||
var files = cordovaProject.projectConfig.getFileResources('android');
|
||||
|
||||
@ -426,7 +422,6 @@ function updateFileResources(cordovaProject, platformDir) {
|
||||
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
||||
}
|
||||
|
||||
|
||||
function cleanFileResources (projectRoot, projectConfig, platformDir) {
|
||||
var files = projectConfig.getFileResources('android', true);
|
||||
if (files.length > 0) {
|
||||
@ -439,7 +434,8 @@ function cleanFileResources(projectRoot, projectConfig, platformDir) {
|
||||
});
|
||||
|
||||
FileUpdater.updatePaths(
|
||||
resourceMap, { rootDir: projectRoot, all: true}, logFileOp);
|
||||
resourceMap, {
|
||||
rootDir: projectRoot, all: true}, logFileOp);
|
||||
}
|
||||
}
|
||||
|
||||
|
45
bin/templates/cordova/lib/run.js
vendored
45
bin/templates/cordova/lib/run.js
vendored
@ -21,12 +21,12 @@
|
||||
|
||||
/* jshint loopfunc:true */
|
||||
|
||||
var path = require('path'),
|
||||
build = require('./build'),
|
||||
emulator = require('./emulator'),
|
||||
device = require('./device'),
|
||||
Q = require('q'),
|
||||
events = require('cordova-common').events;
|
||||
var path = require('path');
|
||||
var build = require('./build');
|
||||
var emulator = require('./emulator');
|
||||
var device = require('./device');
|
||||
var Q = require('q');
|
||||
var events = require('cordova-common').events;
|
||||
|
||||
function getInstallTarget (runOptions) {
|
||||
var install_target;
|
||||
@ -56,12 +56,10 @@ function getInstallTarget(runOptions) {
|
||||
var self = this;
|
||||
var install_target = getInstallTarget(runOptions);
|
||||
|
||||
return Q()
|
||||
.then(function() {
|
||||
return Q().then(function () {
|
||||
if (!install_target) {
|
||||
// no target given, deploy to device if available, otherwise use the emulator.
|
||||
return device.list()
|
||||
.then(function(device_list) {
|
||||
return device.list().then(function (device_list) {
|
||||
if (device_list.length > 0) {
|
||||
events.emit('warn', 'No target specified, deploying to device \'' + device_list[0] + '\'.');
|
||||
install_target = device_list[0];
|
||||
@ -72,35 +70,30 @@ function getInstallTarget(runOptions) {
|
||||
});
|
||||
}
|
||||
}).then(function () {
|
||||
if (install_target == '--device') {
|
||||
if (install_target === '--device') {
|
||||
return device.resolveTarget(null);
|
||||
} else if (install_target == '--emulator') {
|
||||
} else if (install_target === '--emulator') {
|
||||
// Give preference to any already started emulators. Else, start one.
|
||||
return emulator.list_started()
|
||||
.then(function(started) {
|
||||
return emulator.list_started().then(function (started) {
|
||||
return started && started.length > 0 ? started[0] : emulator.start();
|
||||
}).then(function (emulatorId) {
|
||||
return emulator.resolveTarget(emulatorId);
|
||||
});
|
||||
}
|
||||
// They specified a specific device/emulator ID.
|
||||
return device.list()
|
||||
.then(function(devices) {
|
||||
return device.list().then(function (devices) {
|
||||
if (devices.indexOf(install_target) > -1) {
|
||||
return device.resolveTarget(install_target);
|
||||
}
|
||||
return emulator.list_started()
|
||||
.then(function(started_emulators) {
|
||||
return emulator.list_started().then(function (started_emulators) {
|
||||
if (started_emulators.indexOf(install_target) > -1) {
|
||||
return emulator.resolveTarget(install_target);
|
||||
}
|
||||
return emulator.list_images()
|
||||
.then(function(avds) {
|
||||
return emulator.list_images().then(function (avds) {
|
||||
// if target emulator isn't started, then start it.
|
||||
for (var avd in avds) {
|
||||
if (avds[avd].name == install_target) {
|
||||
return emulator.start(install_target)
|
||||
.then(function(emulatorId) {
|
||||
if (avds[avd].name === install_target) {
|
||||
return emulator.start(install_target).then(function (emulatorId) {
|
||||
return emulator.resolveTarget(emulatorId);
|
||||
});
|
||||
}
|
||||
@ -114,11 +107,9 @@ function getInstallTarget(runOptions) {
|
||||
// build results (according to platformApi spec) so they are in different
|
||||
// format than emulator.install expects.
|
||||
// TODO: Update emulator/device.install to handle this change
|
||||
return build.run.call(self, runOptions, resolvedTarget)
|
||||
.then(function(buildResults) {
|
||||
return build.run.call(self, runOptions, resolvedTarget).then(function (buildResults) {
|
||||
if (resolvedTarget.isEmulator) {
|
||||
return emulator.wait_for_boot(resolvedTarget.target)
|
||||
.then(function () {
|
||||
return emulator.wait_for_boot(resolvedTarget.target).then(function () {
|
||||
return emulator.install(resolvedTarget, buildResults);
|
||||
});
|
||||
}
|
||||
|
393
bin/templates/project/assets/www/cordova.js
vendored
393
bin/templates/project/assets/www/cordova.js
vendored
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -19,10 +19,10 @@
|
||||
"apache"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "npm run jshint && jasmine",
|
||||
"test": "npm run eslint && jasmine",
|
||||
"cover": "istanbul cover --root bin/templates/cordova --print detail jasmine",
|
||||
"test-build": "jasmine --captureExceptions --color spec/e2e/*.spec.js",
|
||||
"jshint": "jshint bin && jshint spec"
|
||||
"eslint": "eslint bin && eslint spec"
|
||||
},
|
||||
"author": "Apache Software Foundation",
|
||||
"license": "Apache-2.0",
|
||||
@ -43,9 +43,15 @@
|
||||
"shelljs"
|
||||
],
|
||||
"devDependencies": {
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-semistandard": "^11.0.0",
|
||||
"eslint-config-standard": "^10.2.1",
|
||||
"eslint-plugin-import": "^2.3.0",
|
||||
"eslint-plugin-node": "^5.0.0",
|
||||
"eslint-plugin-promise": "^3.5.0",
|
||||
"eslint-plugin-standard": "^3.0.1",
|
||||
"istanbul": "^0.4.2",
|
||||
"jasmine": "^2.5.2",
|
||||
"jshint": "^2.6.0",
|
||||
"promise-matchers": "~0",
|
||||
"rewire": "^2.1.3"
|
||||
},
|
||||
|
2
spec/.eslintrc.yml
Normal file
2
spec/.eslintrc.yml
Normal file
@ -0,0 +1,2 @@
|
||||
env:
|
||||
jasmine: true
|
@ -32,7 +32,6 @@ function createAndBuild(projectname, projectid, done) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
describe('create', function () {
|
||||
|
||||
it('Test#001 : create project with ascii name, no spaces', function (done) {
|
||||
|
@ -17,11 +17,11 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var PluginInfoProvider = require('cordova-common').PluginInfoProvider,
|
||||
shell = require('shelljs'),
|
||||
cp = require('child_process'),
|
||||
path = require('path'),
|
||||
util = require('util');
|
||||
var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
|
||||
var shell = require('shelljs');
|
||||
var cp = require('child_process');
|
||||
var path = require('path');
|
||||
var util = require('util');
|
||||
|
||||
var cordova_bin = path.join(__dirname, '../../../bin');
|
||||
|
||||
|
@ -17,8 +17,8 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var path = require('path'),
|
||||
actions = require('./helpers/projectActions.js');
|
||||
var path = require('path');
|
||||
var actions = require('./helpers/projectActions.js');
|
||||
|
||||
var PLUGIN_ADD_TIMEOUT = 90000;
|
||||
|
||||
|
@ -17,16 +17,16 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var actions = require('./helpers/projectActions.js'),
|
||||
shell = require('shelljs'),
|
||||
fs = require('fs'),
|
||||
util = require('util'),
|
||||
platformOld = { version: '4.0.0', path: 'cordova-android-old' },
|
||||
platformEdge = { version: getCurrentVersion(), path: '.' };
|
||||
var actions = require('./helpers/projectActions.js');
|
||||
var shell = require('shelljs');
|
||||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
var platformOld = { version: '4.0.0', path: 'cordova-android-old' };
|
||||
var platformEdge = { version: getCurrentVersion(), path: '.' };
|
||||
|
||||
var DOWNLOAD_TIMEOUT = 2 * 60 * 1000,
|
||||
UPDATE_TIMEOUT = 90 * 1000,
|
||||
PLATFORM_GIT_URL = 'https://github.com/apache/cordova-android';
|
||||
var DOWNLOAD_TIMEOUT = 2 * 60 * 1000;
|
||||
var UPDATE_TIMEOUT = 90 * 1000;
|
||||
var PLATFORM_GIT_URL = 'https://github.com/apache/cordova-android';
|
||||
|
||||
function getCurrentVersion () {
|
||||
return fs.readFileSync('VERSION').toString().trim();
|
||||
|
@ -1 +0,0 @@
|
||||
./org.test.plugins.dummyplugin/www/dummyplugin.js
|
@ -2,7 +2,6 @@
|
||||
var path = require('path');
|
||||
var AndroidStudio = require('../../bin/templates/cordova/lib/AndroidStudio');
|
||||
|
||||
|
||||
describe('AndroidStudio module', function () {
|
||||
it('should return true for Android Studio project', function () {
|
||||
var root = path.join(__dirname, '../fixtures/android_studio_project/');
|
||||
|
@ -17,8 +17,6 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
/* jshint node:true */
|
||||
|
||||
var Q = require('q');
|
||||
var os = require('os');
|
||||
var path = require('path');
|
||||
@ -59,9 +57,7 @@ describe('addPlugin method', function () {
|
||||
});
|
||||
|
||||
it('Test#001 : should call gradleBuilder.prepBuildFiles for every plugin with frameworks', function (done) {
|
||||
api.addPlugin(new PluginInfo(path.join(FIXTURES, 'cordova-plugin-fake')))
|
||||
.catch(fail)
|
||||
.fin(function () {
|
||||
api.addPlugin(new PluginInfo(path.join(FIXTURES, 'cordova-plugin-fake'))).catch(fail).fin(function () {
|
||||
expect(fail).not.toHaveBeenCalled();
|
||||
expect(gradleBuilder.prepBuildFiles).toHaveBeenCalled();
|
||||
done();
|
||||
@ -69,9 +65,7 @@ describe('addPlugin method', function () {
|
||||
});
|
||||
|
||||
it('Test#002 : shouldn\'t trigger gradleBuilder.prepBuildFiles for plugins without android frameworks', function (done) {
|
||||
api.addPlugin(new PluginInfo(path.join(FIXTURES, 'cordova-plugin-fake-ios-frameworks')))
|
||||
.catch(fail)
|
||||
.fin(function () {
|
||||
api.addPlugin(new PluginInfo(path.join(FIXTURES, 'cordova-plugin-fake-ios-frameworks'))).catch(fail).fin(function () {
|
||||
expect(fail).not.toHaveBeenCalled();
|
||||
expect(gradleBuilder.prepBuildFiles).not.toHaveBeenCalled();
|
||||
done();
|
||||
|
@ -16,41 +16,37 @@
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
/* jshint laxcomma:true */
|
||||
|
||||
var android_sdk = require("../../bin/templates/cordova/lib/android_sdk");
|
||||
var superspawn = require("cordova-common").superspawn;
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var Q = require("q");
|
||||
var android_sdk = require('../../bin/templates/cordova/lib/android_sdk');
|
||||
var superspawn = require('cordova-common').superspawn;
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var Q = require('q');
|
||||
|
||||
describe("android_sdk", function () {
|
||||
describe("list_targets_with_android", function() {
|
||||
it("should invoke `android` with the `list target` command and _not_ the `list targets` command, as the plural form is not supported in some Android SDK Tools versions", function() {
|
||||
describe('android_sdk', function () {
|
||||
describe('list_targets_with_android', function () {
|
||||
it('should invoke `android` with the `list target` command and _not_ the `list targets` command, as the plural form is not supported in some Android SDK Tools versions', function () {
|
||||
var deferred = Q.defer();
|
||||
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
||||
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
|
||||
android_sdk.list_targets_with_android();
|
||||
expect(superspawn.spawn).toHaveBeenCalledWith("android", ["list", "target"]);
|
||||
expect(superspawn.spawn).toHaveBeenCalledWith('android', ['list', 'target']);
|
||||
});
|
||||
it("should parse and return results from `android list targets` command", function(done) {
|
||||
it('should parse and return results from `android list targets` command', function (done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
||||
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "sdk25.2-android_list_targets.txt"), "utf-8"));
|
||||
return android_sdk.list_targets_with_android()
|
||||
.then(function(list) {
|
||||
[ "Google Inc.:Google APIs:23",
|
||||
"Google Inc.:Google APIs:22",
|
||||
"Google Inc.:Google APIs:21",
|
||||
"android-25",
|
||||
"android-24",
|
||||
"android-N",
|
||||
"android-23",
|
||||
"android-MNC",
|
||||
"android-22",
|
||||
"android-21",
|
||||
"android-20" ].forEach(function(target) {
|
||||
expect(list).toContain(target);
|
||||
});
|
||||
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
|
||||
deferred.resolve(fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.2-android_list_targets.txt'), 'utf-8'));
|
||||
return android_sdk.list_targets_with_android().then(function (list) {
|
||||
[ 'Google Inc.:Google APIs:23',
|
||||
'Google Inc.:Google APIs:22',
|
||||
'Google Inc.:Google APIs:21',
|
||||
'android-25',
|
||||
'android-24',
|
||||
'android-N',
|
||||
'android-23',
|
||||
'android-MNC',
|
||||
'android-22',
|
||||
'android-21',
|
||||
'android-20' ].forEach(function (target) { expect(list).toContain(target); });
|
||||
}).fail(function (err) {
|
||||
console.log(err);
|
||||
expect(err).toBeUndefined();
|
||||
@ -59,14 +55,13 @@ describe("android_sdk", function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("list_targets_with_avdmanager", function() {
|
||||
it("should parse and return results from `avdmanager list target` command", function(done) {
|
||||
describe('list_targets_with_avdmanager', function () {
|
||||
it('should parse and return results from `avdmanager list target` command', function (done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
||||
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "sdk25.3-avdmanager_list_target.txt"), "utf-8"));
|
||||
return android_sdk.list_targets_with_avdmanager()
|
||||
.then(function(list) {
|
||||
expect(list).toContain("android-25");
|
||||
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
|
||||
deferred.resolve(fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.3-avdmanager_list_target.txt'), 'utf-8'));
|
||||
return android_sdk.list_targets_with_avdmanager().then(function (list) {
|
||||
expect(list).toContain('android-25');
|
||||
}).fail(function (err) {
|
||||
console.log(err);
|
||||
expect(err).toBeUndefined();
|
||||
@ -75,56 +70,53 @@ describe("android_sdk", function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("list_targets", function() {
|
||||
it("should parse Android SDK installed target information with `avdmanager` command first", function() {
|
||||
describe('list_targets', function () {
|
||||
it('should parse Android SDK installed target information with `avdmanager` command first', function () {
|
||||
var deferred = Q.defer();
|
||||
var avdmanager_spy = spyOn(android_sdk, "list_targets_with_avdmanager").and.returnValue(deferred.promise);
|
||||
var avdmanager_spy = spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(deferred.promise);
|
||||
android_sdk.list_targets();
|
||||
expect(avdmanager_spy).toHaveBeenCalled();
|
||||
});
|
||||
it("should parse Android SDK installed target information with `android` command if list_targets_with_avdmanager fails with ENOENT", function(done) {
|
||||
it('should parse Android SDK installed target information with `android` command if list_targets_with_avdmanager fails with ENOENT', function (done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, "list_targets_with_avdmanager").and.returnValue(deferred.promise);
|
||||
spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(deferred.promise);
|
||||
deferred.reject({
|
||||
code: "ENOENT"
|
||||
code: 'ENOENT'
|
||||
});
|
||||
var twoferred = Q.defer();
|
||||
twoferred.resolve(["target1"]);
|
||||
var avdmanager_spy = spyOn(android_sdk, "list_targets_with_android").and.returnValue(twoferred.promise);
|
||||
return android_sdk.list_targets()
|
||||
.then(function(targets) {
|
||||
twoferred.resolve(['target1']);
|
||||
var avdmanager_spy = spyOn(android_sdk, 'list_targets_with_android').and.returnValue(twoferred.promise);
|
||||
return android_sdk.list_targets().then(function (targets) {
|
||||
expect(avdmanager_spy).toHaveBeenCalled();
|
||||
expect(targets[0]).toEqual("target1");
|
||||
expect(targets[0]).toEqual('target1');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should parse Android SDK installed target information with `android` command if list_targets_with_avdmanager fails with not-recognized error (Windows)", function(done) {
|
||||
it('should parse Android SDK installed target information with `android` command if list_targets_with_avdmanager fails with not-recognized error (Windows)', function (done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, "list_targets_with_avdmanager").and.returnValue(deferred.promise);
|
||||
spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(deferred.promise);
|
||||
deferred.reject({
|
||||
code: 1,
|
||||
stderr: "'avdmanager' is not recognized as an internal or external commmand,\r\noperable program or batch file.\r\n"
|
||||
});
|
||||
var twoferred = Q.defer();
|
||||
twoferred.resolve(["target1"]);
|
||||
var avdmanager_spy = spyOn(android_sdk, "list_targets_with_android").and.returnValue(twoferred.promise);
|
||||
return android_sdk.list_targets()
|
||||
.then(function(targets) {
|
||||
twoferred.resolve(['target1']);
|
||||
var avdmanager_spy = spyOn(android_sdk, 'list_targets_with_android').and.returnValue(twoferred.promise);
|
||||
return android_sdk.list_targets().then(function (targets) {
|
||||
expect(avdmanager_spy).toHaveBeenCalled();
|
||||
expect(targets[0]).toEqual("target1");
|
||||
expect(targets[0]).toEqual('target1');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should throw an error if no Android targets were found.", function(done) {
|
||||
it('should throw an error if no Android targets were found.', function (done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, "list_targets_with_avdmanager").and.returnValue(deferred.promise);
|
||||
spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(deferred.promise);
|
||||
deferred.resolve([]);
|
||||
return android_sdk.list_targets()
|
||||
.then(function(targets) {
|
||||
return android_sdk.list_targets().then(function (targets) {
|
||||
done.fail();
|
||||
}).catch(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain("No android targets (SDKs) installed!");
|
||||
expect(err.message).toContain('No android targets (SDKs) installed!');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
var gradle_builder = require('../../../bin/templates/cordova/lib/builders/GradleBuilder.js');
|
||||
|
||||
var Gradle_builder = require('../../../bin/templates/cordova/lib/builders/GradleBuilder.js');
|
||||
var fs = require('fs');
|
||||
var superspawn = require('cordova-common').superspawn;
|
||||
var builder;
|
||||
@ -6,7 +7,7 @@ var builder;
|
||||
describe('Gradle Builder', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||
builder = new gradle_builder('/root');
|
||||
builder = new Gradle_builder('/root');
|
||||
spyOn(superspawn, 'spawn');
|
||||
});
|
||||
|
||||
|
@ -16,16 +16,15 @@
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
/* jshint laxcomma:true */
|
||||
|
||||
var check_reqs = require("../../bin/templates/cordova/lib/check_reqs");
|
||||
var android_sdk = require("../../bin/templates/cordova/lib/android_sdk");
|
||||
var shelljs = require("shelljs");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var Q = require("q");
|
||||
var check_reqs = require('../../bin/templates/cordova/lib/check_reqs');
|
||||
var android_sdk = require('../../bin/templates/cordova/lib/android_sdk');
|
||||
var shelljs = require('shelljs');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var Q = require('q');
|
||||
|
||||
describe("check_reqs", function () {
|
||||
describe('check_reqs', function () {
|
||||
var original_env;
|
||||
beforeAll(function () {
|
||||
original_env = Object.create(process.env);
|
||||
@ -35,23 +34,22 @@ describe("check_reqs", function () {
|
||||
process.env[k] = original_env[k];
|
||||
});
|
||||
});
|
||||
describe("check_android", function() {
|
||||
describe("set ANDROID_HOME if not set", function() {
|
||||
describe('check_android', function () {
|
||||
describe('set ANDROID_HOME if not set', function () {
|
||||
beforeEach(function () {
|
||||
delete process.env.ANDROID_HOME;
|
||||
});
|
||||
describe("even if no Android binaries are on the PATH", function() {
|
||||
describe('even if no Android binaries are on the PATH', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(shelljs, "which").and.returnValue(null);
|
||||
spyOn(fs, "existsSync").and.returnValue(true);
|
||||
spyOn(shelljs, 'which').and.returnValue(null);
|
||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||
});
|
||||
it("it should set ANDROID_HOME on Windows", function(done) {
|
||||
spyOn(check_reqs, "isWindows").and.returnValue(true);
|
||||
process.env.LOCALAPPDATA = "windows-local-app-data";
|
||||
process.env.ProgramFiles = "windows-program-files";
|
||||
return check_reqs.check_android()
|
||||
.then(function() {
|
||||
expect(process.env.ANDROID_HOME).toContain("windows-local-app-data");
|
||||
it('it should set ANDROID_HOME on Windows', function (done) {
|
||||
spyOn(check_reqs, 'isWindows').and.returnValue(true);
|
||||
process.env.LOCALAPPDATA = 'windows-local-app-data';
|
||||
process.env.ProgramFiles = 'windows-program-files';
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.ANDROID_HOME).toContain('windows-local-app-data');
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
@ -61,13 +59,12 @@ describe("check_reqs", function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("it should set ANDROID_HOME on Darwin", function(done) {
|
||||
spyOn(check_reqs, "isWindows").and.returnValue(false);
|
||||
spyOn(check_reqs, "isDarwin").and.returnValue(true);
|
||||
process.env.HOME = "home is where the heart is";
|
||||
return check_reqs.check_android()
|
||||
.then(function() {
|
||||
expect(process.env.ANDROID_HOME).toContain("home is where the heart is");
|
||||
it('it should set ANDROID_HOME on Darwin', function (done) {
|
||||
spyOn(check_reqs, 'isWindows').and.returnValue(false);
|
||||
spyOn(check_reqs, 'isDarwin').and.returnValue(true);
|
||||
process.env.HOME = 'home is where the heart is';
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.ANDROID_HOME).toContain('home is where the heart is');
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
@ -77,134 +74,127 @@ describe("check_reqs", function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("if some Android tooling exists on the PATH", function() {
|
||||
describe('if some Android tooling exists on the PATH', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(fs, "realpathSync").and.callFake(function(path) {
|
||||
spyOn(fs, 'realpathSync').and.callFake(function (path) {
|
||||
return path;
|
||||
});
|
||||
});
|
||||
it("should set ANDROID_HOME based on `android` command if command exists in a SDK-like directory structure", function(done) {
|
||||
spyOn(fs, "existsSync").and.returnValue(true);
|
||||
spyOn(shelljs, "which").and.callFake(function(cmd) {
|
||||
if (cmd == "android") {
|
||||
return "/android/sdk/tools/android";
|
||||
it('should set ANDROID_HOME based on `android` command if command exists in a SDK-like directory structure', function (done) {
|
||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'android') {
|
||||
return '/android/sdk/tools/android';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return check_reqs.check_android()
|
||||
.then(function() {
|
||||
expect(process.env.ANDROID_HOME).toEqual("/android/sdk");
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.ANDROID_HOME).toEqual('/android/sdk');
|
||||
done();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
it("should error out if `android` command exists in a non-SDK-like directory structure", function(done) {
|
||||
spyOn(shelljs, "which").and.callFake(function(cmd) {
|
||||
if (cmd == "android") {
|
||||
return "/just/some/random/path/android";
|
||||
it('should error out if `android` command exists in a non-SDK-like directory structure', function (done) {
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'android') {
|
||||
return '/just/some/random/path/android';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return check_reqs.check_android()
|
||||
.then(function() {
|
||||
return check_reqs.check_android().then(function () {
|
||||
done.fail();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain("update your PATH to include valid path");
|
||||
expect(err.message).toContain('update your PATH to include valid path');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should set ANDROID_HOME based on `adb` command if command exists in a SDK-like directory structure", function(done) {
|
||||
spyOn(fs, "existsSync").and.returnValue(true);
|
||||
spyOn(shelljs, "which").and.callFake(function(cmd) {
|
||||
if (cmd == "adb") {
|
||||
return "/android/sdk/platform-tools/adb";
|
||||
it('should set ANDROID_HOME based on `adb` command if command exists in a SDK-like directory structure', function (done) {
|
||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'adb') {
|
||||
return '/android/sdk/platform-tools/adb';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return check_reqs.check_android()
|
||||
.then(function() {
|
||||
expect(process.env.ANDROID_HOME).toEqual("/android/sdk");
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.ANDROID_HOME).toEqual('/android/sdk');
|
||||
done();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
it("should error out if `adb` command exists in a non-SDK-like directory structure", function(done) {
|
||||
spyOn(shelljs, "which").and.callFake(function(cmd) {
|
||||
if (cmd == "adb") {
|
||||
return "/just/some/random/path/adb";
|
||||
it('should error out if `adb` command exists in a non-SDK-like directory structure', function (done) {
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'adb') {
|
||||
return '/just/some/random/path/adb';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return check_reqs.check_android()
|
||||
.then(function() {
|
||||
return check_reqs.check_android().then(function () {
|
||||
done.fail();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain("update your PATH to include valid path");
|
||||
expect(err.message).toContain('update your PATH to include valid path');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should set ANDROID_HOME based on `avdmanager` command if command exists in a SDK-like directory structure", function(done) {
|
||||
spyOn(fs, "existsSync").and.returnValue(true);
|
||||
spyOn(shelljs, "which").and.callFake(function(cmd) {
|
||||
if (cmd == "avdmanager") {
|
||||
return "/android/sdk/tools/bin/avdmanager";
|
||||
it('should set ANDROID_HOME based on `avdmanager` command if command exists in a SDK-like directory structure', function (done) {
|
||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'avdmanager') {
|
||||
return '/android/sdk/tools/bin/avdmanager';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return check_reqs.check_android()
|
||||
.then(function() {
|
||||
expect(process.env.ANDROID_HOME).toEqual("/android/sdk");
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.ANDROID_HOME).toEqual('/android/sdk');
|
||||
done();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
it("should error out if `avdmanager` command exists in a non-SDK-like directory structure", function(done) {
|
||||
spyOn(shelljs, "which").and.callFake(function(cmd) {
|
||||
if (cmd == "avdmanager") {
|
||||
return "/just/some/random/path/avdmanager";
|
||||
it('should error out if `avdmanager` command exists in a non-SDK-like directory structure', function (done) {
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'avdmanager') {
|
||||
return '/just/some/random/path/avdmanager';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return check_reqs.check_android()
|
||||
.then(function() {
|
||||
return check_reqs.check_android().then(function () {
|
||||
done.fail();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain("update your PATH to include valid path");
|
||||
expect(err.message).toContain('update your PATH to include valid path');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("set PATH for various Android binaries if not available", function() {
|
||||
describe('set PATH for various Android binaries if not available', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(shelljs, "which").and.returnValue(null);
|
||||
process.env.ANDROID_HOME = "let the children play";
|
||||
spyOn(fs, "existsSync").and.returnValue(true);
|
||||
spyOn(shelljs, 'which').and.returnValue(null);
|
||||
process.env.ANDROID_HOME = 'let the children play';
|
||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||
});
|
||||
afterEach(function () {
|
||||
delete process.env.ANDROID_HOME;
|
||||
});
|
||||
it("should add tools/bin,tools,platform-tools to PATH if `avdmanager`,`android`,`adb` is not found", function(done) {
|
||||
return check_reqs.check_android()
|
||||
.then(function() {
|
||||
expect(process.env.PATH).toContain("let the children play" + path.sep + "tools");
|
||||
expect(process.env.PATH).toContain("let the children play" + path.sep + "platform-tools");
|
||||
expect(process.env.PATH).toContain("let the children play" + path.sep + "tools" + path.sep + "bin");
|
||||
it('should add tools/bin,tools,platform-tools to PATH if `avdmanager`,`android`,`adb` is not found', function (done) {
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.PATH).toContain('let the children play' + path.sep + 'tools');
|
||||
expect(process.env.PATH).toContain('let the children play' + path.sep + 'platform-tools');
|
||||
expect(process.env.PATH).toContain('let the children play' + path.sep + 'tools' + path.sep + 'bin');
|
||||
done();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
@ -213,37 +203,35 @@ describe("check_reqs", function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("get_target", function() {
|
||||
it("should retrieve target from framework project.properties file", function() {
|
||||
describe('get_target', function () {
|
||||
it('should retrieve target from framework project.properties file', function () {
|
||||
var target = check_reqs.get_target();
|
||||
expect(target).toBeDefined();
|
||||
expect(target).toContain("android-");
|
||||
expect(target).toContain('android-');
|
||||
});
|
||||
});
|
||||
describe("check_android_target", function() {
|
||||
it("should should return full list of supported targets if there is a match to ideal api level", function(done) {
|
||||
describe('check_android_target', function () {
|
||||
it('should should return full list of supported targets if there is a match to ideal api level', function (done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, "list_targets").and.returnValue(deferred.promise);
|
||||
var fake_targets = ["you are my fire", "my one desire"];
|
||||
spyOn(android_sdk, 'list_targets').and.returnValue(deferred.promise);
|
||||
var fake_targets = ['you are my fire', 'my one desire'];
|
||||
deferred.resolve(fake_targets);
|
||||
spyOn(check_reqs, "get_target").and.returnValue("you are my fire");
|
||||
return check_reqs.check_android_target()
|
||||
.then(function(targets) {
|
||||
spyOn(check_reqs, 'get_target').and.returnValue('you are my fire');
|
||||
return check_reqs.check_android_target().then(function (targets) {
|
||||
expect(targets).toBeDefined();
|
||||
expect(targets).toEqual(fake_targets);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should error out if there is no match between ideal api level and installed targets", function(done) {
|
||||
it('should error out if there is no match between ideal api level and installed targets', function (done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, "list_targets").and.returnValue(deferred.promise);
|
||||
var fake_targets = ["you are my fire", "my one desire"];
|
||||
spyOn(android_sdk, 'list_targets').and.returnValue(deferred.promise);
|
||||
var fake_targets = ['you are my fire', 'my one desire'];
|
||||
deferred.resolve(fake_targets);
|
||||
spyOn(check_reqs, "get_target").and.returnValue("and i knowwwwwwwwwwww");
|
||||
return check_reqs.check_android_target()
|
||||
.catch(function(err) {
|
||||
spyOn(check_reqs, 'get_target').and.returnValue('and i knowwwwwwwwwwww');
|
||||
return check_reqs.check_android_target().catch(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain("Please install Android target");
|
||||
expect(err.message).toContain('Please install Android target');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -16,39 +16,37 @@
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
/* jshint laxcomma:true */
|
||||
|
||||
var create = require("../../bin/lib/create");
|
||||
var create = require('../../bin/lib/create');
|
||||
|
||||
describe("create", function () {
|
||||
describe("validatePackageName", function() {
|
||||
describe('create', function () {
|
||||
describe('validatePackageName', function () {
|
||||
var valid = [
|
||||
"org.apache.mobilespec"
|
||||
, "com.example"
|
||||
, "com.floors42.package"
|
||||
, "ball8.ball8.ball8ball"
|
||||
'org.apache.mobilespec',
|
||||
'com.example',
|
||||
'com.floors42.package',
|
||||
'ball8.ball8.ball8ball'
|
||||
];
|
||||
var invalid = [
|
||||
""
|
||||
, "com.class.is.bad"
|
||||
, "0com.example.mobilespec"
|
||||
, "c-m.e@a!p%e.mobilespec"
|
||||
, "notenoughdots"
|
||||
, ".starts.with.a.dot"
|
||||
, "ends.with.a.dot."
|
||||
, "_underscore.anything"
|
||||
, "underscore._something"
|
||||
, "_underscore._all._the._things"
|
||||
, "8.ball"
|
||||
, "8ball.ball"
|
||||
, "ball8.8ball"
|
||||
, "ball8.com.8ball"
|
||||
'',
|
||||
'com.class.is.bad',
|
||||
'0com.example.mobilespec',
|
||||
'c-m.e@a!p%e.mobilespec',
|
||||
'notenoughdots',
|
||||
'.starts.with.a.dot',
|
||||
'ends.with.a.dot.',
|
||||
'_underscore.anything',
|
||||
'underscore._something',
|
||||
'_underscore._all._the._things',
|
||||
'8.ball',
|
||||
'8ball.ball',
|
||||
'ball8.8ball',
|
||||
'ball8.com.8ball'
|
||||
];
|
||||
|
||||
valid.forEach(function (package_name) {
|
||||
it("Test#001 : should accept " + package_name, function(done) {
|
||||
return create.validatePackageName(package_name)
|
||||
.then(function() {
|
||||
it('Test#001 : should accept ' + package_name, function (done) {
|
||||
return create.validatePackageName(package_name).then(function () {
|
||||
// resolved
|
||||
done();
|
||||
}).fail(function (err) {
|
||||
@ -58,9 +56,8 @@ describe("create", function () {
|
||||
});
|
||||
|
||||
invalid.forEach(function (package_name) {
|
||||
it("Test#002 : should reject " + package_name, function(done) {
|
||||
return create.validatePackageName(package_name)
|
||||
.then(function() {
|
||||
it('Test#002 : should reject ' + package_name, function (done) {
|
||||
return create.validatePackageName(package_name).then(function () {
|
||||
// shouldn't be here
|
||||
expect(true).toBe(false);
|
||||
}).fail(function (err) {
|
||||
@ -70,23 +67,22 @@ describe("create", function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("validateProjectName", function() {
|
||||
describe('validateProjectName', function () {
|
||||
var valid = [
|
||||
"mobilespec"
|
||||
, "package_name"
|
||||
, "PackageName"
|
||||
, "CordovaLib"
|
||||
'mobilespec',
|
||||
'package_name',
|
||||
'PackageName',
|
||||
'CordovaLib'
|
||||
];
|
||||
var invalid = [
|
||||
""
|
||||
, "0startswithdigit"
|
||||
, "CordovaActivity"
|
||||
'',
|
||||
'0startswithdigit',
|
||||
'CordovaActivity'
|
||||
];
|
||||
|
||||
valid.forEach(function (project_name) {
|
||||
it("Test#003 : should accept " + project_name, function(done) {
|
||||
return create.validateProjectName(project_name)
|
||||
.then(function() {
|
||||
it('Test#003 : should accept ' + project_name, function (done) {
|
||||
return create.validateProjectName(project_name).then(function () {
|
||||
// resolved
|
||||
done();
|
||||
}).fail(function (err) {
|
||||
@ -96,9 +92,8 @@ describe("create", function () {
|
||||
});
|
||||
|
||||
invalid.forEach(function (project_name) {
|
||||
it("Test#004 : should reject " + project_name, function(done) {
|
||||
return create.validateProjectName(project_name)
|
||||
.then(function() {
|
||||
it('Test#004 : should reject ' + project_name, function (done) {
|
||||
return create.validateProjectName(project_name).then(function () {
|
||||
// shouldn't be here
|
||||
expect(true).toBe(false);
|
||||
}).fail(function (err) {
|
||||
@ -109,4 +104,3 @@ describe("create", function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -16,26 +16,26 @@
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
var emu = require("../../bin/templates/cordova/lib/emulator");
|
||||
var superspawn = require("cordova-common").superspawn;
|
||||
var Q = require("q");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var shelljs = require("shelljs");
|
||||
|
||||
describe("emulator", function () {
|
||||
describe("list_images_using_avdmanager", function() {
|
||||
it("should properly parse details of SDK Tools 25.3.1 `avdmanager` output", function(done) {
|
||||
var emu = require('../../bin/templates/cordova/lib/emulator');
|
||||
var superspawn = require('cordova-common').superspawn;
|
||||
var Q = require('q');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var shelljs = require('shelljs');
|
||||
|
||||
describe('emulator', function () {
|
||||
describe('list_images_using_avdmanager', function () {
|
||||
it('should properly parse details of SDK Tools 25.3.1 `avdmanager` output', function (done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
||||
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "sdk25.3-avdmanager_list_avd.txt"), "utf-8"));
|
||||
return emu.list_images_using_avdmanager()
|
||||
.then(function(list) {
|
||||
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
|
||||
deferred.resolve(fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.3-avdmanager_list_avd.txt'), 'utf-8'));
|
||||
return emu.list_images_using_avdmanager().then(function (list) {
|
||||
expect(list).toBeDefined();
|
||||
expect(list[0].name).toEqual("nexus5-5.1");
|
||||
expect(list[0].target).toEqual("Android 5.1 (API level 22)");
|
||||
expect(list[1].device).toEqual("pixel (Google)");
|
||||
expect(list[2].abi).toEqual("default/x86_64");
|
||||
expect(list[0].name).toEqual('nexus5-5.1');
|
||||
expect(list[0].target).toEqual('Android 5.1 (API level 22)');
|
||||
expect(list[1].device).toEqual('pixel (Google)');
|
||||
expect(list[2].abi).toEqual('default/x86_64');
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
}).fin(function () {
|
||||
@ -43,26 +43,25 @@ describe("emulator", function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("list_images_using_android", function() {
|
||||
it("should invoke `android` with the `list avd` command and _not_ the `list avds` command, as the plural form is not supported in some Android SDK Tools versions", function() {
|
||||
describe('list_images_using_android', function () {
|
||||
it('should invoke `android` with the `list avd` command and _not_ the `list avds` command, as the plural form is not supported in some Android SDK Tools versions', function () {
|
||||
var deferred = Q.defer();
|
||||
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
||||
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
|
||||
emu.list_images_using_android();
|
||||
expect(superspawn.spawn).toHaveBeenCalledWith("android", ["list", "avd"]);
|
||||
expect(superspawn.spawn).toHaveBeenCalledWith('android', ['list', 'avd']);
|
||||
});
|
||||
it("should properly parse details of SDK Tools pre-25.3.1 `android list avd` output", function(done) {
|
||||
it('should properly parse details of SDK Tools pre-25.3.1 `android list avd` output', function (done) {
|
||||
var deferred = Q.defer();
|
||||
spyOn(superspawn, "spawn").and.returnValue(deferred.promise);
|
||||
deferred.resolve(fs.readFileSync(path.join("spec", "fixtures", "sdk25.2-android_list_avd.txt"), "utf-8"));
|
||||
return emu.list_images_using_android()
|
||||
.then(function(list) {
|
||||
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
|
||||
deferred.resolve(fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.2-android_list_avd.txt'), 'utf-8'));
|
||||
return emu.list_images_using_android().then(function (list) {
|
||||
expect(list).toBeDefined();
|
||||
expect(list[0].name).toEqual("QWR");
|
||||
expect(list[0].device).toEqual("Nexus 5 (Google)");
|
||||
expect(list[0].path).toEqual("/Users/shazron/.android/avd/QWR.avd");
|
||||
expect(list[0].target).toEqual("Android 7.1.1 (API level 25)");
|
||||
expect(list[0].abi).toEqual("google_apis/x86_64");
|
||||
expect(list[0].skin).toEqual("1080x1920");
|
||||
expect(list[0].name).toEqual('QWR');
|
||||
expect(list[0].device).toEqual('Nexus 5 (Google)');
|
||||
expect(list[0].path).toEqual('/Users/shazron/.android/avd/QWR.avd');
|
||||
expect(list[0].target).toEqual('Android 7.1.1 (API level 25)');
|
||||
expect(list[0].abi).toEqual('google_apis/x86_64');
|
||||
expect(list[0].skin).toEqual('1080x1920');
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
}).fin(function () {
|
||||
@ -70,42 +69,41 @@ describe("emulator", function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("list_images", function() {
|
||||
describe('list_images', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(fs, "realpathSync").and.callFake(function(cmd) {
|
||||
spyOn(fs, 'realpathSync').and.callFake(function (cmd) {
|
||||
return cmd;
|
||||
});
|
||||
});
|
||||
it("should try to parse AVD information using `avdmanager` first", function() {
|
||||
spyOn(shelljs, "which").and.callFake(function(cmd) {
|
||||
if (cmd == "avdmanager") {
|
||||
it('should try to parse AVD information using `avdmanager` first', function () {
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'avdmanager') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
var avdmanager_spy = spyOn(emu, "list_images_using_avdmanager").and.returnValue({catch:function(){}});
|
||||
var avdmanager_spy = spyOn(emu, 'list_images_using_avdmanager').and.returnValue({catch: function () {}});
|
||||
emu.list_images();
|
||||
expect(avdmanager_spy).toHaveBeenCalled();
|
||||
});
|
||||
it("should delegate to `android` if `avdmanager` cant be found and `android` can", function() {
|
||||
spyOn(shelljs, "which").and.callFake(function(cmd) {
|
||||
if (cmd == "avdmanager") {
|
||||
it('should delegate to `android` if `avdmanager` cant be found and `android` can', function () {
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'avdmanager') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
var android_spy = spyOn(emu, "list_images_using_android");
|
||||
var android_spy = spyOn(emu, 'list_images_using_android');
|
||||
emu.list_images();
|
||||
expect(android_spy).toHaveBeenCalled();
|
||||
});
|
||||
it("should throw an error if neither `avdmanager` nor `android` are able to be found", function(done) {
|
||||
spyOn(shelljs, "which").and.returnValue(false);
|
||||
return emu.list_images()
|
||||
.catch(function(err) {
|
||||
it('should throw an error if neither `avdmanager` nor `android` are able to be found', function (done) {
|
||||
spyOn(shelljs, 'which').and.returnValue(false);
|
||||
return emu.list_images().catch(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain("Could not find either `android` or `avdmanager`");
|
||||
expect(err.message).toContain('Could not find either `android` or `avdmanager`');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -48,8 +48,8 @@ describe('common platform handler', function() {
|
||||
shell.mkdir('-p', project_dir);
|
||||
fs.writeFileSync(non_plugin_file, 'contents', 'utf-8');
|
||||
var outside_file = '../non_plugin_file';
|
||||
expect(function(){copyFile(test_dir, outside_file, project_dir, dest);}).
|
||||
toThrow(new Error('File "' + path.resolve(test_dir, outside_file) + '" is located outside the plugin directory "' + test_dir + '"'));
|
||||
expect(function () { copyFile(test_dir, outside_file, project_dir, dest); })
|
||||
.toThrow(new Error('File "' + path.resolve(test_dir, outside_file) + '" is located outside the plugin directory "' + test_dir + '"'));
|
||||
shell.rm('-rf', test_dir);
|
||||
});
|
||||
|
||||
@ -75,16 +75,16 @@ describe('common platform handler', function() {
|
||||
return;
|
||||
}
|
||||
|
||||
expect(function(){copyFile(test_dir, symlink_file, project_dir, dest);}).
|
||||
toThrow(new Error('File "' + path.resolve(test_dir, symlink_file) + '" is located outside the plugin directory "' + test_dir + '"'));
|
||||
expect(function () { copyFile(test_dir, symlink_file, project_dir, dest); })
|
||||
.toThrow(new Error('File "' + path.resolve(test_dir, symlink_file) + '" is located outside the plugin directory "' + test_dir + '"'));
|
||||
shell.rm('-rf', project_dir);
|
||||
});
|
||||
|
||||
it('Test#005 : should throw if dest is outside the project directory', function () {
|
||||
shell.mkdir('-p', java_dir);
|
||||
fs.writeFileSync(java_file, 'contents', 'utf-8');
|
||||
expect(function(){copyFile(test_dir, java_file, project_dir, non_plugin_file);}).
|
||||
toThrow(new Error('Destination "' + path.resolve(project_dir, non_plugin_file) + '" for source file "' + path.resolve(test_dir, java_file) + '" is located outside the project'));
|
||||
expect(function () { copyFile(test_dir, java_file, project_dir, non_plugin_file); })
|
||||
.toThrow(new Error('Destination "' + path.resolve(project_dir, non_plugin_file) + '" for source file "' + path.resolve(test_dir, java_file) + '" is located outside the project'));
|
||||
shell.rm('-rf', project_dir);
|
||||
});
|
||||
|
||||
@ -121,8 +121,8 @@ describe('common platform handler', function() {
|
||||
describe('copyNewFile', function () {
|
||||
it('Test#008 : should throw if target path exists', function () {
|
||||
shell.mkdir('-p', dest);
|
||||
expect(function(){copyNewFile(test_dir, src, project_dir, dest);}).
|
||||
toThrow(new Error('"' + dest + '" already exists!'));
|
||||
expect(function () { copyNewFile(test_dir, src, project_dir, dest); })
|
||||
.toThrow(new Error('"' + dest + '" already exists!'));
|
||||
shell.rm('-rf', dest);
|
||||
});
|
||||
});
|
||||
|
@ -34,9 +34,9 @@ var PluginInfo = require('cordova-common').PluginInfo;
|
||||
var AndroidProject = require('../../../bin/templates/cordova/lib/AndroidProject');
|
||||
|
||||
var dummyPluginInfo = new PluginInfo(dummyplugin);
|
||||
var valid_source = dummyPluginInfo.getSourceFiles('android'),
|
||||
valid_resources = dummyPluginInfo.getResourceFiles('android'),
|
||||
valid_libs = dummyPluginInfo.getLibFiles('android');
|
||||
var valid_source = dummyPluginInfo.getSourceFiles('android');
|
||||
var valid_resources = dummyPluginInfo.getResourceFiles('android');
|
||||
var valid_libs = dummyPluginInfo.getLibFiles('android');
|
||||
|
||||
var faultyPluginInfo = new PluginInfo(faultyplugin);
|
||||
var invalid_source = faultyPluginInfo.getSourceFiles('android');
|
||||
@ -198,7 +198,8 @@ describe('android project handler', function() {
|
||||
|
||||
describe('of <asset> elements', function () {
|
||||
var asset = {src: 'www/dummyPlugin.js', target: 'foo/dummy.js'};
|
||||
var wwwDest, platformWwwDest;
|
||||
var wwwDest; /* eslint no-unused-vars: "off" */
|
||||
var platformWwwDest; /* eslint no-unused-vars: "off" */
|
||||
|
||||
beforeEach(function () {
|
||||
wwwDest = path.resolve(dummyProject.www, asset.target);
|
||||
@ -321,10 +322,10 @@ describe('android project handler', function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('of <js-module> elements', function () {
|
||||
var jsModule = {src: 'www/dummyPlugin.js'};
|
||||
var wwwDest, platformWwwDest;
|
||||
var wwwDest;
|
||||
var platformWwwDest;
|
||||
|
||||
beforeEach(function () {
|
||||
wwwDest = path.resolve(dummyProject.www, 'plugins', dummyPluginInfo.id, jsModule.src);
|
||||
|
@ -17,21 +17,21 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var rewire = require("rewire");
|
||||
var run = rewire("../../bin/templates/cordova/lib/run");
|
||||
var getInstallTarget = run.__get__("getInstallTarget");
|
||||
var rewire = require('rewire');
|
||||
var run = rewire('../../bin/templates/cordova/lib/run');
|
||||
var getInstallTarget = run.__get__('getInstallTarget');
|
||||
|
||||
describe("run", function () {
|
||||
describe("getInstallTarget", function() {
|
||||
var targetOpts = { target: "emu" };
|
||||
describe('run', function () {
|
||||
describe('getInstallTarget', function () {
|
||||
var targetOpts = { target: 'emu' };
|
||||
var deviceOpts = { device: true };
|
||||
var emulatorOpts = { emulator: true };
|
||||
var emptyOpts = {};
|
||||
|
||||
it("Test#001 : should select correct target based on the run opts", function() {
|
||||
expect(getInstallTarget(targetOpts)).toBe("emu");
|
||||
expect(getInstallTarget(deviceOpts)).toBe("--device");
|
||||
expect(getInstallTarget(emulatorOpts)).toBe("--emulator");
|
||||
it('Test#001 : should select correct target based on the run opts', function () {
|
||||
expect(getInstallTarget(targetOpts)).toBe('emu');
|
||||
expect(getInstallTarget(deviceOpts)).toBe('--device');
|
||||
expect(getInstallTarget(emulatorOpts)).toBe('--emulator');
|
||||
expect(getInstallTarget(emptyOpts)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user