diff --git a/lib/commands/run.ts b/lib/commands/run.ts index 38365c2a59..f2d361d609 100644 --- a/lib/commands/run.ts +++ b/lib/commands/run.ts @@ -28,7 +28,7 @@ export class RunCommandBase implements ICommand { this.platform = this.$devicePlatformsConstants.Android; } - this.$liveSyncCommandHelper.validatePlatform(this.platform); + await this.$liveSyncCommandHelper.validatePlatform(this.platform); return true; } diff --git a/lib/constants.ts b/lib/constants.ts index 31fa4d306f..7983e71a1a 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -135,7 +135,10 @@ export const enum TrackActionNames { CreateProject = "Create project", Debug = "Debug", Deploy = "Deploy", - LiveSync = "LiveSync" + LiveSync = "LiveSync", + RunSetupScript = "Run Setup Script", + CheckLocalBuildSetup = "Check Local Build Setup", + CheckEnvironmentRequirements = "Check Environment Requirements" } export const enum BuildStates { diff --git a/lib/definitions/platform.d.ts b/lib/definitions/platform.d.ts index 190467ddd0..4f098575eb 100644 --- a/lib/definitions/platform.d.ts +++ b/lib/definitions/platform.d.ts @@ -381,5 +381,5 @@ interface IUpdateAppOptions extends IOptionalFilesToSync, IOptionalFilesToRemove } interface IPlatformEnvironmentRequirements { - checkEnvironmentRequirements(platform: string): Promise; + checkEnvironmentRequirements(platform?: string): Promise; } \ No newline at end of file diff --git a/lib/services/analytics/analytics-service.ts b/lib/services/analytics/analytics-service.ts index 3c28cd138f..5e24e81871 100644 --- a/lib/services/analytics/analytics-service.ts +++ b/lib/services/analytics/analytics-service.ts @@ -73,7 +73,7 @@ export class AnalyticsService extends AnalyticsServiceBase { // In some cases (like in case action is Build and platform is Android), we do not know if the deviceType is emulator or device. // Just exclude the device_type in this case. - if (isForDevice !== null) { + if (isForDevice !== null && isForDevice !== undefined) { const deviceType = isForDevice ? DeviceTypes.Device : (this.$mobileHelper.isAndroidPlatform(platform) ? DeviceTypes.Emulator : DeviceTypes.Simulator); label = this.addDataToLabel(label, deviceType); } diff --git a/lib/services/analytics/google-analytics-provider.ts b/lib/services/analytics/google-analytics-provider.ts index 2ce3a8284e..785e6d1c10 100644 --- a/lib/services/analytics/google-analytics-provider.ts +++ b/lib/services/analytics/google-analytics-provider.ts @@ -4,7 +4,6 @@ import { AnalyticsClients } from "../../common/constants"; export class GoogleAnalyticsProvider implements IGoogleAnalyticsProvider { private static GA_TRACKING_ID = "UA-111455-44"; - private static GA_CROSS_CLIENT_TRACKING_ID = "UA-111455-51"; private currentPage: string; constructor(private clientId: string, @@ -15,15 +14,12 @@ export class GoogleAnalyticsProvider implements IGoogleAnalyticsProvider { } public async trackHit(trackInfo: IGoogleAnalyticsData): Promise { - const trackingIds = [GoogleAnalyticsProvider.GA_TRACKING_ID, GoogleAnalyticsProvider.GA_CROSS_CLIENT_TRACKING_ID]; const sessionId = uuid.v4(); - for (const gaTrackingId of trackingIds) { - try { - await this.track(gaTrackingId, trackInfo, sessionId); - } catch (e) { - this.$logger.trace("Analytics exception: ", e); - } + try { + await this.track(GoogleAnalyticsProvider.GA_TRACKING_ID, trackInfo, sessionId); + } catch (e) { + this.$logger.trace("Analytics exception: ", e); } } @@ -41,14 +37,7 @@ export class GoogleAnalyticsProvider implements IGoogleAnalyticsProvider { } }); - switch (gaTrackingId) { - case GoogleAnalyticsProvider.GA_CROSS_CLIENT_TRACKING_ID: - this.setCrossClientCustomDimensions(visitor, sessionId); - break; - default: - await this.setCustomDimensions(visitor, trackInfo.customDimensions, sessionId); - break; - } + await this.setCustomDimensions(visitor, trackInfo.customDimensions, sessionId); switch (trackInfo.googleAnalyticsDataType) { case GoogleAnalyticsDataType.Page: @@ -83,18 +72,6 @@ export class GoogleAnalyticsProvider implements IGoogleAnalyticsProvider { }); } - private async setCrossClientCustomDimensions(visitor: ua.Visitor, sessionId: string): Promise { - const customDimensions: IStringDictionary = { - [GoogleAnalyticsCrossClientCustomDimensions.sessionId]: sessionId, - [GoogleAnalyticsCrossClientCustomDimensions.clientId]: this.clientId, - [GoogleAnalyticsCrossClientCustomDimensions.crossClientId]: this.clientId, - }; - - _.each(customDimensions, (value, key) => { - visitor.set(key, value); - }); - } - private trackEvent(visitor: ua.Visitor, trackInfo: IGoogleAnalyticsEventData): Promise { return new Promise((resolve, reject) => { visitor.event(trackInfo.category, trackInfo.action, trackInfo.label, trackInfo.value, { p: this.currentPage }, (err: Error) => { diff --git a/lib/services/doctor-service.ts b/lib/services/doctor-service.ts index 4b0b95580b..514614833c 100644 --- a/lib/services/doctor-service.ts +++ b/lib/services/doctor-service.ts @@ -1,22 +1,19 @@ import { EOL } from "os"; import * as path from "path"; import * as helpers from "../common/helpers"; +import { TrackActionNames } from "../constants"; import { doctor, constants } from "nativescript-doctor"; class DoctorService implements IDoctorService { private static DarwinSetupScriptLocation = path.join(__dirname, "..", "..", "setup", "mac-startup-shell-script.sh"); - private static DarwinSetupDocsLink = "https://docs.nativescript.org/start/ns-setup-os-x"; private static WindowsSetupScriptExecutable = "powershell.exe"; private static WindowsSetupScriptArguments = ["start-process", "-FilePath", "PowerShell.exe", "-NoNewWindow", "-Wait", "-ArgumentList", '"-NoProfile -ExecutionPolicy Bypass -Command iex ((new-object net.webclient).DownloadString(\'https://www.nativescript.org/setup/win\'))"']; - private static WindowsSetupDocsLink = "https://docs.nativescript.org/start/ns-setup-win"; - private static LinuxSetupDocsLink = "https://docs.nativescript.org/start/ns-setup-linux"; constructor(private $analyticsService: IAnalyticsService, private $hostInfo: IHostInfo, private $logger: ILogger, private $childProcess: IChildProcess, - private $opener: IOpener, - private $prompter: IPrompter, + private $injector: IInjector, private $terminalSpinnerService: ITerminalSpinnerService, private $versionsService: IVersionsService) { } @@ -41,7 +38,6 @@ class DoctorService implements IDoctorService { if (hasWarnings) { this.$logger.info("There seem to be issues with your configuration."); - await this.promptForHelp(); } else { this.$logger.out("No issues were detected.".bold); } @@ -51,61 +47,65 @@ class DoctorService implements IDoctorService { } catch (err) { this.$logger.error("Cannot get the latest versions information from npm. Please try again later."); } + + await this.$injector.resolve("platformEnvironmentRequirements").checkEnvironmentRequirements(null); } - public runSetupScript(): Promise { + public async runSetupScript(): Promise { + await this.$analyticsService.trackEventActionInGoogleAnalytics({ + action: TrackActionNames.RunSetupScript, + additionalData: "Starting", + }); + if (this.$hostInfo.isLinux) { + await this.$analyticsService.trackEventActionInGoogleAnalytics({ + action: TrackActionNames.RunSetupScript, + additionalData: "Skipped as OS is Linux", + }); return; } this.$logger.out("Running the setup script to try and automatically configure your environment."); if (this.$hostInfo.isDarwin) { - return this.runSetupScriptCore(DoctorService.DarwinSetupScriptLocation, []); + await this.runSetupScriptCore(DoctorService.DarwinSetupScriptLocation, []); } if (this.$hostInfo.isWindows) { - return this.runSetupScriptCore(DoctorService.WindowsSetupScriptExecutable, DoctorService.WindowsSetupScriptArguments); + await this.runSetupScriptCore(DoctorService.WindowsSetupScriptExecutable, DoctorService.WindowsSetupScriptArguments); } + + await this.$analyticsService.trackEventActionInGoogleAnalytics({ + action: TrackActionNames.RunSetupScript, + additionalData: "Finished", + }); } public async canExecuteLocalBuild(platform?: string): Promise { + await this.$analyticsService.trackEventActionInGoogleAnalytics({ + action: TrackActionNames.CheckLocalBuildSetup, + additionalData: "Starting", + }); const infos = await doctor.getInfos({ platform }); const warnings = this.filterInfosByType(infos, constants.WARNING_TYPE_NAME); - if (warnings.length > 0) { + const hasWarnings = warnings.length > 0; + if (hasWarnings) { + await this.$analyticsService.trackEventActionInGoogleAnalytics({ + action: TrackActionNames.CheckLocalBuildSetup, + additionalData: `Warnings:${warnings.map(w => w.message).join("__")}`, + }); this.printInfosCore(infos); } else { infos.map(info => this.$logger.trace(info.message)); } - return warnings.length === 0; - } - - private async promptForDocs(link: string): Promise { - if (await this.$prompter.confirm("Do you want to visit the official documentation?", () => helpers.isInteractive())) { - this.$opener.open(link); - } - } - - private async promptForSetupScript(executablePath: string, setupScriptArgs: string[]): Promise { - if (await this.$prompter.confirm("Do you want to run the setup script?", () => helpers.isInteractive())) { - await this.runSetupScriptCore(executablePath, setupScriptArgs); - } - } - private async promptForHelp(): Promise { - if (this.$hostInfo.isDarwin) { - await this.promptForHelpCore(DoctorService.DarwinSetupDocsLink, DoctorService.DarwinSetupScriptLocation, []); - } else if (this.$hostInfo.isWindows) { - await this.promptForHelpCore(DoctorService.WindowsSetupDocsLink, DoctorService.WindowsSetupScriptExecutable, DoctorService.WindowsSetupScriptArguments); - } else { - await this.promptForDocs(DoctorService.LinuxSetupDocsLink); - } - } + await this.$analyticsService.trackEventActionInGoogleAnalytics({ + action: TrackActionNames.CheckLocalBuildSetup, + additionalData: `Finished: Is setup correct: ${!hasWarnings}`, + }); - private async promptForHelpCore(link: string, setupScriptExecutablePath: string, setupScriptArgs: string[]): Promise { - await this.promptForDocs(link); - await this.promptForSetupScript(setupScriptExecutablePath, setupScriptArgs); + return !hasWarnings; } private async runSetupScriptCore(executablePath: string, setupScriptArgs: string[]): Promise { diff --git a/lib/services/platform-environment-requirements.ts b/lib/services/platform-environment-requirements.ts index 0eba53eb58..cfc1213c2f 100644 --- a/lib/services/platform-environment-requirements.ts +++ b/lib/services/platform-environment-requirements.ts @@ -1,4 +1,4 @@ -import * as constants from "../constants"; +import { NATIVESCRIPT_CLOUD_EXTENSION_NAME, TrackActionNames } from "../constants"; import { isInteractive } from "../common/helpers"; import { EOL } from "os"; @@ -9,16 +9,19 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ private $logger: ILogger, private $nativeScriptCloudExtensionService: INativeScriptCloudExtensionService, private $prompter: IPrompter, - private $staticConfig: IStaticConfig) { } + private $staticConfig: IStaticConfig, + private $analyticsService: IAnalyticsService) { } public static CLOUD_SETUP_OPTION_NAME = "Configure for Cloud Builds"; public static LOCAL_SETUP_OPTION_NAME = "Configure for Local Builds"; + public static TRY_CLOUD_OPERATION_OPTION_NAME = "Try Cloud Operation"; public static MANUALLY_SETUP_OPTION_NAME = "Skip Step and Configure Manually"; private static BOTH_CLOUD_SETUP_AND_LOCAL_SETUP_OPTION_NAME = "Configure for Both Local and Cloud Builds"; private static CHOOSE_OPTIONS_MESSAGE = "To continue, choose one of the following options: "; - private static NOT_CONFIGURED_ENV_AFTER_SETUP_SCRIPT_MESSAGE = `The setup script was not able to configure your environment for local builds. To execute local builds, you have to set up your environment manually. In case you have any questions, you can check our forum: 'http://forum.nativescript.org' and our public Slack channel: 'https://nativescriptcommunity.slack.com/'. ${PlatformEnvironmentRequirements.CHOOSE_OPTIONS_MESSAGE}`; + private static NOT_CONFIGURED_ENV_AFTER_SETUP_SCRIPT_MESSAGE = `The setup script was not able to configure your environment for local builds. To execute local builds, you have to set up your environment manually. In case you have any questions, you can check our forum: 'http://forum.nativescript.org' and our public Slack channel: 'https://nativescriptcommunity.slack.com/'.`; private static MISSING_LOCAL_SETUP_MESSAGE = "Your environment is not configured properly and you will not be able to execute local builds."; - private static MISSING_LOCAL_AND_CLOUD_SETUP_MESSAGE = `You are missing the ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension and you will not be able to execute cloud builds. ${PlatformEnvironmentRequirements.MISSING_LOCAL_SETUP_MESSAGE} ${PlatformEnvironmentRequirements.CHOOSE_OPTIONS_MESSAGE} `; + private static MISSING_LOCAL_AND_CLOUD_SETUP_MESSAGE = `You are missing the ${NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension and you will not be able to execute cloud builds. ${PlatformEnvironmentRequirements.MISSING_LOCAL_SETUP_MESSAGE} ${PlatformEnvironmentRequirements.CHOOSE_OPTIONS_MESSAGE} `; + private static MISSING_LOCAL_BUT_CLOUD_SETUP_MESSAGE = `You have ${NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension installed, so you can execute cloud builds, but ${_.lowerFirst(PlatformEnvironmentRequirements.MISSING_LOCAL_SETUP_MESSAGE)}`; private static RUN_TNS_SETUP_MESSAGE = 'Run $ tns setup command to run the setup script to try to automatically configure your environment for local builds.'; private cliCommandToCloudCommandName: IStringDictionary = { @@ -27,23 +30,43 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ "deploy": "tns cloud deploy" }; - public async checkEnvironmentRequirements(platform: string): Promise { + public async checkEnvironmentRequirements(platform?: string): Promise { if (process.env.NS_SKIP_ENV_CHECK) { + await this.$analyticsService.trackEventActionInGoogleAnalytics({ + action: TrackActionNames.CheckEnvironmentRequirements, + additionalData: "Skipped: NS_SKIP_ENV_CHECK is set" + }); return true; } const canExecute = await this.$doctorService.canExecuteLocalBuild(platform); if (!canExecute) { if (!isInteractive()) { + await this.$analyticsService.trackEventActionInGoogleAnalytics({ + action: TrackActionNames.CheckEnvironmentRequirements, + additionalData: "Non-interactive terminal, unable to execute local builds." + }); this.fail(this.getNonInteractiveConsoleMessage(platform)); } - this.$logger.info(this.getInteractiveConsoleMessage(platform)); + const infoMessage = this.getInteractiveConsoleMessage(platform); + this.$logger.info(infoMessage); - const selectedOption = await this.promptForChoice(); + const choices = this.$nativeScriptCloudExtensionService.isInstalled() ? [ + PlatformEnvironmentRequirements.TRY_CLOUD_OPERATION_OPTION_NAME, + PlatformEnvironmentRequirements.LOCAL_SETUP_OPTION_NAME, + PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME, + ] : [ + PlatformEnvironmentRequirements.CLOUD_SETUP_OPTION_NAME, + PlatformEnvironmentRequirements.LOCAL_SETUP_OPTION_NAME, + PlatformEnvironmentRequirements.BOTH_CLOUD_SETUP_AND_LOCAL_SETUP_OPTION_NAME, + PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME, + ]; - await this.processCloudBuildsIfNeeded(platform, selectedOption); - this.processManuallySetupIfNeeded(platform, selectedOption); + const selectedOption = await this.promptForChoice({ infoMessage, choices }); + + await this.processCloudBuildsIfNeeded(selectedOption, platform); + this.processManuallySetupIfNeeded(selectedOption, platform); if (selectedOption === PlatformEnvironmentRequirements.LOCAL_SETUP_OPTION_NAME) { await this.$doctorService.runSetupScript(); @@ -53,48 +76,61 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ } if (this.$nativeScriptCloudExtensionService.isInstalled()) { - this.processManuallySetup(platform); + const option = await this.promptForChoice({ + infoMessage: PlatformEnvironmentRequirements.NOT_CONFIGURED_ENV_AFTER_SETUP_SCRIPT_MESSAGE, + choices: [ + PlatformEnvironmentRequirements.TRY_CLOUD_OPERATION_OPTION_NAME, + PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME + ] + }); + + this.processTryCloudSetupIfNeeded(option, platform); + this.processManuallySetupIfNeeded(option, platform); } else { - const option = await this.$prompter.promptForChoice(PlatformEnvironmentRequirements.NOT_CONFIGURED_ENV_AFTER_SETUP_SCRIPT_MESSAGE, [ - PlatformEnvironmentRequirements.CLOUD_SETUP_OPTION_NAME, - PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME - ]); - - await this.processCloudBuildsIfNeeded(platform, option); - - this.processManuallySetupIfNeeded(platform, option); + const option = await this.promptForChoice({ + infoMessage: PlatformEnvironmentRequirements.NOT_CONFIGURED_ENV_AFTER_SETUP_SCRIPT_MESSAGE, + choices: [ + PlatformEnvironmentRequirements.CLOUD_SETUP_OPTION_NAME, + PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME + ] + }); + + await this.processCloudBuildsIfNeeded(option, platform); + this.processManuallySetupIfNeeded(option, platform); } } if (selectedOption === PlatformEnvironmentRequirements.BOTH_CLOUD_SETUP_AND_LOCAL_SETUP_OPTION_NAME) { - await this.processBothCloudBuildsAndSetupScript(platform); + await this.processBothCloudBuildsAndSetupScript(); if (await this.$doctorService.canExecuteLocalBuild(platform)) { return true; } this.processManuallySetup(platform); } + + this.processTryCloudSetupIfNeeded(selectedOption, platform); } return true; } - private async processCloudBuildsIfNeeded(platform: string, selectedOption: string): Promise { + private async processCloudBuildsIfNeeded(selectedOption: string, platform?: string): Promise { if (selectedOption === PlatformEnvironmentRequirements.CLOUD_SETUP_OPTION_NAME) { await this.processCloudBuilds(platform); } } private async processCloudBuilds(platform: string): Promise { - await this.processCloudBuildsCore(platform); + await this.processCloudBuildsCore(); this.fail(this.getCloudBuildsMessage(platform)); } - private processCloudBuildsCore(platform: string): Promise { + private processCloudBuildsCore(): Promise { return this.$nativeScriptCloudExtensionService.install(); } - private getCloudBuildsMessage(platform: string): string { + private getCloudBuildsMessage(platform?: string): string { const cloudCommandName = this.cliCommandToCloudCommandName[this.$commandsService.currentCommandData.commandName]; if (!cloudCommandName) { return `In order to test your application use the $ tns login command to log in with your account and then $ tns cloud build command to build your app in the cloud.`; @@ -107,21 +143,27 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ return `Use the $ tns login command to log in with your account and then $ ${cloudCommandName.toLowerCase()} ${platform.toLowerCase()} command.`; } - private processManuallySetupIfNeeded(platform: string, selectedOption: string) { + private processTryCloudSetupIfNeeded(selectedOption: string, platform?: string) { + if (selectedOption === PlatformEnvironmentRequirements.TRY_CLOUD_OPERATION_OPTION_NAME) { + this.fail(this.getCloudBuildsMessage(platform)); + } + } + + private processManuallySetupIfNeeded(selectedOption: string, platform?: string) { if (selectedOption === PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME) { this.processManuallySetup(platform); } } - private processManuallySetup(platform: string): void { - this.fail(`To be able to build for ${platform}, verify that your environment is configured according to the system requirements described at ${this.$staticConfig.SYS_REQUIREMENTS_LINK}`); + private processManuallySetup(platform?: string): void { + this.fail(`To be able to ${platform ? `build for ${platform}` : 'build'}, verify that your environment is configured according to the system requirements described at ${this.$staticConfig.SYS_REQUIREMENTS_LINK}. In case you have any questions, you can check our forum: 'http://forum.nativescript.org' and our public Slack channel: 'https://nativescriptcommunity.slack.com/'.`); } - private async processBothCloudBuildsAndSetupScript(platform: string): Promise { + private async processBothCloudBuildsAndSetupScript(): Promise { try { - await this.processCloudBuildsCore(platform); + await this.processCloudBuildsCore(); } catch (e) { - this.$logger.trace(`Error while installing ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension. ${e.message}.`); + this.$logger.trace(`Error while installing ${NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension. ${e.message}.`); } await this.$doctorService.runSetupScript(); @@ -142,42 +184,43 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ this.buildMultilineMessage([ PlatformEnvironmentRequirements.MISSING_LOCAL_AND_CLOUD_SETUP_MESSAGE, PlatformEnvironmentRequirements.RUN_TNS_SETUP_MESSAGE, - `Run $ tns cloud setup command to install the ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension to configure your environment for cloud builds.`, + `Run $ tns cloud setup command to install the ${NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension to configure your environment for cloud builds.`, this.getEnvVerificationMessage() ]); } private getInteractiveConsoleMessage(platform: string) { - const message = `The ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension is installed and you can ${_.lowerFirst(this.getCloudBuildsMessage(platform))}`; - return this.$nativeScriptCloudExtensionService.isInstalled() ? this.buildMultilineMessage([ - `${message.bold}`, - `${PlatformEnvironmentRequirements.MISSING_LOCAL_SETUP_MESSAGE} ${PlatformEnvironmentRequirements.CHOOSE_OPTIONS_MESSAGE}`, + `${PlatformEnvironmentRequirements.MISSING_LOCAL_BUT_CLOUD_SETUP_MESSAGE} ${PlatformEnvironmentRequirements.CHOOSE_OPTIONS_MESSAGE}`, `Select "Configure for Local Builds" to run the setup script and automatically configure your environment for local builds.`, `Select "Skip Step and Configure Manually" to disregard this option and install any required components manually.` ]) : this.buildMultilineMessage([ PlatformEnvironmentRequirements.MISSING_LOCAL_AND_CLOUD_SETUP_MESSAGE, - `Select "Configure for Cloud Builds" to install the ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension and automatically configure your environment for cloud builds.`, + `Select "Configure for Cloud Builds" to install the ${NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension and automatically configure your environment for cloud builds.`, `Select "Configure for Local Builds" to run the setup script and automatically configure your environment for local builds.`, `Select "Configure for Both Local and Cloud Builds" to automatically configure your environment for both options.`, `Select "Configure for Both Local and Cloud Builds" to automatically configure your environment for both options.` ]); } - private promptForChoice(): Promise { - const choices = this.$nativeScriptCloudExtensionService.isInstalled() ? [ - PlatformEnvironmentRequirements.LOCAL_SETUP_OPTION_NAME, - PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME, - ] : [ - PlatformEnvironmentRequirements.CLOUD_SETUP_OPTION_NAME, - PlatformEnvironmentRequirements.LOCAL_SETUP_OPTION_NAME, - PlatformEnvironmentRequirements.BOTH_CLOUD_SETUP_AND_LOCAL_SETUP_OPTION_NAME, - PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME, - ]; - - return this.$prompter.promptForChoice(PlatformEnvironmentRequirements.CHOOSE_OPTIONS_MESSAGE, choices); + private async promptForChoice(opts: { infoMessage: string, choices: string[], }): Promise { + this.$logger.info(opts.infoMessage); + + await this.$analyticsService.trackEventActionInGoogleAnalytics({ + action: TrackActionNames.CheckEnvironmentRequirements, + additionalData: `User should select: ${opts.infoMessage}` + }); + + const selection = await this.$prompter.promptForChoice(PlatformEnvironmentRequirements.CHOOSE_OPTIONS_MESSAGE, opts.choices); + + await this.$analyticsService.trackEventActionInGoogleAnalytics({ + action: TrackActionNames.CheckEnvironmentRequirements, + additionalData: `User selected: ${selection}` + }); + + return selection; } private getEnvVerificationMessage() { diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index c817cbf714..94fff61155 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -341,7 +341,7 @@ export class PlatformService extends EventEmitter implements IPlatformService { } const platformData = this.$platformsData.getPlatformData(platform, projectData); - const forDevice = !buildConfig || buildConfig.buildForDevice; + const forDevice = !buildConfig || !!buildConfig.buildForDevice; outputPath = outputPath || (forDevice ? platformData.deviceBuildOutputPath : platformData.emulatorBuildOutputPath || platformData.deviceBuildOutputPath); if (!this.$fs.exists(outputPath)) { return true; diff --git a/test/services/platform-environment-requirements.ts b/test/services/platform-environment-requirements.ts index abb8bb76ee..28d577b120 100644 --- a/test/services/platform-environment-requirements.ts +++ b/test/services/platform-environment-requirements.ts @@ -13,6 +13,9 @@ const nonInteractiveConsoleMessageWhenExtensionIsInstalled = `Your environment i function createTestInjector() { const testInjector = new Yok(); + testInjector.register("analyticsService", { + trackEventActionInGoogleAnalytics: () => ({}) + }); testInjector.register("commandsService", {currentCommandData: {commandName: "test", commandArguments: [""]}}); testInjector.register("doctorService", {}); testInjector.register("errors", { @@ -103,7 +106,7 @@ describe("platformEnvironmentRequirements ", () => { await assert.isRejected(platformEnvironmentRequirements.checkEnvironmentRequirements(platform)); assert.isTrue(promptForChoiceData.length === 1); assert.deepEqual("To continue, choose one of the following options: ", promptForChoiceData[0].message); - assert.deepEqual(['Configure for Local Builds', 'Skip Step and Configure Manually'], promptForChoiceData[0].choices); + assert.deepEqual(['Try Cloud Operation', 'Configure for Local Builds', 'Skip Step and Configure Manually'], promptForChoiceData[0].choices); }); it("should skip env chech when NS_SKIP_ENV_CHECK environment variable is passed", async() => { process.env.NS_SKIP_ENV_CHECK = true;