diff --git a/CHANGELOG.md b/CHANGELOG.md index 964c7eed2e..0eac55eda0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,20 @@ NativeScript CLI Changelog ================ +1.5.1 (2015, December 03) +== +### New +* [Implemented #452](https://github.com/NativeScript/nativescript-cli/issues/452): Build should report malformed XML. +* [Implemented #1263](https://github.com/NativeScript/nativescript-cli/issues/1263): Add timestamps to LiveSync messages. + +### Fixed +* [Fixed #1234](https://github.com/NativeScript/nativescript-cli/issues/1234): LiveSync does not work for iOS platform specific .xml/.css files on iOS Simulator. +* [Fixed #1242](https://github.com/NativeScript/nativescript-cli/issues/1242): `ANDROID_HOME environment variable is not set correctly` error is thrown when `tns run ios --log trace` command is executed. +* [Fixed #1245](https://github.com/NativeScript/nativescript-cli/issues/1245): `TypeError: Cannot read property 'match' of null` error is thrown on various commands. +* [Fixed #1246](https://github.com/NativeScript/nativescript-cli/issues/1246): LiveSync on android device is throwing ENAMTOOLONG error on Windows. +* [Fixed #1253](https://github.com/NativeScript/nativescript-cli/issues/1253): iOS debugger does not work with iOS Simulator with Xcode7+. +* [Fixed #1268](https://github.com/NativeScript/nativescript-cli/issues/1268): Hook failures treated as bad user input. + 1.5.0 (2015, November 24) == @@ -280,7 +294,7 @@ Building NativeScript projects for Android requires Android SDK 22, Android SDK * Introduced new project structure. To migrate to the new structure, complete the following steps. 1. Manually move all files and folders from the inner `app` folder one level up inside the outer `app` folder. 1. Remove the now empty inner `app` folder. - 1. Verify that your project structure reflects the structure described [here](README.md#create-project). + 1. Verify that your project structure reflects the structure described [here](https://github.com/NativeScript/nativescript-cli/blob/production/README.md#create-project). ### New diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 7f52036ac6..2e04ac4ae6 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -38,8 +38,11 @@ export class AndroidToolsInfo implements IAndroidToolsInfo { private $logger: ILogger, private $options: IOptions) {} - public getPathToAndroidExecutable(): IFuture { + public getPathToAndroidExecutable(options?: {showWarningsAsErrors: boolean}): IFuture { return ((): string => { + if(options) { + this.showWarningsAsErrors = options.showWarningsAsErrors; + } if (!this.pathToAndroidExecutable) { if(this.validateAndroidHomeEnvVariable(this.androidHome).wait()) { let androidPath = path.join(this.androidHome, "tools", this.androidExecutableName); @@ -47,7 +50,7 @@ export class AndroidToolsInfo implements IAndroidToolsInfo { this.printMessage(`Unable to find "${this.androidExecutableName}" executable file. Make sure you have set ANDROID_HOME environment variable correctly.`); } } else { - this.printMessage("ANDROID_HOME environment variable is not set correctly."); + this.$logger.trace("ANDROID_HOME environment variable is not set correctly."); } } @@ -338,11 +341,14 @@ export class AndroidToolsInfo implements IAndroidToolsInfo { return (() => { if (!this.installedTargetsCache) { try { - let result = this.$childProcess.spawnFromEvent(this.getPathToAndroidExecutable().wait(), ["list", "targets"], "close", {}, {throwError: false}).wait(); - if(result.stdout) { - this.$logger.trace(result.stdout); - this.installedTargetsCache = []; - result.stdout.replace(/id: \d+ or "(.+)"/g, (m:string, p1:string) => (this.installedTargetsCache.push(p1), m)); + let pathToAndroidExecutable = this.getPathToAndroidExecutable().wait(); + if(pathToAndroidExecutable) { + let result = this.$childProcess.spawnFromEvent(pathToAndroidExecutable, ["list", "targets"], "close", {}, {throwError: false}).wait(); + if(result && result.stdout) { + this.$logger.trace(result.stdout); + this.installedTargetsCache = []; + result.stdout.replace(/id: \d+ or "(.+)"/g, (m:string, p1:string) => (this.installedTargetsCache.push(p1), m)); + } } } catch(err) { this.$logger.trace("Unable to get Android targets. Error is: " + err); diff --git a/lib/common b/lib/common index ed9af3330c..416012b69c 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit ed9af3330c8c340faf217376d6f6d51916d0bf36 +Subproject commit 416012b69cd8bf67e9470d7f3670d631830e08c5 diff --git a/lib/declarations.ts b/lib/declarations.ts index e8906ca5df..9c90f22085 100644 --- a/lib/declarations.ts +++ b/lib/declarations.ts @@ -126,9 +126,10 @@ interface IAndroidToolsInfo { /** * Returns the path to `android` executable. It should be `$ANDROID_HOME/tools/android`. * In case ANDROID_HOME is not defined, check if `android` is part of $PATH. + * @param {any} options Defines if the warning messages should treated as error. * @return {string} Path to the `android` executable. */ - getPathToAndroidExecutable(): IFuture; + getPathToAndroidExecutable(options?: {showWarningsAsErrors: boolean}): IFuture; /** * Gets the path to `adb` executable from ANDROID_HOME. It should be `$ANDROID_HOME/platform-tools/adb` in case it exists. diff --git a/lib/services/android-project-service.ts b/lib/services/android-project-service.ts index bdca9896d3..b33193f4c3 100644 --- a/lib/services/android-project-service.ts +++ b/lib/services/android-project-service.ts @@ -79,7 +79,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject this.validateProjectName(this.$projectData.projectName); // this call will fail in case `android` is not set correctly. - this.$androidToolsInfo.getPathToAndroidExecutable().wait(); + this.$androidToolsInfo.getPathToAndroidExecutable({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/platform-service.ts b/lib/services/platform-service.ts index 5cc1698b69..a114fc2564 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -8,6 +8,7 @@ import * as helpers from "../common/helpers"; import * as semver from "semver"; import * as minimatch from "minimatch"; import Future = require("fibers/future"); +import {EOL} from "os"; export class PlatformService implements IPlatformService { private static TNS_MODULES_FOLDER_NAME = "tns_modules"; @@ -179,15 +180,20 @@ export class PlatformService implements IPlatformService { .forEach(file => { let fileContents = this.$fs.readText(file).wait(); let hasErrors = false; - let domErrorHandler = (level:any, msg:string) => hasErrors = true; + let errorOutput = ""; + let domErrorHandler = (level:any, msg:string) => { + errorOutput += level + EOL + msg + EOL; + 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); + if (hasErrors) { + this.$logger.warn(`${file} has syntax errors.`); + this.$logger.out(errorOutput); } }); return !xmlHasErrors; @@ -231,10 +237,7 @@ export class PlatformService implements IPlatformService { } // verify .xml files are well-formed - let validXmlFiles = this.checkXmlFiles(sourceFiles).wait(); - if (!validXmlFiles) { - return false; - } + this.checkXmlFiles(sourceFiles).wait(); // Remove .ts and .js.map files PlatformService.EXCLUDE_FILES_PATTERN.forEach(pattern => sourceFiles = sourceFiles.filter(file => !minimatch(file, pattern, {nocase: true}))); diff --git a/lib/services/usb-livesync-service.ts b/lib/services/usb-livesync-service.ts index 299920d45a..13eb2a3ce5 100644 --- a/lib/services/usb-livesync-service.ts +++ b/lib/services/usb-livesync-service.ts @@ -9,6 +9,7 @@ import * as semver from "semver"; import * as net from "net"; import Future = require("fibers/future"); import * as helpers from "../common/helpers"; +import * as moment from "moment"; export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncServiceBase implements IUsbLiveSyncService { @@ -149,7 +150,7 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer }); } - this.$logger.info(`Successfully synced application ${this.$projectData.projectId}.`); + this.$logger.info(`Successfully synced application ${this.$projectData.projectId} at ${moment().format("ll LTS")}.`); }).future()(); }); }; diff --git a/test/platform-service.ts b/test/platform-service.ts index edac69f78e..9e941685a0 100644 --- a/test/platform-service.ts +++ b/test/platform-service.ts @@ -331,10 +331,17 @@ describe('Platform Service Tests', () => { projectData.projectDir = tempFolder; platformService = testInjector.resolve("platformService"); - let result = platformService.preparePlatform("android").wait(); + let oldLoggerWarner = testInjector.resolve("$logger").warn; + let warnings: string = ""; + try { + testInjector.resolve("$logger").warn = (text: string) => warnings += text; + platformService.preparePlatform("android").wait(); + } finally { + testInjector.resolve("$logger").warn = oldLoggerWarner; + } // Asserts that prepare has caught invalid xml - assert.isFalse(result); + assert.isFalse(warnings.indexOf("has errors") !== -1); }); }); }); diff --git a/test/test-bootstrap.ts b/test/test-bootstrap.ts index ee807cabce..b90c40cdf7 100644 --- a/test/test-bootstrap.ts +++ b/test/test-bootstrap.ts @@ -1,3 +1,5 @@ +import * as shelljs from "shelljs"; +shelljs.config.silent = true; global._ = require("lodash"); global.$injector = require("../lib/common/yok").injector;