Skip to content

Commit efd8a22

Browse files
committed
Get sysInfos based on specified platform
In case when android platform is specified, checks only android related things. In case when iOS platform is specified, checks only iOS related things. When no platform is specified, checks both Android and iOS things. This will improve the time {N} CLI needs to check if environment is correctly configured for platform specific commands. This also will fix failing cloud builds.
1 parent df2dbec commit efd8a22

File tree

4 files changed

+250
-140
lines changed

4 files changed

+250
-140
lines changed

lib/doctor.ts

+62-39
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,51 @@ export class Doctor implements NativeScriptDoctor.IDoctor {
3232
let result: NativeScriptDoctor.IInfo[] = [];
3333
const sysInfoData = await this.sysInfo.getSysInfo(config);
3434

35+
result = result.concat(
36+
this.processSysInfoItem({
37+
item: sysInfoData.gitVer,
38+
infoMessage: "Git is installed and is configured properly.",
39+
warningMessage: "Git is not installed or not configured properly.",
40+
additionalInformation: "You will not be able to create and work with Screen Builder projects." + EOL
41+
+ "To be able to work with Screen Builder projects, download and install Git as described" + EOL
42+
+ "in https://git-scm.com/downloads and add the git executable to your PATH.",
43+
platforms: Constants.SUPPORTED_PLATFORMS
44+
})
45+
);
46+
47+
if (config && config.platform === Constants.ANDROID_PLATFORM_NAME) {
48+
result = result.concat(this.getAndroidInfos(sysInfoData));
49+
}
50+
51+
if (config && config.platform === Constants.IOS_PLATFORM_NAME) {
52+
result = result.concat(await this.getiOSInfos(sysInfoData));
53+
}
54+
55+
if (!config || !config.platform) {
56+
result = result.concat(this.getAndroidInfos(sysInfoData), await this.getiOSInfos(sysInfoData));
57+
}
58+
59+
if (!this.hostInfo.isDarwin) {
60+
result.push({
61+
message: "Local builds for iOS can be executed only on a macOS system. To build for iOS on a different operating system, you can use the NativeScript cloud infrastructure.",
62+
additionalInformation: "",
63+
platforms: [Constants.IOS_PLATFORM_NAME],
64+
type: Constants.INFO_TYPE_NAME
65+
});
66+
}
67+
68+
return result;
69+
}
70+
71+
public async getWarnings(config?: NativeScriptDoctor.ISysInfoConfig): Promise<NativeScriptDoctor.IWarning[]> {
72+
const info = await this.getInfos(config);
73+
return info.filter(item => item.type === Constants.WARNING_TYPE_NAME)
74+
.map(item => this.convertInfoToWarning(item));
75+
}
76+
77+
private getAndroidInfos(sysInfoData: NativeScriptDoctor.ISysInfoData): NativeScriptDoctor.IInfo[] {
78+
let result: NativeScriptDoctor.IInfo[] = [];
79+
3580
result = result.concat(
3681
this.processValidationErrors({
3782
warnings: this.androidToolsInfo.validateAndroidHomeEnvVariable(),
@@ -66,9 +111,24 @@ export class Doctor implements NativeScriptDoctor.IDoctor {
66111
warnings: this.androidToolsInfo.validateJavacVersion(sysInfoData.javacVersion),
67112
infoMessage: "Javac is installed and is configured properly.",
68113
platforms: [Constants.ANDROID_PLATFORM_NAME]
114+
}),
115+
this.processSysInfoItem({
116+
item: sysInfoData.javacVersion,
117+
infoMessage: "The Java Development Kit (JDK) is installed and is configured properly.",
118+
warningMessage: "The Java Development Kit (JDK) is not installed or is not configured properly.",
119+
additionalInformation: "You will not be able to work with the Android SDK and you might not be able" + EOL
120+
+ "to perform some Android-related operations. To ensure that you can develop and" + EOL
121+
+ "test your apps for Android, verify that you have installed the JDK as" + EOL
122+
+ "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8).",
123+
platforms: [Constants.ANDROID_PLATFORM_NAME]
69124
})
70125
);
71126

127+
return result;
128+
}
129+
130+
private async getiOSInfos(sysInfoData: NativeScriptDoctor.ISysInfoData): Promise<NativeScriptDoctor.IInfo[]> {
131+
let result: NativeScriptDoctor.IInfo[] = [];
72132
if (this.hostInfo.isDarwin) {
73133
result = result.concat(
74134
this.processSysInfoItem({
@@ -103,7 +163,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor {
103163
platforms: [Constants.IOS_PLATFORM_NAME]
104164
})
105165
);
106-
166+
107167
if (sysInfoData.xcodeVer && sysInfoData.cocoaPodsVer) {
108168
let isCocoaPodsWorkingCorrectly = await this.sysInfo.isCocoaPodsWorkingCorrectly();
109169
result = result.concat(
@@ -116,7 +176,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor {
116176
})
117177
);
118178
}
119-
179+
120180
result = result.concat(
121181
this.processSysInfoItem({
122182
item: !sysInfoData.cocoaPodsVer || !semver.valid(sysInfoData.cocoaPodsVer) || !semver.lt(sysInfoData.cocoaPodsVer, Doctor.MIN_SUPPORTED_POD_VERSION),
@@ -144,46 +204,9 @@ export class Doctor implements NativeScriptDoctor.IDoctor {
144204
);
145205
}
146206

147-
result = result.concat(
148-
this.processSysInfoItem({
149-
item: sysInfoData.javacVersion,
150-
infoMessage: "The Java Development Kit (JDK) is installed and is configured properly.",
151-
warningMessage: "The Java Development Kit (JDK) is not installed or is not configured properly.",
152-
additionalInformation: "You will not be able to work with the Android SDK and you might not be able" + EOL
153-
+ "to perform some Android-related operations. To ensure that you can develop and" + EOL
154-
+ "test your apps for Android, verify that you have installed the JDK as" + EOL
155-
+ "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8).",
156-
platforms: [Constants.ANDROID_PLATFORM_NAME]
157-
}),
158-
this.processSysInfoItem({
159-
item: sysInfoData.gitVer,
160-
infoMessage: "Git is installed and is configured properly.",
161-
warningMessage: "Git is not installed or not configured properly.",
162-
additionalInformation: "You will not be able to create and work with Screen Builder projects." + EOL
163-
+ "To be able to work with Screen Builder projects, download and install Git as described" + EOL
164-
+ "in https://git-scm.com/downloads and add the git executable to your PATH.",
165-
platforms: Constants.SUPPORTED_PLATFORMS
166-
})
167-
);
168-
169-
if (!this.hostInfo.isDarwin) {
170-
result.push({
171-
message: "Local builds for iOS can be executed only on a macOS system. To build for iOS on a different operating system, you can use the NativeScript cloud infrastructure.",
172-
additionalInformation: "",
173-
platforms: [Constants.IOS_PLATFORM_NAME],
174-
type: Constants.INFO_TYPE_NAME
175-
});
176-
}
177-
178207
return result;
179208
}
180209

181-
public async getWarnings(config?: NativeScriptDoctor.ISysInfoConfig): Promise<NativeScriptDoctor.IWarning[]> {
182-
const info = await this.getInfos(config);
183-
return info.filter(item => item.type === Constants.WARNING_TYPE_NAME)
184-
.map(item => this.convertInfoToWarning(item));
185-
}
186-
187210
private processSysInfoItem(data: { item: string | boolean, infoMessage: string, warningMessage: string, additionalInformation?: string, platforms: string[] }): NativeScriptDoctor.IInfo {
188211
if (!data.item) {
189212
return {

lib/sys-info.ts

+66-36
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import * as path from "path";
99
import * as osenv from "osenv";
1010
import * as temp from "temp";
1111
import * as semver from "semver";
12+
import { constants } from "zlib";
13+
import { Constants } from "./constants";
1214

1315
export class SysInfo implements NativeScriptDoctor.ISysInfo {
1416
private static JAVA_COMPILER_VERSION_REGEXP = /^javac (.*)/im;
@@ -34,7 +36,11 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo {
3436
private monoVerCache: string;
3537
private gitVerCache: string;
3638
private gradleVerCache: string;
37-
private sysInfoCache: NativeScriptDoctor.ISysInfoData;
39+
40+
private commonSysInfoCache: NativeScriptDoctor.ICommonSysInfoData;
41+
private androidSysInfoCache: NativeScriptDoctor.IAndroidSysInfoData;
42+
private iOSSysInfoCache: NativeScriptDoctor.IiOSSysInfoData;
43+
3844
private isCocoaPodsWorkingCorrectlyCache: boolean;
3945
private nativeScriptCliVersionCache: string;
4046
private xcprojInfoCache: NativeScriptDoctor.IXcprojInfo;
@@ -215,43 +221,16 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo {
215221
});
216222
}
217223

218-
public getSysInfo(config?: NativeScriptDoctor.ISysInfoConfig): Promise<NativeScriptDoctor.ISysInfoData> {
219-
return this.getValueForProperty(() => this.sysInfoCache, async (): Promise<NativeScriptDoctor.ISysInfoData> => {
220-
const result: NativeScriptDoctor.ISysInfoData = Object.create(null);
221-
222-
// os stuff
223-
result.platform = platform();
224-
result.shell = osenv.shell();
225-
result.os = await this.getOs();
226-
227-
// node stuff
228-
result.procArch = process.arch;
229-
result.nodeVer = await this.getNodeVersion();
230-
result.npmVer = await this.getNpmVersion();
231-
result.nodeGypVer = await this.getNodeGypVersion();
232-
233-
result.dotNetVer = await this.hostInfo.dotNetVersion();
234-
result.javacVersion = await this.getJavaCompilerVersion();
235-
result.xcodeVer = await this.getXcodeVersion();
236-
result.xcodeprojLocation = await this.getXcodeprojLocation();
237-
result.itunesInstalled = await this.isITunesInstalled();
238-
result.cocoaPodsVer = await this.getCocoaPodsVersion();
239-
result.adbVer = await this.getAdbVersion(config && config.androidToolsInfo && config.androidToolsInfo.pathToAdb);
240-
result.androidInstalled = await this.isAndroidInstalled();
241-
result.monoVer = await this.getMonoVersion();
242-
result.gitVer = await this.getGitVersion();
243-
result.gradleVer = await this.getGradleVersion();
244-
result.isCocoaPodsWorkingCorrectly = await this.isCocoaPodsWorkingCorrectly();
245-
246-
result.nativeScriptCliVersion = await this.getNativeScriptCliVersion();
247-
248-
result.isCocoaPodsUpdateRequired = await this.isCocoaPodsUpdateRequired();
249-
result.isAndroidSdkConfiguredCorrectly = await this.isAndroidSdkConfiguredCorrectly();
224+
public async getSysInfo(config?: NativeScriptDoctor.ISysInfoConfig): Promise<NativeScriptDoctor.ISysInfoData> {
225+
if (config && config.platform === Constants.ANDROID_PLATFORM_NAME) {
226+
return <NativeScriptDoctor.ISysInfoData>Object.assign(await this.getCommonSysInfo(), await this.getAndroidSysInfo(config));
227+
}
250228

251-
result.pythonInfo = await this.getPythonInfo();
229+
if (config && config.platform === Constants.IOS_PLATFORM_NAME) {
230+
return <NativeScriptDoctor.ISysInfoData>Object.assign(await this.getCommonSysInfo(), await this.getiOSSysInfo());
231+
}
252232

253-
return result;
254-
});
233+
return Object.assign(await this.getCommonSysInfo(), await this.getAndroidSysInfo(), await this.getiOSSysInfo());
255234
}
256235

257236
public isCocoaPodsWorkingCorrectly(): Promise<boolean> {
@@ -467,4 +446,55 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo {
467446
private unixVer(): Promise<string> {
468447
return this.execCommand("uname -a");
469448
}
449+
450+
private getCommonSysInfo(): Promise<NativeScriptDoctor.ICommonSysInfoData> {
451+
return this.getValueForProperty(() => this.commonSysInfoCache, async (): Promise<NativeScriptDoctor.ICommonSysInfoData> => {
452+
const result: NativeScriptDoctor.ICommonSysInfoData = Object.create(null);
453+
454+
// os stuff
455+
result.platform = platform();
456+
result.shell = osenv.shell();
457+
result.os = await this.getOs();
458+
result.procArch = process.arch;
459+
result.nodeVer = await this.getNodeVersion();
460+
result.npmVer = await this.getNpmVersion();
461+
result.nodeGypVer = await this.getNodeGypVersion();
462+
result.nativeScriptCliVersion = await this.getNativeScriptCliVersion();
463+
result.gitVer = await this.getGitVersion();
464+
465+
return result;
466+
});
467+
}
468+
469+
private async getiOSSysInfo(): Promise<NativeScriptDoctor.IiOSSysInfoData> {
470+
return this.getValueForProperty(() => this.iOSSysInfoCache, async (): Promise<NativeScriptDoctor.IiOSSysInfoData> => {
471+
const result: NativeScriptDoctor.IiOSSysInfoData = Object.create(null);
472+
473+
result.xcodeVer = await this.getXcodeVersion();
474+
result.xcodeprojLocation = await this.getXcodeprojLocation();
475+
result.itunesInstalled = await this.isITunesInstalled();
476+
result.cocoaPodsVer = await this.getCocoaPodsVersion();
477+
result.isCocoaPodsWorkingCorrectly = await this.isCocoaPodsWorkingCorrectly();
478+
result.isCocoaPodsUpdateRequired = await this.isCocoaPodsUpdateRequired();
479+
result.pythonInfo = await this.getPythonInfo();
480+
481+
return result;
482+
});
483+
}
484+
485+
private async getAndroidSysInfo(config?: NativeScriptDoctor.ISysInfoConfig): Promise<NativeScriptDoctor.IAndroidSysInfoData> {
486+
return this.getValueForProperty(() => this.androidSysInfoCache, async (): Promise<NativeScriptDoctor.IAndroidSysInfoData> => {
487+
const result: NativeScriptDoctor.IAndroidSysInfoData = Object.create(null);
488+
489+
result.dotNetVer = await this.hostInfo.dotNetVersion();
490+
result.javacVersion = await this.getJavaCompilerVersion();
491+
result.adbVer = await this.getAdbVersion(config && config.androidToolsInfo && config.androidToolsInfo.pathToAdb);
492+
result.androidInstalled = await this.isAndroidInstalled();
493+
result.monoVer = await this.getMonoVersion();
494+
result.gradleVer = await this.getGradleVersion();
495+
result.isAndroidSdkConfiguredCorrectly = await this.isAndroidSdkConfiguredCorrectly();
496+
497+
return result;
498+
});
499+
}
470500
}

test/sys-info.ts

+70
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { EOL } from "os";
44
import { SysInfo } from "../lib/sys-info";
55
import { Helpers } from "../lib/helpers";
66
import { ChildProcess } from "../lib/wrappers/child-process";
7+
import { constants } from "zlib";
78

89
const JavaHomeName = "JAVA_HOME";
910
const AndroidHomeName = "ANDROID_HOME";
@@ -493,5 +494,74 @@ ${expectedCliVersion}`;
493494
});
494495
});
495496
});
497+
498+
describe("returns correct sysInfo when", () => {
499+
const assertCommonSysInfo = (result: NativeScriptDoctor.ISysInfoData) => {
500+
assert.deepEqual(result.npmVer, childProcessResult.npmV.result.stdout);
501+
assert.deepEqual(result.nodeVer, "6.0.0");
502+
assert.deepEqual(result.nodeGypVer, childProcessResult.nodeGypVersion.result.stdout);
503+
assert.deepEqual(result.gitVer, "1.9.5");
504+
assert.deepEqual(result.nativeScriptCliVersion, childProcessResult.nativeScriptCliVersion.result.stdout);
505+
};
506+
507+
const assertAndroidSysInfo = (result: NativeScriptDoctor.IAndroidSysInfoData) => {
508+
assert.deepEqual(result.adbVer, "1.0.32");
509+
assert.deepEqual(result.androidInstalled, false);
510+
assert.deepEqual(result.monoVer, "1.0.6");
511+
assert.deepEqual(result.gradleVer, "2.8");
512+
assert.deepEqual(result.javacVersion, "1.8.0_60");
513+
assert.deepEqual(result.isAndroidSdkConfiguredCorrectly, undefined);
514+
};
515+
516+
const assertiOSSysInfo = (result: NativeScriptDoctor.IiOSSysInfoData) => {
517+
assert.deepEqual(result.xcodeVer, "6.4.0");
518+
assert.deepEqual(result.itunesInstalled, undefined);
519+
assert.deepEqual(result.cocoaPodsVer, "0.38.2");
520+
assert.deepEqual(result.xcodeprojLocation, null);
521+
assert.deepEqual(result.isCocoaPodsWorkingCorrectly, undefined);
522+
assert.deepEqual(result.xcprojInfo, undefined);
523+
assert.deepEqual(result.isCocoaPodsUpdateRequired, false);
524+
assert.deepEqual(result.pythonInfo, {isInstalled: false, isSixPackageInstalled: false, installationErrorMessage: "Cannot read property 'shouldThrowError' of undefined"});
525+
};
526+
527+
it("iOS platform is specified", async () => {
528+
sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion });
529+
const result = await sysInfo.getSysInfo({platform: "iOS"});
530+
531+
assertCommonSysInfo(result);
532+
assertiOSSysInfo(result);
533+
// Android specific properties should be undefined
534+
assert.deepEqual(result.adbVer, undefined);
535+
assert.deepEqual(result.androidInstalled, undefined);
536+
assert.deepEqual(result.monoVer, undefined);
537+
assert.deepEqual(result.gradleVer, undefined);
538+
assert.deepEqual(result.javacVersion, undefined);
539+
assert.deepEqual(result.isAndroidSdkConfiguredCorrectly, undefined);
540+
});
541+
it("Android platform is specified", async () => {
542+
sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion });
543+
const result = await sysInfo.getSysInfo({platform: "Android"});
544+
545+
assertCommonSysInfo(result);
546+
assertAndroidSysInfo(result);
547+
// iOS specific properties should be undefined
548+
assert.deepEqual(result.xcodeVer, undefined);
549+
assert.deepEqual(result.itunesInstalled, undefined);
550+
assert.deepEqual(result.cocoaPodsVer, undefined);
551+
assert.deepEqual(result.xcodeprojLocation, undefined);
552+
assert.deepEqual(result.isCocoaPodsWorkingCorrectly, undefined);
553+
assert.deepEqual(result.xcprojInfo, undefined);
554+
assert.deepEqual(result.isCocoaPodsUpdateRequired, undefined);
555+
assert.deepEqual(result.pythonInfo, undefined);
556+
557+
});
558+
it("no platform is specified", async() => {
559+
sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion });
560+
const result = await sysInfo.getSysInfo();
561+
assertCommonSysInfo(result);
562+
assertAndroidSysInfo(result);
563+
assertiOSSysInfo(result);
564+
});
565+
});
496566
});
497567
});

0 commit comments

Comments
 (0)