1
1
import { EOL } from "os" ;
2
- import * as semver from "semver" ;
3
2
import * as path from "path" ;
4
3
import * as helpers from "../common/helpers" ;
4
+ import { doctor , constants } from "nativescript-doctor" ;
5
5
6
6
class DoctorService implements IDoctorService {
7
- private static PROJECT_NAME_PLACEHOLDER = "__PROJECT_NAME__" ;
8
- private static MIN_SUPPORTED_POD_VERSION = "1.0.0" ;
9
7
private static DarwinSetupScriptLocation = path . join ( __dirname , ".." , ".." , "setup" , "mac-startup-shell-script.sh" ) ;
10
8
private static DarwinSetupDocsLink = "https://docs.nativescript.org/start/ns-setup-os-x" ;
11
9
private static WindowsSetupScriptExecutable = "powershell.exe" ;
@@ -14,104 +12,32 @@ class DoctorService implements IDoctorService {
14
12
private static LinuxSetupDocsLink = "https://docs.nativescript.org/start/ns-setup-linux" ;
15
13
16
14
constructor ( private $analyticsService : IAnalyticsService ,
17
- private $androidToolsInfo : IAndroidToolsInfo ,
18
- private $cocoapodsService : ICocoaPodsService ,
19
15
private $hostInfo : IHostInfo ,
20
16
private $logger : ILogger ,
21
- private $progressIndicator : IProgressIndicator ,
22
- private $staticConfig : IStaticConfig ,
23
- private $sysInfo : ISysInfo ,
24
17
private $childProcess : IChildProcess ,
25
- private $config : IConfiguration ,
26
- private $npm : INodePackageManager ,
27
18
private $opener : IOpener ,
28
19
private $prompter : IPrompter ,
29
- private $fs : IFileSystem ,
30
- private $versionsService : IVersionsService ,
31
- private $xcprojService : IXcprojService ) { }
20
+ private $versionsService : IVersionsService ) { }
32
21
33
22
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 ;
54
25
26
+ const hasAndroidWarnings = warnings . filter ( warning => _ . includes ( warning . platforms , constants . ANDROID_PLATFORM_NAME ) ) . length > 0 ;
27
+ if ( hasAndroidWarnings ) {
55
28
this . printPackageManagerTip ( ) ;
56
- result = true ;
57
29
}
58
30
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
-
110
31
if ( ! configOptions || configOptions . trackResult ) {
111
- await this . $analyticsService . track ( "DoctorEnvironmentSetup" , doctorResult ? "incorrect" : "correct" ) ;
32
+ await this . $analyticsService . track ( "DoctorEnvironmentSetup" , hasWarnings ? "incorrect" : "correct" ) ;
112
33
}
113
34
114
- if ( doctorResult ) {
35
+ if ( hasWarnings ) {
36
+ warnings . map ( warning => {
37
+ this . $logger . warn ( warning . warning ) ;
38
+ this . $logger . out ( warning . additionalInformation ) ;
39
+ } ) ;
40
+
115
41
this . $logger . info ( "There seem to be issues with your configuration." ) ;
116
42
if ( this . $hostInfo . isDarwin ) {
117
43
await this . promptForHelp ( DoctorService . DarwinSetupDocsLink , DoctorService . DarwinSetupScriptLocation , [ ] ) ;
@@ -128,7 +54,7 @@ class DoctorService implements IDoctorService {
128
54
this . $logger . error ( "Cannot get the latest versions information from npm. Please try again later." ) ;
129
55
}
130
56
131
- return doctorResult ;
57
+ return hasWarnings ;
132
58
}
133
59
134
60
private async promptForDocs ( link : string ) : Promise < void > {
@@ -152,81 +78,5 @@ class DoctorService implements IDoctorService {
152
78
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 ) ;
153
79
}
154
80
}
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
- }
231
81
}
232
82
$injector . register ( "doctorService" , DoctorService ) ;
0 commit comments