forked from github/cordova-android
refactor: use es6 class (#911)
Refactored to Classes: * Api * AndroidManifest * AndroidProject
This commit is contained in:
parent
de105e8651
commit
c56cd4d5a8
595
bin/templates/cordova/Api.js
vendored
595
bin/templates/cordova/Api.js
vendored
@ -51,317 +51,320 @@ function setupEvents (externalEventEmitter) {
|
|||||||
* The PlatformApi instance also should define the following field:
|
* The PlatformApi instance also should define the following field:
|
||||||
*
|
*
|
||||||
* * platform: String that defines a platform name.
|
* * platform: String that defines a platform name.
|
||||||
|
* @class Api
|
||||||
*/
|
*/
|
||||||
function Api (platform, platformRootDir, events) {
|
class Api {
|
||||||
this.platform = PLATFORM;
|
constructor (platform, platformRootDir, events) {
|
||||||
this.root = path.resolve(__dirname, '..');
|
this.platform = PLATFORM;
|
||||||
|
this.root = path.resolve(__dirname, '..');
|
||||||
|
|
||||||
setupEvents(events);
|
setupEvents(events);
|
||||||
|
|
||||||
const appMain = path.join(this.root, 'app', 'src', 'main');
|
const appMain = path.join(this.root, 'app', 'src', 'main');
|
||||||
const appRes = path.join(appMain, 'res');
|
const appRes = path.join(appMain, 'res');
|
||||||
|
|
||||||
this.locations = {
|
this.locations = {
|
||||||
root: this.root,
|
root: this.root,
|
||||||
www: path.join(appMain, 'assets', 'www'),
|
www: path.join(appMain, 'assets', 'www'),
|
||||||
res: appRes,
|
res: appRes,
|
||||||
platformWww: path.join(this.root, 'platform_www'),
|
platformWww: path.join(this.root, 'platform_www'),
|
||||||
configXml: path.join(appRes, 'xml', 'config.xml'),
|
configXml: path.join(appRes, 'xml', 'config.xml'),
|
||||||
defaultConfigXml: path.join(this.root, 'cordova', 'defaults.xml'),
|
defaultConfigXml: path.join(this.root, 'cordova', 'defaults.xml'),
|
||||||
strings: path.join(appRes, 'values', 'strings.xml'),
|
strings: path.join(appRes, 'values', 'strings.xml'),
|
||||||
manifest: path.join(appMain, 'AndroidManifest.xml'),
|
manifest: path.join(appMain, 'AndroidManifest.xml'),
|
||||||
build: path.join(this.root, 'build'),
|
build: path.join(this.root, 'build'),
|
||||||
javaSrc: path.join(appMain, 'java')
|
javaSrc: path.join(appMain, 'java')
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Installs platform to specified directory and creates a platform project.
|
|
||||||
*
|
|
||||||
* @param {String} destination Destination directory, where insatll platform to
|
|
||||||
* @param {ConfigParser} [config] ConfgiParser instance, used to retrieve
|
|
||||||
* project creation options, such as package id and project name.
|
|
||||||
* @param {Object} [options] An options object. The most common options are:
|
|
||||||
* @param {String} [options.customTemplate] A path to custom template, that
|
|
||||||
* should override the default one from platform.
|
|
||||||
* @param {Boolean} [options.link] Flag that indicates that platform's
|
|
||||||
* sources will be linked to installed platform instead of copying.
|
|
||||||
* @param {EventEmitter} [events] An EventEmitter instance that will be used for
|
|
||||||
* logging purposes. If no EventEmitter provided, all events will be logged to
|
|
||||||
* console
|
|
||||||
*
|
|
||||||
* @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
|
|
||||||
* instance or rejected with CordovaError.
|
|
||||||
*/
|
|
||||||
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) {
|
|
||||||
return new Api(PLATFORM, destination, events);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
events.emit('error', 'createPlatform is not callable from the android project API.');
|
|
||||||
throw (e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates already installed platform.
|
|
||||||
*
|
|
||||||
* @param {String} destination Destination directory, where platform installed
|
|
||||||
* @param {Object} [options] An options object. The most common options are:
|
|
||||||
* @param {String} [options.customTemplate] A path to custom template, that
|
|
||||||
* should override the default one from platform.
|
|
||||||
* @param {Boolean} [options.link] Flag that indicates that platform's
|
|
||||||
* sources will be linked to installed platform instead of copying.
|
|
||||||
* @param {EventEmitter} [events] An EventEmitter instance that will be used for
|
|
||||||
* logging purposes. If no EventEmitter provided, all events will be logged to
|
|
||||||
* console
|
|
||||||
*
|
|
||||||
* @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
|
|
||||||
* instance or rejected with CordovaError.
|
|
||||||
*/
|
|
||||||
Api.updatePlatform = function (destination, options, events) {
|
|
||||||
events = setupEvents(events);
|
|
||||||
var result;
|
|
||||||
try {
|
|
||||||
result = require('../../lib/create').update(destination, options, events).then(function (destination) {
|
|
||||||
return new Api(PLATFORM, destination, events);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
events.emit('error', 'updatePlatform is not callable from the android project API, you will need to do this manually.');
|
|
||||||
throw (e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a CordovaPlatform object, that represents the platform structure.
|
|
||||||
*
|
|
||||||
* @return {CordovaPlatform} A structure that contains the description of
|
|
||||||
* platform's file structure and other properties of platform.
|
|
||||||
*/
|
|
||||||
Api.prototype.getPlatformInfo = function () {
|
|
||||||
var result = {};
|
|
||||||
result.locations = this.locations;
|
|
||||||
result.root = this.root;
|
|
||||||
result.name = this.platform;
|
|
||||||
result.version = require('./version');
|
|
||||||
result.projectConfig = this._config;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates installed platform with provided www assets and new app
|
|
||||||
* configuration. This method is required for CLI workflow and will be called
|
|
||||||
* each time before build, so the changes, made to app configuration and www
|
|
||||||
* code, will be applied to platform.
|
|
||||||
*
|
|
||||||
* @param {CordovaProject} cordovaProject A CordovaProject instance, that defines a
|
|
||||||
* project structure and configuration, that should be applied to platform
|
|
||||||
* (contains project's www location and ConfigParser instance for project's
|
|
||||||
* config).
|
|
||||||
*
|
|
||||||
* @return {Promise} Return a promise either fulfilled, or rejected with
|
|
||||||
* CordovaError instance.
|
|
||||||
*/
|
|
||||||
Api.prototype.prepare = function (cordovaProject, prepareOptions) {
|
|
||||||
cordovaProject.projectConfig = new ConfigParser(cordovaProject.locations.rootConfigXml || cordovaProject.projectConfig.path);
|
|
||||||
|
|
||||||
return require('./lib/prepare').prepare.call(this, cordovaProject, prepareOptions);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Installs a new plugin into platform. This method only copies non-www files
|
|
||||||
* (sources, libs, etc.) to platform. It also doesn't resolves the
|
|
||||||
* dependencies of plugin. Both of handling of www files, such as assets and
|
|
||||||
* js-files and resolving dependencies are the responsibility of caller.
|
|
||||||
*
|
|
||||||
* @param {PluginInfo} plugin A PluginInfo instance that represents plugin
|
|
||||||
* that will be installed.
|
|
||||||
* @param {Object} installOptions An options object. Possible options below:
|
|
||||||
* @param {Boolean} installOptions.link: Flag that specifies that plugin
|
|
||||||
* sources will be symlinked to app's directory instead of copying (if
|
|
||||||
* possible).
|
|
||||||
* @param {Object} installOptions.variables An object that represents
|
|
||||||
* variables that will be used to install plugin. See more details on plugin
|
|
||||||
* variables in documentation:
|
|
||||||
* https://cordova.apache.org/docs/en/4.0.0/plugin_ref_spec.md.html
|
|
||||||
*
|
|
||||||
* @return {Promise} Return a promise either fulfilled, or rejected with
|
|
||||||
* CordovaError instance.
|
|
||||||
*/
|
|
||||||
Api.prototype.addPlugin = function (plugin, installOptions) {
|
|
||||||
var project = AndroidProject.getProjectFile(this.root);
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
installOptions = installOptions || {};
|
|
||||||
installOptions.variables = installOptions.variables || {};
|
|
||||||
// Add PACKAGE_NAME variable into vars
|
|
||||||
if (!installOptions.variables.PACKAGE_NAME) {
|
|
||||||
installOptions.variables.PACKAGE_NAME = project.getPackageName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.resolve().then(function () {
|
/**
|
||||||
return PluginManager.get(self.platform, self.locations, project).addPlugin(plugin, installOptions);
|
* Gets a CordovaPlatform object, that represents the platform structure.
|
||||||
}).then(function () {
|
*
|
||||||
if (plugin.getFrameworks(this.platform).length === 0) return;
|
* @return {CordovaPlatform} A structure that contains the description of
|
||||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
* platform's file structure and other properties of platform.
|
||||||
// This should pick the correct builder, not just get gradle
|
*/
|
||||||
require('./lib/builders/builders').getBuilder().prepBuildFiles();
|
getPlatformInfo () {
|
||||||
}.bind(this))
|
var result = {};
|
||||||
// CB-11022 Return truthy value to prevent running prepare after
|
result.locations = this.locations;
|
||||||
.then(() => true);
|
result.root = this.root;
|
||||||
};
|
result.name = this.platform;
|
||||||
|
result.version = require('./version');
|
||||||
|
result.projectConfig = this._config;
|
||||||
|
|
||||||
/**
|
return result;
|
||||||
* Removes an installed plugin from platform.
|
|
||||||
*
|
|
||||||
* Since method accepts PluginInfo instance as input parameter instead of plugin
|
|
||||||
* id, caller shoud take care of managing/storing PluginInfo instances for
|
|
||||||
* future uninstalls.
|
|
||||||
*
|
|
||||||
* @param {PluginInfo} plugin A PluginInfo instance that represents plugin
|
|
||||||
* that will be installed.
|
|
||||||
*
|
|
||||||
* @return {Promise} Return a promise either fulfilled, or rejected with
|
|
||||||
* CordovaError instance.
|
|
||||||
*/
|
|
||||||
Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
|
||||||
var project = AndroidProject.getProjectFile(this.root);
|
|
||||||
|
|
||||||
if (uninstallOptions && uninstallOptions.usePlatformWww === true) {
|
|
||||||
uninstallOptions.usePlatformWww = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PluginManager.get(this.platform, this.locations, project)
|
/**
|
||||||
.removePlugin(plugin, uninstallOptions)
|
* Updates installed platform with provided www assets and new app
|
||||||
.then(function () {
|
* configuration. This method is required for CLI workflow and will be called
|
||||||
|
* each time before build, so the changes, made to app configuration and www
|
||||||
|
* code, will be applied to platform.
|
||||||
|
*
|
||||||
|
* @param {CordovaProject} cordovaProject A CordovaProject instance, that defines a
|
||||||
|
* project structure and configuration, that should be applied to platform
|
||||||
|
* (contains project's www location and ConfigParser instance for project's
|
||||||
|
* config).
|
||||||
|
*
|
||||||
|
* @return {Promise} Return a promise either fulfilled, or rejected with
|
||||||
|
* CordovaError instance.
|
||||||
|
*/
|
||||||
|
prepare (cordovaProject, prepareOptions) {
|
||||||
|
cordovaProject.projectConfig = new ConfigParser(cordovaProject.locations.rootConfigXml || cordovaProject.projectConfig.path);
|
||||||
|
|
||||||
|
return require('./lib/prepare').prepare.call(this, cordovaProject, prepareOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installs a new plugin into platform. This method only copies non-www files
|
||||||
|
* (sources, libs, etc.) to platform. It also doesn't resolves the
|
||||||
|
* dependencies of plugin. Both of handling of www files, such as assets and
|
||||||
|
* js-files and resolving dependencies are the responsibility of caller.
|
||||||
|
*
|
||||||
|
* @param {PluginInfo} plugin A PluginInfo instance that represents plugin
|
||||||
|
* that will be installed.
|
||||||
|
* @param {Object} installOptions An options object. Possible options below:
|
||||||
|
* @param {Boolean} installOptions.link: Flag that specifies that plugin
|
||||||
|
* sources will be symlinked to app's directory instead of copying (if
|
||||||
|
* possible).
|
||||||
|
* @param {Object} installOptions.variables An object that represents
|
||||||
|
* variables that will be used to install plugin. See more details on plugin
|
||||||
|
* variables in documentation:
|
||||||
|
* https://cordova.apache.org/docs/en/4.0.0/plugin_ref_spec.md.html
|
||||||
|
*
|
||||||
|
* @return {Promise} Return a promise either fulfilled, or rejected with
|
||||||
|
* CordovaError instance.
|
||||||
|
*/
|
||||||
|
addPlugin (plugin, installOptions) {
|
||||||
|
var project = AndroidProject.getProjectFile(this.root);
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
installOptions = installOptions || {};
|
||||||
|
installOptions.variables = installOptions.variables || {};
|
||||||
|
// Add PACKAGE_NAME variable into vars
|
||||||
|
if (!installOptions.variables.PACKAGE_NAME) {
|
||||||
|
installOptions.variables.PACKAGE_NAME = project.getPackageName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve().then(function () {
|
||||||
|
return PluginManager.get(self.platform, self.locations, project).addPlugin(plugin, installOptions);
|
||||||
|
}).then(function () {
|
||||||
if (plugin.getFrameworks(this.platform).length === 0) return;
|
if (plugin.getFrameworks(this.platform).length === 0) return;
|
||||||
|
|
||||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
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().prepBuildFiles();
|
require('./lib/builders/builders').getBuilder().prepBuildFiles();
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
// CB-11022 Return truthy value to prevent running prepare after
|
// CB-11022 Return truthy value to prevent running prepare after
|
||||||
.then(() => true);
|
.then(() => true);
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds an application package for current platform.
|
|
||||||
*
|
|
||||||
* @param {Object} buildOptions A build options. This object's structure is
|
|
||||||
* highly depends on platform's specific. The most common options are:
|
|
||||||
* @param {Boolean} buildOptions.debug Indicates that packages should be
|
|
||||||
* built with debug configuration. This is set to true by default unless the
|
|
||||||
* 'release' option is not specified.
|
|
||||||
* @param {Boolean} buildOptions.release Indicates that packages should be
|
|
||||||
* built with release configuration. If not set to true, debug configuration
|
|
||||||
* will be used.
|
|
||||||
* @param {Boolean} buildOptions.device Specifies that built app is intended
|
|
||||||
* to run on device
|
|
||||||
* @param {Boolean} buildOptions.emulator: Specifies that built app is
|
|
||||||
* intended to run on emulator
|
|
||||||
* @param {String} buildOptions.target Specifies the device id that will be
|
|
||||||
* used to run built application.
|
|
||||||
* @param {Boolean} buildOptions.nobuild Indicates that this should be a
|
|
||||||
* dry-run call, so no build artifacts will be produced.
|
|
||||||
* @param {String[]} buildOptions.archs Specifies chip architectures which
|
|
||||||
* app packages should be built for. List of valid architectures is depends on
|
|
||||||
* platform.
|
|
||||||
* @param {String} buildOptions.buildConfig The path to build configuration
|
|
||||||
* file. The format of this file is depends on platform.
|
|
||||||
* @param {String[]} buildOptions.argv Raw array of command-line arguments,
|
|
||||||
* passed to `build` command. The purpose of this property is to pass a
|
|
||||||
* platform-specific arguments, and eventually let platform define own
|
|
||||||
* arguments processing logic.
|
|
||||||
*
|
|
||||||
* @return {Promise<Object[]>} A promise either fulfilled with an array of build
|
|
||||||
* artifacts (application packages) if package was built successfully,
|
|
||||||
* or rejected with CordovaError. The resultant build artifact objects is not
|
|
||||||
* strictly typed and may conatin arbitrary set of fields as in sample below.
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* architecture: 'x86',
|
|
||||||
* buildType: 'debug',
|
|
||||||
* path: '/path/to/build',
|
|
||||||
* type: 'app'
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* The return value in most cases will contain only one item but in some cases
|
|
||||||
* there could be multiple items in output array, e.g. when multiple
|
|
||||||
* arhcitectures is specified.
|
|
||||||
*/
|
|
||||||
Api.prototype.build = function (buildOptions) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
return require('./lib/check_reqs').run().then(function () {
|
|
||||||
return require('./lib/build').run.call(self, buildOptions);
|
|
||||||
}).then(function (buildResults) {
|
|
||||||
// Cast build result to array of build artifacts
|
|
||||||
return buildResults.paths.map(function (apkPath) {
|
|
||||||
return {
|
|
||||||
buildType: buildResults.buildType,
|
|
||||||
buildMethod: buildResults.buildMethod,
|
|
||||||
path: apkPath,
|
|
||||||
type: path.extname(apkPath).replace(/\./g, '')
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds an application package for current platform and runs it on
|
|
||||||
* specified/default device. If no 'device'/'emulator'/'target' options are
|
|
||||||
* specified, then tries to run app on default device if connected, otherwise
|
|
||||||
* runs the app on emulator.
|
|
||||||
*
|
|
||||||
* @param {Object} runOptions An options object. The structure is the same
|
|
||||||
* as for build options.
|
|
||||||
*
|
|
||||||
* @return {Promise} A promise either fulfilled if package was built and ran
|
|
||||||
* successfully, or rejected with CordovaError.
|
|
||||||
*/
|
|
||||||
Api.prototype.run = function (runOptions) {
|
|
||||||
var self = this;
|
|
||||||
return require('./lib/check_reqs').run().then(function () {
|
|
||||||
return require('./lib/run').run.call(self, runOptions);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleans out the build artifacts from platform's directory, and also
|
|
||||||
* cleans out the platform www directory if called without options specified.
|
|
||||||
*
|
|
||||||
* @return {Promise} Return a promise either fulfilled, or rejected with
|
|
||||||
* CordovaError.
|
|
||||||
*/
|
|
||||||
Api.prototype.clean = function (cleanOptions) {
|
|
||||||
var self = this;
|
|
||||||
// This will lint, checking for null won't
|
|
||||||
if (typeof cleanOptions === 'undefined') {
|
|
||||||
cleanOptions = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return require('./lib/check_reqs').run().then(function () {
|
/**
|
||||||
return require('./lib/build').runClean.call(self, cleanOptions);
|
* Removes an installed plugin from platform.
|
||||||
}).then(function () {
|
*
|
||||||
return require('./lib/prepare').clean.call(self, cleanOptions);
|
* Since method accepts PluginInfo instance as input parameter instead of plugin
|
||||||
});
|
* id, caller shoud take care of managing/storing PluginInfo instances for
|
||||||
};
|
* future uninstalls.
|
||||||
|
*
|
||||||
|
* @param {PluginInfo} plugin A PluginInfo instance that represents plugin
|
||||||
|
* that will be installed.
|
||||||
|
*
|
||||||
|
* @return {Promise} Return a promise either fulfilled, or rejected with
|
||||||
|
* CordovaError instance.
|
||||||
|
*/
|
||||||
|
removePlugin (plugin, uninstallOptions) {
|
||||||
|
var project = AndroidProject.getProjectFile(this.root);
|
||||||
|
|
||||||
/**
|
if (uninstallOptions && uninstallOptions.usePlatformWww === true) {
|
||||||
* Performs a requirements check for current platform. Each platform defines its
|
uninstallOptions.usePlatformWww = false;
|
||||||
* own set of requirements, which should be resolved before platform can be
|
}
|
||||||
* built successfully.
|
|
||||||
*
|
return PluginManager.get(this.platform, this.locations, project)
|
||||||
* @return {Promise<Requirement[]>} Promise, resolved with set of Requirement
|
.removePlugin(plugin, uninstallOptions)
|
||||||
* objects for current platform.
|
.then(function () {
|
||||||
*/
|
if (plugin.getFrameworks(this.platform).length === 0) return;
|
||||||
Api.prototype.requirements = function () {
|
|
||||||
return require('./lib/check_reqs').check_all();
|
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||||
};
|
require('./lib/builders/builders').getBuilder().prepBuildFiles();
|
||||||
|
}.bind(this))
|
||||||
|
// CB-11022 Return truthy value to prevent running prepare after
|
||||||
|
.then(() => true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds an application package for current platform.
|
||||||
|
*
|
||||||
|
* @param {Object} buildOptions A build options. This object's structure is
|
||||||
|
* highly depends on platform's specific. The most common options are:
|
||||||
|
* @param {Boolean} buildOptions.debug Indicates that packages should be
|
||||||
|
* built with debug configuration. This is set to true by default unless the
|
||||||
|
* 'release' option is not specified.
|
||||||
|
* @param {Boolean} buildOptions.release Indicates that packages should be
|
||||||
|
* built with release configuration. If not set to true, debug configuration
|
||||||
|
* will be used.
|
||||||
|
* @param {Boolean} buildOptions.device Specifies that built app is intended
|
||||||
|
* to run on device
|
||||||
|
* @param {Boolean} buildOptions.emulator: Specifies that built app is
|
||||||
|
* intended to run on emulator
|
||||||
|
* @param {String} buildOptions.target Specifies the device id that will be
|
||||||
|
* used to run built application.
|
||||||
|
* @param {Boolean} buildOptions.nobuild Indicates that this should be a
|
||||||
|
* dry-run call, so no build artifacts will be produced.
|
||||||
|
* @param {String[]} buildOptions.archs Specifies chip architectures which
|
||||||
|
* app packages should be built for. List of valid architectures is depends on
|
||||||
|
* platform.
|
||||||
|
* @param {String} buildOptions.buildConfig The path to build configuration
|
||||||
|
* file. The format of this file is depends on platform.
|
||||||
|
* @param {String[]} buildOptions.argv Raw array of command-line arguments,
|
||||||
|
* passed to `build` command. The purpose of this property is to pass a
|
||||||
|
* platform-specific arguments, and eventually let platform define own
|
||||||
|
* arguments processing logic.
|
||||||
|
*
|
||||||
|
* @return {Promise<Object[]>} A promise either fulfilled with an array of build
|
||||||
|
* artifacts (application packages) if package was built successfully,
|
||||||
|
* or rejected with CordovaError. The resultant build artifact objects is not
|
||||||
|
* strictly typed and may conatin arbitrary set of fields as in sample below.
|
||||||
|
*
|
||||||
|
* {
|
||||||
|
* architecture: 'x86',
|
||||||
|
* buildType: 'debug',
|
||||||
|
* path: '/path/to/build',
|
||||||
|
* type: 'app'
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* The return value in most cases will contain only one item but in some cases
|
||||||
|
* there could be multiple items in output array, e.g. when multiple
|
||||||
|
* arhcitectures is specified.
|
||||||
|
*/
|
||||||
|
build (buildOptions) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
return require('./lib/check_reqs').run().then(function () {
|
||||||
|
return require('./lib/build').run.call(self, buildOptions);
|
||||||
|
}).then(function (buildResults) {
|
||||||
|
// Cast build result to array of build artifacts
|
||||||
|
return buildResults.paths.map(function (apkPath) {
|
||||||
|
return {
|
||||||
|
buildType: buildResults.buildType,
|
||||||
|
buildMethod: buildResults.buildMethod,
|
||||||
|
path: apkPath,
|
||||||
|
type: path.extname(apkPath).replace(/\./g, '')
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds an application package for current platform and runs it on
|
||||||
|
* specified/default device. If no 'device'/'emulator'/'target' options are
|
||||||
|
* specified, then tries to run app on default device if connected, otherwise
|
||||||
|
* runs the app on emulator.
|
||||||
|
*
|
||||||
|
* @param {Object} runOptions An options object. The structure is the same
|
||||||
|
* as for build options.
|
||||||
|
*
|
||||||
|
* @return {Promise} A promise either fulfilled if package was built and ran
|
||||||
|
* successfully, or rejected with CordovaError.
|
||||||
|
*/
|
||||||
|
run (runOptions) {
|
||||||
|
var self = this;
|
||||||
|
return require('./lib/check_reqs').run().then(function () {
|
||||||
|
return require('./lib/run').run.call(self, runOptions);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans out the build artifacts from platform's directory, and also
|
||||||
|
* cleans out the platform www directory if called without options specified.
|
||||||
|
*
|
||||||
|
* @return {Promise} Return a promise either fulfilled, or rejected with
|
||||||
|
* CordovaError.
|
||||||
|
*/
|
||||||
|
clean (cleanOptions) {
|
||||||
|
var self = this;
|
||||||
|
// This will lint, checking for null won't
|
||||||
|
if (typeof cleanOptions === 'undefined') {
|
||||||
|
cleanOptions = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return require('./lib/check_reqs').run().then(function () {
|
||||||
|
return require('./lib/build').runClean.call(self, cleanOptions);
|
||||||
|
}).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
|
||||||
|
* built successfully.
|
||||||
|
*
|
||||||
|
* @return {Promise<Requirement[]>} Promise, resolved with set of Requirement
|
||||||
|
* objects for current platform.
|
||||||
|
*/
|
||||||
|
requirements () {
|
||||||
|
return require('./lib/check_reqs').check_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installs platform to specified directory and creates a platform project.
|
||||||
|
*
|
||||||
|
* @param {String} destination Destination directory, where insatll platform to
|
||||||
|
* @param {ConfigParser} [config] ConfgiParser instance, used to retrieve
|
||||||
|
* project creation options, such as package id and project name.
|
||||||
|
* @param {Object} [options] An options object. The most common options are:
|
||||||
|
* @param {String} [options.customTemplate] A path to custom template, that
|
||||||
|
* should override the default one from platform.
|
||||||
|
* @param {Boolean} [options.link] Flag that indicates that platform's
|
||||||
|
* sources will be linked to installed platform instead of copying.
|
||||||
|
* @param {EventEmitter} [events] An EventEmitter instance that will be used for
|
||||||
|
* logging purposes. If no EventEmitter provided, all events will be logged to
|
||||||
|
* console
|
||||||
|
*
|
||||||
|
* @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
|
||||||
|
* instance or rejected with CordovaError.
|
||||||
|
*/
|
||||||
|
static createPlatform (destination, config, options, events) {
|
||||||
|
events = setupEvents(events);
|
||||||
|
var result;
|
||||||
|
try {
|
||||||
|
result = require('../../lib/create').create(destination, config, options, events).then(function (destination) {
|
||||||
|
return new Api(PLATFORM, destination, events);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
events.emit('error', 'createPlatform is not callable from the android project API.');
|
||||||
|
throw (e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates already installed platform.
|
||||||
|
*
|
||||||
|
* @param {String} destination Destination directory, where platform installed
|
||||||
|
* @param {Object} [options] An options object. The most common options are:
|
||||||
|
* @param {String} [options.customTemplate] A path to custom template, that
|
||||||
|
* should override the default one from platform.
|
||||||
|
* @param {Boolean} [options.link] Flag that indicates that platform's
|
||||||
|
* sources will be linked to installed platform instead of copying.
|
||||||
|
* @param {EventEmitter} [events] An EventEmitter instance that will be used for
|
||||||
|
* logging purposes. If no EventEmitter provided, all events will be logged to
|
||||||
|
* console
|
||||||
|
*
|
||||||
|
* @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
|
||||||
|
* instance or rejected with CordovaError.
|
||||||
|
*/
|
||||||
|
static updatePlatform (destination, options, events) {
|
||||||
|
events = setupEvents(events);
|
||||||
|
var result;
|
||||||
|
try {
|
||||||
|
result = require('../../lib/create').update(destination, options, events).then(function (destination) {
|
||||||
|
return new Api(PLATFORM, destination, events);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
events.emit('error', 'updatePlatform is not callable from the android project API, you will need to do this manually.');
|
||||||
|
throw (e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = Api;
|
module.exports = Api;
|
||||||
|
196
bin/templates/cordova/lib/AndroidManifest.js
vendored
196
bin/templates/cordova/lib/AndroidManifest.js
vendored
@ -23,104 +23,106 @@ var xml = require('cordova-common').xmlHelpers;
|
|||||||
var DEFAULT_ORIENTATION = 'default';
|
var DEFAULT_ORIENTATION = 'default';
|
||||||
|
|
||||||
/** Wraps an AndroidManifest file */
|
/** Wraps an AndroidManifest file */
|
||||||
function AndroidManifest (path) {
|
class AndroidManifest {
|
||||||
this.path = path;
|
constructor (path) {
|
||||||
this.doc = xml.parseElementtreeSync(path);
|
this.path = path;
|
||||||
if (this.doc.getroot().tag !== 'manifest') {
|
this.doc = xml.parseElementtreeSync(path);
|
||||||
throw new Error('AndroidManifest at ' + path + ' has incorrect root node name (expected "manifest")');
|
if (this.doc.getroot().tag !== 'manifest') {
|
||||||
|
throw new Error('AndroidManifest at ' + path + ' has incorrect root node name (expected "manifest")');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getVersionName () {
|
||||||
|
return this.doc.getroot().attrib['android:versionName'];
|
||||||
|
}
|
||||||
|
|
||||||
|
setVersionName (versionName) {
|
||||||
|
this.doc.getroot().attrib['android:versionName'] = versionName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
getVersionCode () {
|
||||||
|
return this.doc.getroot().attrib['android:versionCode'];
|
||||||
|
}
|
||||||
|
|
||||||
|
setVersionCode (versionCode) {
|
||||||
|
this.doc.getroot().attrib['android:versionCode'] = versionCode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPackageId () {
|
||||||
|
return this.doc.getroot().attrib['package'];
|
||||||
|
}
|
||||||
|
|
||||||
|
setPackageId (pkgId) {
|
||||||
|
this.doc.getroot().attrib['package'] = pkgId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
getActivity () {
|
||||||
|
var activity = this.doc.getroot().find('./application/activity');
|
||||||
|
return {
|
||||||
|
getName: function () {
|
||||||
|
return activity.attrib['android:name'];
|
||||||
|
},
|
||||||
|
setName: function (name) {
|
||||||
|
if (!name) {
|
||||||
|
delete activity.attrib['android:name'];
|
||||||
|
} else {
|
||||||
|
activity.attrib['android:name'] = name;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
getOrientation: function () {
|
||||||
|
return activity.attrib['android:screenOrientation'];
|
||||||
|
},
|
||||||
|
setOrientation: function (orientation) {
|
||||||
|
if (!orientation || orientation.toLowerCase() === DEFAULT_ORIENTATION) {
|
||||||
|
delete activity.attrib['android:screenOrientation'];
|
||||||
|
} else {
|
||||||
|
activity.attrib['android:screenOrientation'] = orientation;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
getLaunchMode: function () {
|
||||||
|
return activity.attrib['android:launchMode'];
|
||||||
|
},
|
||||||
|
setLaunchMode: function (launchMode) {
|
||||||
|
if (!launchMode) {
|
||||||
|
delete activity.attrib['android:launchMode'];
|
||||||
|
} else {
|
||||||
|
activity.attrib['android:launchMode'] = launchMode;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getDebuggable () {
|
||||||
|
return this.doc.getroot().find('./application').attrib['android:debuggable'] === 'true';
|
||||||
|
}
|
||||||
|
|
||||||
|
setDebuggable (value) {
|
||||||
|
var application = this.doc.getroot().find('./application');
|
||||||
|
if (value) {
|
||||||
|
application.attrib['android:debuggable'] = 'true';
|
||||||
|
} else {
|
||||||
|
// The default value is "false", so we can remove attribute at all.
|
||||||
|
delete application.attrib['android:debuggable'];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes manifest to disk syncronously. If filename is specified, then manifest
|
||||||
|
* will be written to that file
|
||||||
|
*
|
||||||
|
* @param {String} [destPath] File to write manifest to. If omitted,
|
||||||
|
* manifest will be written to file it has been read from.
|
||||||
|
*/
|
||||||
|
write (destPath) {
|
||||||
|
fs.writeFileSync(destPath || this.path, this.doc.write({ indent: 4 }), 'utf-8');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidManifest.prototype.getVersionName = function () {
|
|
||||||
return this.doc.getroot().attrib['android:versionName'];
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.setVersionName = function (versionName) {
|
|
||||||
this.doc.getroot().attrib['android:versionName'] = versionName;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.getVersionCode = function () {
|
|
||||||
return this.doc.getroot().attrib['android:versionCode'];
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.setVersionCode = function (versionCode) {
|
|
||||||
this.doc.getroot().attrib['android:versionCode'] = versionCode;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.getPackageId = function () {
|
|
||||||
return this.doc.getroot().attrib['package'];
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.setPackageId = function (pkgId) {
|
|
||||||
this.doc.getroot().attrib['package'] = pkgId;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.getActivity = function () {
|
|
||||||
var activity = this.doc.getroot().find('./application/activity');
|
|
||||||
return {
|
|
||||||
getName: function () {
|
|
||||||
return activity.attrib['android:name'];
|
|
||||||
},
|
|
||||||
setName: function (name) {
|
|
||||||
if (!name) {
|
|
||||||
delete activity.attrib['android:name'];
|
|
||||||
} else {
|
|
||||||
activity.attrib['android:name'] = name;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
getOrientation: function () {
|
|
||||||
return activity.attrib['android:screenOrientation'];
|
|
||||||
},
|
|
||||||
setOrientation: function (orientation) {
|
|
||||||
if (!orientation || orientation.toLowerCase() === DEFAULT_ORIENTATION) {
|
|
||||||
delete activity.attrib['android:screenOrientation'];
|
|
||||||
} else {
|
|
||||||
activity.attrib['android:screenOrientation'] = orientation;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
getLaunchMode: function () {
|
|
||||||
return activity.attrib['android:launchMode'];
|
|
||||||
},
|
|
||||||
setLaunchMode: function (launchMode) {
|
|
||||||
if (!launchMode) {
|
|
||||||
delete activity.attrib['android:launchMode'];
|
|
||||||
} else {
|
|
||||||
activity.attrib['android:launchMode'] = launchMode;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.getDebuggable = function () {
|
|
||||||
return this.doc.getroot().find('./application').attrib['android:debuggable'] === 'true';
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidManifest.prototype.setDebuggable = function (value) {
|
|
||||||
var application = this.doc.getroot().find('./application');
|
|
||||||
if (value) {
|
|
||||||
application.attrib['android:debuggable'] = 'true';
|
|
||||||
} else {
|
|
||||||
// The default value is "false", so we can remove attribute at all.
|
|
||||||
delete application.attrib['android:debuggable'];
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes manifest to disk syncronously. If filename is specified, then manifest
|
|
||||||
* will be written to that file
|
|
||||||
*
|
|
||||||
* @param {String} [destPath] File to write manifest to. If omitted,
|
|
||||||
* manifest will be written to file it has been read from.
|
|
||||||
*/
|
|
||||||
AndroidManifest.prototype.write = function (destPath) {
|
|
||||||
fs.writeFileSync(destPath || this.path, this.doc.write({ indent: 4 }), 'utf-8');
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = AndroidManifest;
|
module.exports = AndroidManifest;
|
||||||
|
284
bin/templates/cordova/lib/AndroidProject.js
vendored
284
bin/templates/cordova/lib/AndroidProject.js
vendored
@ -55,148 +55,148 @@ function getRelativeLibraryPath (parentDir, subDir) {
|
|||||||
return (path.sep === '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath;
|
return (path.sep === '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
function AndroidProject (projectDir) {
|
class AndroidProject {
|
||||||
this._propertiesEditors = {};
|
constructor (projectDir) {
|
||||||
this._subProjectDirs = {};
|
this._propertiesEditors = {};
|
||||||
this._dirty = false;
|
this._subProjectDirs = {};
|
||||||
this.projectDir = projectDir;
|
this._dirty = false;
|
||||||
this.platformWww = path.join(this.projectDir, 'platform_www');
|
this.projectDir = projectDir;
|
||||||
this.www = path.join(this.projectDir, 'app/src/main/assets/www');
|
this.platformWww = path.join(this.projectDir, 'platform_www');
|
||||||
|
this.www = path.join(this.projectDir, 'app/src/main/assets/www');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the package name out of the Android Manifest file
|
||||||
|
*
|
||||||
|
* @param {String} projectDir The absolute path to the directory containing the project
|
||||||
|
* @return {String} The name of the package
|
||||||
|
*/
|
||||||
|
getPackageName () {
|
||||||
|
var manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml');
|
||||||
|
return new AndroidManifest(manifestPath).getPackageId();
|
||||||
|
}
|
||||||
|
|
||||||
|
getCustomSubprojectRelativeDir (plugin_id, src) {
|
||||||
|
// All custom subprojects are prefixed with the last portion of the package id.
|
||||||
|
// This is to avoid collisions when opening multiple projects in Eclipse that have subprojects with the same name.
|
||||||
|
var packageName = this.getPackageName();
|
||||||
|
var lastDotIndex = packageName.lastIndexOf('.');
|
||||||
|
var prefix = packageName.substring(lastDotIndex + 1);
|
||||||
|
var subRelativeDir = path.join(plugin_id, prefix + '-' + path.basename(src));
|
||||||
|
return subRelativeDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
addSubProject (parentDir, subDir) {
|
||||||
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
|
var subProjectFile = path.resolve(subDir, 'project.properties');
|
||||||
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
|
// TODO: Setting the target needs to happen only for pre-3.7.0 projects
|
||||||
|
if (fs.existsSync(subProjectFile)) {
|
||||||
|
var subProperties = this._getPropertiesFile(subProjectFile);
|
||||||
|
subProperties.set('target', parentProperties.get('target'));
|
||||||
|
subProperties.dirty = true;
|
||||||
|
this._subProjectDirs[subDir] = true;
|
||||||
|
}
|
||||||
|
addToPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir));
|
||||||
|
|
||||||
|
this._dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeSubProject (parentDir, subDir) {
|
||||||
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
|
removeFromPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir));
|
||||||
|
delete this._subProjectDirs[subDir];
|
||||||
|
this._dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
addGradleReference (parentDir, subDir) {
|
||||||
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
|
addToPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
|
||||||
|
this._dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeGradleReference (parentDir, subDir) {
|
||||||
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
|
removeFromPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
|
||||||
|
this._dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
addSystemLibrary (parentDir, value) {
|
||||||
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
|
addToPropertyList(parentProperties, 'cordova.system.library', value);
|
||||||
|
this._dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeSystemLibrary (parentDir, value) {
|
||||||
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
|
removeFromPropertyList(parentProperties, 'cordova.system.library', value);
|
||||||
|
this._dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
write () {
|
||||||
|
if (!this._dirty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._dirty = false;
|
||||||
|
|
||||||
|
for (var filename in this._propertiesEditors) {
|
||||||
|
var editor = this._propertiesEditors[filename];
|
||||||
|
if (editor.dirty) {
|
||||||
|
fs.writeFileSync(filename, editor.toString());
|
||||||
|
editor.dirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getInstaller (type) {
|
||||||
|
return pluginHandlers.getInstaller(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUninstaller (type) {
|
||||||
|
return pluginHandlers.getUninstaller(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This checks if an Android project is clean or has old build artifacts
|
||||||
|
*/
|
||||||
|
isClean () {
|
||||||
|
var build_path = path.join(this.projectDir, 'build');
|
||||||
|
// If the build directory doesn't exist, it's clean
|
||||||
|
return !(fs.existsSync(build_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
_getPropertiesFile (filename) {
|
||||||
|
if (!this._propertiesEditors[filename]) {
|
||||||
|
if (fs.existsSync(filename)) {
|
||||||
|
this._propertiesEditors[filename] = properties_parser.createEditor(filename);
|
||||||
|
} else {
|
||||||
|
this._propertiesEditors[filename] = properties_parser.createEditor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._propertiesEditors[filename];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getProjectFile (projectDir) {
|
||||||
|
if (!projectFileCache[projectDir]) {
|
||||||
|
projectFileCache[projectDir] = new AndroidProject(projectDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return projectFileCache[projectDir];
|
||||||
|
}
|
||||||
|
|
||||||
|
static purgeCache (projectDir) {
|
||||||
|
if (projectDir) {
|
||||||
|
delete projectFileCache[projectDir];
|
||||||
|
} else {
|
||||||
|
projectFileCache = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidProject.getProjectFile = function (projectDir) {
|
|
||||||
if (!projectFileCache[projectDir]) {
|
|
||||||
projectFileCache[projectDir] = new AndroidProject(projectDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectFileCache[projectDir];
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.purgeCache = function (projectDir) {
|
|
||||||
if (projectDir) {
|
|
||||||
delete projectFileCache[projectDir];
|
|
||||||
} else {
|
|
||||||
projectFileCache = {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the package name out of the Android Manifest file
|
|
||||||
*
|
|
||||||
* @param {String} projectDir The absolute path to the directory containing the project
|
|
||||||
*
|
|
||||||
* @return {String} The name of the package
|
|
||||||
*/
|
|
||||||
AndroidProject.prototype.getPackageName = function () {
|
|
||||||
var manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml');
|
|
||||||
return new AndroidManifest(manifestPath).getPackageId();
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.getCustomSubprojectRelativeDir = function (plugin_id, src) {
|
|
||||||
// All custom subprojects are prefixed with the last portion of the package id.
|
|
||||||
// This is to avoid collisions when opening multiple projects in Eclipse that have subprojects with the same name.
|
|
||||||
var packageName = this.getPackageName();
|
|
||||||
var lastDotIndex = packageName.lastIndexOf('.');
|
|
||||||
var prefix = packageName.substring(lastDotIndex + 1);
|
|
||||||
var subRelativeDir = path.join(plugin_id, prefix + '-' + path.basename(src));
|
|
||||||
return subRelativeDir;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.addSubProject = function (parentDir, subDir) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var subProjectFile = path.resolve(subDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
// TODO: Setting the target needs to happen only for pre-3.7.0 projects
|
|
||||||
if (fs.existsSync(subProjectFile)) {
|
|
||||||
var subProperties = this._getPropertiesFile(subProjectFile);
|
|
||||||
subProperties.set('target', parentProperties.get('target'));
|
|
||||||
subProperties.dirty = true;
|
|
||||||
this._subProjectDirs[subDir] = true;
|
|
||||||
}
|
|
||||||
addToPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir));
|
|
||||||
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.removeSubProject = function (parentDir, subDir) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
removeFromPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir));
|
|
||||||
delete this._subProjectDirs[subDir];
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.addGradleReference = function (parentDir, subDir) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
addToPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.removeGradleReference = function (parentDir, subDir) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
removeFromPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.addSystemLibrary = function (parentDir, value) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
addToPropertyList(parentProperties, 'cordova.system.library', value);
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.removeSystemLibrary = function (parentDir, value) {
|
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
|
||||||
removeFromPropertyList(parentProperties, 'cordova.system.library', value);
|
|
||||||
this._dirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.write = function () {
|
|
||||||
if (!this._dirty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._dirty = false;
|
|
||||||
|
|
||||||
for (var filename in this._propertiesEditors) {
|
|
||||||
var editor = this._propertiesEditors[filename];
|
|
||||||
if (editor.dirty) {
|
|
||||||
fs.writeFileSync(filename, editor.toString());
|
|
||||||
editor.dirty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype._getPropertiesFile = function (filename) {
|
|
||||||
if (!this._propertiesEditors[filename]) {
|
|
||||||
if (fs.existsSync(filename)) {
|
|
||||||
this._propertiesEditors[filename] = properties_parser.createEditor(filename);
|
|
||||||
} else {
|
|
||||||
this._propertiesEditors[filename] = properties_parser.createEditor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._propertiesEditors[filename];
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.getInstaller = function (type) {
|
|
||||||
return pluginHandlers.getInstaller(type);
|
|
||||||
};
|
|
||||||
|
|
||||||
AndroidProject.prototype.getUninstaller = function (type) {
|
|
||||||
return pluginHandlers.getUninstaller(type);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This checks if an Android project is clean or has old build artifacts
|
|
||||||
*/
|
|
||||||
|
|
||||||
AndroidProject.prototype.isClean = function () {
|
|
||||||
var build_path = path.join(this.projectDir, 'build');
|
|
||||||
// If the build directory doesn't exist, it's clean
|
|
||||||
return !(fs.existsSync(build_path));
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = AndroidProject;
|
module.exports = AndroidProject;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user