| /** |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| */ |
| |
| var path = require('path'); |
| var events = require('cordova-common').events; |
| var JsprojManager = require('./lib/JsprojManager'); |
| var PluginManager = require('cordova-common').PluginManager; |
| var CordovaLogger = require('cordova-common').CordovaLogger; |
| var PlatformMunger = require('./lib/ConfigChanges.js').PlatformMunger; |
| var PlatformJson = require('cordova-common').PlatformJson; |
| var PluginInfo = require('./lib/PluginInfo').PluginInfo; |
| var ConfigParser = require('./lib/ConfigParser'); |
| var PluginInfoProvider = require('cordova-common').PluginInfoProvider; |
| |
| var PLATFORM = 'windows'; |
| |
| function setupEvents (externalEventEmitter) { |
| if (externalEventEmitter) { |
| // This will make the platform internal events visible outside |
| events.forwardEventsTo(externalEventEmitter); |
| return; |
| } |
| |
| // There is no logger if external emitter is not present, |
| // so attach a console logger |
| CordovaLogger.get().subscribe(events); |
| } |
| |
| /** |
| * Class, that acts as abstraction over particular platform. Encapsulates the |
| * platform's properties and methods. |
| * |
| * Platform that implements own PlatformApi instance _should implement all |
| * prototype methods_ of this class to be fully compatible with cordova-lib. |
| * |
| * The PlatformApi instance also should define the following field: |
| * |
| * * platform: String that defines a platform name. |
| */ |
| function Api (platform, platformRootDir, eventEmitter) { |
| this.platform = PLATFORM; |
| this.root = path.resolve(__dirname, '..'); |
| |
| setupEvents(eventEmitter); |
| |
| var self = this; |
| this.locations = { |
| root: self.root, |
| www: path.join(self.root, 'www'), |
| platformWww: path.join(self.root, 'platform_www'), |
| configXml: path.join(self.root, 'config.xml'), |
| defaultConfigXml: path.join(self.root, 'cordova/defaults.xml'), |
| // NOTE: Due to platformApi spec we need to return relative paths here |
| cordovaJs: 'template/www/cordova.js', |
| cordovaJsSrc: 'cordova-js-src' |
| }; |
| } |
| |
| /** |
| * Installs platform to specified directory and creates a platform project. |
| * |
| * @param {String} destinationDir A directory, where platform should be |
| * created/installed. |
| * @param {ConfigParser} [projectConfig] A ConfigParser instance, used to get |
| * some application properties for new platform like application name, package |
| * id, etc. If not defined, this means that platform is used as standalone |
| * project and is not a part of cordova project, so platform will use some |
| * default values. |
| * @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=false] Flag that indicates that platform's |
| * sources will be linked to installed platform instead of copying. |
| * |
| * @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi |
| * instance or rejected with CordovaError. |
| */ |
| Api.createPlatform = function (destinationDir, projectConfig, options, events) { |
| setupEvents(events); |
| var result; |
| |
| try { |
| result = require('../../bin/lib/create') |
| .create(destinationDir, projectConfig, options) |
| .then(function () { |
| var PlatformApi = require(path.resolve(destinationDir, 'cordova/Api')); |
| return new PlatformApi(PLATFORM, destinationDir, events); |
| }); |
| } catch (e) { |
| events.emit('error', 'createPlatform is not callable from the windows project API.'); |
| throw (e); |
| } |
| |
| return result; |
| }; |
| |
| /** |
| * Updates already installed platform. |
| * |
| * @param {String} destinationDir A directory, where existing platform |
| * installed, that should be updated. |
| * @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=false] Flag that indicates that platform's sources |
| * will be linked to installed platform instead of copying. |
| * @param {EventEmitter} [events] The emitter that will be used for logging |
| * |
| * @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi |
| * instance or rejected with CordovaError. |
| */ |
| Api.updatePlatform = function (destinationDir, options, events) { |
| setupEvents(events); |
| try { |
| return require('../../bin/lib/update') |
| .update(destinationDir, options) |
| .then(function () { |
| var PlatformApi = require(path.resolve(destinationDir, 'cordova/Api')); |
| return new PlatformApi(PLATFORM, destinationDir, events); |
| }); |
| } catch (e) { |
| events.emit('error', 'updatePlatform is not callable from the windows project API.'); |
| throw (e); |
| } |
| }; |
| |
| /** |
| * 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) { |
| var configPath = cordovaProject.projectConfig.path; |
| cordovaProject.projectConfig = new ConfigParser(configPath); |
| 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 self = this; |
| |
| // We need to use custom PluginInfo to trigger windows-specific processing |
| // of changes in .appxmanifest files. See PluginInfo.js for details |
| var pluginInfo = new PluginInfo(plugin.dir); |
| var jsProject = JsprojManager.getProject(this.root); |
| installOptions = installOptions || {}; |
| installOptions.variables = installOptions.variables || {}; |
| // Add PACKAGE_NAME variable into vars |
| if (!installOptions.variables.PACKAGE_NAME) { |
| installOptions.variables.PACKAGE_NAME = jsProject.getPackageName(); |
| } |
| |
| var platformJson = PlatformJson.load(this.root, this.platform); |
| var pluginManager = PluginManager.get(this.platform, this.locations, jsProject); |
| pluginManager.munger = new PlatformMunger(this.platform, this.locations.root, platformJson, new PluginInfoProvider()); |
| return pluginManager |
| .addPlugin(pluginInfo, installOptions) |
| .then(function () { |
| // CB-11657 Add BOM to www files here because files added by plugin |
| // probably don't have it. Prepare would add BOM but it might not be called |
| return require('./lib/prepare').addBOMSignature(self.locations.www); |
| }) |
| // CB-11022 return non-falsy value to indicate |
| // that there is no need to run prepare after |
| .thenResolve(true); |
| }; |
| |
| /** |
| * 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 self = this; |
| |
| // We need to use custom PluginInfo to trigger windows-specific processing |
| // of changes in .appxmanifest files. See PluginInfo.js for details |
| var pluginInfo = new PluginInfo(plugin.dir); |
| var jsProject = JsprojManager.getProject(this.root); |
| var platformJson = PlatformJson.load(this.root, this.platform); |
| var pluginManager = PluginManager.get(this.platform, this.locations, jsProject); |
| // CB-11933 We override this field by windows specific one because windows has special logic |
| // for appxmanifest's capabilities removal (see also https://issues.apache.org/jira/browse/CB-11066) |
| pluginManager.munger = new PlatformMunger(this.platform, this.locations.root, platformJson, new PluginInfoProvider()); |
| return pluginManager |
| .removePlugin(pluginInfo, uninstallOptions) |
| .then(function () { |
| // CB-11657 Add BOM to cordova_plugins, since it is was |
| // regenerated after plugin uninstallation and does not have BOM |
| return require('./lib/prepare').addBOMToFile(path.resolve(self.locations.www, 'cordova_plugins.js')); |
| }) |
| // CB-11022 return non-falsy value to indicate |
| // that there is no need to run prepare after |
| .thenResolve(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) { |
| // TODO: Should we run check_reqs first? Android does this, but Windows appears doesn't. |
| return require('./lib/build').run.call(this, buildOptions) |
| .then(function (result) { |
| // Wrap result into array according to PlatformApi spec |
| return [result]; |
| }); |
| }; |
| |
| /** |
| * 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) { |
| // TODO: Should we run check_reqs first? Android does this, but Windows appears doesn't. |
| return require('./lib/run').run.call(this, runOptions); |
| }; |
| |
| /** |
| * Cleans out the build artifacts from platform's directory. |
| * |
| * @return {Promise} Return a promise either fulfilled, or rejected with |
| * CordovaError. |
| */ |
| Api.prototype.clean = function (cleanOpts) { |
| var self = this; |
| return require('./lib/build').clean.call(this, cleanOpts) |
| .then(function () { |
| return require('./lib/prepare').clean.call(self, cleanOpts); |
| }); |
| }; |
| |
| /** |
| * 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. |
| */ |
| Api.prototype.requirements = function () { |
| return require('./lib/check_reqs').check_all(); |
| }; |
| |
| module.exports = Api; |