Skip to content

Commit 61f4b6c

Browse files
author
Fatme
authored
Merge pull request #3390 from NativeScript/fatme/doctor-package-integration
feat(doctor): Integrate nativescript-doctor package
2 parents e313cb9 + 19d8478 commit 61f4b6c

8 files changed

+245
-184
lines changed

lib/services/android-project-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
153153

154154
this.$androidToolsInfo.validateAndroidHomeEnvVariable({ showWarningsAsErrors: true });
155155

156-
const javaCompilerVersion = await this.$sysInfo.getJavaCompilerVersion();
156+
const javaCompilerVersion = (await this.$sysInfo.getSysInfo()).javacVersion;
157157

158158
this.$androidToolsInfo.validateJavacVersion(javaCompilerVersion, { showWarningsAsErrors: true });
159159

lib/services/doctor-service.ts

Lines changed: 14 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { EOL } from "os";
2-
import * as semver from "semver";
32
import * as path from "path";
43
import * as helpers from "../common/helpers";
4+
import { doctor, constants } from "nativescript-doctor";
55

66
class DoctorService implements IDoctorService {
7-
private static PROJECT_NAME_PLACEHOLDER = "__PROJECT_NAME__";
8-
private static MIN_SUPPORTED_POD_VERSION = "1.0.0";
97
private static DarwinSetupScriptLocation = path.join(__dirname, "..", "..", "setup", "mac-startup-shell-script.sh");
108
private static DarwinSetupDocsLink = "https://docs.nativescript.org/start/ns-setup-os-x";
119
private static WindowsSetupScriptExecutable = "powershell.exe";
@@ -14,104 +12,32 @@ class DoctorService implements IDoctorService {
1412
private static LinuxSetupDocsLink = "https://docs.nativescript.org/start/ns-setup-linux";
1513

1614
constructor(private $analyticsService: IAnalyticsService,
17-
private $androidToolsInfo: IAndroidToolsInfo,
18-
private $cocoapodsService: ICocoaPodsService,
1915
private $hostInfo: IHostInfo,
2016
private $logger: ILogger,
21-
private $progressIndicator: IProgressIndicator,
22-
private $staticConfig: IStaticConfig,
23-
private $sysInfo: ISysInfo,
2417
private $childProcess: IChildProcess,
25-
private $config: IConfiguration,
26-
private $npm: INodePackageManager,
2718
private $opener: IOpener,
2819
private $prompter: IPrompter,
29-
private $fs: IFileSystem,
30-
private $versionsService: IVersionsService,
31-
private $xcprojService: IXcprojService) { }
20+
private $versionsService: IVersionsService) { }
3221

3322
public async printWarnings(configOptions?: { trackResult: boolean }): Promise<boolean> {
34-
let result = false;
35-
const sysInfo = await this.$sysInfo.getSysInfo(this.$staticConfig.pathToPackageJson);
36-
37-
if (!sysInfo.adbVer) {
38-
this.$logger.warn("WARNING: adb from the Android SDK is not installed or is not configured properly.");
39-
this.$logger.out("For Android-related operations, the NativeScript CLI will use a built-in version of adb." + EOL
40-
+ "To avoid possible issues with the native Android emulator, Genymotion or connected" + EOL
41-
+ "Android devices, verify that you have installed the latest Android SDK and" + EOL
42-
+ "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL);
43-
44-
this.printPackageManagerTip();
45-
result = true;
46-
}
47-
48-
if (!sysInfo.emulatorInstalled) {
49-
this.$logger.warn("WARNING: The Android SDK is not installed or is not configured properly.");
50-
this.$logger.out("You will not be able to build your projects for Android and run them in the native emulator." + EOL
51-
+ "To be able to build for Android and run apps in the native emulator, verify that you have" + EOL
52-
+ "installed the latest Android SDK and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL
53-
);
23+
const warnings = await doctor.getWarnings();
24+
const hasWarnings = warnings.length > 0;
5425

26+
const hasAndroidWarnings = warnings.filter(warning => _.includes(warning.platforms, constants.ANDROID_PLATFORM_NAME)).length > 0;
27+
if (hasAndroidWarnings) {
5528
this.printPackageManagerTip();
56-
result = true;
5729
}
5830

59-
if (this.$hostInfo.isDarwin) {
60-
if (!sysInfo.xcodeVer) {
61-
this.$logger.warn("WARNING: Xcode is not installed or is not configured properly.");
62-
this.$logger.out("You will not be able to build your projects for iOS or run them in the iOS Simulator." + EOL
63-
+ "To be able to build for iOS and run apps in the native emulator, verify that you have installed Xcode." + EOL);
64-
result = true;
65-
}
66-
67-
if (!sysInfo.xcodeprojLocation) {
68-
this.$logger.warn("WARNING: xcodeproj gem is not installed or is not configured properly.");
69-
this.$logger.out("You will not be able to build your projects for iOS." + EOL
70-
+ "To be able to build for iOS and run apps in the native emulator, verify that you have installed xcodeproj." + EOL);
71-
result = true;
72-
}
73-
74-
if (!sysInfo.cocoapodVer) {
75-
this.$logger.warn("WARNING: CocoaPods is not installed or is not configured properly.");
76-
this.$logger.out("You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL
77-
+ "To be able to build such projects, verify that you have installed CocoaPods.");
78-
result = true;
79-
}
80-
81-
if (sysInfo.xcodeVer && sysInfo.cocoapodVer) {
82-
const problemWithCocoaPods = await this.verifyCocoaPods();
83-
if (problemWithCocoaPods) {
84-
this.$logger.warn("WARNING: There was a problem with CocoaPods");
85-
this.$logger.out("Verify that CocoaPods are configured properly.");
86-
result = true;
87-
}
88-
}
89-
90-
if (sysInfo.cocoapodVer && semver.valid(sysInfo.cocoapodVer) && semver.lt(sysInfo.cocoapodVer, DoctorService.MIN_SUPPORTED_POD_VERSION)) {
91-
this.$logger.warn(`WARNING: Your current CocoaPods version is earlier than ${DoctorService.MIN_SUPPORTED_POD_VERSION}.`);
92-
this.$logger.out("You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL
93-
+ `To be able to build such projects, verify that you have at least ${DoctorService.MIN_SUPPORTED_POD_VERSION} version installed.`);
94-
result = true;
95-
}
96-
97-
if (sysInfo.xcodeVer && sysInfo.cocoapodVer && await this.$xcprojService.verifyXcproj(false)) {
98-
result = true;
99-
}
100-
} else {
101-
this.$logger.out("NOTE: You can develop for iOS only on Mac OS X systems.");
102-
this.$logger.out("To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later." + EOL);
103-
}
104-
105-
const androidToolsIssues = this.$androidToolsInfo.validateInfo();
106-
const javaCompilerVersionIssue = this.$androidToolsInfo.validateJavacVersion(sysInfo.javacVersion);
107-
const pythonIssues = await this.validatePythonPackages();
108-
const doctorResult = result || androidToolsIssues || javaCompilerVersionIssue || pythonIssues;
109-
11031
if (!configOptions || configOptions.trackResult) {
111-
await this.$analyticsService.track("DoctorEnvironmentSetup", doctorResult ? "incorrect" : "correct");
32+
await this.$analyticsService.track("DoctorEnvironmentSetup", hasWarnings ? "incorrect" : "correct");
11233
}
11334

114-
if (doctorResult) {
35+
if (hasWarnings) {
36+
warnings.map(warning => {
37+
this.$logger.warn(warning.warning);
38+
this.$logger.out(warning.additionalInformation);
39+
});
40+
11541
this.$logger.info("There seem to be issues with your configuration.");
11642
if (this.$hostInfo.isDarwin) {
11743
await this.promptForHelp(DoctorService.DarwinSetupDocsLink, DoctorService.DarwinSetupScriptLocation, []);
@@ -128,7 +54,7 @@ class DoctorService implements IDoctorService {
12854
this.$logger.error("Cannot get the latest versions information from npm. Please try again later.");
12955
}
13056

131-
return doctorResult;
57+
return hasWarnings;
13258
}
13359

13460
private async promptForDocs(link: string): Promise<void> {
@@ -152,81 +78,5 @@ class DoctorService implements IDoctorService {
15278
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);
15379
}
15480
}
155-
156-
private async verifyCocoaPods(): Promise<boolean> {
157-
this.$logger.out("Verifying CocoaPods. This may take more than a minute, please be patient.");
158-
159-
const temp = require("temp");
160-
temp.track();
161-
const projDir = temp.mkdirSync("nativescript-check-cocoapods");
162-
const packageJsonData = {
163-
"name": "nativescript-check-cocoapods",
164-
"version": "0.0.1"
165-
};
166-
this.$fs.writeJson(path.join(projDir, "package.json"), packageJsonData);
167-
168-
const spinner = this.$progressIndicator.getSpinner("Installing iOS runtime.");
169-
try {
170-
spinner.start();
171-
await this.$npm.install("tns-ios", projDir, {
172-
global: false,
173-
production: true,
174-
save: true,
175-
disableNpmInstall: false,
176-
frameworkPath: null,
177-
ignoreScripts: true
178-
});
179-
spinner.stop();
180-
const iosDir = path.join(projDir, "node_modules", "tns-ios", "framework");
181-
this.$fs.writeFile(
182-
path.join(iosDir, "Podfile"),
183-
`${this.$cocoapodsService.getPodfileHeader(DoctorService.PROJECT_NAME_PLACEHOLDER)}pod 'AFNetworking', '~> 1.0'${this.$cocoapodsService.getPodfileFooter()}`
184-
);
185-
186-
spinner.message("Verifying CocoaPods. This may take some time, please be patient.");
187-
spinner.start();
188-
const future = this.$childProcess.spawnFromEvent(
189-
this.$config.USE_POD_SANDBOX ? "sandbox-pod" : "pod",
190-
["install"],
191-
"exit",
192-
{ cwd: iosDir },
193-
{ throwError: false }
194-
);
195-
196-
const result = await this.$progressIndicator.showProgressIndicator(future, 5000);
197-
if (result.exitCode) {
198-
this.$logger.out(result.stdout, result.stderr);
199-
return true;
200-
}
201-
202-
return !(this.$fs.exists(path.join(iosDir, `${DoctorService.PROJECT_NAME_PLACEHOLDER}.xcworkspace`)));
203-
} catch (err) {
204-
this.$logger.trace(`verifyCocoaPods error: ${err}`);
205-
return true;
206-
} finally {
207-
spinner.stop();
208-
}
209-
}
210-
211-
private async validatePythonPackages(): Promise<boolean> {
212-
let hasInvalidPackages = false;
213-
if (this.$hostInfo.isDarwin) {
214-
try {
215-
await this.$childProcess.exec(`python -c "import six"`);
216-
} catch (error) {
217-
// error.code = 1 so the Python is present, but we don't have six.
218-
if (error.code === 1) {
219-
hasInvalidPackages = true;
220-
this.$logger.warn("The Python 'six' package not found.");
221-
this.$logger.out("This package is required by the Debugger library (LLDB) for iOS. You can install it by running 'pip install six' from the terminal.");
222-
} else {
223-
this.$logger.warn("Couldn't retrieve installed python packages.");
224-
this.$logger.out("We cannot verify your python installation is setup correctly. Please, make sure you have both 'python' and 'pip' installed.");
225-
this.$logger.trace(`Error while validating Python packages. Error is: ${error.message}`);
226-
}
227-
}
228-
}
229-
return hasInvalidPackages;
230-
}
23181
}
23282
$injector.register("doctorService", DoctorService);

lib/services/ios-project-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
365365
const installedPlugins = await (<IPluginsService>this.$injector.resolve("pluginsService")).getAllInstalledPlugins(projectData);
366366
for (const pluginData of installedPlugins) {
367367
const pluginsFolderExists = this.$fs.exists(path.join(pluginData.pluginPlatformsFolderPath(this.$devicePlatformsConstants.iOS.toLowerCase()), "Podfile"));
368-
const cocoaPodVersion = await this.$sysInfo.getCocoapodVersion();
368+
const cocoaPodVersion = (await this.$sysInfo.getSysInfo()).cocoaPodsVer;
369369
if (pluginsFolderExists && !cocoaPodVersion) {
370370
this.$errors.failWithoutHelp(`${pluginData.name} has Podfile and you don't have Cocoapods installed or it is not configured correctly. Please verify Cocoapods can work on your machine.`);
371371
}

lib/services/xcproj-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class XcprojService implements IXcprojService {
3030

3131
public async getXcprojInfo(): Promise<IXcprojInfo> {
3232
if (!this.xcprojInfoCache) {
33-
let cocoapodVer = await this.$sysInfo.getCocoapodVersion();
33+
let cocoapodVer = (await this.$sysInfo.getSysInfo()).cocoaPodsVer;
3434
const xcodeVersion = await this.$xcodeSelectService.getXcodeVersion();
3535

3636
if (cocoapodVer && !semver.valid(cocoapodVer)) {

lib/sys-info.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
1-
import { SysInfoBase } from "./common/sys-info-base";
21
import * as path from "path";
2+
import { sysInfo } from "nativescript-doctor";
33

4-
export class SysInfo extends SysInfoBase {
5-
constructor(protected $childProcess: IChildProcess,
6-
protected $hostInfo: IHostInfo,
7-
protected $iTunesValidator: Mobile.IiTunesValidator,
8-
protected $logger: ILogger,
9-
protected $winreg: IWinReg,
10-
protected $androidEmulatorServices: Mobile.IAndroidEmulatorServices,
11-
private $androidToolsInfo: IAndroidToolsInfo) {
12-
super($childProcess, $hostInfo, $iTunesValidator, $logger, $winreg, $androidEmulatorServices);
13-
}
4+
export class SysInfo implements ISysInfo {
5+
private sysInfo: ISysInfoData = null;
6+
7+
public async getSysInfo(config?: NativeScriptDoctor.ISysInfoConfig): Promise<NativeScriptDoctor.ISysInfoData> {
8+
if (!this.sysInfo) {
9+
const pathToNativeScriptCliPackageJson = (config && config.pathToNativeScriptCliPackageJson) || path.join(__dirname, "..", "package.json");
10+
const androidToolsInfo = config && config.androidToolsInfo;
1411

15-
public async getSysInfo(pathToPackageJson: string, androidToolsInfo?: { pathToAdb: string }): Promise<ISysInfoData> {
16-
const defaultAndroidToolsInfo = {
17-
pathToAdb: await this.$androidToolsInfo.getPathToAdbFromAndroidHome()
18-
};
12+
this.sysInfo = await sysInfo.getSysInfo({pathToNativeScriptCliPackageJson, androidToolsInfo});
13+
}
1914

20-
return super.getSysInfo(pathToPackageJson || await path.join(__dirname, "..", "package.json"), androidToolsInfo || defaultAndroidToolsInfo);
15+
return this.sysInfo;
2116
}
2217
}
2318
$injector.register("sysInfo", SysInfo);

0 commit comments

Comments
 (0)