From ce14282304fb2c575bd85ab8c4083380868e268b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20N=C3=A9vola?= Date: Wed, 19 Jun 2019 19:07:26 +0200 Subject: [PATCH] Enable running multiple Cordova apps from same application source (#10577) Fixes #10576. --- History.md | 13 +++++++++++++ tools/cli/commands.js | 29 +++++++++++++++++++++++------ tools/cli/help.txt | 15 +++++++++++++++ tools/cordova/builder.js | 22 +++++++++++++--------- tools/cordova/project.js | 2 ++ tools/tests/cordova-run.js | 7 +++++++ 6 files changed, 73 insertions(+), 15 deletions(-) diff --git a/History.md b/History.md index c415b5d0ea..601f174a4e 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,18 @@ ## v.NEXT +### Breaking changes +N/A + +### Migration Steps +N/A + +### Changes + +* Add `--cordova-server-port` option to override local port where Cordova will + serve static resources, which is useful when multiple Cordova apps are built + from the same application source code, since by default the port is generated + using the ID from the application's `.meteor/.id` file. + ## v1.8.1, 2019-04-03 ### Breaking changes diff --git a/tools/cli/commands.js b/tools/cli/commands.js index 8b7b18c65d..d43ccbf07d 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -82,7 +82,9 @@ export function parseServerOptionsForRunCommand(options, runTargets) { isRunOnDeviceRequested); } - return { parsedServerUrl, parsedMobileServerUrl }; + const parsedCordovaServerPort = parseCordovaServerPortOption(options); + + return { parsedServerUrl, parsedMobileServerUrl, parsedCordovaServerPort }; } function parsePortOption(portOption) { @@ -110,6 +112,11 @@ function parseMobileServerOption(mobileServerOption, return parsedMobileServerUrl; } +function parseCordovaServerPortOption(options = {}) { + const cordovaServerPortOption = options['cordova-server-port']; + return cordovaServerPortOption ? parseInt(cordovaServerPortOption, 10) : null; +} + function detectMobileServerUrl(parsedServerUrl, isRunOnDeviceRequested) { // Always try to use an auto-detected IP first try { @@ -290,6 +297,7 @@ var runCommandOptions = { options: { port: { type: String, short: "p", default: DEFAULT_PORT }, 'mobile-server': { type: String }, + 'cordova-server-port': { type: String }, // XXX COMPAT WITH 0.9.2.2 'mobile-port': { type: String }, 'app-port': { type: String }, @@ -326,7 +334,7 @@ function doRunCommand(options) { // Additional args are interpreted as run targets const runTargets = parseRunTargets(options.args); - const { parsedServerUrl, parsedMobileServerUrl } = + const { parsedServerUrl, parsedMobileServerUrl, parsedCordovaServerPort } = parseServerOptionsForRunCommand(options, runTargets); var includePackages = []; @@ -401,7 +409,8 @@ function doRunCommand(options) { main.captureAndExit('', 'preparing Cordova project', () => { const cordovaProject = new CordovaProject(projectContext, { settingsFile: options.settings, - mobileServerUrl: utils.formatUrl(parsedMobileServerUrl) }); + mobileServerUrl: utils.formatUrl(parsedMobileServerUrl), + cordovaServerPort: parsedCordovaServerPort }); if (buildmessage.jobHasMessages()) return; cordovaRunner = new CordovaRunner(cordovaProject, runTargets); @@ -431,6 +440,7 @@ function doRunCommand(options) { mongoUrl: process.env.MONGO_URL, oplogUrl: process.env.MONGO_OPLOG_URL, mobileServerUrl: utils.formatUrl(parsedMobileServerUrl), + cordovaServerPort: parsedCordovaServerPort, once: options.once, noReleaseCheck: options['no-release-check'] || process.env.METEOR_NO_RELEASE_CHECK, cordovaRunner: cordovaRunner @@ -888,6 +898,7 @@ var buildCommands = { "server-only": { type: Boolean }, 'mobile-settings': { type: String }, server: { type: String }, + "cordova-server-port": { type: String }, // XXX COMPAT WITH 0.9.2.2 "mobile-port": { type: String }, // Indicates whether these build is running headless, e.g. in a @@ -986,6 +997,7 @@ var buildCommand = function (options) { let cordovaPlatforms; let parsedMobileServerUrl; + let parsedCordovaServerPort; if (!serverOnly) { cordovaPlatforms = projectContext.platformList.getCordovaPlatforms(); @@ -1008,6 +1020,7 @@ on an OS X system."); } parsedMobileServerUrl = parseMobileServerOption(mobileServerOption, 'server'); + parsedCordovaServerPort = parseCordovaServerPortOption(options); } } else { cordovaPlatforms = []; @@ -1096,7 +1109,8 @@ ${Console.command("meteor build ../output")}`, cordovaProject = new CordovaProject(projectContext, { settingsFile: options.settings, - mobileServerUrl: utils.formatUrl(parsedMobileServerUrl) }); + mobileServerUrl: utils.formatUrl(parsedMobileServerUrl), + cordovaServerPort: parsedCordovaServerPort }); if (buildmessage.jobHasMessages()) return; const pluginVersions = pluginVersionsFromStarManifest( @@ -1550,6 +1564,7 @@ testCommandOptions = { options: { port: { type: String, short: "p", default: DEFAULT_PORT }, 'mobile-server': { type: String }, + 'cordova-server-port': { type: String }, // XXX COMPAT WITH 0.9.2.2 'mobile-port': { type: String }, 'debug-port': { type: String }, @@ -1648,7 +1663,7 @@ function doTestCommand(options) { const runTargets = parseRunTargets(_.intersection( Object.keys(options), ['ios', 'ios-device', 'android', 'android-device'])); - const { parsedServerUrl, parsedMobileServerUrl } = + const { parsedServerUrl, parsedMobileServerUrl, parsedCordovaServerPort } = parseServerOptionsForRunCommand(options, runTargets); // Make a temporary app dir (based on the test runner app). This will be @@ -1865,7 +1880,8 @@ function doTestCommand(options) { const cordovaProject = new CordovaProject(projectContext, { settingsFile: options.settings, - mobileServerUrl: utils.formatUrl(parsedMobileServerUrl) }); + mobileServerUrl: utils.formatUrl(parsedMobileServerUrl), + cordovaServerPort: parsedCordovaServerPort }); if (buildmessage.jobHasMessages()) return; cordovaRunner = new CordovaRunner(cordovaProject, runTargets); @@ -1884,6 +1900,7 @@ function doTestCommand(options) { options, { mobileServerUrl: utils.formatUrl(parsedMobileServerUrl), + cordovaServerPort: parsedCordovaServerPort, proxyPort: parsedServerUrl.port, proxyHost: parsedServerUrl.hostname, } diff --git a/tools/cli/help.txt b/tools/cli/help.txt index d359e87cae..300f04e704 100644 --- a/tools/cli/help.txt +++ b/tools/cli/help.txt @@ -83,6 +83,11 @@ Options: Defaults to your local IP and the port that the Meteor server binds to. Can include a URL scheme (for example, --mobile-server=https://example.com:443). + --cordova-server-port + Local port where Cordova will serve the content. It's + important when multiple Cordova apps are build from the same + Meteor app source code as by default the port is generated + using the id inside .meteor/.id file. --production Simulate production mode. Minify and bundle CSS and JS files. --raw-logs Run without parsing logs from stdout and stderr. --settings, -s Set optional data for Meteor.settings on the server. @@ -598,6 +603,11 @@ Options: port that the Meteor server binds to. Can include a URL scheme (for example, --mobile-server=https://example.com:443). + --cordova-server-port + Local port where Cordova will serve the content. It's + important when multiple Cordova apps are build from the same + Meteor app source code as by default the port is generated + using the id inside .meteor/.id file. --production Simulate production mode. Minify and bundle CSS, JS files. --settings, -s Set optional data for Meteor.settings on the server @@ -682,6 +692,11 @@ Options: port that the Meteor server binds to. Can include a URL scheme (for example, --mobile-server=https://example.com:443). + --cordova-server-port + Local port where Cordova will serve the content. It's + important when multiple Cordova apps are build from the same + Meteor app source code as by default the port is generated + using the id inside .meteor/.id file. --raw-logs Run without parsing logs from stdout and stderr. --settings, -s Set optional data for Meteor.settings on the server diff --git a/tools/cordova/builder.js b/tools/cordova/builder.js index 1c77569b20..8de83b8180 100644 --- a/tools/cordova/builder.js +++ b/tools/cordova/builder.js @@ -91,14 +91,18 @@ export class CordovaBuilder { } initalizeDefaults() { - // Convert the appId (a base 36 string) to a number - const appIdAsNumber = parseInt(this.projectContext.appIdentifier, 36); - // We use the appId to choose a local server port between 12000-13000. - // This range should be large enough to avoid collisions with other - // Meteor apps, and has also been chosen to avoid collisions - // with other apps or services on the device (although this can never be - // guaranteed). - const localServerPort = 12000 + (appIdAsNumber % 1000); + let { cordovaServerPort } = this.options; + // if --cordova-server-port is not present on run command + if (!cordovaServerPort) { + // Convert the appId (a base 36 string) to a number + const appIdAsNumber = parseInt(this.projectContext.appIdentifier, 36); + // We use the appId to choose a local server port between 12000-13000. + // This range should be large enough to avoid collisions with other + // Meteor apps, and has also been chosen to avoid collisions + // with other apps or services on the device (although this can never be + // guaranteed). + cordovaServerPort = 12000 + (appIdAsNumber % 1000); + } this.metadata = { id: 'com.id' + this.projectContext.appIdentifier, @@ -109,7 +113,7 @@ export class CordovaBuilder { author: 'A Meteor Developer', email: 'n/a', website: 'n/a', - contentUrl: `http://localhost:${localServerPort}/` + contentUrl: `http://localhost:${cordovaServerPort}/` }; // Set some defaults different from the Cordova defaults diff --git a/tools/cordova/project.js b/tools/cordova/project.js index d543c05116..e4c106ac1a 100644 --- a/tools/cordova/project.js +++ b/tools/cordova/project.js @@ -152,6 +152,7 @@ outdated platforms`); this.projectContext, templatePath, { mobileServerUrl: this.options.mobileServerUrl, + cordovaServerPort: this.options.cordovaServerPort, settingsFile: this.options.settingsFile } ); @@ -226,6 +227,7 @@ outdated platforms`); this.projectContext, this.projectRoot, { mobileServerUrl: this.options.mobileServerUrl, + cordovaServerPort: this.options.cordovaServerPort, settingsFile: this.options.settingsFile } ); diff --git a/tools/tests/cordova-run.js b/tools/tests/cordova-run.js index e0bc2b353d..bbdeb98e69 100644 --- a/tools/tests/cordova-run.js +++ b/tools/tests/cordova-run.js @@ -44,4 +44,11 @@ selftest.define('get mobile server argument for meteor run', ['cordova'], functi port: "example.com:3000", "mobile-server": "http://example.com:4000" }).parsedMobileServerUrl, { hostname: "example.com", port: "4000", protocol: "http" }); + + // meteor run -p example.com:3000 --cordova-server-port 12500 => + // cordovaServerPort should be 12500 + selftest.expectEqual(parseServerOptionsForRunCommand({ + port: "example.com:3000", + "cordova-server-port": "12500" + }).parsedCordovaServerPort, 12500); });