11import { EOL } from "os" ;
2- import * as semver from "semver" ;
32import * as path from "path" ;
43import * as helpers from "../common/helpers" ;
4+ import { doctor , constants } from "nativescript-doctor" ;
55
66class 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 ) ;
0 commit comments