Skip to content

Commit 360b9c9

Browse files
author
Fatme
authored
Merge pull request #3418 from NativeScript/fatme/info-messages
Getting started improvements
2 parents 75ad246 + d61fe60 commit 360b9c9

12 files changed

+343
-136
lines changed

lib/bootstrap.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,4 @@ $injector.requirePublic("extensibilityService", "./services/extensibility-servic
144144

145145
$injector.require("nodeModulesDependenciesBuilder", "./tools/node-modules/node-modules-dependencies-builder");
146146
$injector.require("subscriptionService", "./services/subscription-service");
147+
$injector.require("terminalSpinnerService", "./services/terminal-spinner-service");

lib/commands/post-install.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export class PostInstallCliCommand extends PostInstallCommand {
1010
$doctorService: IDoctorService,
1111
$analyticsService: IAnalyticsService,
1212
$logger: ILogger) {
13-
super($fs, $staticConfig, $commandsService, $helpService, $settingsService, $doctorService, $analyticsService, $logger);
13+
super($fs, $staticConfig, $commandsService, $helpService, $settingsService, $analyticsService, $logger);
1414
}
1515

1616
public async execute(args: string[]): Promise<void> {
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
interface ITerminalSpinnerService {
2+
createSpinner(spinnerOptions?: ITerminalSpinnerOptions): ITerminalSpinner;
3+
execute<T>(spinnerOptions: ITerminalSpinnerOptions, action: () => Promise<T>): Promise<T>;
4+
}
5+
6+
type SpinnerName =
7+
'dots'
8+
| 'dots2'
9+
| 'dots3'
10+
| 'dots4'
11+
| 'dots5'
12+
| 'dots6'
13+
| 'dots7'
14+
| 'dots8'
15+
| 'dots9'
16+
| 'dots10'
17+
| 'dots11'
18+
| 'dots12'
19+
| 'line'
20+
| 'line2'
21+
| 'pipe'
22+
| 'simpleDots'
23+
| 'simpleDotsScrolling'
24+
| 'star'
25+
| 'star2'
26+
| 'flip'
27+
| 'hamburger'
28+
| 'growVertical'
29+
| 'growHorizontal'
30+
| 'balloon'
31+
| 'balloon2'
32+
| 'noise'
33+
| 'bounce'
34+
| 'boxBounce'
35+
| 'boxBounce2'
36+
| 'triangle'
37+
| 'arc'
38+
| 'circle'
39+
| 'squareCorners'
40+
| 'circleQuarters'
41+
| 'circleHalves'
42+
| 'squish'
43+
| 'toggle'
44+
| 'toggle2'
45+
| 'toggle3'
46+
| 'toggle4'
47+
| 'toggle5'
48+
| 'toggle6'
49+
| 'toggle7'
50+
| 'toggle8'
51+
| 'toggle9'
52+
| 'toggle10'
53+
| 'toggle11'
54+
| 'toggle12'
55+
| 'toggle13'
56+
| 'arrow'
57+
| 'arrow2'
58+
| 'arrow3'
59+
| 'bouncingBar'
60+
| 'bouncingBall'
61+
| 'smiley'
62+
| 'monkey'
63+
| 'hearts'
64+
| 'clock'
65+
| 'earth'
66+
| 'moon'
67+
| 'runner'
68+
| 'pong'
69+
| 'shark'
70+
| 'dqpb';
71+
72+
interface Spinner {
73+
interval?: number;
74+
frames: string[];
75+
}
76+
77+
interface ITerminalSpinner {
78+
text: string;
79+
start(text?: string): ITerminalSpinner;
80+
stop(): ITerminalSpinner;
81+
succeed(text?: string): ITerminalSpinner;
82+
fail(text?: string): ITerminalSpinner;
83+
warn(text?: string): ITerminalSpinner;
84+
info(text?: string): ITerminalSpinner;
85+
clear(): ITerminalSpinner;
86+
render(): ITerminalSpinner;
87+
frame(): ITerminalSpinner;
88+
}
89+
90+
interface ITerminalSpinnerOptions {
91+
text?: string;
92+
spinner?: SpinnerName | Spinner;
93+
color?: 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'gray';
94+
interval?: number;
95+
stream?: NodeJS.WritableStream;
96+
enabled?: boolean;
97+
}

lib/services/doctor-service.ts

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@ class DoctorService implements IDoctorService {
1717
private $childProcess: IChildProcess,
1818
private $opener: IOpener,
1919
private $prompter: IPrompter,
20+
private $terminalSpinnerService: ITerminalSpinnerService,
2021
private $versionsService: IVersionsService) { }
2122

2223
public async printWarnings(configOptions?: { trackResult: boolean }): Promise<boolean> {
23-
const warnings = await doctor.getWarnings();
24+
const infos = await this.$terminalSpinnerService.execute<NativeScriptDoctor.IInfo[]>({
25+
text: `Getting environment information ${EOL}`
26+
}, () => doctor.getInfos());
27+
28+
const warnings = infos.filter(info => info.type === constants.WARNING_TYPE_NAME);
2429
const hasWarnings = warnings.length > 0;
2530

2631
const hasAndroidWarnings = warnings.filter(warning => _.includes(warning.platforms, constants.ANDROID_PLATFORM_NAME)).length > 0;
@@ -32,20 +37,11 @@ class DoctorService implements IDoctorService {
3237
await this.$analyticsService.track("DoctorEnvironmentSetup", hasWarnings ? "incorrect" : "correct");
3338
}
3439

35-
if (hasWarnings) {
36-
warnings.map(warning => {
37-
this.$logger.warn(warning.warning);
38-
this.$logger.out(warning.additionalInformation);
39-
});
40+
this.printInfosCore(infos);
4041

42+
if (hasWarnings) {
4143
this.$logger.info("There seem to be issues with your configuration.");
42-
if (this.$hostInfo.isDarwin) {
43-
await this.promptForHelp(DoctorService.DarwinSetupDocsLink, DoctorService.DarwinSetupScriptLocation, []);
44-
} else if (this.$hostInfo.isWindows) {
45-
await this.promptForHelp(DoctorService.WindowsSetupDocsLink, DoctorService.WindowsSetupScriptExecutable, DoctorService.WindowsSetupScriptArguments);
46-
} else {
47-
await this.promptForDocs(DoctorService.LinuxSetupDocsLink);
48-
}
44+
await this.promptForHelp();
4945
}
5046

5147
try {
@@ -63,20 +59,46 @@ class DoctorService implements IDoctorService {
6359
}
6460
}
6561

66-
private async promptForHelp(link: string, commandName: string, commandArguments: string[]): Promise<void> {
62+
private async promptForHelpCore(link: string, commandName: string, commandArguments: string[]): Promise<void> {
6763
await this.promptForDocs(link);
6864

6965
if (await this.$prompter.confirm("Do you want to run the setup script?", () => helpers.isInteractive())) {
7066
await this.$childProcess.spawnFromEvent(commandName, commandArguments, "close", { stdio: "inherit" });
7167
}
7268
}
7369

70+
private async promptForHelp(): Promise<void> {
71+
if (this.$hostInfo.isDarwin) {
72+
await this.promptForHelpCore(DoctorService.DarwinSetupDocsLink, DoctorService.DarwinSetupScriptLocation, []);
73+
} else if (this.$hostInfo.isWindows) {
74+
await this.promptForHelpCore(DoctorService.WindowsSetupDocsLink, DoctorService.WindowsSetupScriptExecutable, DoctorService.WindowsSetupScriptArguments);
75+
} else {
76+
await this.promptForDocs(DoctorService.LinuxSetupDocsLink);
77+
}
78+
}
79+
7480
private printPackageManagerTip() {
7581
if (this.$hostInfo.isWindows) {
7682
this.$logger.out("TIP: To avoid setting up the necessary environment variables, you can use the chocolatey package manager to install the Android SDK and its dependencies." + EOL);
7783
} else if (this.$hostInfo.isDarwin) {
7884
this.$logger.out("TIP: To avoid setting up the necessary environment variables, you can use the Homebrew package manager to install the Android SDK and its dependencies." + EOL);
7985
}
8086
}
87+
88+
private printInfosCore(infos: NativeScriptDoctor.IInfo[]): void {
89+
infos.filter(info => info.type === constants.INFO_TYPE_NAME)
90+
.map(info => {
91+
const spinner = this.$terminalSpinnerService.createSpinner();
92+
spinner.text = info.message;
93+
spinner.succeed();
94+
});
95+
96+
infos.filter(info => info.type === constants.WARNING_TYPE_NAME)
97+
.map(info => {
98+
const spinner = this.$terminalSpinnerService.createSpinner();
99+
spinner.text = `${info.message.yellow} ${EOL} ${info.additionalInformation} ${EOL}`;
100+
spinner.fail();
101+
});
102+
}
81103
}
82104
$injector.register("doctorService", DoctorService);

lib/services/platform-service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ export class PlatformService extends EventEmitter implements IPlatformService {
2424
constructor(private $devicesService: Mobile.IDevicesService,
2525
private $preparePlatformNativeService: IPreparePlatformService,
2626
private $preparePlatformJSService: IPreparePlatformService,
27-
private $progressIndicator: IProgressIndicator,
2827
private $errors: IErrors,
2928
private $fs: IFileSystem,
3029
private $logger: ILogger,
@@ -40,7 +39,8 @@ export class PlatformService extends EventEmitter implements IPlatformService {
4039
private $npm: INodePackageManager,
4140
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
4241
private $projectChangesService: IProjectChangesService,
43-
private $analyticsService: IAnalyticsService) {
42+
private $analyticsService: IAnalyticsService,
43+
private $terminalSpinnerService: ITerminalSpinnerService) {
4444
super();
4545
}
4646

@@ -115,7 +115,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
115115
npmOptions["version"] = version;
116116
}
117117

118-
const spinner = this.$progressIndicator.getSpinner("Installing " + packageToInstall);
118+
const spinner = this.$terminalSpinnerService.createSpinner();
119119
const projectDir = projectData.projectDir;
120120
const platformPath = path.join(projectData.platformsDir, platform);
121121

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import * as ora from 'ora';
2+
3+
export class TerminalSpinnerService implements ITerminalSpinnerService {
4+
public createSpinner(spinnerOptions: ITerminalSpinnerOptions = {}): ITerminalSpinner {
5+
spinnerOptions.stream = spinnerOptions.stream || process.stdout;
6+
return new ora(spinnerOptions);
7+
}
8+
9+
public async execute<T>(spinnerOptions: ITerminalSpinnerOptions, action: () => Promise<T>): Promise<T> {
10+
const spinner = this.createSpinner(spinnerOptions);
11+
12+
spinner.start();
13+
14+
let result: T = null;
15+
try {
16+
result = await action();
17+
} catch (err) {
18+
spinner.fail();
19+
return null;
20+
}
21+
22+
spinner.succeed();
23+
24+
return result;
25+
}
26+
}
27+
$injector.register('terminalSpinnerService', TerminalSpinnerService);

0 commit comments

Comments
 (0)