diff --git a/CHANGELOG.md b/CHANGELOG.md
index edf411cf88..964c7eed2e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,33 @@
NativeScript CLI Changelog
================
+1.5.0 (2015, November 24)
+==
+
+### New
+* [Implemented #493](https://github.com/NativeScript/nativescript-cli/issues/493): Enable transpilers support in NativeScript projects.
+* [Implemented #594](https://github.com/NativeScript/nativescript-cli/issues/594): Implement a hard dependency on the node.js version and exit if not satisfied.
+* [Implemented #684](https://github.com/NativeScript/nativescript-cli/issues/684): Enable commands hooks.
+* [Implemented #955](https://github.com/NativeScript/nativescript-cli/issues/955): Support for Xcode7 simulator.
+* [Implemented #1007](https://github.com/NativeScript/nativescript-cli/issues/1007): Smarter and faster LiveSync.
+* [Implemented #1048](https://github.com/NativeScript/nativescript-cli/issues/1048): Support Gradle files from plugins, merge android resource files using aapt and respect AndroidManifest.xml from App_Resources.
+* [Implemented #1113](https://github.com/NativeScript/nativescript-cli/issues/1113): Let users create and execute unit tests in their projects.
+* [Implemented #1117](https://github.com/NativeScript/nativescript-cli/issues/1117): Support for TypeScript-based NativeScript projects.
+* [Implemented #1130](https://github.com/NativeScript/nativescript-cli/issues/1130): Show application output from livesync command for iOS devices and android devices and emulators.
+* [Implemented #1164](https://github.com/NativeScript/nativescript-cli/issues/1164): Use android tools from ANDROID_HOME.
+* [Implemented #1229](https://github.com/NativeScript/nativescript-cli/issues/1229): Support for Node 5.1.0.
+
+### Fixed
+* [Fixed #727](https://github.com/NativeScript/nativescript-cli/issues/727): Double logging with tns run ios.
+* [Fixed #1044](https://github.com/NativeScript/nativescript-cli/issues/1044): iOS debug break on Simulator causes app crash when the debugger is paused on the first line for a long time.
+* [Fixed #1086](https://github.com/NativeScript/nativescript-cli/issues/1086): --key-store-path option to look for the keystore file path relative to the app root.
+* [Fixed #1106](https://github.com/NativeScript/nativescript-cli/issues/1106): Livesync double restarts for TS projects.
+* [Fixed #1110](https://github.com/NativeScript/nativescript-cli/issues/1110): `tns doctor` command should detect invalid java version.
+* [Fixed #1167](https://github.com/NativeScript/nativescript-cli/issues/1167): `tns run`, `tns emulate` and `tns deploy` commands do not check if device is available before build.
+* [Fixed #1177](https://github.com/NativeScript/nativescript-cli/issues/1177): `tns run` command fails when multiple devices with same platform are attached.
+* [Fixed #1185](https://github.com/NativeScript/nativescript-cli/issues/1185): `tns device` command fails when VS Emulator is running.
+* [Fixed #1204](https://github.com/NativeScript/nativescript-cli/issues/1204): Incorrect prepare when using npm 3.x.
+
1.4.3 (2015, October 21)
==
diff --git a/PLUGINS.md b/PLUGINS.md
index f1909f9724..4e5346a6a4 100644
--- a/PLUGINS.md
+++ b/PLUGINS.md
@@ -74,14 +74,16 @@ my-plugin/
│ └── AndroidManifest.xml
└── ios/
└── Info.plist
+ └── Podfile
```
-* `index.js`: This file is the CommonJS module which exposes the native API. You can use platform-specific `*.platform.js` files. For example: `index.ios.js` and `index.android.js`. During the plugin installation, the NativeScript CLI will copy the platform resources to the `tns_modules` subdirectory in the correct platform destination in the `platforms` directory of your project.
Alternatively, you can give any name to this CommonJS module. In this case, however, you need to point to this file by setting the `main` key in the `package.json` for the plugin. For more information, see [Folders as Modules](https://nodejs.org/api/modules.html#modules_folders_as_modules).
+* `index.js`: This file is the CommonJS module which exposes the native API. You can use platform-specific `*.platform.js` files. For example: `index.ios.js` and `index.android.js`. During the plugin installation, the NativeScript CLI will copy the platform resources to the `tns_modules` subdirectory in the correct platform destination in the `platforms` directory of your project.
Alternatively, you can give any name to this CommonJS module. In this case, however, you need to point to this file by setting the `main` key in the `package.json` for the plugin. For more information, see [Folders as Modules](https://nodejs.org/api/modules.html#modules_folders_as_modules).
* `package.json`: This file contains the metadata for your plugin. It sets the supported runtimes, the plugin name and version and any dependencies. The `package.json` specification is described in detail below.
* `platforms\android\AndroidManifest.xml`: This file describes any specific configuration changes required for your plugin to work. For example: required permissions. For more information about the format of `AndroidManifest.xml`, see [App Manifest](http://developer.android.com/guide/topics/manifest/manifest-intro.html).
During build, gradle will merge the plugin `AndroidManifest.xml` with the `AndroidManifest.xml` for your project. The NativeScript CLI will not resolve any contradicting or duplicate entries during the merge. After the plugin is installed, you need to manually resolve such issues.
* `platforms\android\include.gradle`: This file modifies the native Android configuration of your NativeScript project such as native dependencies, build types and configurations. For more information about the format of `include.gradle`, see [include.gradle file](#includegradle-specification).
* `platforms/android/res`: (Optional) This directory contains resources declared by the `AndroidManifest.xml` file. You can look at the folder structure [here](http://developer.android.com/guide/topics/resources/providing-resources.html#ResourceTypes).
-* `platforms/ios/Info.plist`: This file describes any specific configuration changes required for your plugin to work. For example: required permissions. For more information about the format of `Info.plist`, see [About Information Property List Files](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html).
During the plugin installation, the NativeScript CLI will merge the plugin `Info.plist` with the `Info.plist` for your project. The NativeScript CLI will not resolve any contradicting or duplicate entries during the merge. After the plugin is installed, you need to manually resolve such issues.
+* `platforms/ios/Info.plist`: This file describes any specific configuration changes required for your plugin to work. For example: required permissions. For more information about the format of `Info.plist`, see [About Information Property List Files](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html).
During the plugin installation, the NativeScript CLI will merge the plugin `Info.plist` with the `Info.plist` for your project. The NativeScript CLI will not resolve any contradicting or duplicate entries during the merge. After the plugin is installed, you need to manually resolve such issues.
+* `platforms/ios/Podfile`: This file describes the dependency to the library that you want to use. For more information, see [CocoaPods.md](CocoaPods.md).
NativeScript plugins which contain both native Android and iOS libraries might have the following directory structure.
diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts
index 84723e6581..7f52036ac6 100644
--- a/lib/android-tools-info.ts
+++ b/lib/android-tools-info.ts
@@ -44,10 +44,10 @@ export class AndroidToolsInfo implements IAndroidToolsInfo {
if(this.validateAndroidHomeEnvVariable(this.androidHome).wait()) {
let androidPath = path.join(this.androidHome, "tools", this.androidExecutableName);
if(!this.trySetAndroidPath(androidPath).wait() && !this.trySetAndroidPath(this.androidExecutableName).wait()) {
- this.$errors.failWithoutHelp(`Unable to find "${this.androidExecutableName}" executable file. Make sure you have set ANDROID_HOME environment variable correctly.`);
+ this.printMessage(`Unable to find "${this.androidExecutableName}" executable file. Make sure you have set ANDROID_HOME environment variable correctly.`);
}
} else {
- this.$errors.failWithoutHelp("ANDROID_HOME environment variable is not set correctly.");
+ this.printMessage("ANDROID_HOME environment variable is not set correctly.");
}
}
diff --git a/lib/commands/prepare.ts b/lib/commands/prepare.ts
index 7f07f4644e..4fbf79ad92 100644
--- a/lib/commands/prepare.ts
+++ b/lib/commands/prepare.ts
@@ -2,11 +2,16 @@
"use strict";
export class PrepareCommand implements ICommand {
- constructor(private $platformService: IPlatformService,
+ constructor(private $errors: IErrors,
+ private $platformService: IPlatformService,
private $platformCommandParameter: ICommandParameter) { }
execute(args: string[]): IFuture {
- return this.$platformService.preparePlatform(args[0]);
+ return (() => {
+ if (!this.$platformService.preparePlatform(args[0]).wait()) {
+ this.$errors.failWithoutHelp("Unable to prepare the project.");
+ }
+ }).future()();
}
allowedParameters = [this.$platformCommandParameter];
diff --git a/lib/common b/lib/common
index 6e5218d5c5..66516b388a 160000
--- a/lib/common
+++ b/lib/common
@@ -1 +1 @@
-Subproject commit 6e5218d5c5303f359a5957c559abe613231ffe83
+Subproject commit 66516b388a771dc24018d56367aa5c6f1cbe945d
diff --git a/lib/definitions/platform.d.ts b/lib/definitions/platform.d.ts
index b3a068c579..7f46dcbdab 100644
--- a/lib/definitions/platform.d.ts
+++ b/lib/definitions/platform.d.ts
@@ -6,7 +6,7 @@ interface IPlatformService {
removePlatforms(platforms: string[]): IFuture;
updatePlatforms(platforms: string[]): IFuture;
runPlatform(platform: string, buildConfig?: IBuildConfig): IFuture;
- preparePlatform(platform: string): IFuture;
+ preparePlatform(platform: string): IFuture;
buildPlatform(platform: string, buildConfig?: IBuildConfig): IFuture;
installOnDevice(platform: string, buildConfig?: IBuildConfig): IFuture;
deployOnDevice(platform: string, buildConfig?: IBuildConfig): IFuture;
diff --git a/lib/providers/device-log-provider.ts b/lib/providers/device-log-provider.ts
index 746a60cd65..3b2230f127 100644
--- a/lib/providers/device-log-provider.ts
+++ b/lib/providers/device-log-provider.ts
@@ -3,7 +3,9 @@
export class DeviceLogProvider implements Mobile.IDeviceLogProvider {
//sample line is "I/Web Console( 4438): Received Event: deviceready at file:///storage/emulated/0/Icenium/com.telerik.TestApp/js/index.js:48"
- private static LINE_REGEX = /.\/(.+?)\s*\(\s*(\d+?)\): (.*)/;
+ private static LINE_REGEX = /.\/(.+?)\s*\(\s*\d+?\): (.*)/;
+ // sample line is "11-23 12:39:07.310 1584 1597 I art : Background sticky concurrent mark sweep GC freed 21966(1780KB) AllocSpace objects, 4(80KB) LOS objects, 77% free, 840KB/3MB, paused 4.018ms total 158.629ms"
+ private static API_LEVEL_23_LINE_REGEX = /.+?\s+?(?:[A-Z]\s+?)([A-Za-z ]+?)\s+?\: (.*)/;
constructor(private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
private $logger: ILogger) { }
@@ -25,15 +27,12 @@ export class DeviceLogProvider implements Mobile.IDeviceLogProvider {
private getConsoleLogFromLine(lineText: String): any {
let acceptedTags = ["chromium", "Web Console", "JS"];
- let match = lineText.match(DeviceLogProvider.LINE_REGEX);
- if (match) {
- if(acceptedTags.indexOf(match[1]) !== -1) {
- return {tag: match[1], message: match[3]};
- }
- } else if (_.any(acceptedTags, (tag: string) => { return lineText.indexOf(tag) !== -1; })) {
- return {message: match[3]};
+ let match = lineText.match(DeviceLogProvider.LINE_REGEX) || lineText.match(DeviceLogProvider.API_LEVEL_23_LINE_REGEX);
+ if (match && acceptedTags.indexOf(match[1].trim()) !== -1) {
+ return {tag: match[1].trim(), message: match[2]};
}
- return null;
+ let matchingTag = _.any(acceptedTags, (tag: string) => { return lineText.indexOf(tag) !== -1; });
+ return matchingTag ? { message: lineText } : null;
}
}
$injector.register("deviceLogProvider", DeviceLogProvider);
diff --git a/lib/services/android-project-service.ts b/lib/services/android-project-service.ts
index 6a66beccc3..bdca9896d3 100644
--- a/lib/services/android-project-service.ts
+++ b/lib/services/android-project-service.ts
@@ -80,7 +80,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
// this call will fail in case `android` is not set correctly.
this.$androidToolsInfo.getPathToAndroidExecutable().wait();
- this.$androidToolsInfo.validateJavacVersion(this.$sysInfo.getSysInfo().wait().javacVersion, {showWarningsAsErrors: true}).wait();
+ this.$androidToolsInfo.validateJavacVersion(this.$sysInfo.getSysInfo(path.join(__dirname, "..", "..", "package.json")).wait().javacVersion, {showWarningsAsErrors: true}).wait();
}).future()();
}
diff --git a/lib/services/doctor-service.ts b/lib/services/doctor-service.ts
index f016d51834..9cc8ec43d7 100644
--- a/lib/services/doctor-service.ts
+++ b/lib/services/doctor-service.ts
@@ -2,6 +2,7 @@
"use strict";
import {EOL} from "os";
import * as semver from "semver";
+import * as path from "path";
class DoctorService implements IDoctorService {
private static MIN_SUPPORTED_POD_VERSION = "0.38.2";
@@ -13,7 +14,7 @@ class DoctorService implements IDoctorService {
public printWarnings(): boolean {
let result = false;
- let sysInfo = this.$sysInfo.getSysInfo().wait();
+ let sysInfo = this.$sysInfo.getSysInfo(path.join(__dirname, "..", "..", "package.json")).wait();
if (!sysInfo.adbVer) {
this.$logger.warn("WARNING: adb from the Android SDK is not installed or is not configured properly.");
diff --git a/lib/services/ios-debug-service.ts b/lib/services/ios-debug-service.ts
index ac709a3922..279b33f631 100644
--- a/lib/services/ios-debug-service.ts
+++ b/lib/services/ios-debug-service.ts
@@ -76,13 +76,14 @@ class IOSDebugService implements IDebugService {
this.$platformService.buildPlatform(this.platform).wait();
let emulatorPackage = this.$platformService.getLatestApplicationPackageForEmulator(platformData).wait();
- let child_process = this.$iOSEmulatorServices.startEmulator(emulatorPackage.packageName, { waitForDebugger: true, captureStdin: true, args: "--nativescript-debug-brk" }).wait();
+ let child_process = this.$iOSEmulatorServices.startEmulator(emulatorPackage.packageName, { waitForDebugger: true, captureStdin: true,
+ args: "--nativescript-debug-brk", appId: this.$projectData.projectId }).wait();
let lineStream = byline(child_process.stdout);
lineStream.on('data', (line: NodeBuffer) => {
let lineText = line.toString();
- if(lineText && _.startsWith(lineText, emulatorPackage.packageName)) {
- let pid = _.trimLeft(lineText, emulatorPackage.packageName + ": ");
+ if(lineText && _.startsWith(lineText, this.$projectData.projectId)) {
+ let pid = _.trimLeft(lineText, this.$projectData.projectId + ": ");
this.$childProcess.exec(`lldb -p ${pid} -o "process continue"`);
} else {
diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts
index 5b7b510829..5cc1698b69 100644
--- a/lib/services/platform-service.ts
+++ b/lib/services/platform-service.ts
@@ -154,7 +154,7 @@ export class PlatformService implements IPlatformService {
}).future()();
}
- public preparePlatform(platform: string): IFuture {
+ public preparePlatform(platform: string): IFuture {
return (() => {
this.validatePlatform(platform);
@@ -166,12 +166,36 @@ export class PlatformService implements IPlatformService {
this.$errors.failWithoutHelp(`Unable to install dependencies. Make sure your package.json is valid and all dependencies are correct. Error is: ${err.message}`);
}
- this.preparePlatformCore(platform).wait();
- }).future()();
+ return this.preparePlatformCore(platform).wait();
+ }).future()();
+ }
+
+ private checkXmlFiles(sourceFiles: string[]): IFuture {
+ return (() => {
+ let xmlHasErrors = false;
+ let DomParser = require("xmldom").DOMParser;
+ sourceFiles
+ .filter(file => _.endsWith(file, ".xml"))
+ .forEach(file => {
+ let fileContents = this.$fs.readText(file).wait();
+ let hasErrors = false;
+ let domErrorHandler = (level:any, msg:string) => hasErrors = true;
+ let parser = new DomParser({
+ locator:{},
+ errorHandler: domErrorHandler
+ });
+ parser.parseFromString(fileContents, "text/xml");
+ xmlHasErrors = xmlHasErrors || hasErrors;
+ if (xmlHasErrors) {
+ this.$logger.out("Error: ".red.bold + file + " has syntax errors.".red.bold);
+ }
+ });
+ return !xmlHasErrors;
+ }).future()();
}
@helpers.hook('prepare')
- private preparePlatformCore(platform: string): IFuture {
+ private preparePlatformCore(platform: string): IFuture {
return (() => {
platform = platform.toLowerCase();
this.ensurePlatformInstalled(platform).wait();
@@ -206,6 +230,12 @@ export class PlatformService implements IPlatformService {
sourceFiles = sourceFiles.filter(source => !minimatch(source, `**/${constants.TNS_MODULES_FOLDER_NAME}/**`, {nocase: true}));
}
+ // verify .xml files are well-formed
+ let validXmlFiles = this.checkXmlFiles(sourceFiles).wait();
+ if (!validXmlFiles) {
+ return false;
+ }
+
// Remove .ts and .js.map files
PlatformService.EXCLUDE_FILES_PATTERN.forEach(pattern => sourceFiles = sourceFiles.filter(file => !minimatch(file, pattern, {nocase: true})));
let copyFileFutures = sourceFiles.map(source => {
@@ -245,13 +275,16 @@ export class PlatformService implements IPlatformService {
platformData.platformProjectService.processConfigurationFilesFromAppResources().wait();
this.$logger.out("Project successfully prepared");
- }).future()();
+ return true;
+ }).future()();
}
public buildPlatform(platform: string, buildConfig?: IBuildConfig): IFuture {
return (() => {
platform = platform.toLowerCase();
- this.preparePlatform(platform).wait();
+ if (!this.preparePlatform(platform).wait()) {
+ this.$errors.failWithoutHelp("Verify that listed files are well-formed and try again the operation.");
+ }
let platformData = this.$platformsData.getPlatformData(platform);
platformData.platformProjectService.buildProject(platformData.projectRoot, buildConfig).wait();
diff --git a/lib/services/test-execution-service.ts b/lib/services/test-execution-service.ts
index 0ce884f7e1..0fccee6b09 100644
--- a/lib/services/test-execution-service.ts
+++ b/lib/services/test-execution-service.ts
@@ -33,7 +33,8 @@ class TestExecutionService implements ITestExecutionService {
private $logger: ILogger,
private $fs: IFileSystem,
private $options: IOptions,
- private $pluginsService: IPluginsService) {
+ private $pluginsService: IPluginsService,
+ private $errors: IErrors) {
}
public startTestRunner(platform: string) : IFuture {
@@ -58,7 +59,9 @@ class TestExecutionService implements ITestExecutionService {
let socketIoJs = this.$httpClient.httpRequest(socketIoJsUrl).wait().body;
this.$fs.writeFile(path.join(projectDir, TestExecutionService.SOCKETIO_JS_FILE_NAME), socketIoJs).wait();
- this.$platformService.preparePlatform(platform).wait();
+ if (!this.$platformService.preparePlatform(platform).wait()) {
+ this.$errors.failWithoutHelp("Verify that listed files are well-formed and try again the operation.");
+ }
this.detourEntryPoint(projectFilesPath).wait();
let watchGlob = path.join(projectDir, constants.APP_FOLDER_NAME);
@@ -88,13 +91,22 @@ class TestExecutionService implements ITestExecutionService {
let beforeBatchLiveSyncAction = (filePath: string): IFuture => {
return (() => {
- this.$platformService.preparePlatform(platform).wait();
+ if (!this.$platformService.preparePlatform(platform).wait()) {
+ this.$logger.out("Verify that listed files are well-formed and try again the operation.");
+ return;
+ }
return path.join(projectFilesPath, path.relative(path.join(this.$projectData.projectDir, constants.APP_FOLDER_NAME), filePath));
}).future()();
};
let localProjectRootPath = platform.toLowerCase() === "ios" ? platformData.appDestinationDirectoryPath : null;
+ let getApplicationPathForiOSSimulatorAction = (): IFuture => {
+ return (() => {
+ return this.$platformService.getLatestApplicationPackageForEmulator(platformData).wait().packageName;
+ }).future()();
+ };
+
let liveSyncData = {
platform: platform,
appIdentifier: this.$projectData.projectId,
@@ -104,6 +116,7 @@ class TestExecutionService implements ITestExecutionService {
platformSpecificLiveSyncServices: platformSpecificLiveSyncServices,
notInstalledAppOnDeviceAction: notInstalledAppOnDeviceAction,
notRunningiOSSimulatorAction: notRunningiOSSimulatorAction,
+ getApplicationPathForiOSSimulatorAction: getApplicationPathForiOSSimulatorAction,
localProjectRootPath: localProjectRootPath,
beforeBatchLiveSyncAction: beforeBatchLiveSyncAction,
shouldRestartApplication: (localToDevicePaths: Mobile.ILocalToDevicePathData[]) => Future.fromResult(!this.$options.debugBrk),
diff --git a/lib/services/usb-livesync-service.ts b/lib/services/usb-livesync-service.ts
index 79c378cef6..299920d45a 100644
--- a/lib/services/usb-livesync-service.ts
+++ b/lib/services/usb-livesync-service.ts
@@ -34,6 +34,7 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
private $projectDataService: IProjectDataService,
private $prompter: IPrompter,
+ private $errors: IErrors,
$hostInfo: IHostInfo) {
super($devicesService, $mobileHelper, $localToDevicePathDataFactory, $logger, $options,
$deviceAppDataFactory, $fs, $dispatcher, $injector, $childProcess, $iOSEmulatorServices,
@@ -65,7 +66,9 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer
}
}
- this.$platformService.preparePlatform(platform).wait();
+ if (!this.$platformService.preparePlatform(platform).wait()) {
+ this.$errors.failWithoutHelp("Verify that listed files are well-formed and try again the operation.");
+ }
let projectFilesPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME);
@@ -83,7 +86,7 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer
let beforeBatchLiveSyncAction = (filePath: string): IFuture => {
return (() => {
- let projectFileInfo = this.getProjectFileInfo(filePath);
+ let projectFileInfo = this.getProjectFileInfo(filePath, platform);
let mappedFilePath = path.join(projectFilesPath, path.relative(path.join(this.$projectData.projectDir, constants.APP_FOLDER_NAME), projectFileInfo.onDeviceName));
// Handle files that are in App_Resources/
@@ -121,7 +124,10 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer
let fastLiveSync = (filePath: string) => {
this.$dispatcher.dispatch(() => {
return (() => {
- this.$platformService.preparePlatform(platform).wait();
+ if (!this.$platformService.preparePlatform(platform).wait()) {
+ this.$logger.out("Verify that listed files are well-formed and try again the operation.");
+ return;
+ }
let mappedFilePath = beforeBatchLiveSyncAction(filePath).wait();
if (this.shouldSynciOSSimulator(platform).wait()) {
@@ -148,6 +154,12 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer
});
};
+ let getApplicationPathForiOSSimulatorAction = (): IFuture => {
+ return (() => {
+ return this.$platformService.getLatestApplicationPackageForEmulator(platformData).wait().packageName;
+ }).future()();
+ };
+
let liveSyncData = {
platform: platform,
appIdentifier: this.$projectData.projectId,
@@ -157,6 +169,7 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer
platformSpecificLiveSyncServices: platformSpecificLiveSyncServices,
notInstalledAppOnDeviceAction: notInstalledAppOnDeviceAction,
notRunningiOSSimulatorAction: notRunningiOSSimulatorAction,
+ getApplicationPathForiOSSimulatorAction: getApplicationPathForiOSSimulatorAction,
localProjectRootPath: localProjectRootPath,
beforeLiveSyncAction: beforeLiveSyncAction,
beforeBatchLiveSyncAction: beforeBatchLiveSyncAction,
@@ -170,7 +183,10 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer
}
protected preparePlatformForSync(platform: string) {
- this.$platformService.preparePlatform(platform).wait();
+ if (!this.$platformService.preparePlatform(platform).wait()) {
+ this.$logger.out("Verify that listed files are well-formed and try again the operation.");
+ return;
+ }
}
private resolveUsbLiveSyncService(platform: string, device: Mobile.IDevice): IPlatformSpecificUsbLiveSyncService {
diff --git a/lib/sys-info.ts b/lib/sys-info.ts
index 0a7f1c47b6..6d660177cc 100644
--- a/lib/sys-info.ts
+++ b/lib/sys-info.ts
@@ -2,23 +2,25 @@
"use strict";
import {SysInfoBase} from "./common/sys-info-base";
+import * as path from "path";
export class SysInfo extends SysInfoBase {
constructor(protected $childProcess: IChildProcess,
protected $hostInfo: IHostInfo,
protected $iTunesValidator: Mobile.IiTunesValidator,
protected $logger: ILogger,
+ protected $winreg: IWinReg,
private $androidToolsInfo: IAndroidToolsInfo) {
- super($childProcess, $hostInfo, $iTunesValidator, $logger);
+ super($childProcess, $hostInfo, $iTunesValidator, $logger, $winreg);
}
- public getSysInfo(androidToolsInfo?: {pathToAdb: string, pathToAndroid: string}): IFuture {
+ public getSysInfo(pathToPackageJson: string, androidToolsInfo?: {pathToAdb: string, pathToAndroid: string}): IFuture {
return ((): ISysInfoData => {
let defaultAndroidToolsInfo = {
pathToAdb: this.$androidToolsInfo.getPathToAdbFromAndroidHome().wait(),
pathToAndroid: this.$androidToolsInfo.getPathToAndroidExecutable().wait()
};
- return super.getSysInfo(androidToolsInfo || defaultAndroidToolsInfo).wait();
+ return super.getSysInfo(pathToPackageJson || path.join(__dirname, "..", "package.json"), androidToolsInfo || defaultAndroidToolsInfo).wait();
}).future()();
}
}
diff --git a/package.json b/package.json
index 13472763f7..8531b29067 100644
--- a/package.json
+++ b/package.json
@@ -29,20 +29,20 @@
"broccoli": "0.16.4",
"broccoli-funnel": "0.2.3",
"bufferpack": "0.0.6",
- "bufferutil": "https://github.com/telerik/bufferutil/tarball/v1.0.1.0",
+ "bufferutil": "https://github.com/telerik/bufferutil/tarball/v1.0.1.1",
"byline": "4.2.1",
"chalk": "1.1.0",
"cli-table": "https://github.com/telerik/cli-table/tarball/v0.3.1.1",
"colors": "1.1.2",
"esprima": "2.7.0",
- "ffi": "https://github.com/icenium/node-ffi/tarball/v2.0.0.0",
- "fibers": "https://github.com/icenium/node-fibers/tarball/v1.0.6.2",
+ "ffi": "https://github.com/icenium/node-ffi/tarball/v2.0.0.1",
+ "fibers": "https://github.com/icenium/node-fibers/tarball/v1.0.6.3",
"filesize": "3.1.2",
"gaze": "0.5.1",
"gulp": "3.9.0",
"iconv-lite": "0.4.11",
"inquirer": "0.9.0",
- "ios-sim-portable": "1.0.13-epsilon",
+ "ios-sim-portable": "1.0.15",
"lockfile": "1.0.1",
"lodash": "3.10.0",
"log4js": "0.6.26",
@@ -50,6 +50,7 @@
"marked-terminal": "1.5.0",
"minimatch": "2.0.10",
"mkdirp": "0.5.1",
+ "moment": "2.10.6",
"mute-stream": "0.0.5",
"node-inspector": "https://github.com/NativeScript/node-inspector/tarball/v0.7.4.0",
"node-uuid": "1.4.3",
@@ -61,15 +62,15 @@
"progress-stream": "1.1.1",
"prompt": "https://github.com/Icenium/prompt/tarball/master",
"properties-parser": "0.2.3",
- "ref": "https://github.com/icenium/ref/tarball/v1.1.3.0",
- "ref-struct": "https://github.com/telerik/ref-struct/tarball/v1.0.2.0",
+ "ref": "https://github.com/icenium/ref/tarball/v1.1.3.1",
+ "ref-struct": "https://github.com/telerik/ref-struct/tarball/v1.0.2.1",
"rimraf": "2.4.2",
"semver": "5.0.1",
"shelljs": "0.5.1",
"tabtab": "https://github.com/Icenium/node-tabtab/tarball/master",
"temp": "0.8.3",
"through2": "2.0.0",
- "utf-8-validate": "https://github.com/telerik/utf-8-validate/tarball/v1.0.1.0",
+ "utf-8-validate": "https://github.com/telerik/utf-8-validate/tarball/v1.0.1.1",
"vinyl-filter-since": "2.0.2",
"winreg": "0.0.12",
"ws": "0.7.1",
@@ -98,6 +99,6 @@
},
"license": "Apache-2.0",
"engines": {
- "node": ">=0.10.40 <0.11.0 || >=0.12.7 <0.13.0 || >=4.2.1 <5.0.0"
+ "node": ">=0.10.40 <0.11.0 || >=0.12.7 <0.13.0 || >=4.2.1 <5.0.0 || >=5.1.0 <6.0.0"
}
}
diff --git a/test/platform-service.ts b/test/platform-service.ts
index a4a766ecb5..edac69f78e 100644
--- a/test/platform-service.ts
+++ b/test/platform-service.ts
@@ -181,7 +181,8 @@ describe('Platform Service Tests', () => {
testInjector.register("fs", fsLib.FileSystem);
fs = testInjector.resolve("fs");
});
- it("should process only files in app folder when preparing for iOS platform", () => {
+
+ function prepareDirStructure() {
let tempFolder = temp.mkdirSync("prepare platform");
let appFolderPath = path.join(tempFolder, "app");
@@ -193,6 +194,12 @@ describe('Platform Service Tests', () => {
let appDestFolderPath = path.join(tempFolder, "appDest");
let appResourcesFolderPath = path.join(appDestFolderPath, "App_Resources");
+ return { tempFolder, appFolderPath, app1FolderPath, appDestFolderPath, appResourcesFolderPath };
+ }
+
+ it("should process only files in app folder when preparing for iOS platform", () => {
+ let { tempFolder, appFolderPath, app1FolderPath, appDestFolderPath, appResourcesFolderPath } = prepareDirStructure();
+
// Add platform specific files to app and app1 folders
let platformSpecificFiles = [
"test1.ios.js", "test1-ios-js", "test2.android.js", "test2-android-js"
@@ -242,16 +249,7 @@ describe('Platform Service Tests', () => {
assert.isFalse(fs.exists(path.join(appDestFolderPath, "app1")).wait());
});
it("should process only files in app folder when preparing for Android platform", () => {
- let tempFolder = temp.mkdirSync("prepare platform");
-
- let appFolderPath = path.join(tempFolder, "app");
- fs.createDirectory(appFolderPath).wait();
-
- let app1FolderPath = path.join(tempFolder, "app1");
- fs.createDirectory(app1FolderPath).wait();
-
- let appDestFolderPath = path.join(tempFolder, "appDest");
- let appResourcesFolderPath = path.join(appDestFolderPath, "App_Resources");
+ let { tempFolder, appFolderPath, app1FolderPath, appDestFolderPath, appResourcesFolderPath } = prepareDirStructure();
// Add platform specific files to app and app1 folders
let platformSpecificFiles = [
@@ -301,5 +299,42 @@ describe('Platform Service Tests', () => {
// Asserts that the files in app1 folder aren't process as platform specific
assert.isFalse(fs.exists(path.join(appDestFolderPath, "app1")).wait());
});
+
+ it("invalid xml is caught", () => {
+ require("colors");
+ let { tempFolder, appFolderPath, appDestFolderPath, appResourcesFolderPath } = prepareDirStructure();
+
+ // generate invalid xml
+ let fileFullPath = path.join(appFolderPath, "file.xml");
+ fs.writeFile(fileFullPath, "").wait();
+
+ let platformsData = testInjector.resolve("platformsData");
+ platformsData.platformsNames = ["android"];
+ platformsData.getPlatformData = (platform: string) => {
+ return {
+ appDestinationDirectoryPath: appDestFolderPath,
+ appResourcesDestinationDirectoryPath: appResourcesFolderPath,
+ normalizedPlatformName: "Android",
+ platformProjectService: {
+ prepareProject: () => Future.fromResult(),
+ validate: () => Future.fromResult(),
+ createProject: (projectRoot: string, frameworkDir: string) => Future.fromResult(),
+ interpolateData: (projectRoot: string) => Future.fromResult(),
+ afterCreateProject: (projectRoot: string) => Future.fromResult(),
+ getAppResourcesDestinationDirectoryPath: () => Future.fromResult(""),
+ processConfigurationFilesFromAppResources: () => Future.fromResult()
+ }
+ };
+ };
+
+ let projectData = testInjector.resolve("projectData");
+ projectData.projectDir = tempFolder;
+
+ platformService = testInjector.resolve("platformService");
+ let result = platformService.preparePlatform("android").wait();
+
+ // Asserts that prepare has caught invalid xml
+ assert.isFalse(result);
+ });
});
});