Skip to content

Commit 9497818

Browse files
Fatmerosen-vladimirov
authored andcommitted
* Show getting started prompts on doctor command
* Fix unit test * Show message that user can use forum or slack when manually setup is selected * Fix message when nativescript-cloud extension is installed
1 parent 676b774 commit 9497818

6 files changed

+30
-64
lines changed

lib/definitions/platform.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -381,5 +381,5 @@ interface IUpdateAppOptions extends IOptionalFilesToSync, IOptionalFilesToRemove
381381
}
382382

383383
interface IPlatformEnvironmentRequirements {
384-
checkEnvironmentRequirements(platform: string, projectDir: string): Promise<boolean>;
384+
checkEnvironmentRequirements(platform?: string): Promise<boolean>;
385385
}

lib/services/android-project-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
133133
this.validatePackageName(projectData.projectId);
134134
this.validateProjectName(projectData.projectName);
135135

136-
await this.$platformEnvironmentRequirements.checkEnvironmentRequirements(this.getPlatformData(projectData).normalizedPlatformName, projectData.projectDir);
136+
await this.$platformEnvironmentRequirements.checkEnvironmentRequirements(this.getPlatformData(projectData).normalizedPlatformName);
137137
this.$androidToolsInfo.validateTargetSdk({ showWarningsAsErrors: true });
138138
}
139139

lib/services/doctor-service.ts

+3-33
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,14 @@ import { doctor, constants } from "nativescript-doctor";
55

66
class DoctorService implements IDoctorService {
77
private static DarwinSetupScriptLocation = path.join(__dirname, "..", "..", "setup", "mac-startup-shell-script.sh");
8-
private static DarwinSetupDocsLink = "https://docs.nativescript.org/start/ns-setup-os-x";
98
private static WindowsSetupScriptExecutable = "powershell.exe";
109
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\'))"'];
11-
private static WindowsSetupDocsLink = "https://docs.nativescript.org/start/ns-setup-win";
12-
private static LinuxSetupDocsLink = "https://docs.nativescript.org/start/ns-setup-linux";
1310

1411
constructor(private $analyticsService: IAnalyticsService,
1512
private $hostInfo: IHostInfo,
1613
private $logger: ILogger,
1714
private $childProcess: IChildProcess,
18-
private $opener: IOpener,
19-
private $prompter: IPrompter,
15+
private $injector: IInjector,
2016
private $terminalSpinnerService: ITerminalSpinnerService,
2117
private $versionsService: IVersionsService) { }
2218

@@ -41,7 +37,6 @@ class DoctorService implements IDoctorService {
4137

4238
if (hasWarnings) {
4339
this.$logger.info("There seem to be issues with your configuration.");
44-
await this.promptForHelp();
4540
} else {
4641
this.$logger.out("No issues were detected.".bold);
4742
}
@@ -51,6 +46,8 @@ class DoctorService implements IDoctorService {
5146
} catch (err) {
5247
this.$logger.error("Cannot get the latest versions information from npm. Please try again later.");
5348
}
49+
50+
await this.$injector.resolve("platformEnvironmentRequirements").checkEnvironmentRequirements(null);
5451
}
5552

5653
public async runSetupScript(): Promise<ISpawnResult> {
@@ -113,33 +110,6 @@ class DoctorService implements IDoctorService {
113110
return !hasWarnings;
114111
}
115112

116-
private async promptForDocs(link: string): Promise<void> {
117-
if (await this.$prompter.confirm("Do you want to visit the official documentation?", () => helpers.isInteractive())) {
118-
this.$opener.open(link);
119-
}
120-
}
121-
122-
private async promptForSetupScript(executablePath: string, setupScriptArgs: string[]): Promise<void> {
123-
if (await this.$prompter.confirm("Do you want to run the setup script?", () => helpers.isInteractive())) {
124-
await this.runSetupScriptCore(executablePath, setupScriptArgs);
125-
}
126-
}
127-
128-
private async promptForHelp(): Promise<void> {
129-
if (this.$hostInfo.isDarwin) {
130-
await this.promptForHelpCore(DoctorService.DarwinSetupDocsLink, DoctorService.DarwinSetupScriptLocation, []);
131-
} else if (this.$hostInfo.isWindows) {
132-
await this.promptForHelpCore(DoctorService.WindowsSetupDocsLink, DoctorService.WindowsSetupScriptExecutable, DoctorService.WindowsSetupScriptArguments);
133-
} else {
134-
await this.promptForDocs(DoctorService.LinuxSetupDocsLink);
135-
}
136-
}
137-
138-
private async promptForHelpCore(link: string, setupScriptExecutablePath: string, setupScriptArgs: string[]): Promise<void> {
139-
await this.promptForDocs(link);
140-
await this.promptForSetupScript(setupScriptExecutablePath, setupScriptArgs);
141-
}
142-
143113
private async runSetupScriptCore(executablePath: string, setupScriptArgs: string[]): Promise<ISpawnResult> {
144114
return this.$childProcess.spawnFromEvent(executablePath, setupScriptArgs, "close", { stdio: "inherit" });
145115
}

lib/services/ios-project-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
139139
return;
140140
}
141141

142-
await this.$platformEnvironmentRequirements.checkEnvironmentRequirements(this.getPlatformData(projectData).normalizedPlatformName, projectData.projectDir);
142+
await this.$platformEnvironmentRequirements.checkEnvironmentRequirements(this.getPlatformData(projectData).normalizedPlatformName);
143143

144144
const xcodeBuildVersion = await this.getXcodeVersion();
145145
if (helpers.versionCompare(xcodeBuildVersion, IOSProjectService.XCODEBUILD_MIN_VERSION) < 0) {

lib/services/platform-environment-requirements.ts

+20-27
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ
2121
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}`;
2222
private static MISSING_LOCAL_SETUP_MESSAGE = "Your environment is not configured properly and you will not be able to execute local builds.";
2323
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} `;
24+
private static MISSING_LOCAL_BUT_CLOUD_SETUP_MESSAGE = `You have ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension installed but ${_.lowerFirst(PlatformEnvironmentRequirements.MISSING_LOCAL_SETUP_MESSAGE)}`;
2425
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.';
2526

2627
private cliCommandToCloudCommandName: IStringDictionary = {
@@ -29,12 +30,11 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ
2930
"deploy": "tns cloud deploy"
3031
};
3132

32-
public async checkEnvironmentRequirements(platform: string, projectDir: string): Promise<boolean> {
33+
public async checkEnvironmentRequirements(platform?: string): Promise<boolean> {
3334
if (process.env.NS_SKIP_ENV_CHECK) {
3435
await this.$analyticsService.trackEventActionInGoogleAnalytics({
3536
action: "Check Environment Requirements",
36-
additionalData: "Skipped:NS_SKIP_ENV_CHECK is set",
37-
projectDir
37+
additionalData: "Skipped:NS_SKIP_ENV_CHECK is set"
3838
});
3939
return true;
4040
}
@@ -44,8 +44,7 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ
4444
if (!isInteractive()) {
4545
await this.$analyticsService.trackEventActionInGoogleAnalytics({
4646
action: "Check Environment Requirements",
47-
additionalData: "Non-interactive terminal, unable to execute local builds.",
48-
projectDir
47+
additionalData: "Non-interactive terminal, unable to execute local builds."
4948
});
5049
this.fail(this.getNonInteractiveConsoleMessage(platform));
5150
}
@@ -54,8 +53,8 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ
5453

5554
const selectedOption = await this.promptForChoice();
5655

57-
await this.processCloudBuildsIfNeeded(platform, selectedOption);
58-
this.processManuallySetupIfNeeded(platform, selectedOption);
56+
await this.processCloudBuildsIfNeeded(selectedOption, platform);
57+
this.processManuallySetupIfNeeded(selectedOption, platform);
5958

6059
if (selectedOption === PlatformEnvironmentRequirements.LOCAL_SETUP_OPTION_NAME) {
6160
await this.$doctorService.runSetupScript();
@@ -72,14 +71,13 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ
7271
PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME
7372
]);
7473

75-
await this.processCloudBuildsIfNeeded(platform, option);
76-
77-
this.processManuallySetupIfNeeded(platform, option);
74+
await this.processCloudBuildsIfNeeded(option, platform);
75+
this.processManuallySetupIfNeeded(option, platform);
7876
}
7977
}
8078

8179
if (selectedOption === PlatformEnvironmentRequirements.BOTH_CLOUD_SETUP_AND_LOCAL_SETUP_OPTION_NAME) {
82-
await this.processBothCloudBuildsAndSetupScript(platform);
80+
await this.processBothCloudBuildsAndSetupScript();
8381
if (await this.$doctorService.canExecuteLocalBuild(platform)) {
8482
return true;
8583
}
@@ -88,30 +86,29 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ
8886
}
8987

9088
if (selectedOption === PlatformEnvironmentRequirements.TRY_CLOUD_OPERATION_OPTION_NAME) {
91-
const message = `You can use ${_.lowerFirst(this.getCloudBuildsMessage(platform))}`;
92-
this.fail(message);
89+
this.fail(this.getCloudBuildsMessage(platform));
9390
}
9491
}
9592

9693
return true;
9794
}
9895

99-
private async processCloudBuildsIfNeeded(platform: string, selectedOption: string): Promise<void> {
96+
private async processCloudBuildsIfNeeded(selectedOption: string, platform?: string): Promise<void> {
10097
if (selectedOption === PlatformEnvironmentRequirements.CLOUD_SETUP_OPTION_NAME) {
10198
await this.processCloudBuilds(platform);
10299
}
103100
}
104101

105102
private async processCloudBuilds(platform: string): Promise<void> {
106-
await this.processCloudBuildsCore(platform);
103+
await this.processCloudBuildsCore();
107104
this.fail(this.getCloudBuildsMessage(platform));
108105
}
109106

110-
private processCloudBuildsCore(platform: string): Promise<IExtensionData> {
107+
private processCloudBuildsCore(): Promise<IExtensionData> {
111108
return this.$nativeScriptCloudExtensionService.install();
112109
}
113110

114-
private getCloudBuildsMessage(platform: string): string {
111+
private getCloudBuildsMessage(platform?: string): string {
115112
const cloudCommandName = this.cliCommandToCloudCommandName[this.$commandsService.currentCommandData.commandName];
116113
if (!cloudCommandName) {
117114
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.`;
@@ -124,19 +121,19 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ
124121
return `Use the $ tns login command to log in with your account and then $ ${cloudCommandName.toLowerCase()} ${platform.toLowerCase()} command.`;
125122
}
126123

127-
private processManuallySetupIfNeeded(platform: string, selectedOption: string) {
124+
private processManuallySetupIfNeeded(selectedOption: string, platform?: string) {
128125
if (selectedOption === PlatformEnvironmentRequirements.MANUALLY_SETUP_OPTION_NAME) {
129126
this.processManuallySetup(platform);
130127
}
131128
}
132129

133-
private processManuallySetup(platform: string): void {
134-
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}`);
130+
private processManuallySetup(platform?: string): void {
131+
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/'.`);
135132
}
136133

137-
private async processBothCloudBuildsAndSetupScript(platform: string): Promise<void> {
134+
private async processBothCloudBuildsAndSetupScript(): Promise<void> {
138135
try {
139-
await this.processCloudBuildsCore(platform);
136+
await this.processCloudBuildsCore();
140137
} catch (e) {
141138
this.$logger.trace(`Error while installing ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension. ${e.message}.`);
142139
}
@@ -165,12 +162,9 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ
165162
}
166163

167164
private getInteractiveConsoleMessage(platform: string) {
168-
const message = `The ${constants.NATIVESCRIPT_CLOUD_EXTENSION_NAME} extension is installed and you can ${_.lowerFirst(this.getCloudBuildsMessage(platform))}`;
169-
170165
return this.$nativeScriptCloudExtensionService.isInstalled() ?
171166
this.buildMultilineMessage([
172-
`${message.bold}`,
173-
`${PlatformEnvironmentRequirements.MISSING_LOCAL_SETUP_MESSAGE} ${PlatformEnvironmentRequirements.CHOOSE_OPTIONS_MESSAGE}`,
167+
`${PlatformEnvironmentRequirements.MISSING_LOCAL_BUT_CLOUD_SETUP_MESSAGE} ${PlatformEnvironmentRequirements.CHOOSE_OPTIONS_MESSAGE}`,
174168
`Select "Configure for Local Builds" to run the setup script and automatically configure your environment for local builds.`,
175169
`Select "Skip Step and Configure Manually" to disregard this option and install any required components manually.`
176170
]) :
@@ -199,7 +193,6 @@ export class PlatformEnvironmentRequirements implements IPlatformEnvironmentRequ
199193
await this.$analyticsService.trackEventActionInGoogleAnalytics({
200194
action: "Check Environment Requirements",
201195
additionalData: `User selected: ${selection}`
202-
// consider passing projectDir here
203196
});
204197
return selection;
205198
}

test/services/platform-environment-requirements.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ const nonInteractiveConsoleMessageWhenExtensionIsInstalled = `Your environment i
1313
function createTestInjector() {
1414
const testInjector = new Yok();
1515

16+
testInjector.register("analyticsService", {
17+
trackEventActionInGoogleAnalytics: () => ({})
18+
});
1619
testInjector.register("commandsService", {currentCommandData: {commandName: "test", commandArguments: [""]}});
1720
testInjector.register("doctorService", {});
1821
testInjector.register("errors", {
@@ -103,7 +106,7 @@ describe("platformEnvironmentRequirements ", () => {
103106
await assert.isRejected(platformEnvironmentRequirements.checkEnvironmentRequirements(platform));
104107
assert.isTrue(promptForChoiceData.length === 1);
105108
assert.deepEqual("To continue, choose one of the following options: ", promptForChoiceData[0].message);
106-
assert.deepEqual(['Configure for Local Builds', 'Skip Step and Configure Manually'], promptForChoiceData[0].choices);
109+
assert.deepEqual(['Try Cloud Operation', 'Configure for Local Builds', 'Skip Step and Configure Manually'], promptForChoiceData[0].choices);
107110
});
108111
it("should skip env chech when NS_SKIP_ENV_CHECK environment variable is passed", async() => {
109112
process.env.NS_SKIP_ENV_CHECK = true;

0 commit comments

Comments
 (0)