Skip to content

Commit bf96de4

Browse files
Add warning for new versions of nativescript components
When executing tns doctor outside of project if the nativescript cli needs update it will print information for the available update. If tns doctor is executed in project it will check the installed runtimes versions and the nativescript core modules version and print information if an update is needed. Add tns info command to display versions information for NativeScript CLI, core modules and runtimes.
1 parent e3c2b10 commit bf96de4

File tree

12 files changed

+347
-81
lines changed

12 files changed

+347
-81
lines changed

docs/man_pages/general/doctor.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ General | `$ tns doctor`
77

88
Checks your system for configuration problems which might prevent the NativeScript CLI from working properly.
99

10-
<% if(isHtml) { %>
10+
<% if(isHtml) { %>
1111
### Related Commands
1212

1313
Command | Description
@@ -16,4 +16,5 @@ Command | Description
1616
[error-reporting](error-reporting.html) | Configures anonymous error reporting for the NativeScript CLI.
1717
[autocomplete](autocomplete.html) | Prints your current command-line completion settings. If disabled, prompts you to enable it.
1818
[help](help.html) | Lists the available commands or shows information about the selected command.
19-
<% } %>
19+
[info](info.html) | Displays version information for NativeScript CLI, core modules and runtimes.
20+
<% } %>

docs/man_pages/general/help.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ General | `$ tns help [<Command>]`
77

88
Opens the command reference for all commands in your browser or shows information about the selected command in the browser.
99

10-
To list all commands in the console, run `$ tns -h`
10+
To list all commands in the console, run `$ tns -h`
1111
To print information about a selected command in the console, run `$ tns <Command> -h`
1212

1313
### Attributes
1414
* `<Command>` is any of the available commands as listed by `$ tns help` or `$ tns -h`
1515

16-
<% if(isHtml) { %>
16+
<% if(isHtml) { %>
1717
### Related Commands
1818

1919
Command | Description
@@ -22,4 +22,5 @@ Command | Description
2222
[error-reporting](error-reporting.html) | Configures anonymous error reporting for the NativeScript CLI.
2323
[autocomplete](autocomplete.html) | Prints your current command-line completion settings. If disabled, prompts you to enable it.
2424
[doctor](doctor.html) | Checks your system for configuration problems which might prevent the NativeScript CLI from working properly.
25-
<% } %>
25+
[info](info.html) | Displays version information for NativeScript CLI, core modules and runtimes.
26+
<% } %>

docs/man_pages/general/info.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Info
2+
==========
3+
4+
Usage | Synopsis
5+
------|-------
6+
General | `$ tns info`
7+
8+
Displays version information for NativeScript CLI, core modules and runtimes.
9+
10+
<% if(isHtml) { %>
11+
### Related Commands
12+
13+
Command | Description
14+
----------|----------
15+
[usage-reporting](usage-reporting.html) | Configures anonymous usage reporting for the NativeScript CLI.
16+
[error-reporting](error-reporting.html) | Configures anonymous error reporting for the NativeScript CLI.
17+
[autocomplete](autocomplete.html) | Prints your current command-line completion settings. If disabled, prompts you to enable it.
18+
[help](help.html) | Lists the available commands or shows information about the selected command.
19+
[doctor](doctor.html) | Checks your system for configuration problems which might prevent the NativeScript CLI from working properly.
20+
<% } %>

docs/man_pages/index.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Command | Description
1414
[usage-reporting](general/usage-reporting.html) | Configures anonymous usage reporting for the NativeScript CLI.
1515
[error-reporting](general/error-reporting.html) | Configures anonymous error reporting for the NativeScript CLI.
1616
[doctor](general/doctor.html) | Checks your system for configuration problems which might prevent the NativeScript CLI from working properly.
17+
[info](general/info.html) | Displays version information for NativeScript CLI, core modules and runtimes.
1718

1819
## Project Development Commands
1920
Command | Description
@@ -56,4 +57,4 @@ Option | Description
5657
--help, -h, /? | Prints help about the selected command in the console.
5758
--path `<Directory>` | Specifies the directory that contains the project. If not set, the project is searched for in the current directory and all directories above it.
5859
--version | Prints the client version.
59-
--log trace | Prints a detailed diagnostic log for the execution of the current command.
60+
--log trace | Prints a detailed diagnostic log for the execution of the current command.

lib/bootstrap.ts

+4
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,15 @@ $injector.requireCommand("plugin|add", "./commands/plugin/add-plugin");
8080
$injector.requireCommand("plugin|remove", "./commands/plugin/remove-plugin");
8181

8282
$injector.require("doctorService", "./services/doctor-service");
83+
$injector.require("versionsService", "./services/versions-service");
8384
$injector.requireCommand("install", "./commands/install");
8485

8586
$injector.require("initService", "./services/init-service");
8687
$injector.requireCommand("init", "./commands/init");
8788

89+
$injector.require("infoService", "./services/info-service");
90+
$injector.requireCommand("info", "./commands/info");
91+
8892
$injector.require("androidToolsInfo", "./android-tools-info");
8993

9094
$injector.requireCommand("livesync", "./commands/livesync");

lib/commands/info.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
///<reference path="../.d.ts"/>
2+
"use strict";
3+
4+
export class InfoCommand implements ICommand {
5+
constructor(private $infoService: IInfoService) { }
6+
7+
public allowedParameters: ICommandParameter[] = [];
8+
public enableHooks = false;
9+
10+
public execute(args: string[]): IFuture<void> {
11+
return this.$infoService.printComponentsInfo();
12+
}
13+
}
14+
$injector.registerCommand("info", InfoCommand);

lib/constants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export let NATIVESCRIPT_KEY_NAME = "nativescript";
88
export let NODE_MODULES_FOLDER_NAME = "node_modules";
99
export let TNS_MODULES_FOLDER_NAME = "tns_modules";
1010
export let TNS_CORE_MODULES_NAME = "tns-core-modules";
11+
export let TNS_ANDROID_RUNTIME_NAME = "tns-android";
12+
export let TNS_IOS_RUNTIME_NAME = "tns-ios";
1113
export let PACKAGE_JSON_FILE_NAME = "package.json";
1214
export let NODE_MODULE_CACHE_PATH_KEY_NAME = "node-modules-cache-path";
1315
export let DEFAULT_APP_IDENTIFIER_PREFIX = "org.nativescript";

lib/declarations.ts

+46
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ interface IInitService {
9191
initialize(): IFuture<void>;
9292
}
9393

94+
interface IInfoService {
95+
printComponentsInfo(): IFuture<void>;
96+
}
97+
9498
/**
9599
* Describes standard username/password type credentials.
96100
*/
@@ -257,6 +261,47 @@ interface IXmlValidator {
257261
getXmlFileErrors(sourceFile: string): IFuture<string>;
258262
}
259263

264+
interface IVersionInformation {
265+
componentName: string;
266+
currentVersion?: string;
267+
latestVersion: string;
268+
}
269+
270+
/**
271+
* Describes methods for working with versions.
272+
*/
273+
interface IVersionsService {
274+
/**
275+
* Gets version information about nativescript cli.
276+
* @return {IFuture<IVersionInformation>} The version information.
277+
*/
278+
getNativescriptCliVersion(): IFuture<IVersionInformation>;
279+
280+
/**
281+
* Gets version information about nativescript core modules.
282+
* @return {IFuture<IVersionInformation>} The version information.
283+
*/
284+
getNativescriptCoreModulesVersion(): IFuture<IVersionInformation>;
285+
286+
/**
287+
* Gets versions information about nativescript runtimes.
288+
* @return {IFuture<IVersionInformation[]>} The version information.
289+
*/
290+
getRuntimesVersions(): IFuture<IVersionInformation[]>;
291+
292+
/**
293+
* Gets versions information about the nativescript components with new.
294+
* @return {IFuture<IVersionInformation[]>} The version information.
295+
*/
296+
getComponentsForUpdate(): IFuture<IVersionInformation[]>;
297+
298+
/**
299+
* Gets versions information about all nativescript components.
300+
* @return {IFuture<IVersionInformation[]>} The version information.
301+
*/
302+
getAllComponentsVersions(): IFuture<IVersionInformation[]>;
303+
}
304+
260305
/**
261306
* Describes methods for project name.
262307
*/
@@ -269,3 +314,4 @@ interface IProjectNameService {
269314
*/
270315
ensureValidName(projectName: string, validateOptions?: {force: boolean}): IFuture<string>;
271316
}
317+

lib/services/doctor-service.ts

+92-74
Original file line numberDiff line numberDiff line change
@@ -26,96 +26,114 @@ class DoctorService implements IDoctorService {
2626
private $npm: INodePackageManager,
2727
private $opener: IOpener,
2828
private $prompter: IPrompter,
29-
private $fs: IFileSystem) { }
29+
private $fs: IFileSystem,
30+
private $versionsService: IVersionsService) { }
3031

31-
public printWarnings(configOptions?: { trackResult: boolean }): boolean {
32-
let result = false;
33-
let sysInfo = this.$sysInfo.getSysInfo(path.join(__dirname, "..", "..", "package.json")).wait();
34-
35-
if (!sysInfo.adbVer) {
36-
this.$logger.warn("WARNING: adb from the Android SDK is not installed or is not configured properly.");
37-
this.$logger.out("For Android-related operations, the NativeScript CLI will use a built-in version of adb." + EOL
38-
+ "To avoid possible issues with the native Android emulator, Genymotion or connected" + EOL
39-
+ "Android devices, verify that you have installed the latest Android SDK and" + EOL
40-
+ "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL);
41-
42-
this.printPackageManagerTip();
43-
result = true;
44-
}
45-
46-
if (!sysInfo.androidInstalled) {
47-
this.$logger.warn("WARNING: The Android SDK is not installed or is not configured properly.");
48-
this.$logger.out("You will not be able to build your projects for Android and run them in the native emulator." + EOL
49-
+ "To be able to build for Android and run apps in the native emulator, verify that you have" + EOL
50-
+ "installed the latest Android SDK and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL
51-
);
32+
public printWarnings(configOptions?: { trackResult: boolean }): IFuture<boolean> {
33+
return (() => {
34+
let result = false;
35+
let sysInfo = this.$sysInfo.getSysInfo(path.join(__dirname, "..", "..", "package.json")).wait();
5236

53-
this.printPackageManagerTip();
54-
result = true;
55-
}
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);
5643

57-
if (this.$hostInfo.isDarwin) {
58-
if(!sysInfo.xcodeVer) {
59-
this.$logger.warn("WARNING: Xcode is not installed or is not configured properly.");
60-
this.$logger.out("You will not be able to build your projects for iOS or run them in the iOS Simulator." + EOL
61-
+ "To be able to build for iOS and run apps in the native emulator, verify that you have installed Xcode." + EOL);
44+
this.printPackageManagerTip();
6245
result = true;
6346
}
6447

65-
if(!sysInfo.cocoapodVer) {
66-
this.$logger.warn("WARNING: CocoaPods is not installed or is not configured properly.");
67-
this.$logger.out("You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL
68-
+ "To be able to build such projects, verify that you have installed CocoaPods.");
48+
if (!sysInfo.androidInstalled) {
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+
);
54+
55+
this.printPackageManagerTip();
6956
result = true;
7057
}
7158

72-
if (sysInfo.xcodeVer && sysInfo.cocoapodVer) {
73-
let problemWithCocoaPods = this.verifyCocoaPods();
74-
if (problemWithCocoaPods) {
75-
this.$logger.warn("WARNING: There was a problem with CocoaPods");
76-
this.$logger.out("Verify that CocoaPods are configured properly.");
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.cocoapodVer) {
68+
this.$logger.warn("WARNING: CocoaPods is not installed or is not configured properly.");
69+
this.$logger.out("You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL
70+
+ "To be able to build such projects, verify that you have installed CocoaPods.");
71+
result = true;
72+
}
73+
74+
if (sysInfo.xcodeVer && sysInfo.cocoapodVer) {
75+
let problemWithCocoaPods = this.verifyCocoaPods();
76+
if (problemWithCocoaPods) {
77+
this.$logger.warn("WARNING: There was a problem with CocoaPods");
78+
this.$logger.out("Verify that CocoaPods are configured properly.");
79+
result = true;
80+
}
81+
}
82+
83+
if (sysInfo.cocoapodVer && semver.valid(sysInfo.cocoapodVer) === null) {
84+
this.$logger.warn(`WARNING: CocoaPods version is not a valid semver version.`);
85+
this.$logger.out("You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL
86+
+ `To be able to build such projects, verify that you have at least ${DoctorService.MIN_SUPPORTED_POD_VERSION} version installed.`);
7787
result = true;
7888
}
89+
90+
if (sysInfo.cocoapodVer && semver.valid(sysInfo.cocoapodVer) && semver.lt(sysInfo.cocoapodVer, DoctorService.MIN_SUPPORTED_POD_VERSION)) {
91+
this.$logger.warn(`WARNING: CocoaPods version is lower 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+
} else {
97+
this.$logger.out("NOTE: You can develop for iOS only on Mac OS X systems.");
98+
this.$logger.out("To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later." + EOL);
7999
}
80100

81-
if (sysInfo.cocoapodVer && semver.valid(sysInfo.cocoapodVer) === null) {
82-
this.$logger.warn(`WARNING: CocoaPods version is not a valid semver version.`);
83-
this.$logger.out("You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL
84-
+ `To be able to build such projects, verify that you have at least ${DoctorService.MIN_SUPPORTED_POD_VERSION} version installed.`);
85-
result = true;
101+
let androidToolsIssues = this.$androidToolsInfo.validateInfo().wait();
102+
let javaVersionIssue = this.$androidToolsInfo.validateJavacVersion(sysInfo.javacVersion).wait();
103+
let doctorResult = result || androidToolsIssues || javaVersionIssue;
104+
105+
if (!configOptions || configOptions.trackResult) {
106+
this.$analyticsService.track("DoctorEnvironmentSetup", doctorResult ? "incorrect" : "correct").wait();
86107
}
87108

88-
if (sysInfo.cocoapodVer && semver.valid(sysInfo.cocoapodVer) && semver.lt(sysInfo.cocoapodVer, DoctorService.MIN_SUPPORTED_POD_VERSION)) {
89-
this.$logger.warn(`WARNING: CocoaPods version is lower than ${DoctorService.MIN_SUPPORTED_POD_VERSION}.`);
90-
this.$logger.out("You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL
91-
+ `To be able to build such projects, verify that you have at least ${DoctorService.MIN_SUPPORTED_POD_VERSION} version installed.`);
92-
result = true;
109+
if (doctorResult) {
110+
this.$logger.info("There seem to be issues with your configuration.");
111+
if (this.$hostInfo.isDarwin) {
112+
this.promptForHelp(DoctorService.DarwinSetupDocsLink, DoctorService.DarwinSetupScriptLocation, []).wait();
113+
} else if (this.$hostInfo.isWindows) {
114+
this.promptForHelp(DoctorService.WindowsSetupDocsLink, DoctorService.WindowsSetupScriptExecutable, DoctorService.WindowsSetupScriptArguments).wait();
115+
} else {
116+
this.promptForDocs(DoctorService.LinuxSetupDocsLink).wait();
117+
}
93118
}
94-
} else {
95-
this.$logger.out("NOTE: You can develop for iOS only on Mac OS X systems.");
96-
this.$logger.out("To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later." + EOL);
97-
}
98119

99-
let androidToolsIssues = this.$androidToolsInfo.validateInfo().wait();
100-
let javaVersionIssue = this.$androidToolsInfo.validateJavacVersion(sysInfo.javacVersion).wait();
101-
let doctorResult = result || androidToolsIssues || javaVersionIssue;
120+
let versionsInformation: IVersionInformation[] = this.$versionsService.getComponentsForUpdate().wait();
102121

103-
if(!configOptions || configOptions.trackResult) {
104-
this.$analyticsService.track("DoctorEnvironmentSetup", doctorResult ? "incorrect" : "correct").wait();
105-
}
122+
this.printVersionsInformation(versionsInformation);
106123

107-
if(doctorResult) {
108-
this.$logger.info("There seem to be issues with your configuration.");
109-
if (this.$hostInfo.isDarwin) {
110-
this.promptForHelp(DoctorService.DarwinSetupDocsLink, DoctorService.DarwinSetupScriptLocation, []).wait();
111-
} else if (this.$hostInfo.isWindows) {
112-
this.promptForHelp(DoctorService.WindowsSetupDocsLink, DoctorService.WindowsSetupScriptExecutable, DoctorService.WindowsSetupScriptArguments).wait();
113-
} else {
114-
this.promptForDocs(DoctorService.LinuxSetupDocsLink).wait();
115-
}
116-
}
124+
return doctorResult;
125+
}).future<boolean>()();
126+
}
127+
128+
private printVersionsInformation(versionsInformation: IVersionInformation[]) {
129+
if (versionsInformation && versionsInformation.length) {
130+
let table: any = helpers.createTableWithVersionsInformation(versionsInformation);
117131

118-
return doctorResult;
132+
this.$logger.warn("Updates available");
133+
this.$logger.out(table.toString() + EOL);
134+
} else {
135+
this.$logger.out("Your components are up to date." + EOL);
136+
}
119137
}
120138

121139
private promptForDocs(link: string): IFuture<void> {
@@ -165,17 +183,17 @@ class DoctorService implements IDoctorService {
165183
spinner.message("Verifying CocoaPods. This may take some time, please be patient.");
166184
spinner.start();
167185
let future = this.$childProcess.spawnFromEvent(
168-
this.$config.USE_POD_SANDBOX ? "sandbox-pod": "pod",
186+
this.$config.USE_POD_SANDBOX ? "sandbox-pod" : "pod",
169187
["install"],
170188
"exit",
171-
{stdio: "inherit", cwd: iosDir},
189+
{ stdio: "inherit", cwd: iosDir },
172190
{ throwError: true }
173-
);
191+
);
174192

175193
this.$progressIndicator.showProgressIndicator(future, 5000).wait();
176194

177195
return !(this.$fs.exists(path.join(iosDir, "__PROJECT_NAME__.xcworkspace")).wait());
178-
} catch(err) {
196+
} catch (err) {
179197
this.$logger.trace(`verifyCocoaPods error: ${err}`);
180198
return true;
181199
} finally {

0 commit comments

Comments
 (0)