From 8472d767ce75fd7a0a3fea96599338900007e26d Mon Sep 17 00:00:00 2001 From: Todor Totev Date: Wed, 26 Aug 2015 11:33:27 +0300 Subject: [PATCH] More tslint changes --- lib/bootstrap.ts | 2 +- lib/commands/add-library.ts | 14 +- lib/commands/init.ts | 4 +- lib/commands/install.ts | 14 +- lib/commands/list-platforms.ts | 3 +- lib/commands/livesync.ts | 10 +- lib/commands/plugin/add-plugin.ts | 12 +- lib/commands/plugin/remove-plugin.ts | 10 +- lib/commands/run.ts | 2 +- lib/common | 2 +- lib/config.ts | 8 +- lib/declarations.ts | 2 +- lib/lockfile.ts | 4 +- lib/node-package-manager.ts | 20 +- lib/npm-installation-manager.ts | 30 +-- lib/options.ts | 8 +- lib/project-data.ts | 2 +- lib/providers/device-app-data-provider.ts | 22 +- lib/services/android-debug-service.ts | 40 ++-- .../android-project-properties-manager.ts | 30 ++- lib/services/android-project-service.ts | 62 ++--- lib/services/doctor-service.ts | 52 ++--- lib/services/init-service.ts | 48 ++-- lib/services/ios-debug-service.ts | 64 +++--- lib/services/ios-project-service.ts | 86 +++---- lib/services/platform-project-service-base.ts | 6 +- lib/services/platform-service.ts | 32 +-- lib/services/plugins-service.ts | 118 +++++----- lib/services/project-data-service.ts | 2 +- lib/services/project-files-manager.ts | 14 +- lib/services/project-service.ts | 8 +- lib/services/usb-livesync-service.ts | 89 ++++---- lib/tools/broccoli/broccoli-plugin-wrapper.ts | 16 +- lib/tools/broccoli/builder.ts | 38 ++-- lib/tools/broccoli/node-modules-dest-copy.ts | 48 ++-- lib/tools/broccoli/tree-differ.ts | 5 +- lib/tools/broccoli/trees/node-modules-tree.ts | 7 +- test/android-project-properties-manager.ts | 89 ++++---- test/ios-project-service.ts | 68 +++--- test/npm-support.ts | 69 +++--- test/platform-commands.ts | 6 +- test/platform-service.ts | 54 ++--- test/plugins-service.ts | 214 +++++++++--------- test/project-files-manager.ts | 22 +- test/project-service.ts | 60 ++--- test/stubs.ts | 4 +- tslint.json | 11 +- 47 files changed, 770 insertions(+), 761 deletions(-) diff --git a/lib/bootstrap.ts b/lib/bootstrap.ts index 78e3976244..57cbfd6d6d 100644 --- a/lib/bootstrap.ts +++ b/lib/bootstrap.ts @@ -33,7 +33,7 @@ $injector.requireCommand("platform|add", "./commands/add-platform"); $injector.requireCommand("platform|remove", "./commands/remove-platform"); $injector.requireCommand("platform|update", "./commands/update-platform"); $injector.requireCommand("library|add", "./commands/add-library"); -$injector.requireCommand("run|ios", "./commands/run"); +$injector.requireCommand("run|ios", "./commands/run"); $injector.requireCommand("run|android", "./commands/run"); $injector.requireCommand("debug|ios", "./commands/debug"); diff --git a/lib/commands/add-library.ts b/lib/commands/add-library.ts index f012d7577c..002e16e0a6 100644 --- a/lib/commands/add-library.ts +++ b/lib/commands/add-library.ts @@ -25,23 +25,25 @@ export class AddLibraryCommand implements ICommand { if (args.length !== 2) { this.$errors.fail("This command needs two parameters."); } - - let platform = args[0]; - let platformLowerCase = platform.toLowerCase(); + + let platform = args[0]; + let platformLowerCase = platform.toLowerCase(); let libraryPath = path.resolve(args[1]); if(platformLowerCase === "android") { if(!this.$fs.exists(path.join(libraryPath, "project.properties")).wait()) { let files = this.$fs.enumerateFilesInDirectorySync(libraryPath); if(!_.any(files, file => path.extname(file) === ".jar")) { - this.$errors.failWithoutHelp("Invalid library path. Ensure that the library path is the file path to a directory containing one or more `*.jar` files or to a directory containing the `project.properties` files."); + this.$errors.failWithoutHelp("Invalid library path. Ensure that the library path is the file path to a directory " + + "containing one or more `*.jar` files or to a directory containing the `project.properties` files."); } } } else if(platformLowerCase === "ios") { if(path.extname(libraryPath) !== ".framework") { - this.$errors.failWithoutHelp("Invalid library path. Ensure that the library path is a Cocoa Touch Framework with all build architectures enabled."); + this.$errors.failWithoutHelp("Invalid library path. Ensure that the library path is a Cocoa Touch Framework with " + + "all build architectures enabled."); } } - + this.$platformService.validatePlatformInstalled(args[0]); return true; }).future()(); diff --git a/lib/commands/init.ts b/lib/commands/init.ts index 0fae9f1502..b0bca9780a 100644 --- a/lib/commands/init.ts +++ b/lib/commands/init.ts @@ -3,10 +3,10 @@ export class InitCommand implements ICommand { constructor(private $initService: IInitService) { } - + public allowedParameters: ICommandParameter[] = []; public enableHooks = false; - + public execute(args: string[]): IFuture { return this.$initService.initialize(); } diff --git a/lib/commands/install.ts b/lib/commands/install.ts index 2722c11533..48108c7876 100644 --- a/lib/commands/install.ts +++ b/lib/commands/install.ts @@ -8,17 +8,17 @@ export class InstallCommand implements ICommand { private $projectDataService: IProjectDataService, private $pluginsService: IPluginsService, private $logger: ILogger) { } - + public enableHooks = false; - + public allowedParameters: ICommandParameter[] = []; - + public execute(args: string[]): IFuture { return (() => { let error: string = ""; - + this.$pluginsService.ensureAllDependenciesAreInstalled().wait(); - + this.$projectDataService.initialize(this.$projectData.projectDir); _.each(this.$platformsData.platformsNames, platform => { let platformData = this.$platformsData.getPlatformData(platform); @@ -31,11 +31,11 @@ export class InstallCommand implements ICommand { } } }); - + if(error) { this.$logger.error(error); } - + }).future()(); } } diff --git a/lib/commands/list-platforms.ts b/lib/commands/list-platforms.ts index c1de5b5784..196dc87526 100644 --- a/lib/commands/list-platforms.ts +++ b/lib/commands/list-platforms.ts @@ -20,7 +20,8 @@ export class ListPlatformsCommand implements ICommand { } this.$logger.out("Installed platforms: ", helpers.formatListOfNames(installedPlatforms, "and")); } else { - this.$logger.out("Available platforms for this OS: ", helpers.formatListOfNames(this.$platformService.getAvailablePlatforms().wait(), "and")); + let formattedPlatformsList = helpers.formatListOfNames(this.$platformService.getAvailablePlatforms().wait(), "and"); + this.$logger.out("Available platforms for this OS: ", formattedPlatformsList); this.$logger.out("No installed platforms found. Use $ tns platform add"); } }).future()(); diff --git a/lib/commands/livesync.ts b/lib/commands/livesync.ts index f1d81c01de..3e0fb4f98f 100644 --- a/lib/commands/livesync.ts +++ b/lib/commands/livesync.ts @@ -9,25 +9,25 @@ export class LivesyncCommand implements ICommand { private $errors: IErrors) { } public execute(args: string[]): IFuture { - this.$options.justlaunch = true; + this.$options.justlaunch = true; return this.$usbLiveSyncService.liveSync(args[0]); } - + public canExecute(args: string[]): IFuture { return (() => { if(args.length >= 2) { this.$errors.fail("Invalid number of arguments."); } - + let platform = args[0]; if(platform) { return _.contains(this.$mobileHelper.platformNames, this.$mobileHelper.normalizePlatformName(platform)); } - + return true; }).future()(); } - + allowedParameters: ICommandParameter[] = []; } $injector.registerCommand("livesync", LivesyncCommand); diff --git a/lib/commands/plugin/add-plugin.ts b/lib/commands/plugin/add-plugin.ts index 8c2ad5a894..c9a0aa246e 100644 --- a/lib/commands/plugin/add-plugin.ts +++ b/lib/commands/plugin/add-plugin.ts @@ -4,27 +4,27 @@ export class AddPluginCommand implements ICommand { constructor(private $pluginsService: IPluginsService, private $errors: IErrors) { } - + execute(args: string[]): IFuture { return this.$pluginsService.add(args[0]); } - + canExecute(args: string[]): IFuture { return (() => { if(!args[0]) { this.$errors.fail("You must specify plugin name."); } - + let installedPlugins = this.$pluginsService.getAllInstalledPlugins().wait(); let pluginName = args[0].toLowerCase(); if(_.any(installedPlugins, (plugin: IPluginData) => plugin.name.toLowerCase() === pluginName)) { this.$errors.failWithoutHelp(`Plugin "${pluginName}" is already installed.`); } - - return true; + + return true; }).future()(); } - + public allowedParameters: ICommandParameter[] = []; } $injector.registerCommand("plugin|add", AddPluginCommand); diff --git a/lib/commands/plugin/remove-plugin.ts b/lib/commands/plugin/remove-plugin.ts index b5782cd698..ca3631b572 100644 --- a/lib/commands/plugin/remove-plugin.ts +++ b/lib/commands/plugin/remove-plugin.ts @@ -4,27 +4,27 @@ export class RemovePluginCommand implements ICommand { constructor(private $pluginsService: IPluginsService, private $errors: IErrors) { } - + execute(args: string[]): IFuture { return this.$pluginsService.remove(args[0]); } - + canExecute(args: string[]): IFuture { return (() => { if(!args[0]) { this.$errors.fail("You must specify plugin name."); } - + let installedPlugins = this.$pluginsService.getAllInstalledPlugins().wait(); let pluginName = args[0].toLowerCase(); if(!_.any(installedPlugins, (plugin: IPluginData) => plugin.name.toLowerCase() === pluginName)) { this.$errors.failWithoutHelp(`Plugin "${pluginName}" is not installed.`); } - + return true; }).future()(); } - + public allowedParameters: ICommandParameter[] = []; } $injector.registerCommand("plugin|remove", RemovePluginCommand); diff --git a/lib/commands/run.ts b/lib/commands/run.ts index 7bbbb1e596..6b81087957 100644 --- a/lib/commands/run.ts +++ b/lib/commands/run.ts @@ -28,7 +28,7 @@ export class RunAndroidCommand extends RunCommandBase implements ICommand { private $platformsData: IPlatformsData) { super($platformService); } - + public allowedParameters: ICommandParameter[] = []; public execute(args: string[]): IFuture { diff --git a/lib/common b/lib/common index 35f03103af..f62630430e 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 35f03103af87f6a31793aeb183a6ea2d93dfc8d9 +Subproject commit f62630430e91e21fb86793aadf72cdd5c8a2682e diff --git a/lib/config.ts b/lib/config.ts index 096640e685..65a729673e 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -30,11 +30,11 @@ export class StaticConfig extends staticConfigBaseLibPath.StaticConfigBase imple public ERROR_REPORT_SETTING_NAME = "TrackExceptions"; public ANALYTICS_INSTALLATION_ID_SETTING_NAME = "AnalyticsInstallationID"; public START_PACKAGE_ACTIVITY_NAME = "com.tns.NativeScriptActivity"; - + constructor($injector: IInjector) { - super($injector); + super($injector); } - + public get SYS_REQUIREMENTS_LINK(): string { let linkToSysRequirements: string; switch(process.platform) { @@ -63,7 +63,7 @@ export class StaticConfig extends staticConfigBaseLibPath.StaticConfigBase imple public get HTML_CLI_HELPERS_DIR(): string { return path.join(__dirname, "../docs/helpers"); } - + public get pathToPackageJson(): string { return path.join(__dirname, "..", "package.json"); } diff --git a/lib/declarations.ts b/lib/declarations.ts index 2e41e6a447..b5ba12ac0e 100644 --- a/lib/declarations.ts +++ b/lib/declarations.ts @@ -27,7 +27,7 @@ interface INpmInstallOptions { interface IDependencyData { name: string; version: string; - nativescript: any; + nativescript: any; dependencies?: IStringDictionary; devDependencies?: IStringDictionary; } diff --git a/lib/lockfile.ts b/lib/lockfile.ts index fc68de5511..25ef0462e5 100644 --- a/lib/lockfile.ts +++ b/lib/lockfile.ts @@ -7,11 +7,11 @@ import * as path from "path"; export class LockFile implements ILockFile { private lockFilePath: string; - + constructor(private $options: IOptions) { this.lockFilePath = path.join(this.$options.profileDir, ".lock"); } - + private static LOCK_EXPIRY_PERIOD_SEC = 180; private static LOCK_PARAMS = { retryWait: 100, diff --git a/lib/node-package-manager.ts b/lib/node-package-manager.ts index 3df980a015..ed8bec1cf4 100644 --- a/lib/node-package-manager.ts +++ b/lib/node-package-manager.ts @@ -2,7 +2,7 @@ "use strict"; import Future = require("fibers/future"); -import npm = require("npm"); +import * as npm from "npm"; export class NodePackageManager implements INodePackageManager { constructor(private $childProcess: IChildProcess, @@ -15,7 +15,7 @@ export class NodePackageManager implements INodePackageManager { public getCache(): string { return npm.cache; } - + public load(config?: any): IFuture { let future = new Future(); npm.load(config, (err) => { @@ -27,7 +27,7 @@ export class NodePackageManager implements INodePackageManager { }); return future; } - + public install(packageName: string, pathToSave: string, config?: any): IFuture { if(this.$options.ignoreScripts) { config = config || {}; @@ -36,7 +36,7 @@ export class NodePackageManager implements INodePackageManager { return this.loadAndExecute("install", [pathToSave, packageName], { config: config }); } - + public uninstall(packageName: string, config?: any): IFuture { return this.loadAndExecute("uninstall", [[packageName]], { config: config }); } @@ -45,12 +45,12 @@ export class NodePackageManager implements INodePackageManager { // function cache (pkg, ver, where, scrub, cb) return this.loadAndExecute("cache", [packageName, version, undefined, false], { subCommandName: "add", config: config }); } - + public cacheUnpack(packageName: string, version: string, unpackTarget?: string): IFuture { // function unpack (pkg, ver, unpackTarget, dMode, fMode, uid, gid, cb) return this.loadAndExecute("cache", [packageName, version, unpackTarget, null, null, null, null], { subCommandName: "unpack" }); } - + public view(packageName: string, propertyName: string): IFuture { return this.loadAndExecute("view", [[packageName, propertyName], [false]]); } @@ -58,7 +58,7 @@ export class NodePackageManager implements INodePackageManager { public executeNpmCommand(npmCommandName: string, currentWorkingDirectory: string): IFuture { return this.$childProcess.exec(npmCommandName, { cwd: currentWorkingDirectory }); } - + private loadAndExecute(commandName: string, args: any[], opts?: { config?: any, subCommandName?: string }): IFuture { return (() => { opts = opts || {}; @@ -66,7 +66,7 @@ export class NodePackageManager implements INodePackageManager { return this.executeCore(commandName, args, opts.subCommandName).wait(); }).future()(); } - + private executeCore(commandName: string, args: any[], subCommandName?: string): IFuture { let future = new Future(); let callback = (err: Error, data: any) => { @@ -77,10 +77,10 @@ export class NodePackageManager implements INodePackageManager { } }; args.push(callback); - + let command = subCommandName ? npm.commands[commandName][subCommandName] : npm.commands[commandName]; command.apply(this, args); - + return future; } } diff --git a/lib/npm-installation-manager.ts b/lib/npm-installation-manager.ts index c83ec9bb71..e050a62091 100644 --- a/lib/npm-installation-manager.ts +++ b/lib/npm-installation-manager.ts @@ -7,23 +7,23 @@ import * as npm from "npm"; import * as constants from "./constants"; export class NpmInstallationManager implements INpmInstallationManager { - private static NPM_LOAD_FAILED = "Failed to retrieve data from npm. Please try again a little bit later."; - private versionsCache: IDictionary; - + private static NPM_LOAD_FAILED = "Failed to retrieve data from npm. Please try again a little bit later."; + private versionsCache: IDictionary; + constructor(private $npm: INodePackageManager, private $logger: ILogger, private $lockfile: ILockFile, private $errors: IErrors, private $options: IOptions, private $fs: IFileSystem) { - this.versionsCache = {}; - this.$npm.load().wait(); + this.versionsCache = {}; + this.$npm.load().wait(); } - + public getCacheRootPath(): string { return this.$npm.getCache(); } - + public getCachedPackagePath(packageName: string, version: string): string { return path.join(this.getCacheRootPath(), packageName, version, "package"); } @@ -47,17 +47,17 @@ export class NpmInstallationManager implements INpmInstallationManager { unpackTarget = unpackTarget || path.join(npm.cache, packageName, version, "package"); return this.$npm.cacheUnpack(packageName, version, unpackTarget); } - + public getLatestVersion(packageName: string): IFuture { return (() => { - let data = this.$npm.view(packageName, "dist-tags").wait(); + let data = this.$npm.view(packageName, "dist-tags").wait(); let latestVersion = _.first(_.keys(data)); this.$logger.trace("Using version %s. ", latestVersion); - + return latestVersion; }).future()(); } - + public install(packageName: string, opts?: INpmInstallOptions): IFuture { return (() => { this.$lockfile.lock().wait(); @@ -139,7 +139,7 @@ export class NpmInstallationManager implements INpmInstallationManager { } }).future()(); } - + private npmInstall(packageName: string, pathToSave: string, version: string): IFuture { this.$logger.out("Installing ", packageName); @@ -150,7 +150,7 @@ export class NpmInstallationManager implements INpmInstallationManager { return this.$npm.install(packageName, pathToSave); } - + private isPackageCached(packagePath: string): IFuture { return this.$fs.exists(packagePath); } @@ -158,9 +158,9 @@ export class NpmInstallationManager implements INpmInstallationManager { private isPackageUnpacked(packagePath: string): IFuture { return (() => { return this.$fs.getFsStats(packagePath).wait().isDirectory() && - this.$fs.exists(path.join(packagePath, "framework")).wait() && + this.$fs.exists(path.join(packagePath, "framework")).wait() && this.$fs.enumerateFilesInDirectorySync(path.join(packagePath, "framework")).length > 1; }).future()(); - } + } } $injector.register("npmInstallationManager", NpmInstallationManager); diff --git a/lib/options.ts b/lib/options.ts index 987eb2ea26..1e56d7d130 100644 --- a/lib/options.ts +++ b/lib/options.ts @@ -1,9 +1,9 @@ /// "use strict"; -import commonOptionsLibPath = require("./common/options"); -import osenv = require("osenv"); -import path = require("path"); +import * as commonOptionsLibPath from "./common/options"; +import * as osenv from "osenv"; +import * as path from "path"; let OptionType = commonOptionsLibPath.OptionType; @@ -28,7 +28,7 @@ export class Options extends commonOptionsLibPath.OptionsBase { keyStoreAliasPassword: { type: OptionType.String }, sdk: { type: OptionType.String }, ignoreScripts: {type: OptionType.Boolean }, - tnsModulesVersion: { type: OptionType.String } + tnsModulesVersion: { type: OptionType.String } }, path.join($hostInfo.isWindows ? process.env.LocalAppData : path.join(osenv.home(), ".local/share"), ".nativescript-cli"), $errors, $staticConfig); diff --git a/lib/project-data.ts b/lib/project-data.ts index 9cafb6f06a..d9895201d4 100644 --- a/lib/project-data.ts +++ b/lib/project-data.ts @@ -47,7 +47,7 @@ export class ProjectData implements IProjectData { } else { // This is the case when we have package.json file but nativescipt key is not presented in it this.tryToUpgradeProject().wait(); } - } + } } else { // This is the case when no project file found this.tryToUpgradeProject().wait(); } diff --git a/lib/providers/device-app-data-provider.ts b/lib/providers/device-app-data-provider.ts index ee6d5dbee1..c9c3af3978 100644 --- a/lib/providers/device-app-data-provider.ts +++ b/lib/providers/device-app-data-provider.ts @@ -5,15 +5,15 @@ import Future = require("fibers/future"); export class IOSAppIdentifier extends deviceAppDataBaseLib.DeviceAppDataBase implements Mobile.IDeviceAppData { private static DEVICE_PROJECT_ROOT_PATH = "Library/Application Support/LiveSync"; - + constructor(_appIdentifier: string) { - super(_appIdentifier); + super(_appIdentifier); } - + public get deviceProjectRootPath(): string { return this.getDeviceProjectRootPath(IOSAppIdentifier.DEVICE_PROJECT_ROOT_PATH); } - + public isLiveSyncSupported(device: Mobile.IDevice): IFuture { return Future.fromResult(true); } @@ -21,15 +21,15 @@ export class IOSAppIdentifier extends deviceAppDataBaseLib.DeviceAppDataBase imp export class AndroidAppIdentifier extends deviceAppDataBaseLib.DeviceAppDataBase implements Mobile.IDeviceAppData { constructor(_appIdentifier: string) { - super(_appIdentifier); + super(_appIdentifier); } - + public get deviceProjectRootPath(): string { let options: IOptions = $injector.resolve("options"); let syncFolderName = options.watch ? "sync" : "fullsync"; - return `/data/local/tmp/${this.appIdentifier}/${syncFolderName}`; + return `/data/local/tmp/${this.appIdentifier}/${syncFolderName}`; } - + public isLiveSyncSupported(device: Mobile.IDevice): IFuture { return Future.fromResult(true); } @@ -37,11 +37,11 @@ export class AndroidAppIdentifier extends deviceAppDataBaseLib.DeviceAppDataBase export class AndroidCompanionAppIdentifier extends deviceAppDataBaseLib.CompanionDeviceAppDataBase implements Mobile.IDeviceAppData { private static APP_IDENTIFIER = "com.telerik.NativeScript"; - + constructor() { - super(AndroidCompanionAppIdentifier.APP_IDENTIFIER); + super(AndroidCompanionAppIdentifier.APP_IDENTIFIER); } - + public get deviceProjectRootPath(): string { return `/mnt/sdcard/Android/data/${this.appIdentifier}/files/12590FAA-5EDD-4B12-856D-F52A0A1599F2`; } diff --git a/lib/services/android-debug-service.ts b/lib/services/android-debug-service.ts index dcf490e742..c4184ef89c 100644 --- a/lib/services/android-debug-service.ts +++ b/lib/services/android-debug-service.ts @@ -9,9 +9,9 @@ class AndroidDebugService implements IDebugService { private static ENV_DEBUG_OUT_FILENAME = "envDebug.out"; private static DEFAULT_NODE_INSPECTOR_URL = "http://127.0.0.1:8080/debug"; private static PACKAGE_EXTERNAL_DIR_TEMPLATE = "/sdcard/Android/data/%s/files/"; - + private _device: Mobile.IAndroidDevice = null; - + constructor(private $devicesServices: Mobile.IDevicesServices, private $platformService: IPlatformService, private $platformsData: IPlatformsData, @@ -28,15 +28,15 @@ class AndroidDebugService implements IDebugService { private $config: IConfiguration) { } private get platform() { return "android"; } - + private get device(): Mobile.IAndroidDevice { return this._device; } - + private set device(newDevice) { this._device = newDevice; } - + public debug(): IFuture { return this.$options.emulator ? this.debugOnEmulator() @@ -55,7 +55,7 @@ class AndroidDebugService implements IDebugService { let packageFile = ""; if(!this.$options.debugBrk && !this.$options.start && !this.$options.getPort && !this.$options.stop) { - this.$logger.warn("Neither --debug-brk nor --start option was specified. Defaulting to --debug-brk."); + this.$logger.warn("Neither --debug-brk nor --start option was specified. Defaulting to --debug-brk."); this.$options.debugBrk = true; } @@ -76,11 +76,11 @@ class AndroidDebugService implements IDebugService { }).future()(); } - + private debugCore(device: Mobile.IAndroidDevice, packageFile: string, packageName: string): IFuture { return (() => { this.device = device; - + if (this.$options.getPort) { this.printDebugPort(packageName).wait(); } else if (this.$options.start) { @@ -92,18 +92,18 @@ class AndroidDebugService implements IDebugService { } }).future()(); } - + private printDebugPort(packageName: string): IFuture { return (() => { let res = this.device.adb.executeShellCommand(["am", "broadcast", "-a", packageName + "-GetDgbPort"]).wait(); this.$logger.info(res); }).future()(); } - + private attachDebugger(packageName: string): void { let startDebuggerCommand = ["am", "broadcast", "-a", '\"${packageName}-Debug\"', "--ez", "enable", "true"]; let port = this.$options.debugPort; - + if (port > 0) { startDebuggerCommand.push("--ei", "debuggerPort", port.toString()); this.device.adb.executeShellCommand(startDebuggerCommand).wait(); @@ -135,18 +135,18 @@ class AndroidDebugService implements IDebugService { this.device.applicationManager.uninstallApplication(packageName).wait(); this.device.applicationManager.installApplication(packageFile).wait(); } - + let packageDir = util.format(AndroidDebugService.PACKAGE_EXTERNAL_DIR_TEMPLATE, packageName); let envDebugOutFullpath = this.$mobileHelper.buildDevicePath(packageDir, AndroidDebugService.ENV_DEBUG_OUT_FILENAME); - + this.device.adb.executeShellCommand(["rm", `${envDebugOutFullpath}`]).wait(); this.device.adb.executeShellCommand(["mkdir", "-p", `${packageDir}`]).wait(); - + let debugBreakPath = this.$mobileHelper.buildDevicePath(packageDir, "debugbreak"); this.device.adb.executeShellCommand([`cat /dev/null > ${debugBreakPath}`]).wait(); - + this.device.applicationManager.startApplication(packageName).wait(); - + let dbgPort = this.startAndGetPort(packageName).wait(); if (dbgPort > 0) { this.tcpForward(dbgPort, dbgPort).wait(); @@ -155,7 +155,7 @@ class AndroidDebugService implements IDebugService { } }).future()(); } - + private tcpForward(src: Number, dest: Number): IFuture { return this.device.adb.executeCommand(["forward", `tcp:${src.toString()}`, `tcp:${dest.toString()}`]); } @@ -196,8 +196,8 @@ class AndroidDebugService implements IDebugService { private startAndGetPort(packageName: string): IFuture { return (() => { let port = -1; - let timeout = this.$utils.getParsedTimeout(90); - + let timeout = this.$utils.getParsedTimeout(90); + let packageDir = util.format(AndroidDebugService.PACKAGE_EXTERNAL_DIR_TEMPLATE, packageName); let envDebugInFullpath = packageDir + AndroidDebugService.ENV_DEBUG_IN_FILENAME; this.device.adb.executeShellCommand(["rm", `${envDebugInFullpath}`]).wait(); @@ -210,7 +210,7 @@ class AndroidDebugService implements IDebugService { break; } } - + if (isRunning) { this.device.adb.executeShellCommand([`cat /dev/null > ${envDebugInFullpath}`]).wait(); diff --git a/lib/services/android-project-properties-manager.ts b/lib/services/android-project-properties-manager.ts index 7abba90921..317f106554 100644 --- a/lib/services/android-project-properties-manager.ts +++ b/lib/services/android-project-properties-manager.ts @@ -8,16 +8,14 @@ export class AndroidProjectPropertiesManager implements IAndroidProjectPropertie private filePath: string = null; private projectReferences: ILibRef[]; private dirty = false; - + constructor(private $propertiesParser: IPropertiesParser, private $fs: IFileSystem, private $logger: ILogger, directoryPath: string) { this.filePath = path.join(directoryPath, "project.properties"); } - - - + public getProjectReferences(): IFuture { return (() => { if(!this.projectReferences || this.dirty) { @@ -28,11 +26,11 @@ export class AndroidProjectPropertiesManager implements IAndroidProjectPropertie .map(key => this.createLibraryReference(key, allProjectProperties[key])) .value(); } - + return this.projectReferences; }).future()(); } - + public addProjectReference(referencePath: string): IFuture { return (() => { let references = this.getProjectReferences().wait(); @@ -42,7 +40,7 @@ export class AndroidProjectPropertiesManager implements IAndroidProjectPropertie } }).future()(); } - + public removeProjectReference(referencePath: string): IFuture { return (() => { let references = this.getProjectReferences().wait(); @@ -54,21 +52,21 @@ export class AndroidProjectPropertiesManager implements IAndroidProjectPropertie } }).future()(); } - + private createEditor(): IFuture { return (() => { return this._editor || this.$propertiesParser.createEditor(this.filePath).wait(); }).future()(); } - + private buildKeyName(key: string, index: number): string { return `${key}.${index}`; } - + private getAllProjectProperties(): IFuture { return this.$propertiesParser.read(this.filePath); } - + private createLibraryReference(referenceName: string, referencePath: string): ILibRef { return { idx: parseInt(referenceName.split("android.library.reference.")[1]), @@ -77,7 +75,7 @@ export class AndroidProjectPropertiesManager implements IAndroidProjectPropertie adjustedPath: path.join(path.dirname(this.filePath), referencePath) }; } - + private addToPropertyList(key: string, value: string): IFuture { return (() => { let editor = this.createEditor().wait(); @@ -85,13 +83,13 @@ export class AndroidProjectPropertiesManager implements IAndroidProjectPropertie while (editor.get(this.buildKeyName(key, i))) { i++; } - + editor.set(this.buildKeyName(key, i), value); this.$propertiesParser.saveEditor().wait(); this.dirty = true; }).future()(); } - + private removeFromPropertyList(key: string, value: string): IFuture { return (() => { let editor = this.createEditor().wait(); @@ -101,7 +99,7 @@ export class AndroidProjectPropertiesManager implements IAndroidProjectPropertie while (currentValue = editor.get(this.buildKeyName(key, i))) { if (currentValue.toLowerCase() === valueLowerCase) { while (currentValue = editor.get(this.buildKeyName(key, i+1))) { - editor.set(this.buildKeyName(key, i), currentValue); + editor.set(this.buildKeyName(key, i), currentValue); i++; } editor.set(this.buildKeyName(key, i)); @@ -111,6 +109,6 @@ export class AndroidProjectPropertiesManager implements IAndroidProjectPropertie } this.$propertiesParser.saveEditor().wait(); this.dirty = true; - }).future()(); + }).future()(); } } diff --git a/lib/services/android-project-service.ts b/lib/services/android-project-service.ts index c51af00ef6..a248528a09 100644 --- a/lib/services/android-project-service.ts +++ b/lib/services/android-project-service.ts @@ -79,7 +79,7 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService public createProject(projectRoot: string, frameworkDir: string): IFuture { return (() => { this.$fs.ensureDirectoryExists(projectRoot).wait(); - + let newTarget = this.getAndroidTarget(frameworkDir).wait(); this.$logger.trace(`Using Android SDK '${newTarget}'.`); let versionNumber = _.last(newTarget.split("-")); @@ -117,9 +117,9 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService let directoriesToCopy = [AndroidProjectService.VALUES_DIRNAME]; let directoriesInResFolder = this.$fs.readDirectory(resSourceDir).wait(); let integerFrameworkVersion = parseInt(versionNumber); - let versionDir = _.find(directoriesInResFolder, dir => dir === versionDirName) || + let versionDir = _.find(directoriesInResFolder, dir => dir === versionDirName) || _(directoriesInResFolder) - .map(dir => { + .map(dir => { return { dirName: dir, sdkNum: parseInt(dir.substr(AndroidProjectService.VALUES_VERSION_DIRNAME_PREFIX.length)) @@ -194,10 +194,10 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService if(!this._androidProjectPropertiesManagers[filePath]) { this._androidProjectPropertiesManagers[filePath] = this.$injector.resolve(androidProjectPropertiesManagerLib.AndroidProjectPropertiesManager, { directoryPath: filePath }); } - + return this._androidProjectPropertiesManagers[filePath]; } - + private parseProjectProperties(projDir: string, destDir: string): IFuture { // projDir is libraryPath, targetPath is the path to lib folder return (() => { projDir = projDir.trim(); @@ -206,17 +206,17 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService this.$logger.warn("Warning: File %s does not exist", projProp); return; } - + let projectPropertiesManager = this.getProjectPropertiesManager(projDir); let references = projectPropertiesManager.getProjectReferences().wait(); _.each(references, reference => { let adjustedPath = this.$fs.isRelativePath(reference.path) ? path.join(projDir, reference.path) : reference.path; this.parseProjectProperties(adjustedPath, destDir).wait(); }); - + this.$logger.info("Copying %s", projDir); shell.cp("-Rf", projDir, destDir); - + let targetDir = path.join(destDir, path.basename(projDir)); let targetSdk = `android-${this.$options.sdk || AndroidProjectService.MIN_SUPPORTED_VERSION}`; this.$logger.info("Generate build.xml for %s", targetDir); @@ -228,7 +228,7 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService return (() => { let name = path.basename(libraryPath); let targetLibPath = this.getLibraryPath(name); - + let targetPath = path.dirname(targetLibPath); this.$fs.ensureDirectoryExists(targetPath).wait(); @@ -248,11 +248,11 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService } }).future()(); } - + public getFrameworkFilesExtensions(): string[] { return [".jar", ".dat"]; } - + public prepareProject(): IFuture { return Future.fromResult(); } @@ -264,60 +264,60 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService let resourcesDirs = this.$fs.readDirectory(resourcesDirPath).wait().filter(resDir => !resDir.match(valuesDirRegExp)); _.each(resourcesDirs, resourceDir => { this.$fs.deleteDirectory(path.join(this.platformData.appResourcesDestinationDirectoryPath, resourceDir)).wait(); - }); + }); }).future()(); } public preparePluginNativeCode(pluginData: IPluginData): IFuture { return (() => { let pluginPlatformsFolderPath = this.getPluginPlatformsFolderPath(pluginData, AndroidProjectService.ANDROID_PLATFORM_NAME); - + // Handle *.jars inside libs folder let libsFolderPath = path.join(pluginPlatformsFolderPath, AndroidProjectService.LIBS_FOLDER_NAME); if(this.$fs.exists(libsFolderPath).wait()) { this.addLibrary(libsFolderPath).wait(); } - + // Handle android libraries let librarries = this.getAllLibrariesForPlugin(pluginData).wait(); _.each(librarries, libraryName => this.addLibrary(path.join(pluginPlatformsFolderPath, libraryName)).wait()); }).future()(); } - + public removePluginNativeCode(pluginData: IPluginData): IFuture { return (() => { - let projectPropertiesManager = this.getProjectPropertiesManager(this.platformData.projectRoot); - - let libraries = this.getAllLibrariesForPlugin(pluginData).wait(); + let projectPropertiesManager = this.getProjectPropertiesManager(this.platformData.projectRoot); + + let libraries = this.getAllLibrariesForPlugin(pluginData).wait(); _.each(libraries, libraryName => { let libraryPath = this.getLibraryPath(libraryName); let libraryRelativePath = this.getLibraryRelativePath(this.platformData.projectRoot, libraryPath); projectPropertiesManager.removeProjectReference(libraryRelativePath).wait(); this.$fs.deleteDirectory(libraryPath).wait(); }); - + }).future()(); } - + public afterPrepareAllPlugins(): IFuture { return Future.fromResult(); } - + private getLibraryRelativePath(basePath: string, libraryPath: string): string { - return path.relative(basePath, libraryPath).split("\\").join("/"); + return path.relative(basePath, libraryPath).split("\\").join("/"); } - + private getLibraryPath(libraryName: string): string { return path.join(this.$projectData.projectDir, "lib", this.platformData.normalizedPlatformName, libraryName); } - + private updateProjectReferences(projDir: string, libraryPath: string): IFuture { let relLibDir = this.getLibraryRelativePath(projDir, libraryPath); - - let projectPropertiesManager = this.getProjectPropertiesManager(projDir); + + let projectPropertiesManager = this.getProjectPropertiesManager(projDir); return projectPropertiesManager.addProjectReference(relLibDir); } - + private getAllLibrariesForPlugin(pluginData: IPluginData): IFuture { return (() => { let filterCallback = (fileName: string, pluginPlatformsFolderPath: string) => fileName !== AndroidProjectService.LIBS_FOLDER_NAME && this.$fs.exists(path.join(pluginPlatformsFolderPath, fileName, "project.properties")).wait(); @@ -402,7 +402,7 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService } private getAndroidTarget(frameworkDir: string): IFuture { - return ((): string => { + return ((): string => { let newTarget = this.$options.sdk ? `${AndroidProjectService.ANDROID_TARGET_PREFIX}-${this.$options.sdk}` : this.getLatestValidAndroidTarget(frameworkDir).wait(); if(!_.contains(this.SUPPORTED_TARGETS, newTarget)) { let versionNumber = parseInt(_.last(newTarget.split("-"))); @@ -428,8 +428,8 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService // adjust to the latest available version let newTarget = _(this.SUPPORTED_TARGETS).sort().findLast(supportedTarget => _.contains(installedTargets, supportedTarget)); if (!newTarget) { - this.$errors.failWithoutHelp(`Could not find supported Android target. Please install one of the following: ${this.SUPPORTED_TARGETS.join(", ")}.` + - " Make sure you have the latest Android tools installed as well." + + this.$errors.failWithoutHelp(`Could not find supported Android target. Please install one of the following: ${this.SUPPORTED_TARGETS.join(", ")}.` + + " Make sure you have the latest Android tools installed as well." + ' Run "android" from your command-line to install/update any missing SDKs or tools.'); } @@ -481,7 +481,7 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService return this.targetApi; }).future()(); } - + private checkJava(): IFuture { return (() => { try { diff --git a/lib/services/doctor-service.ts b/lib/services/doctor-service.ts index 51e7f585e1..87f70ce474 100644 --- a/lib/services/doctor-service.ts +++ b/lib/services/doctor-service.ts @@ -1,42 +1,42 @@ /// "use strict"; -import os = require("os"); +import {EOL} from "os"; class DoctorService implements IDoctorService { - + constructor( private $hostInfo: IHostInfo, private $sysInfo: ISysInfo, private $logger: ILogger) { } - + public printWarnings(): boolean { let result = false; let sysInfo = this.$sysInfo.getSysInfo(); - + if (!sysInfo.adbVer) { this.$logger.warn("WARNING: adb from the Android SDK is not installed or is not configured properly."); - this.$logger.out("For Android-related operations, the NativeScript CLI will use a built-in version of adb." + os.EOL - + "To avoid possible issues with the native Android emulator, Genymotion or connected" + os.EOL - + "Android devices, verify that you have installed the latest Android SDK and" + os.EOL - + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + os.EOL); + this.$logger.out("For Android-related operations, the NativeScript CLI will use a built-in version of adb." + EOL + + "To avoid possible issues with the native Android emulator, Genymotion or connected" + EOL + + "Android devices, verify that you have installed the latest Android SDK and" + EOL + + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL); this.printPackageManagerTip(); result = true; } if (!sysInfo.antVer) { this.$logger.warn("WARNING: Apache Ant is not installed or is not configured properly."); - this.$logger.out("You will not be able to build your projects for Android." + os.EOL - + "To be able to build for Android, download and install Apache Ant and" + os.EOL - + "its dependencies as described in http://ant.apache.org/manual/index.html" + os.EOL); + this.$logger.out("You will not be able to build your projects for Android." + EOL + + "To be able to build for Android, download and install Apache Ant and" + EOL + + "its dependencies as described in http://ant.apache.org/manual/index.html" + EOL); this.printPackageManagerTip(); result = true; } if (!sysInfo.androidInstalled) { this.$logger.warn("WARNING: The Android SDK is not installed or is not configured properly."); - this.$logger.out("You will not be able to build your projects for Android and run them in the native emulator." + os.EOL - + "To be able to build for Android and run apps in the native emulator, verify that you have" + os.EOL - + "installed the latest Android SDK and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + os.EOL + this.$logger.out("You will not be able to build your projects for Android and run them in the native emulator." + EOL + + "To be able to build for Android and run apps in the native emulator, verify that you have" + EOL + + "installed the latest Android SDK and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL ); this.printPackageManagerTip(); @@ -44,33 +44,33 @@ class DoctorService implements IDoctorService { } if (this.$hostInfo.isDarwin && !sysInfo.xcodeVer) { this.$logger.warn("WARNING: Xcode is not installed or is not configured properly."); - this.$logger.out("You will not be able to build your projects for iOS or run them in the iOS Simulator." + os.EOL - + "To be able to build for iOS and run apps in the native emulator, verify that you have installed Xcode." + os.EOL); + this.$logger.out("You will not be able to build your projects for iOS or run them in the iOS Simulator." + EOL + + "To be able to build for iOS and run apps in the native emulator, verify that you have installed Xcode." + EOL); result = true; } if (!this.$hostInfo.isDarwin) { this.$logger.warn("WARNING: You can work with iOS only on Mac OS X systems."); - this.$logger.out("To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later." + os.EOL); + this.$logger.out("To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later." + EOL); result = true; } if(!sysInfo.javaVer) { this.$logger.warn("WARNING: The Java Development Kit (JDK) is not installed or is not configured properly."); - this.$logger.out("You will not be able to work with the Android SDK and you might not be able" + os.EOL - + "to perform some Android-related operations. To ensure that you can develop and" + os.EOL - + "test your apps for Android, verify that you have installed the JDK as" + os.EOL - + "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8)" + os.EOL - + "or http://docs.oracle.com/javase/7/docs/webnotes/install/ (for JDK 7)." + os.EOL); + this.$logger.out("You will not be able to work with the Android SDK and you might not be able" + EOL + + "to perform some Android-related operations. To ensure that you can develop and" + EOL + + "test your apps for Android, verify that you have installed the JDK as" + EOL + + "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8)" + EOL + + "or http://docs.oracle.com/javase/7/docs/webnotes/install/ (for JDK 7)." + EOL); result = true; } - + return result; } - + private printPackageManagerTip() { if (this.$hostInfo.isWindows) { - this.$logger.out("TIP: To avoid setting up the necessary environment variables, you can use the chocolatey package manager to install the Android SDK and its dependencies." + os.EOL); + this.$logger.out("TIP: To avoid setting up the necessary environment variables, you can use the chocolatey package manager to install the Android SDK and its dependencies." + EOL); } else if (this.$hostInfo.isDarwin) { - 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." + os.EOL); + 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); } } } diff --git a/lib/services/init-service.ts b/lib/services/init-service.ts index f852ff6fb1..865c6d3dbe 100644 --- a/lib/services/init-service.ts +++ b/lib/services/init-service.ts @@ -9,11 +9,11 @@ import semver = require("semver"); export class InitService implements IInitService { private static MIN_SUPPORTED_FRAMEWORK_VERSIONS: IStringDictionary = { "tns-ios": "1.1.0", - "tns-android": "1.1.0" + "tns-android": "1.1.0" }; - + private _projectFilePath: string; - + constructor(private $fs: IFileSystem, private $errors: IErrors, private $logger: ILogger, @@ -24,26 +24,26 @@ export class InitService implements IInitService { private $prompter: IPrompter, private $npm: INodePackageManager, private $npmInstallationManager: INpmInstallationManager) { } - + public initialize(): IFuture { return (() => { let projectData: any = { }; - + if(this.$fs.exists(this.projectFilePath).wait()) { projectData = this.$fs.readJson(this.projectFilePath).wait(); } - - let projectDataBackup = _.extend({}, projectData); - + + let projectDataBackup = _.extend({}, projectData); + if(!projectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE]) { projectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE] = { }; - this.$fs.writeJson(this.projectFilePath, projectData).wait(); // We need to create package.json file here in order to prevent "No project found at or above and neither was a --path specified." when resolving platformsData + this.$fs.writeJson(this.projectFilePath, projectData).wait(); // We need to create package.json file here in order to prevent "No project found at or above and neither was a --path specified." when resolving platformsData } - + try { - + projectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE]["id"] = this.getProjectId().wait(); - + if(this.$options.frameworkName && this.$options.frameworkVersion) { projectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE][this.$options.frameworkName] = this.buildVersionData(this.$options.frameworkVersion); } else { @@ -55,48 +55,48 @@ export class InitService implements IInitService { } }); } - + this.$fs.writeJson(this.projectFilePath, projectData).wait(); } catch(err) { this.$fs.writeJson(this.projectFilePath, projectDataBackup).wait(); throw err; } - - this.$logger.out("Project successfully initialized."); + + this.$logger.out("Project successfully initialized."); }).future()(); } - + private get projectFilePath(): string { if(!this._projectFilePath) { let projectDir = path.resolve(this.$options.path || "."); this._projectFilePath = path.join(projectDir, constants.PACKAGE_JSON_FILE_NAME); } - + return this._projectFilePath; } - + private getProjectId(): IFuture { return (() => { if(this.$options.appid) { return this.$options.appid; } - + let defaultAppId = this.$projectHelper.generateDefaultAppId(path.basename(path.dirname(this.projectFilePath)), constants.DEFAULT_APP_IDENTIFIER_PREFIX); if(this.useDefaultValue) { return defaultAppId; } - + return this.$prompter.getString("Id:", () => defaultAppId).wait(); }).future()(); } - + private getVersionData(packageName: string): IFuture { return (() => { let latestVersion = this.$npmInstallationManager.getLatestVersion(packageName).wait(); if(this.useDefaultValue) { return this.buildVersionData(latestVersion); } - + let data = this.$npm.view(packageName, "versions").wait(); let versions = _.filter(data[latestVersion].versions, (version: string) => semver.gte(version, InitService.MIN_SUPPORTED_FRAMEWORK_VERSIONS[packageName])); if(versions.length === 1) { @@ -108,11 +108,11 @@ export class InitService implements IInitService { return this.buildVersionData(version); }).future()(); } - + private buildVersionData(version: string): IStringDictionary { return { "version": version }; } - + private get useDefaultValue(): boolean { return !helpers.isInteractive() || this.$options.force; } diff --git a/lib/services/ios-debug-service.ts b/lib/services/ios-debug-service.ts index 90de780397..2692206772 100644 --- a/lib/services/ios-debug-service.ts +++ b/lib/services/ios-debug-service.ts @@ -14,7 +14,7 @@ module notification { function formatNotification(bundleId: string, notification: string) { return `${bundleId}:NativeScript.Debug.${notification}`; } - + export function waitForDebug(bundleId: string): string { return formatNotification(bundleId, "WaitForDebugger"); } @@ -30,15 +30,15 @@ module notification { export function readyForAttach(bundleId: string): string { return formatNotification(bundleId, "ReadyForAttach"); } - + export function attachAvailabilityQuery(bundleId: string) { return formatNotification(bundleId, "AttachAvailabilityQuery"); } - + export function alreadyConnected(bundleId: string) { return formatNotification(bundleId, "AlreadyConnected"); } - + export function attachAvailable(bundleId: string) { return formatNotification(bundleId, "AttachAvailable"); } @@ -63,7 +63,7 @@ function connectEventually(factory: () => net.Socket, handler: (_socket: net.Soc class IOSDebugService implements IDebugService { private static TIMEOUT_SECONDS = 90; - + constructor( private $platformService: IPlatformService, private $iOSEmulatorServices: Mobile.IEmulatorPlatformServices, @@ -88,7 +88,7 @@ class IOSDebugService implements IDebugService { if (this.$options.debugBrk && this.$options.start) { this.$errors.failWithoutHelp("Expected exactly one of the --debug-brk or --start options."); } - + if(!this.$options.debugBrk && !this.$options.start) { this.$logger.warn("Neither --debug-brk nor --start option was specified. Defaulting to --debug-brk."); this.$options.debugBrk = true; @@ -129,7 +129,7 @@ class IOSDebugService implements IDebugService { this.executeOpenDebuggerClient().wait(); let projectId = this.$projectData.projectId; let attachRequestMessage = notification.attachRequest(projectId); - + let iOSEmulator = this.$iOSEmulatorServices; iOSEmulator.postDarwinNotification(attachRequestMessage).wait(); }).future()(); @@ -141,11 +141,11 @@ class IOSDebugService implements IDebugService { this.$devicesServices.execute(device => (() => { // we intentionally do not wait on this here, because if we did, we'd miss the AppLaunching notification let deploy = this.$platformService.deployOnDevice(this.platform); - + let iosDevice = device; let projectId = this.$projectData.projectId; let npc = new iOSProxyServices.NotificationProxyClient(iosDevice, this.$injector); - + try { let timeout = this.$utils.getMilliSecondsTimeout(IOSDebugService.TIMEOUT_SECONDS); awaitNotification(npc, notification.appLaunching(projectId), timeout).wait(); @@ -153,13 +153,13 @@ class IOSDebugService implements IDebugService { npc.postNotificationAndAttachForData(notification.waitForDebug(projectId)); npc.postNotificationAndAttachForData(notification.attachRequest(projectId)); }); - + awaitNotification(npc, notification.readyForAttach(projectId), this.getReadyForAttachTimeout(timeout)).wait(); } catch(e) { this.$logger.trace(`Timeout error: ${e}`); this.$errors.failWithoutHelp("Timeout waiting for NativeScript debugger."); } - + createWebSocketProxy(this.$logger, (callback) => connectEventually(() => iosDevice.connectToPort(InspectorBackendPort), callback)); this.executeOpenDebuggerClient().wait(); deploy.wait(); @@ -174,31 +174,32 @@ class IOSDebugService implements IDebugService { let iosDevice = device; let projectId = this.$projectData.projectId; let npc = new iOSProxyServices.NotificationProxyClient(iosDevice, this.$injector); - + let timeout = this.getReadyForAttachTimeout(); let [alreadyConnected, readyForAttach, attachAvailable] = [ notification.alreadyConnected(projectId), notification.readyForAttach(projectId), notification.attachAvailable(projectId) ].map((notification) => awaitNotification(npc, notification, timeout)); - + npc.postNotificationAndAttachForData(notification.attachAvailabilityQuery(projectId)); - + let receivedNotification: IFuture; try { receivedNotification = whenAny(alreadyConnected, readyForAttach, attachAvailable).wait(); } catch (e) { this.$errors.failWithoutHelp(`The application ${projectId} does not appear to be running on ${device.deviceInfo.displayName} or is not built with debugging enabled.`); } - + switch (receivedNotification) { case alreadyConnected: this.$errors.failWithoutHelp("A debugger is already connected."); break; case attachAvailable: process.nextTick(() => npc.postNotificationAndAttachForData(notification.attachRequest(projectId))); - try { awaitNotification(npc, notification.readyForAttach(projectId), timeout).wait(); } - catch (e) { + try { + awaitNotification(npc, notification.readyForAttach(projectId), timeout).wait(); + } catch (e) { this.$errors.failWithoutHelp(`The application ${projectId} timed out when performing the NativeScript debugger handshake.`); } break; @@ -226,21 +227,21 @@ class IOSDebugService implements IDebugService { this.$projectDataService.initialize(this.$projectData.projectDir); let platformData = this.$platformsData.getPlatformData(this.platform); let frameworkVersion = this.$projectDataService.getValue(platformData.frameworkPackageName).wait().version; - + let inspectorPath = this.getInspectorPath(frameworkVersion).wait(); let inspectorSourceLocation = path.join(inspectorPath, "Safari/Main.html"); let cmd: string = null; - + if(semver.lt(frameworkVersion, "1.2.0")) { - cmd = `open -a Safari "${inspectorSourceLocation}"`; + cmd = `open -a Safari "${inspectorSourceLocation}"`; } else { let inspectorApplicationPath = path.join(inspectorPath, "NativeScript Inspector.app"); if(!this.$fs.exists(inspectorApplicationPath).wait()) { this.$fs.unzip(path.join(inspectorPath, "NativeScript Inspector.zip"), inspectorPath).wait(); } - cmd = `open -a '${inspectorApplicationPath}' --args '${inspectorSourceLocation}' '${this.$projectData.projectName}'`; + cmd = `open -a '${inspectorApplicationPath}' --args '${inspectorSourceLocation}' '${this.$projectData.projectName}'`; } - + this.$childProcess.exec(cmd).wait(); }).future()(); } @@ -262,11 +263,10 @@ class IOSDebugService implements IDebugService { }).future()(); } - private getReadyForAttachTimeout(timeoutInMilliseconds?: number): number { let timeout = timeoutInMilliseconds || this.$utils.getMilliSecondsTimeout(IOSDebugService.TIMEOUT_SECONDS); let readyForAttachTimeout = timeout / 10 ; - let defaultReadyForAttachTimeout = 5000; + let defaultReadyForAttachTimeout = 5000; return readyForAttachTimeout > defaultReadyForAttachTimeout ? readyForAttachTimeout : defaultReadyForAttachTimeout; } } @@ -328,29 +328,29 @@ function createWebSocketProxy($logger: ILogger, socketFactory: (handler: (_socke function awaitNotification(npc: iOSProxyServices.NotificationProxyClient, notification: string, timeout: number): IFuture { let future = new Future(); - + let timeoutObject = setTimeout(() => { detachObserver(); future.throw(new Error(`Timeout receiving ${notification} notification.`)); }, timeout); - + function notificationObserver(_notification: string) { clearTimeout(timeoutObject); detachObserver(); future.return(_notification); } - + function detachObserver() { process.nextTick(() => npc.removeObserver(notification, notificationObserver)); } - + npc.addObserver(notification, notificationObserver); - + return future; } function whenAny(...futures: IFuture[]): IFuture> { - let resultFuture = new Future>(); + let resultFuture = new Future>(); let futuresLeft = futures.length; let futureLocal: IFuture; @@ -358,7 +358,7 @@ function whenAny(...futures: IFuture[]): IFuture> { futureLocal = future; future.resolve((error, result?) => { futuresLeft--; - + if (!resultFuture.isResolved()) { if (typeof error === "undefined") { resultFuture.return(futureLocal); @@ -368,7 +368,7 @@ function whenAny(...futures: IFuture[]): IFuture> { } }); } - + return resultFuture; } diff --git a/lib/services/ios-project-service.ts b/lib/services/ios-project-service.ts index 1d298629c7..b9b2485851 100644 --- a/lib/services/ios-project-service.ts +++ b/lib/services/ios-project-service.ts @@ -16,7 +16,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ private static IOS_PROJECT_NAME_PLACEHOLDER = "__PROJECT_NAME__"; private static IOS_PLATFORM_NAME = "ios"; private static PODFILE_POST_INSTALL_SECTION_NAME = "post_install"; - + private get $npmInstallationManager(): INpmInstallationManager { return this.$injector.resolve("npmInstallationManager"); } @@ -29,7 +29,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ private $iOSEmulatorServices: Mobile.IEmulatorPlatformServices, private $options: IOptions, private $injector: IInjector) { - super($fs); + super($fs); } public get platformData(): IPlatformData { @@ -134,16 +134,16 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ "build", 'SHARED_PRECOMPS_DIR=' + path.join(projectRoot, 'build', 'sharedpch') ]; - + let xcworkspacePath = path.join(projectRoot, this.$projectData.projectName + ".xcworkspace"); if(this.$fs.exists(xcworkspacePath).wait()) { basicArgs.push("-workspace", xcworkspacePath); - basicArgs.push("-scheme", this.$projectData.projectName); + basicArgs.push("-scheme", this.$projectData.projectName); } else { basicArgs.push("-project", path.join(projectRoot, this.$projectData.projectName + ".xcodeproj")); - basicArgs.push("-target", this.$projectData.projectName); + basicArgs.push("-target", this.$projectData.projectName); } - + let args: string[] = []; if(this.$options.forDevice) { args = basicArgs.concat([ @@ -234,74 +234,74 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ this.replaceFileContent(pbxprojFilePath).wait(); }).future()(); } - + public prepareProject(): IFuture { return (() => { let project = this.createPbxProj(); let resources = project.pbxGroupByName("Resources"); - + if(resources) { let references = project.pbxFileReferenceSection(); - + let xcodeProjectImages = _.map(resources.children, resource => this.replace(references[resource.value].name)); this.$logger.trace("Images from Xcode project"); this.$logger.trace(xcodeProjectImages); - + let appResourcesImages = this.$fs.readDirectory(this.platformData.appResourcesDestinationDirectoryPath).wait(); this.$logger.trace("Current images from App_Resources"); this.$logger.trace(appResourcesImages); - + let imagesToAdd = _.difference(appResourcesImages, xcodeProjectImages); - this.$logger.trace(`New images to add into xcode project: ${imagesToAdd.join(", ")}`); + this.$logger.trace(`New images to add into xcode project: ${imagesToAdd.join(", ")}`); _.each(imagesToAdd, image => project.addResourceFile(path.relative(this.platformData.projectRoot, path.join( this.platformData.appResourcesDestinationDirectoryPath, image)))); - + let imagesToRemove = _.difference(xcodeProjectImages, appResourcesImages); - this.$logger.trace(`Images to remove from xcode project: ${imagesToRemove.join(", ")}`); - _.each(imagesToRemove, image => project.removeResourceFile(path.join(this.platformData.appResourcesDestinationDirectoryPath, image))); - + this.$logger.trace(`Images to remove from xcode project: ${imagesToRemove.join(", ")}`); + _.each(imagesToRemove, image => project.removeResourceFile(path.join(this.platformData.appResourcesDestinationDirectoryPath, image))); + this.savePbxProj(project).wait(); } }).future()(); } - + public prepareAppResources(appResourcesDirectoryPath: string): IFuture { return this.$fs.deleteDirectory(this.platformData.appResourcesDestinationDirectoryPath); } - + private get projectPodFilePath(): string { return path.join(this.platformData.projectRoot, "Podfile"); } - + private replace(name: string): string { if(_.startsWith(name, '"')) { name = name.substr(1, name.length-2); } - + return name.replace(/\\\"/g, "\""); } - + private getFrameworkRelativePath(libraryPath: string): string { let frameworkName = path.basename(libraryPath, path.extname(libraryPath)); let targetPath = path.join("lib", this.platformData.normalizedPlatformName); let frameworkPath = path.relative("platforms/ios", path.join(targetPath, frameworkName + ".framework")); return frameworkPath; } - + private get pbxProjPath(): string { return path.join(this.platformData.projectRoot, this.$projectData.projectName + ".xcodeproj", "project.pbxproj"); } - + private createPbxProj(): any { let project = new xcode.project(this.pbxProjPath); project.parseSync(); - + return project; } - + private savePbxProj(project: any): IFuture { return this.$fs.writeFile(this.pbxProjPath, project.writeSync()); } - + public preparePluginNativeCode(pluginData: IPluginData): IFuture { return (() => { let pluginPlatformsFolderPath = pluginData.pluginPlatformsFolderPath(IOSProjectService.IOS_PLATFORM_NAME); @@ -309,7 +309,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ this.prepareCocoapods(pluginPlatformsFolderPath).wait(); }).future()(); } - + public removePluginNativeCode(pluginData: IPluginData): IFuture { return (() => { let pluginPlatformsFolderPath = pluginData.pluginPlatformsFolderPath(IOSProjectService.IOS_PLATFORM_NAME); @@ -317,7 +317,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ this.removeCocoapods(pluginPlatformsFolderPath).wait(); }).future()(); } - + public afterPrepareAllPlugins(): IFuture { return (() => { if(this.$fs.exists(this.projectPodFilePath).wait()) { @@ -325,24 +325,24 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ try { this.$childProcess.exec("gem which cocoapods").wait(); } catch(e) { - this.$errors.failWithoutHelp("CocoaPods are not installed. Run `sudo gem install cocoapods` and try again."); + this.$errors.failWithoutHelp("CocoaPods are not installed. Run `sudo gem install cocoapods` and try again."); } - - let projectPodfileContent = this.$fs.readText(this.projectPodFilePath).wait(); + + let projectPodfileContent = this.$fs.readText(this.projectPodFilePath).wait(); this.$logger.trace("Project Podfile content"); this.$logger.trace(projectPodfileContent); - + let firstPostInstallIndex = projectPodfileContent.indexOf(IOSProjectService.PODFILE_POST_INSTALL_SECTION_NAME); if(firstPostInstallIndex !== -1 && firstPostInstallIndex !== projectPodfileContent.lastIndexOf(IOSProjectService.PODFILE_POST_INSTALL_SECTION_NAME)) { this.$logger.warn(`Podfile contains more than one post_install sections. You need to open ${this.projectPodFilePath} file and manually resolve this issue.`); - } - + } + this.$logger.info("Installing pods..."); this.$childProcess.exec("pod install", { cwd: this.platformData.projectRoot }).wait(); } }).future()(); } - + private getAllDynamicFrameworksForPlugin(pluginData: IPluginData): IFuture { let filterCallback = (fileName: string, pluginPlatformsFolderPath: string) => path.extname(fileName) === ".framework"; return this.getAllNativeLibrariesForPlugin(pluginData, IOSProjectService.IOS_PLATFORM_NAME, filterCallback); @@ -382,13 +382,13 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ this.$fs.rename(path.join(fileRootLocation, oldFileName), path.join(fileRootLocation, newFileName)).wait(); }).future()(); } - + private prepareDynamicFrameworks(pluginPlatformsFolderPath: string, pluginData: IPluginData): IFuture { return (() => { - _.each(this.getAllDynamicFrameworksForPlugin(pluginData).wait(), fileName => this.addLibrary(path.join(pluginPlatformsFolderPath, fileName)).wait()); + _.each(this.getAllDynamicFrameworksForPlugin(pluginData).wait(), fileName => this.addLibrary(path.join(pluginPlatformsFolderPath, fileName)).wait()); }).future()(); } - + private prepareCocoapods(pluginPlatformsFolderPath: string): IFuture { return (() => { let pluginPodFilePath = path.join(pluginPlatformsFolderPath, "Podfile"); @@ -399,21 +399,21 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ } }).future()(); } - + private removeDynamicFrameworks(pluginPlatformsFolderPath: string, pluginData: IPluginData): IFuture { return (() => { let project = this.createPbxProj(); - + _.each(this.getAllDynamicFrameworksForPlugin(pluginData).wait(), fileName => { let fullFrameworkPath = path.join(pluginPlatformsFolderPath, fileName); let relativeFrameworkPath = this.getFrameworkRelativePath(fullFrameworkPath); project.removeFramework(relativeFrameworkPath, { customFramework: true, embed: true }); }); - + this.savePbxProj(project).wait(); }).future()(); } - + private removeCocoapods(pluginPlatformsFolderPath: string): IFuture { return (() => { let pluginPodFilePath = path.join(pluginPlatformsFolderPath, "Podfile"); @@ -430,7 +430,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ } }).future()(); } - + private buildPodfileContent(pluginPodFilePath: string, pluginPodFileContent: string): string { return `# Begin Podfile - ${pluginPodFilePath} ${os.EOL} ${pluginPodFileContent} ${os.EOL} # End Podfile ${os.EOL}`; } diff --git a/lib/services/platform-project-service-base.ts b/lib/services/platform-project-service-base.ts index 550c13ebd9..11c45e8635 100644 --- a/lib/services/platform-project-service-base.ts +++ b/lib/services/platform-project-service-base.ts @@ -3,11 +3,11 @@ export class PlatformProjectServiceBase implements IPlatformProjectServiceBase { constructor(protected $fs: IFileSystem) { } - + public getPluginPlatformsFolderPath(pluginData: IPluginData, platform: string) { return pluginData.pluginPlatformsFolderPath(platform); } - + public getAllNativeLibrariesForPlugin(pluginData: IPluginData, platform: string, filter: (fileName: string, _pluginPlatformsFolderPath: string) => boolean): IFuture { return (() => { let pluginPlatformsFolderPath = this.getPluginPlatformsFolderPath(pluginData, platform), @@ -18,7 +18,7 @@ export class PlatformProjectServiceBase implements IPlatformProjectServiceBase { .filter(platformItemName => filter(platformItemName, pluginPlatformsFolderPath)) .value(); } - + return nativeLibraries; }).future()(); } diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index 83c9661648..1579e8100c 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -9,7 +9,7 @@ import * as semver from "semver"; export class PlatformService implements IPlatformService { private static TNS_MODULES_FOLDER_NAME = "tns_modules"; - + constructor(private $devicesServices: Mobile.IDevicesServices, private $errors: IErrors, private $fs: IFileSystem, @@ -140,27 +140,27 @@ export class PlatformService implements IPlatformService { public preparePlatform(platform: string): IFuture { return (() => { this.validatePlatform(platform); - + platform = platform.toLowerCase(); this.ensurePlatformInstalled(platform).wait(); let platformData = this.$platformsData.getPlatformData(platform); let appDestinationDirectoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME); - let lastModifiedTime = this.$fs.exists(appDestinationDirectoryPath).wait() ? + let lastModifiedTime = this.$fs.exists(appDestinationDirectoryPath).wait() ? this.$fs.getFsStats(appDestinationDirectoryPath).wait().mtime : null; // Copy app folder to native project this.$fs.ensureDirectoryExists(appDestinationDirectoryPath).wait(); let appSourceDirectoryPath = path.join(this.$projectData.projectDir, constants.APP_FOLDER_NAME); - + // Delete the destination app in order to prevent EEXIST errors when symlinks are used. let contents = this.$fs.readDirectory(appDestinationDirectoryPath).wait(); - + _(contents) .filter(directoryName => directoryName !== "tns_modules") .each(directoryName => this.$fs.deleteDirectory(path.join(appDestinationDirectoryPath, directoryName)).wait()) .value(); - shell.cp("-Rf", appSourceDirectoryPath, platformData.appDestinationDirectoryPath); + shell.cp("-Rf", appSourceDirectoryPath, platformData.appDestinationDirectoryPath); // Copy App_Resources to project root folder this.$fs.ensureDirectoryExists(platformData.appResourcesDestinationDirectoryPath).wait(); // Should be deleted @@ -170,7 +170,7 @@ export class PlatformService implements IPlatformService { shell.cp("-Rf", path.join(appResourcesDirectoryPath, platformData.normalizedPlatformName, "*"), platformData.appResourcesDestinationDirectoryPath); this.$fs.deleteDirectory(appResourcesDirectoryPath).wait(); } - + platformData.platformProjectService.prepareProject().wait(); // Process node_modules folder @@ -183,16 +183,16 @@ export class PlatformService implements IPlatformService { this.$errors.fail(`Processing node_modules failed. Error:${error}`); shell.rm("-rf", appResourcesDirectoryPath); } - + // Process platform specific files let directoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME); let excludedDirs = [constants.APP_RESOURCES_FOLDER_NAME]; this.$projectFilesManager.processPlatformSpecificFiles(directoryPath, platform, excludedDirs).wait(); - this.$logger.out("Project successfully prepared"); + this.$logger.out("Project successfully prepared"); }).future()(); } - + public buildPlatform(platform: string): IFuture { return (() => { platform = platform.toLowerCase(); @@ -219,15 +219,15 @@ export class PlatformService implements IPlatformService { public removePlatforms(platforms: string[]): IFuture { return (() => { this.$projectDataService.initialize(this.$projectData.projectDir); - + _.each(platforms, platform => { this.validatePlatformInstalled(platform); - let platformData = this.$platformsData.getPlatformData(platform); + let platformData = this.$platformsData.getPlatformData(platform); let platformDir = path.join(this.$projectData.platformsDir, platform); this.$fs.deleteDirectory(platformDir).wait(); this.$projectDataService.removeProperty(platformData.frameworkPackageName).wait(); - + this.$logger.out(`Platform ${platform} successfully removed.`); }); @@ -265,12 +265,12 @@ export class PlatformService implements IPlatformService { this.$devicesServices.initialize({platform: platform, deviceId: this.$options.device}).wait(); let action = (device: Mobile.IDevice): IFuture => { return (() => { - device.deploy(packageFile, this.$projectData.projectId).wait(); - + device.deploy(packageFile, this.$projectData.projectId).wait(); + if (!this.$options.justlaunch) { device.openDeviceLogStream(); } - }).future()(); + }).future()(); }; this.$devicesServices.execute(action).wait(); this.$commandsService.tryExecuteCommand("device", ["run", this.$projectData.projectId]).wait(); diff --git a/lib/services/plugins-service.ts b/lib/services/plugins-service.ts index a2a19aed7b..520a6ef448 100644 --- a/lib/services/plugins-service.ts +++ b/lib/services/plugins-service.ts @@ -14,8 +14,8 @@ export class PluginsService implements IPluginsService { private static NPM_CONFIG = { save: true }; - - constructor(private $platformsData: IPlatformsData, + + constructor(private $platformsData: IPlatformsData, private $npm: INodePackageManager, private $fs: IFileSystem, private $projectData: IProjectData, @@ -25,7 +25,7 @@ export class PluginsService implements IPluginsService { private $logger: ILogger, private $errors: IErrors, private $projectFilesManager: IProjectFilesManager) { } - + public add(plugin: string): IFuture { return (() => { this.ensure().wait(); @@ -33,14 +33,14 @@ export class PluginsService implements IPluginsService { if(dependencyData.nativescript) { this.executeNpmCommand(PluginsService.INSTALL_COMMAND_NAME, plugin).wait(); this.prepare(dependencyData).wait(); - this.$logger.out(`Successfully installed plugin ${dependencyData.name}.`); + this.$logger.out(`Successfully installed plugin ${dependencyData.name}.`); } else { - this.$errors.failWithoutHelp(`${plugin} is not a valid NativeScript plugin. Verify that the plugin package.json file contains a nativescript key and try again.`); + this.$errors.failWithoutHelp(`${plugin} is not a valid NativeScript plugin. Verify that the plugin package.json file contains a nativescript key and try again.`); } - + }).future()(); } - + public remove(pluginName: string): IFuture { return (() => { let removePluginNativeCodeAction = (modulesDestinationPath: string, platform: string, platformData: IPlatformData) => { @@ -49,32 +49,32 @@ export class PluginsService implements IPluginsService { return platformData.platformProjectService.removePluginNativeCode(pluginData); }; this.executeForAllInstalledPlatforms(removePluginNativeCodeAction).wait(); - + this.executeNpmCommand(PluginsService.UNINSTALL_COMMAND_NAME, pluginName).wait(); let showMessage = true; let action = (modulesDestinationPath: string, platform: string, platformData: IPlatformData) => { return (() => { shelljs.rm("-rf", path.join(modulesDestinationPath, pluginName)); - + this.$logger.out(`Successfully removed plugin ${pluginName} for ${platform}.`); showMessage = false; }).future()(); }; this.executeForAllInstalledPlatforms(action).wait(); - + if(showMessage) { - this.$logger.out(`Succsessfully removed plugin ${pluginName}`); + this.$logger.out(`Succsessfully removed plugin ${pluginName}`); } }).future()(); } - + public prepare(dependencyData: IDependencyData): IFuture { return (() => { let pluginData = this.convertToPluginData(dependencyData); - + let action = (pluginDestinationPath: string, platform: string, platformData: IPlatformData) => { return (() => { - // Process .js files + // Process .js files let installedFrameworkVersion = this.getInstalledFrameworkVersion(platform).wait(); let pluginPlatformsData = pluginData.platformsData; if(pluginPlatformsData) { @@ -82,53 +82,53 @@ export class PluginsService implements IPluginsService { if(!pluginVersion) { this.$logger.warn(`${pluginData.name} is not supported for ${platform}.`); return; - } - + } + if(semver.gt(pluginVersion, installedFrameworkVersion)) { this.$logger.warn(`${pluginData.name} ${pluginVersion} for ${platform} is not compatible with the currently installed framework version ${installedFrameworkVersion}.`); return; } } - + this.$fs.ensureDirectoryExists(pluginDestinationPath).wait(); shelljs.cp("-Rf", pluginData.fullPath, pluginDestinationPath); - + let pluginPlatformsFolderPath = path.join(pluginDestinationPath, pluginData.name, "platforms", platform); let pluginConfigurationFilePath = path.join(pluginPlatformsFolderPath, platformData.configurationFileName); let configurationFilePath = platformData.configurationFilePath; - + if(this.$fs.exists(pluginConfigurationFilePath).wait()) { // Validate plugin configuration file let pluginConfigurationFileContent = this.$fs.readText(pluginConfigurationFilePath).wait(); this.validateXml(pluginConfigurationFileContent, pluginConfigurationFilePath); - + // Validate configuration file let configurationFileContent = this.$fs.readText(configurationFilePath).wait(); this.validateXml(configurationFileContent, configurationFilePath); - + // Merge xml let resultXml = this.mergeXml(configurationFileContent, pluginConfigurationFileContent, platformData.mergeXmlConfig || []).wait(); this.validateXml(resultXml); - this.$fs.writeFile(configurationFilePath, resultXml).wait(); + this.$fs.writeFile(configurationFilePath, resultXml).wait(); } - - this.$projectFilesManager.processPlatformSpecificFiles(pluginDestinationPath, platform).wait(); - - pluginData.pluginPlatformsFolderPath = (_platform: string) => path.join(pluginData.fullPath, "platforms", _platform); + + this.$projectFilesManager.processPlatformSpecificFiles(pluginDestinationPath, platform).wait(); + + pluginData.pluginPlatformsFolderPath = (_platform: string) => path.join(pluginData.fullPath, "platforms", _platform); platformData.platformProjectService.preparePluginNativeCode(pluginData).wait(); - + shelljs.rm("-rf", path.join(pluginDestinationPath, pluginData.name, "platforms")); - + // Show message this.$logger.out(`Successfully prepared plugin ${pluginData.name} for ${platform}.`); - + }).future()(); }; - + this.executeForAllInstalledPlatforms(action).wait(); }).future()(); } - + public ensureAllDependenciesAreInstalled(): IFuture { let command = "npm install "; if(this.$options.ignoreScripts) { @@ -136,41 +136,41 @@ export class PluginsService implements IPluginsService { } return this.$childProcess.exec(command, { cwd: this.$projectData.projectDir }); } - + public getAllInstalledPlugins(): IFuture { return (() => { let nodeModules = this.getAllInstalledModules().wait(); return _.filter(nodeModules, nodeModuleData => nodeModuleData && nodeModuleData.isPlugin); }).future()(); } - + public afterPrepareAllPlugins(): IFuture { let action = (pluginDestinationPath: string, platform: string, platformData: IPlatformData) => { return platformData.platformProjectService.afterPrepareAllPlugins(); }; - + return this.executeForAllInstalledPlatforms(action); } - + private get nodeModulesPath(): string { return path.join(this.$projectData.projectDir, "node_modules"); } - + private getPackageJsonFilePath(): string { return path.join(this.$projectData.projectDir, "package.json"); } - + private getPackageJsonFilePathForModule(moduleName: string): string { return path.join(this.nodeModulesPath, moduleName, "package.json"); } - + private getDependencies(): string[] { let packageJsonFilePath = this.getPackageJsonFilePath(); return _.keys(require(packageJsonFilePath).dependencies); } - + private getNodeModuleData(moduleName: string): IFuture { - return (() => { + return (() => { let packageJsonFilePath = this.getPackageJsonFilePathForModule(moduleName); if(this.$fs.exists(packageJsonFilePath).wait()) { let data = require(packageJsonFilePath); @@ -179,14 +179,14 @@ export class PluginsService implements IPluginsService { version: data.version, fullPath: path.dirname(packageJsonFilePath), isPlugin: data.nativescript !== undefined, - moduleInfo: data.nativescript + moduleInfo: data.nativescript }; } - + return null; }).future()(); } - + private convertToPluginData(cacheData: any): IPluginData { let pluginData: any = {}; pluginData.name = cacheData.name; @@ -194,48 +194,48 @@ export class PluginsService implements IPluginsService { pluginData.fullPath = cacheData.directory || path.dirname(this.getPackageJsonFilePathForModule(cacheData.name)); pluginData.isPlugin = !!cacheData.nativescript; pluginData.pluginPlatformsFolderPath = (platform: string) => path.join(pluginData.fullPath, "platforms", platform); - + if(pluginData.isPlugin) { pluginData.platformsData = cacheData.nativescript.platforms; } - + return pluginData; } - + private ensure(): IFuture { return (() => { this.ensureAllDependenciesAreInstalled().wait(); this.$fs.ensureDirectoryExists(this.nodeModulesPath).wait(); }).future()(); } - + private getAllInstalledModules(): IFuture { return (() => { this.ensure().wait(); - + let nodeModules = this.getDependencies(); return _.map(nodeModules, nodeModuleName => this.getNodeModuleData(nodeModuleName).wait()); }).future()(); } - + private executeNpmCommand(npmCommandName: string, npmCommandArguments: string): IFuture { return (() => { let result = ""; - + if(npmCommandName === PluginsService.INSTALL_COMMAND_NAME) { - result = this.$npm.install(npmCommandArguments, this.$projectData.projectDir, PluginsService.NPM_CONFIG).wait(); + result = this.$npm.install(npmCommandArguments, this.$projectData.projectDir, PluginsService.NPM_CONFIG).wait(); } else if(npmCommandName === PluginsService.UNINSTALL_COMMAND_NAME) { result = this.$npm.uninstall(npmCommandArguments, PluginsService.NPM_CONFIG).wait(); } - + return this.parseNpmCommandResult(result); }).future()(); } - + private parseNpmCommandResult(npmCommandResult: string): string { // [[name@version, node_modules/name]] return npmCommandResult[0][0].split("@")[0]; // returns plugin name } - + private executeForAllInstalledPlatforms(action: (_pluginDestinationPath: string, pl: string, _platformData: IPlatformData) => IFuture): IFuture { return (() => { let availablePlatforms = _.keys(this.$platformsData.availablePlatforms); @@ -249,7 +249,7 @@ export class PluginsService implements IPluginsService { }); }).future()(); } - + private getInstalledFrameworkVersion(platform: string): IFuture { return (() => { let platformData = this.$platformsData.getPlatformData(platform); @@ -261,18 +261,18 @@ export class PluginsService implements IPluginsService { private mergeXml(xml1: string, xml2: string, config: any[]): IFuture { let future = new Future(); - + try { - xmlmerge.merge(xml1, xml2, config, (mergedXml: string) => { + xmlmerge.merge(xml1, xml2, config, (mergedXml: string) => { future.return(mergedXml); }); } catch(err) { future.throw(err); } - + return future; } - + private validateXml(xml: string, xmlFilePath?: string): void { let doc = new DOMParser({ locator: {}, diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index 7f7bfa2122..87d1370bb9 100644 --- a/lib/services/project-data-service.ts +++ b/lib/services/project-data-service.ts @@ -37,7 +37,7 @@ export class ProjectDataService implements IProjectDataService { this.$fs.writeJson(this.projectFilePath, this.projectData, "\t").wait(); }).future()(); } - + public removeProperty(propertyName: string): IFuture { return (() => { this.loadProjectFile().wait(); diff --git a/lib/services/project-files-manager.ts b/lib/services/project-files-manager.ts index 4efcaa99ee..a63a3e32a7 100644 --- a/lib/services/project-files-manager.ts +++ b/lib/services/project-files-manager.ts @@ -1,17 +1,17 @@ /// "use strict"; -import path = require("path"); -import util = require("util"); +import * as path from "path"; +import * as util from "util"; export class ProjectFilesManager implements IProjectFilesManager { constructor(private $fs: IFileSystem, private $platformsData: IPlatformsData) { } - + public processPlatformSpecificFiles(directoryPath: string, platform: string, excludedDirs?: string[]): IFuture { return (() => { let contents = this.$fs.readDirectory(directoryPath).wait(); let files: string[] = []; - + _.each(contents, fileName => { let filePath = path.join(directoryPath, fileName); let fsStat = this.$fs.getFsStats(filePath).wait(); @@ -22,10 +22,10 @@ export class ProjectFilesManager implements IProjectFilesManager { } }); this.processPlatformSpecificFilesCore(platform, files).wait(); - + }).future()(); } - + private processPlatformSpecificFilesCore(platform: string, files: string[]): IFuture { // Renames the files that have `platform` as substring and removes the files from other platform return (() => { @@ -40,7 +40,7 @@ export class ProjectFilesManager implements IProjectFilesManager { }); }).future()(); } - + private static parsePlatformSpecificFileName(fileName: string, platforms: string[]): any { let regex = util.format("^(.+?)\\.(%s)(\\..+?)$", platforms.join("|")); let parsed = fileName.match(new RegExp(regex, "i")); diff --git a/lib/services/project-service.ts b/lib/services/project-service.ts index a65c52743c..4a74c0afd5 100644 --- a/lib/services/project-service.ts +++ b/lib/services/project-service.ts @@ -34,15 +34,15 @@ export class ProjectService implements IProjectService { if(customAppPath) { customAppPath = path.resolve(customAppPath); if(!this.$fs.exists(customAppPath).wait()) { - this.$errors.failWithoutHelp(`The specified path "${customAppPath}" doesn't exist. Check that you specified the path correctly and try again.`); + this.$errors.failWithoutHelp(`The specified path "${customAppPath}" doesn't exist. Check that you specified the path correctly and try again.`); } - + let customAppContents = this.$fs.enumerateFilesInDirectorySync(customAppPath); if(customAppContents.length === 0) { this.$errors.failWithoutHelp(`The specified path "${customAppPath}" is empty directory.`); } } - + if(this.$fs.exists(projectDir).wait() && !this.$fs.isEmptyDir(projectDir).wait()) { this.$errors.fail("Path already exists and is not empty %s", projectDir); } @@ -110,7 +110,7 @@ export class ProjectService implements IProjectService { this.$projectDataService.initialize(projectDir); this.$projectDataService.setValue("id", projectId).wait(); - + let tnsModulesVersion = this.$options.tnsModulesVersion; let packageName = constants.TNS_CORE_MODULES_NAME; if (tnsModulesVersion) { diff --git a/lib/services/usb-livesync-service.ts b/lib/services/usb-livesync-service.ts index b727116681..0145665bc4 100644 --- a/lib/services/usb-livesync-service.ts +++ b/lib/services/usb-livesync-service.ts @@ -12,7 +12,7 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer private excludedProjectDirsAndFiles = [ "app_resources" ]; - + constructor(private $commandsService: ICommandsService, $devicesServices: Mobile.IDevicesServices, $fs: IFileSystem, @@ -32,90 +32,93 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer private $projectDataService: IProjectDataService, private $prompter: IPrompter, $hostInfo: IHostInfo) { - super($devicesServices, $mobileHelper, $localToDevicePathDataFactory, $logger, $options, $deviceAppDataFactory, $fs, $dispatcher, $injector, $childProcess, $iOSEmulatorServices, $hostInfo); + super($devicesServices, $mobileHelper, $localToDevicePathDataFactory, $logger, $options, + $deviceAppDataFactory, $fs, $dispatcher, $injector, $childProcess, $iOSEmulatorServices, $hostInfo); } - + public liveSync(platform: string): IFuture { return (() => { platform = platform || this.initialize(platform).wait(); let platformLowerCase = platform ? platform.toLowerCase() : null; - let platformData = this.$platformsData.getPlatformData(platformLowerCase); - + let platformData = this.$platformsData.getPlatformData(platformLowerCase); + if(platformLowerCase === this.$devicePlatformsConstants.Android.toLowerCase()) { this.$projectDataService.initialize(this.$projectData.projectDir); let frameworkVersion = this.$projectDataService.getValue(platformData.frameworkPackageName).wait().version; if(semver.lt(frameworkVersion, "1.2.1")) { - let shouldUpdate = this.$prompter.confirm("You need Android Runtime 1.2.1 or later for LiveSync to work properly. Do you want to update your runtime now?").wait(); + let shouldUpdate = this.$prompter.confirm( + "You need Android Runtime 1.2.1 or later for LiveSync to work properly. Do you want to update your runtime now?" + ).wait(); if(shouldUpdate) { - this.$platformService.updatePlatforms([this.$devicePlatformsConstants.Android.toLowerCase()]).wait(); + this.$platformService.updatePlatforms([this.$devicePlatformsConstants.Android.toLowerCase()]).wait(); } else { return; } } } - + this.$platformService.preparePlatform(platform).wait(); - + let projectFilesPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME); let restartAppOnDeviceAction = (device: Mobile.IDevice, deviceAppData: Mobile.IDeviceAppData, localToDevicePaths?: Mobile.ILocalToDevicePathData[]): IFuture => { - let platformSpecificUsbLiveSyncService = this.resolveUsbLiveSyncService(platform || this.$devicesServices.platform, device); + let platformSpecificUsbLiveSyncService = this.resolveUsbLiveSyncService(platform || this.$devicesServices.platform, device); return platformSpecificUsbLiveSyncService.restartApplication(deviceAppData, localToDevicePaths); }; - + let notInstalledAppOnDeviceAction = (device: Mobile.IDevice): IFuture => { return this.$platformService.deployOnDevice(platform); }; - + let notRunningiOSSimulatorAction = (): IFuture => { return this.$platformService.deployOnEmulator(this.$devicePlatformsConstants.iOS.toLowerCase()); }; - + let beforeLiveSyncAction = (device: Mobile.IDevice, deviceAppData: Mobile.IDeviceAppData): IFuture => { let platformSpecificUsbLiveSyncService = this.resolveUsbLiveSyncService(platform || this.$devicesServices.platform, device); if(platformSpecificUsbLiveSyncService.beforeLiveSyncAction) { return platformSpecificUsbLiveSyncService.beforeLiveSyncAction(deviceAppData); } - return Future.fromResult(); + return Future.fromResult(); }; - + let beforeBatchLiveSyncAction = (filePath: string): IFuture => { return (() => { this.$platformService.preparePlatform(platform).wait(); return path.join(projectFilesPath, path.relative(path.join(this.$projectData.projectDir, constants.APP_FOLDER_NAME), filePath)); }).future()(); }; - + let iOSSimulatorRelativeToProjectBasePathAction = (projectFile: string): string => { return path.join(constants.APP_FOLDER_NAME, path.dirname(projectFile.split(`/${constants.APP_FOLDER_NAME}/`)[1])); }; - + let watchGlob = path.join(this.$projectData.projectDir, constants.APP_FOLDER_NAME); - + let platformSpecificLiveSyncServices: IDictionary = { android: AndroidUsbLiveSyncService, ios: IOSUsbLiveSyncService }; - + let localProjectRootPath = platform.toLowerCase() === "ios" ? platformData.appDestinationDirectoryPath : null; - - this.sync(platform, - this.$projectData.projectId, - projectFilesPath, - this.excludedProjectDirsAndFiles, - watchGlob, - platformSpecificLiveSyncServices, - restartAppOnDeviceAction, - notInstalledAppOnDeviceAction, - notRunningiOSSimulatorAction, - localProjectRootPath, - beforeLiveSyncAction, - beforeBatchLiveSyncAction, + + this.sync(platform, + this.$projectData.projectId, + projectFilesPath, + this.excludedProjectDirsAndFiles, + watchGlob, + platformSpecificLiveSyncServices, + restartAppOnDeviceAction, + notInstalledAppOnDeviceAction, + notRunningiOSSimulatorAction, + localProjectRootPath, + beforeLiveSyncAction, + beforeBatchLiveSyncAction, iOSSimulatorRelativeToProjectBasePathAction ).wait(); }).future()(); } - + private resolveUsbLiveSyncService(platform: string, device: Mobile.IDevice): IPlatformSpecificUsbLiveSyncService { let platformSpecificUsbLiveSyncService: IPlatformSpecificUsbLiveSyncService = null; if(platform.toLowerCase() === "android") { @@ -123,22 +126,22 @@ export class UsbLiveSyncService extends usbLivesyncServiceBaseLib.UsbLiveSyncSer } else if(platform.toLowerCase() === "ios") { platformSpecificUsbLiveSyncService = this.$injector.resolve(IOSUsbLiveSyncService, {_device: device}); } - + return platformSpecificUsbLiveSyncService; - } + } } $injector.register("usbLiveSyncService", UsbLiveSyncService); export class IOSUsbLiveSyncService implements IPlatformSpecificUsbLiveSyncService { constructor(private _device: Mobile.IDevice) { } - + private get device(): Mobile.IiOSDevice { return this._device; } - + public restartApplication(deviceAppData: Mobile.IDeviceAppData): IFuture { return this.device.applicationManager.restartApplication(deviceAppData.appIdentifier); - } + } } export class AndroidUsbLiveSyncService extends androidLiveSyncServiceLib.AndroidLiveSyncService implements IPlatformSpecificUsbLiveSyncService { @@ -147,24 +150,24 @@ export class AndroidUsbLiveSyncService extends androidLiveSyncServiceLib.Android $mobileHelper: Mobile.IMobileHelper, private $options: IOptions) { super(_device, $fs, $mobileHelper); - + } - + public restartApplication(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[]): IFuture { return (() => { if(this.$options.companion) { - let commands = [ this.liveSyncCommands.SyncFilesCommand() ]; + let commands = [ this.liveSyncCommands.SyncFilesCommand() ]; this.livesync(deviceAppData.appIdentifier, deviceAppData.deviceProjectRootPath, commands).wait(); } else { let devicePathRoot = `/data/data/${deviceAppData.appIdentifier}/files`; let devicePath = this.$mobileHelper.buildDevicePath(devicePathRoot, "code_cache", "secondary_dexes", "proxyThumb"); this.device.adb.executeShellCommand(["rm", "-rf", devicePath]).wait(); } - + this.device.applicationManager.restartApplication(deviceAppData.appIdentifier).wait(); }).future()(); } - + public beforeLiveSyncAction(deviceAppData: Mobile.IDeviceAppData): IFuture { return (() => { let deviceRootPath = `/data/local/tmp/${deviceAppData.appIdentifier}`; diff --git a/lib/tools/broccoli/broccoli-plugin-wrapper.ts b/lib/tools/broccoli/broccoli-plugin-wrapper.ts index 8373eef816..f7f89f74b0 100644 --- a/lib/tools/broccoli/broccoli-plugin-wrapper.ts +++ b/lib/tools/broccoli/broccoli-plugin-wrapper.ts @@ -18,7 +18,7 @@ export class BroccoliPluginWrapper implements BroccoliTree { cachePath: string = null; outputPath: string = null; - constructor(private pluginClass: any, wrappedPluginArguments: any) { + constructor(private pluginClass: any, wrappedPluginArguments: any) { this.inputTree = wrappedPluginArguments[0]; this.description = this.pluginClass.name; this.absoluteOutputPath = wrappedPluginArguments[1]; @@ -30,10 +30,10 @@ export class BroccoliPluginWrapper implements BroccoliTree { rebuild(): void { try { this.init(); - - let diffResult = this.treeDiffer.diffTree(this.absoluteOutputPath, this.treeRootDirName); + + let diffResult = this.treeDiffer.diffTree(this.absoluteOutputPath, this.treeRootDirName); this.wrappedPlugin.rebuild(diffResult); - + } catch (e) { e.message = `[${this.description}]: ${e.message}`; throw e; @@ -42,10 +42,10 @@ export class BroccoliPluginWrapper implements BroccoliTree { private init() { this.treeDiffer = new TreeDiffer(this.inputPath); - this.wrappedPlugin = this.$injector.resolve(this.pluginClass, - { inputPath: this.inputPath, - cachePath: this.cachePath, - outputRoot: this.absoluteOutputPath, + this.wrappedPlugin = this.$injector.resolve(this.pluginClass, + { inputPath: this.inputPath, + cachePath: this.cachePath, + outputRoot: this.absoluteOutputPath, projectDir: this.projectDir }); } diff --git a/lib/tools/broccoli/builder.ts b/lib/tools/broccoli/builder.ts index 1736f57469..ebce0a8ea0 100644 --- a/lib/tools/broccoli/builder.ts +++ b/lib/tools/broccoli/builder.ts @@ -7,42 +7,42 @@ import destCopyLib = require("./node-modules-dest-copy"); let gulp = require("gulp"); let vinylFilterSince = require("vinyl-filter-since"); -let through = require("through2"); +let through = require("through2"); export class Builder implements IBroccoliBuilder { private nodeModules: any = {}; - + constructor(private $fs: IFileSystem, private $nodeModulesTree: INodeModulesTree, private $projectDataService: IProjectDataService, private $injector: IInjector, private $logger: ILogger) { } - + public prepareNodeModules(absoluteOutputPath: string, projectDir: string, platform: string, lastModifiedTime?: Date): IFuture { return (() => { let isNodeModulesModified = false; let nodeModulesPath = path.join(projectDir, "node_modules"); - + if(lastModifiedTime) { let pipeline = gulp.src(path.join(projectDir, "node_modules/**")) .pipe(vinylFilterSince(lastModifiedTime)) .pipe(through.obj( (chunk: any, enc: any, cb: Function) => { if(chunk.path === nodeModulesPath) { isNodeModulesModified = true; - } - + } + if(!isNodeModulesModified) { let rootModuleName = chunk.path.split(nodeModulesPath)[1].split(path.sep)[1]; let rootModuleFullPath = path.join(nodeModulesPath, rootModuleName); this.nodeModules[rootModuleFullPath] = rootModuleFullPath; } - - cb(null); + + cb(null); })) .pipe(gulp.dest(absoluteOutputPath)); - + let future = new Future(); - + pipeline.on('end', (err: any, data: any) => { if(err) { future.throw(err); @@ -50,17 +50,17 @@ export class Builder implements IBroccoliBuilder { future.return(); } }); - + future.wait(); } - + if(isNodeModulesModified && this.$fs.exists(absoluteOutputPath).wait()) { let currentPreparedTnsModules = this.$fs.readDirectory(absoluteOutputPath).wait(); let tnsModulesInApp = this.$fs.readDirectory(path.join(projectDir, "app", "tns_modules")).wait(); let modulesToDelete = _.difference(currentPreparedTnsModules, tnsModulesInApp); _.each(modulesToDelete, moduleName => this.$fs.deleteDirectory(path.join(absoluteOutputPath, moduleName)).wait()); - } - + } + if(!lastModifiedTime || isNodeModulesModified) { let nodeModulesDirectories = this.$fs.exists(nodeModulesPath).wait() ? this.$fs.readDirectory(nodeModulesPath).wait() : []; _.each(nodeModulesDirectories, nodeModuleDirectoryName => { @@ -68,17 +68,17 @@ export class Builder implements IBroccoliBuilder { this.nodeModules[nodeModuleFullPath] = nodeModuleFullPath; }); } - + let destCopy = this.$injector.resolve(destCopyLib.DestCopy, { - inputPath: projectDir, - cachePath: "", + inputPath: projectDir, + cachePath: "", outputRoot: absoluteOutputPath, projectDir: projectDir, platform: platform }); - + destCopy.rebuildChangedDirectories(_.keys(this.nodeModules)); - + }).future()(); } } diff --git a/lib/tools/broccoli/node-modules-dest-copy.ts b/lib/tools/broccoli/node-modules-dest-copy.ts index dec415f028..de348764d6 100644 --- a/lib/tools/broccoli/node-modules-dest-copy.ts +++ b/lib/tools/broccoli/node-modules-dest-copy.ts @@ -4,7 +4,7 @@ import fs = require("fs"); import * as path from "path"; import semver = require("semver"); -import shelljs = require("shelljs"); +import * as shelljs from "shelljs"; import {wrapBroccoliPlugin} from './broccoli-plugin-wrapper-factory'; import constants = require("../../constants"); @@ -15,10 +15,10 @@ import constants = require("../../constants"); export class DestCopy implements IBroccoliPlugin { private dependencies: IDictionary = null; private devDependencies: IDictionary = null; - - constructor(private inputPath: string, - private cachePath: string, - private outputRoot: string, + + constructor(private inputPath: string, + private cachePath: string, + private outputRoot: string, private projectDir: string, private platform: string, private $fs: IFileSystem, @@ -27,7 +27,7 @@ export class DestCopy implements IBroccoliPlugin { this.dependencies = Object.create(null); this.devDependencies = this.getDevDependencies(projectDir); } - + public rebuildChangedDirectories(changedDirectories: string[], platform: string): void { _.each(changedDirectories, changedDirectoryAbsolutePath => { if(!this.devDependencies[path.basename(changedDirectoryAbsolutePath)]) { @@ -35,10 +35,10 @@ export class DestCopy implements IBroccoliPlugin { let packageJsonFiles = fs.existsSync(pathToPackageJson) ? [pathToPackageJson] : []; let nodeModulesFolderPath = path.join(changedDirectoryAbsolutePath, constants.NODE_MODULES_FOLDER_NAME); packageJsonFiles = packageJsonFiles.concat(this.enumeratePackageJsonFilesSync(nodeModulesFolderPath)); - + _.each(packageJsonFiles, packageJsonFilePath => { let fileContent = require(packageJsonFilePath); - + if(!this.devDependencies[fileContent.name]) { // Don't flatten dev dependencies let currentDependency = { name: fileContent.name, @@ -46,17 +46,17 @@ export class DestCopy implements IBroccoliPlugin { directory: path.dirname(packageJsonFilePath), nativescript: fileContent.nativescript }; - + let addedDependency = this.dependencies[currentDependency.name]; if (addedDependency) { if (semver.gt(currentDependency.version, addedDependency.version)) { let currentDependencyMajorVersion = semver.major(currentDependency.version); let addedDependencyMajorVersion = semver.major(addedDependency.version); - + let message = `The depedency located at ${addedDependency.directory} with version ${addedDependency.version} will be replaced with dependency located at ${currentDependency.directory} with version ${currentDependency.version}`; let logger = $injector.resolve("$logger"); currentDependencyMajorVersion === addedDependencyMajorVersion ? logger.out(message) : logger.warn(message); - + this.dependencies[currentDependency.name] = currentDependency; } } else { @@ -66,7 +66,7 @@ export class DestCopy implements IBroccoliPlugin { }); } }); - + _.each(this.dependencies, dependency => { shelljs.cp("-Rf", dependency.directory, this.outputRoot); shelljs.rm("-rf", path.join(this.outputRoot, dependency.name, "node_modules")); @@ -79,30 +79,30 @@ export class DestCopy implements IBroccoliPlugin { let tnsCoreModulesResourcePath = path.join(this.outputRoot, constants.TNS_CORE_MODULES_NAME); shelljs.cp("-Rf", path.join(tnsCoreModulesResourcePath, "*"), this.outputRoot); this.$fs.deleteDirectory(tnsCoreModulesResourcePath).wait(); - } + } }); - + if(!_.isEmpty(this.dependencies)) { this.$pluginsService.afterPrepareAllPlugins().wait(); } } - public rebuild(treeDiff: IDiffResult): void { + public rebuild(treeDiff: IDiffResult): void { this.rebuildChangedDirectories(treeDiff.changedDirectories, ""); - + // Cache input tree - let projectFilePath = path.join(this.projectDir, constants.PACKAGE_JSON_FILE_NAME); + let projectFilePath = path.join(this.projectDir, constants.PACKAGE_JSON_FILE_NAME); let projectFileContent = require(projectFilePath); - projectFileContent[constants.NATIVESCRIPT_KEY_NAME][constants.NODE_MODULE_CACHE_PATH_KEY_NAME] = this.inputPath; - fs.writeFileSync(projectFilePath, JSON.stringify(projectFileContent, null, "\t"), { encoding: "utf8" }); + projectFileContent[constants.NATIVESCRIPT_KEY_NAME][constants.NODE_MODULE_CACHE_PATH_KEY_NAME] = this.inputPath; + fs.writeFileSync(projectFilePath, JSON.stringify(projectFileContent, null, "\t"), { encoding: "utf8" }); } - + private getDevDependencies(projectDir: string): IDictionary { - let projectFilePath = path.join(projectDir, constants.PACKAGE_JSON_FILE_NAME); + let projectFilePath = path.join(projectDir, constants.PACKAGE_JSON_FILE_NAME); let projectFileContent = require(projectFilePath); - return projectFileContent.devDependencies || {}; + return projectFileContent.devDependencies || {}; } - + private enumeratePackageJsonFilesSync(nodeModulesDirectoryPath: string, foundFiles?: string[]): string[] { foundFiles = foundFiles || []; if(fs.existsSync(nodeModulesDirectoryPath)) { @@ -112,7 +112,7 @@ export class DestCopy implements IBroccoliPlugin { if (fs.existsSync(packageJsonFilePath)) { foundFiles.push(packageJsonFilePath); } - + let directoryPath = path.join(nodeModulesDirectoryPath, contents[i], constants.NODE_MODULES_FOLDER_NAME); if (fs.existsSync(directoryPath)) { this.enumeratePackageJsonFilesSync(directoryPath, foundFiles); diff --git a/lib/tools/broccoli/tree-differ.ts b/lib/tools/broccoli/tree-differ.ts index 18dfedf3da..8e9cd5b999 100644 --- a/lib/tools/broccoli/tree-differ.ts +++ b/lib/tools/broccoli/tree-differ.ts @@ -22,10 +22,9 @@ export class TreeDiffer { let result = new DirtyCheckingDiffResult(); let cachedDirectories = fs.existsSync(rootDir) ? fs.readdirSync(rootDir) : []; // rootPath is funnel_output-path let currentDirectories = fs.existsSync(absoluteOutputPath) ? fs.readdirSync(absoluteOutputPath) : []; // the node_modules in output directory - - result.changedDirectories = _.difference(cachedDirectories, currentDirectories); + + result.changedDirectories = _.difference(cachedDirectories, currentDirectories); result.removedDirectories = _.difference(currentDirectories, cachedDirectories); - return result; } } diff --git a/lib/tools/broccoli/trees/node-modules-tree.ts b/lib/tools/broccoli/trees/node-modules-tree.ts index a03f3f465c..d38e1a4f00 100644 --- a/lib/tools/broccoli/trees/node-modules-tree.ts +++ b/lib/tools/broccoli/trees/node-modules-tree.ts @@ -2,14 +2,13 @@ "use strict"; let Funnel = require("broccoli-funnel"); - import destCopy from "../node-modules-dest-copy"; -export class NodeModulesTree implements INodeModulesTree { +export class NodeModulesTree implements INodeModulesTree { public makeNodeModulesTree(absoluteOutputPath: string, projectDir: string): any { let nodeModulesFunnel = new Funnel(projectDir, { include: ["node_modules/**"] }); - let result = destCopy(nodeModulesFunnel, absoluteOutputPath, "node_modules", projectDir); - return result; + let result = destCopy(nodeModulesFunnel, absoluteOutputPath, "node_modules", projectDir); + return result; } } $injector.register("nodeModulesTree", NodeModulesTree); diff --git a/test/android-project-properties-manager.ts b/test/android-project-properties-manager.ts index 5539df7680..56a7e3b2d7 100644 --- a/test/android-project-properties-manager.ts +++ b/test/android-project-properties-manager.ts @@ -26,114 +26,119 @@ function createTestInjector(): IInjector { testInjector.register("logger", LoggerLib.Logger); testInjector.register("config", ConfigLib.Configuration); testInjector.register("options", OptionsLib.Options); - + return testInjector; } describe("Android project properties parser tests", () => { it("adds project reference", () => { let testInjector = createTestInjector(); - let fs = testInjector.resolve("fs"); - + let fs = testInjector.resolve("fs"); + let projectPropertiesFileContent = 'target=android-21'; - let tempFolder = temp.mkdirSync("AndroidProjectPropertiesManager"); + let tempFolder = temp.mkdirSync("AndroidProjectPropertiesManager"); fs.writeFile(path.join(tempFolder, "project.properties"), projectPropertiesFileContent).wait(); - - let projectPropertiesManager = testInjector.resolve(ProjectPropertiesManagerLib.AndroidProjectPropertiesManager, {directoryPath: tempFolder}); + + let projectPropertiesManager: IAndroidProjectPropertiesManager = testInjector.resolve( + ProjectPropertiesManagerLib.AndroidProjectPropertiesManager, {directoryPath: tempFolder}); projectPropertiesManager.addProjectReference("testValue").wait(); - + let expectedContent = 'target=android-21' + '\n' + 'android.library.reference.1=testValue'; let actualContent = fs.readText(path.join(tempFolder, "project.properties")).wait(); - + assert.equal(expectedContent, actualContent); assert.equal(1, _.keys(projectPropertiesManager.getProjectReferences().wait()).length); }); it("adds project reference if another referencence already exists in project.properties file", () => { let testInjector = createTestInjector(); - let fs = testInjector.resolve("fs"); - + let fs = testInjector.resolve("fs"); + let projectPropertiesFileContent = 'target=android-21' + '\n' + 'android.library.reference.1=someValue'; - let tempFolder = temp.mkdirSync("AndroidProjectPropertiesManager"); + let tempFolder = temp.mkdirSync("AndroidProjectPropertiesManager"); fs.writeFile(path.join(tempFolder, "project.properties"), projectPropertiesFileContent).wait(); - - let projectPropertiesManager = testInjector.resolve(ProjectPropertiesManagerLib.AndroidProjectPropertiesManager, {directoryPath: tempFolder}); + + let projectPropertiesManager = testInjector.resolve( + ProjectPropertiesManagerLib.AndroidProjectPropertiesManager, {directoryPath: tempFolder}); projectPropertiesManager.addProjectReference("testValue").wait(); - + let expectedContent = ['target=android-21', 'android.library.reference.1=someValue', 'android.library.reference.2=testValue'].join('\n'); let actualContent = fs.readText(path.join(tempFolder, "project.properties")).wait(); - + assert.equal(expectedContent, actualContent); assert.equal(2, _.keys(projectPropertiesManager.getProjectReferences().wait()).length); }); it("adds project reference if more than one references exist in project.properties file", () => { let testInjector = createTestInjector(); - let fs = testInjector.resolve("fs"); - - let projectPropertiesFileContent = ['target=android-21', + let fs = testInjector.resolve("fs"); + + let projectPropertiesFileContent = ['target=android-21', 'android.library.reference.1=value1', - 'android.library.reference.2=value2', + 'android.library.reference.2=value2', 'android.library.reference.3=value3', 'android.library.reference.4=value4', 'android.library.reference.5=value5'].join('\n'); - let tempFolder = temp.mkdirSync("AndroidProjectPropertiesManager"); + let tempFolder = temp.mkdirSync("AndroidProjectPropertiesManager"); fs.writeFile(path.join(tempFolder, "project.properties"), projectPropertiesFileContent).wait(); - - let projectPropertiesManager: IAndroidProjectPropertiesManager = testInjector.resolve(ProjectPropertiesManagerLib.AndroidProjectPropertiesManager, {directoryPath: tempFolder}); + + let projectPropertiesManager: IAndroidProjectPropertiesManager = testInjector.resolve( + ProjectPropertiesManagerLib.AndroidProjectPropertiesManager, {directoryPath: tempFolder}); projectPropertiesManager.addProjectReference("testValue").wait(); - - let expectedContent = projectPropertiesFileContent + '\n' + + + let expectedContent = projectPropertiesFileContent + '\n' + 'android.library.reference.6=testValue'; - + let actualContent = fs.readText(path.join(tempFolder, "project.properties")).wait(); - + assert.equal(expectedContent, actualContent); assert.equal(6, _.keys(projectPropertiesManager.getProjectReferences().wait()).length); }); it("removes project reference if only one reference exists", () => { let testInjector = createTestInjector(); - let fs = testInjector.resolve("fs"); - - let projectPropertiesFileContent = 'android.library.reference.1=value1' + '\n' + + let fs = testInjector.resolve("fs"); + + let projectPropertiesFileContent = 'android.library.reference.1=value1' + '\n' + 'target=android-21'; - let tempFolder = temp.mkdirSync("AndroidProjectPropertiesManager"); + let tempFolder = temp.mkdirSync("AndroidProjectPropertiesManager"); fs.writeFile(path.join(tempFolder, "project.properties"), projectPropertiesFileContent).wait(); - - let projectPropertiesManager: IAndroidProjectPropertiesManager = testInjector.resolve(ProjectPropertiesManagerLib.AndroidProjectPropertiesManager, {directoryPath: tempFolder}); + + let projectPropertiesManager: IAndroidProjectPropertiesManager = testInjector.resolve( + ProjectPropertiesManagerLib.AndroidProjectPropertiesManager, {directoryPath: tempFolder}); projectPropertiesManager.removeProjectReference("value1").wait(); - + let expectedContent = 'target=android-21'; let actualContent = fs.readText(path.join(tempFolder, "project.properties")).wait(); - + assert.equal(expectedContent, actualContent); assert.equal(0, _.keys(projectPropertiesManager.getProjectReferences().wait()).length); }); it("removes project reference when another references exist before and after the specified reference", () => { let testInjector = createTestInjector(); - let fs = testInjector.resolve("fs"); - + let fs = testInjector.resolve("fs"); + let projectPropertiesFileContent = ['target=android-17', 'android.library.reference.1=value1', - 'android.library.reference.2=value2', + 'android.library.reference.2=value2', 'android.library.reference.3=value3', 'android.library.reference.4=value4', 'android.library.reference.5=value5'].join('\n'); - let tempFolder = temp.mkdirSync("AndroidProjectPropertiesManager"); + let tempFolder = temp.mkdirSync("AndroidProjectPropertiesManager"); fs.writeFile(path.join(tempFolder, "project.properties"), projectPropertiesFileContent).wait(); - - let projectPropertiesManager: IAndroidProjectPropertiesManager = testInjector.resolve(ProjectPropertiesManagerLib.AndroidProjectPropertiesManager, {directoryPath: tempFolder}); + + let projectPropertiesManager: IAndroidProjectPropertiesManager = testInjector.resolve( + ProjectPropertiesManagerLib.AndroidProjectPropertiesManager, {directoryPath: tempFolder}); projectPropertiesManager.removeProjectReference("value3").wait(); - + let expectedContent = ['target=android-17', 'android.library.reference.1=value1', 'android.library.reference.2=value2', 'android.library.reference.3=value4', 'android.library.reference.4=value5'].join('\n') + '\n'; let actualContent = fs.readText(path.join(tempFolder, "project.properties")).wait(); - + assert.equal(expectedContent, actualContent); assert.equal(4, _.keys(projectPropertiesManager.getProjectReferences().wait()).length); }); diff --git a/test/ios-project-service.ts b/test/ios-project-service.ts index a9cee4b7d8..cbc01b4081 100644 --- a/test/ios-project-service.ts +++ b/test/ios-project-service.ts @@ -26,9 +26,9 @@ function createTestInjector(projectPath: string, projectName: string): IInjector testInjector.register("errors", ErrorsLib.Errors); testInjector.register("fs", FileSystemLib.FileSystem); testInjector.register("hostInfo", HostInfoLib.HostInfo); - testInjector.register("injector", testInjector); + testInjector.register("injector", testInjector); testInjector.register("iOSEmulatorServices", {}); - testInjector.register("iOSProjectService", iOSProjectServiceLib.IOSProjectService); + testInjector.register("iOSProjectService", iOSProjectServiceLib.IOSProjectService); testInjector.register("logger", LoggerLib.Logger); testInjector.register("options", OptionsLib.Options); testInjector.register("projectData", { @@ -37,7 +37,7 @@ function createTestInjector(projectPath: string, projectName: string): IInjector }); testInjector.register("projectHelper", {}); testInjector.register("staticConfig", ConfigLib.StaticConfig); - + return testInjector; } @@ -47,11 +47,11 @@ describe("Cocoapods support", () => { } else { it("adds plugin with Podfile", () => { let projectName = "projectDirectory"; - let projectPath = temp.mkdirSync(projectName); - + let projectPath = temp.mkdirSync(projectName); + let testInjector = createTestInjector(projectPath, projectName); let fs: IFileSystem = testInjector.resolve("fs"); - + let packageJsonData = { "name": "myProject", "version": "0.1.0", @@ -63,43 +63,46 @@ describe("Cocoapods support", () => { } }; fs.writeJson(path.join(projectPath, "package.json"), packageJsonData).wait(); - + let platformsFolderPath = path.join(projectPath, "ios"); fs.createDirectory(platformsFolderPath).wait(); - + let iOSProjectService = testInjector.resolve("iOSProjectService"); iOSProjectService.prepareDynamicFrameworks = (pluginPlatformsFolderPath: string, pluginData: IPluginData): IFuture => { return Future.fromResult(); }; - + let pluginPath = temp.mkdirSync("pluginDirectory"); let pluginPlatformsFolderPath = path.join(pluginPath, "platforms", "ios"); let pluginPodfilePath = path.join(pluginPlatformsFolderPath, "Podfile"); let pluginPodfileContent = ["source 'https://github.com/CocoaPods/Specs.git'", "platform :ios, '8.1'", "pod 'GoogleMaps'"].join("\n"); - fs.writeFile(pluginPodfilePath, pluginPodfileContent).wait(); - + fs.writeFile(pluginPodfilePath, pluginPodfileContent).wait(); + let pluginData = { pluginPlatformsFolderPath(platform: string): string { return pluginPlatformsFolderPath; } }; - + iOSProjectService.preparePluginNativeCode(pluginData).wait(); - + let projectPodfilePath = path.join(platformsFolderPath, "Podfile"); assert.isTrue(fs.exists(projectPodfilePath).wait()); - + let actualProjectPodfileContent = fs.readText(projectPodfilePath).wait(); - let expectedProjectPodfileContent = [`# Begin Podfile - ${pluginPodfilePath} `, ` ${pluginPodfileContent} `, " # End Podfile \n"].join("\n"); + let expectedProjectPodfileContent = [`# Begin Podfile - ${pluginPodfilePath} `, + ` ${pluginPodfileContent} `, + " # End Podfile \n"] + .join("\n"); assert.equal(actualProjectPodfileContent, expectedProjectPodfileContent); - }); + }); it("adds and removes plugin with Podfile", () => { let projectName = "projectDirectory2"; - let projectPath = temp.mkdirSync(projectName); - + let projectPath = temp.mkdirSync(projectName); + let testInjector = createTestInjector(projectPath, projectName); let fs: IFileSystem = testInjector.resolve("fs"); - + let packageJsonData = { "name": "myProject2", "version": "0.1.0", @@ -111,10 +114,10 @@ describe("Cocoapods support", () => { } }; fs.writeJson(path.join(projectPath, "package.json"), packageJsonData).wait(); - + let platformsFolderPath = path.join(projectPath, "ios"); fs.createDirectory(platformsFolderPath).wait(); - + let iOSProjectService = testInjector.resolve("iOSProjectService"); iOSProjectService.prepareDynamicFrameworks = (pluginPlatformsFolderPath: string, pluginData: IPluginData): IFuture => { return Future.fromResult(); @@ -122,31 +125,34 @@ describe("Cocoapods support", () => { iOSProjectService.removeDynamicFrameworks = (pluginPlatformsFolderPath: string, pluginData: IPluginData): IFuture => { return Future.fromResult(); }; - + let pluginPath = temp.mkdirSync("pluginDirectory"); let pluginPlatformsFolderPath = path.join(pluginPath, "platforms", "ios"); let pluginPodfilePath = path.join(pluginPlatformsFolderPath, "Podfile"); let pluginPodfileContent = ["source 'https://github.com/CocoaPods/Specs.git'", "platform :ios, '8.1'", "pod 'GoogleMaps'"].join("\n"); - fs.writeFile(pluginPodfilePath, pluginPodfileContent).wait(); - + fs.writeFile(pluginPodfilePath, pluginPodfileContent).wait(); + let pluginData = { pluginPlatformsFolderPath(platform: string): string { return pluginPlatformsFolderPath; } }; - + iOSProjectService.preparePluginNativeCode(pluginData).wait(); - + let projectPodfilePath = path.join(platformsFolderPath, "Podfile"); assert.isTrue(fs.exists(projectPodfilePath).wait()); - + let actualProjectPodfileContent = fs.readText(projectPodfilePath).wait(); - let expectedProjectPodfileContent = [`# Begin Podfile - ${pluginPodfilePath} `, ` ${pluginPodfileContent} `, " # End Podfile \n"].join("\n"); + let expectedProjectPodfileContent = [`# Begin Podfile - ${pluginPodfilePath} `, + ` ${pluginPodfileContent} `, + " # End Podfile \n"] + .join("\n"); assert.equal(actualProjectPodfileContent, expectedProjectPodfileContent); - + iOSProjectService.removePluginNativeCode(pluginData).wait(); - + assert.isFalse(fs.exists(projectPodfilePath).wait()); - }); + }); } }); diff --git a/test/npm-support.ts b/test/npm-support.ts index fe252eded8..21d5f3ca04 100644 --- a/test/npm-support.ts +++ b/test/npm-support.ts @@ -30,7 +30,6 @@ let assert = require("chai").assert; function createTestInjector(): IInjector { let testInjector = new yok.Yok(); - testInjector.register("fs", FsLib.FileSystem); testInjector.register("options", OptionsLib.Options); testInjector.register("errors", ErrorsLib.Errors); @@ -44,8 +43,8 @@ function createTestInjector(): IInjector { testInjector.register("prompter", {}); testInjector.register("androidProjectService", {}); testInjector.register("iOSProjectService", {}); - testInjector.register("devicesServices", {}); - testInjector.register("resources", {}); + testInjector.register("devicesServices", {}); + testInjector.register("resources", {}); testInjector.register("projectData", ProjectDataLib.ProjectData); testInjector.register("projectHelper", ProjectHelperLib.ProjectHelper); testInjector.register("projectDataService", ProjectDataServiceLib.ProjectDataService); @@ -60,19 +59,19 @@ function createTestInjector(): IInjector { testInjector.register("commandsServiceProvider", { registerDynamicSubCommands: () => { /* intentionally left blank */ } }); - + return testInjector; } function createProject(testInjector: IInjector, dependencies?: any): string { - let tempFolder = temp.mkdirSync("npmSupportTests"); + let tempFolder = temp.mkdirSync("npmSupportTests"); let options = testInjector.resolve("options"); - options.path = tempFolder; - + options.path = tempFolder; + dependencies = dependencies || { "lodash": "3.9.3" }; - + let packageJsonData: any = { "name": "testModuleName", "version": "0.1.0", @@ -85,7 +84,7 @@ function createProject(testInjector: IInjector, dependencies?: any): string { }; packageJsonData["dependencies"] = dependencies; packageJsonData["devDependencies"] = {}; - + testInjector.resolve("fs").writeJson(path.join(tempFolder, "package.json"), packageJsonData).wait(); return tempFolder; } @@ -94,21 +93,21 @@ function setupProject(): IFuture { return (() => { let testInjector = createTestInjector(); let projectFolder = createProject(testInjector); - - let fs = testInjector.resolve("fs"); - + + let fs = testInjector.resolve("fs"); + // Creates app folder let appFolderPath = path.join(projectFolder, "app"); fs.createDirectory(appFolderPath).wait(); - let appResourcesFolderPath = path.join(appFolderPath, "App_Resources"); + let appResourcesFolderPath = path.join(appFolderPath, "App_Resources"); fs.createDirectory(appResourcesFolderPath).wait(); fs.createDirectory(path.join(appResourcesFolderPath, "Android")).wait(); fs.createDirectory(path.join(appFolderPath, "tns_modules")).wait(); - + // Creates platforms/android folder let androidFolderPath = path.join(projectFolder, "platforms", "android"); fs.ensureDirectoryExists(androidFolderPath).wait(); - + // Mock platform data let appDestinationFolderPath = path.join(androidFolderPath, "assets"); let platformsData = testInjector.resolve("platformsData"); @@ -125,7 +124,7 @@ function setupProject(): IFuture { } }; }; - + return { testInjector: testInjector, projectFolder: projectFolder, @@ -139,10 +138,10 @@ function addDependencies(testInjector: IInjector, projectFolder: string, depende let fs = testInjector.resolve("fs"); let packageJsonPath = path.join(projectFolder, "package.json"); let packageJsonData = fs.readJson(packageJsonPath).wait(); - + let currentDependencies = packageJsonData.dependencies; _.extend(currentDependencies, dependencies); - + if(devDependencies) { let currentDevDependencies = packageJsonData.devDependencies; _.extend(currentDevDependencies, devDependencies); @@ -167,18 +166,18 @@ describe("Npm support tests", () => { it("Ensures that the installed dependencies are prepared correctly", () => { // Setup addDependencies(testInjector, projectFolder, {"bplist": "0.0.4"}).wait(); - + // Act preparePlatform(testInjector).wait(); - + // Assert - let tnsModulesFolderPath = path.join(appDestinationFolderPath, "app", "tns_modules"); + let tnsModulesFolderPath = path.join(appDestinationFolderPath, "app", "tns_modules"); let lodashFolderPath = path.join(tnsModulesFolderPath, "lodash"); let bplistFolderPath = path.join(tnsModulesFolderPath, "bplist"); let bplistCreatorFolderPath = path.join(tnsModulesFolderPath, "bplist-creator"); let bplistParserFolderPath = path.join(tnsModulesFolderPath, "bplist-parser"); - - let fs = testInjector.resolve("fs"); + + let fs = testInjector.resolve("fs"); assert.isTrue(fs.exists(lodashFolderPath).wait()); assert.isTrue(fs.exists(bplistFolderPath).wait()); assert.isTrue(fs.exists(bplistCreatorFolderPath).wait()); @@ -192,49 +191,49 @@ describe("Flatten npm modules tests", () => { let testInjector = projectSetup.testInjector; let projectFolder = projectSetup.projectFolder; let appDestinationFolderPath = projectSetup.appDestinationFolderPath; - + let devDependencies = { "gulp": "3.9.0", "gulp-jscs": "1.6.0", "gulp-jshint": "1.11.0" }; - + addDependencies(testInjector, projectFolder, {}, devDependencies).wait(); - + preparePlatform(testInjector).wait(); - + // Assert let fs = testInjector.resolve("fs"); let tnsModulesFolderPath = path.join(appDestinationFolderPath, "app", "tns_modules"); - + let lodashFolderPath = path.join(tnsModulesFolderPath, "lodash"); assert.isTrue(fs.exists(lodashFolderPath).wait()); - + let gulpFolderPath = path.join(tnsModulesFolderPath, "gulp"); assert.isFalse(fs.exists(gulpFolderPath).wait()); - + let gulpJscsFolderPath = path.join(tnsModulesFolderPath, "gulp-jscs"); assert.isFalse(fs.exists(gulpJscsFolderPath).wait()); - + let gulpJshint = path.join(tnsModulesFolderPath, "gulp-jshint"); assert.isFalse(fs.exists(gulpJshint).wait()); - + // Get all gulp dependencies let gulpDependencies = fs.readDirectory(path.join(projectFolder, "node_modules", "gulp", "node_modules")).wait(); _.each(gulpDependencies, dependency => { assert.isFalse(fs.exists(path.join(tnsModulesFolderPath, dependency)).wait()); }); - + // Get all gulp-jscs dependencies let gulpJscsDependencies = fs.readDirectory(path.join(projectFolder, "node_modules", "gulp-jscs", "node_modules")).wait(); _.each(gulpJscsDependencies, dependency => { assert.isFalse(fs.exists(path.join(tnsModulesFolderPath, dependency)).wait()); }); - + // Get all gulp-jshint dependencies let gulpJshintDependencies = fs.readDirectory(path.join(projectFolder, "node_modules", "gulp-jshint", "node_modules")).wait(); _.each(gulpJshintDependencies, dependency => { assert.isFalse(fs.exists(path.join(tnsModulesFolderPath, dependency)).wait()); - }); + }); }); }); diff --git a/test/platform-commands.ts b/test/platform-commands.ts index 611b059837..f16b66bd34 100644 --- a/test/platform-commands.ts +++ b/test/platform-commands.ts @@ -49,7 +49,7 @@ class ErrorsNoFailStub implements IErrors { /* intentionally left blank */ } - return result; + return result; }).future()(); } @@ -72,7 +72,7 @@ class PlatformsData implements IPlatformsData { return null; } - + public get availablePlatforms(): any { return undefined; } @@ -98,7 +98,7 @@ function createTestInjector() { testInjector.registerCommand("platform|remove", PlatformRemoveCommandLib.RemovePlatformCommand); testInjector.registerCommand("platform|update", PlatformUpdateCommandLib.UpdatePlatformCommand); testInjector.register("lockfile", { }); - testInjector.register("resources", {}); + testInjector.register("resources", {}); testInjector.register("commandsServiceProvider", { registerDynamicSubCommands: () => { /* intentionally left blank */ } }); diff --git a/test/platform-service.ts b/test/platform-service.ts index 0fa242c709..99087fc0a1 100644 --- a/test/platform-service.ts +++ b/test/platform-service.ts @@ -12,7 +12,7 @@ import ProjectFilesManagerLib = require("../lib/services/project-files-manager") import * as path from "path"; import Future = require("fibers/future"); import {assert} from "chai"; -require('should'); +require("should"); let temp = require("temp"); temp.track(); @@ -172,7 +172,7 @@ describe('Platform Service Tests', () => { }); }); }); - + describe("prepare platform unit tests", () => { let fs: IFileSystem; beforeEach(() => { @@ -182,32 +182,32 @@ describe('Platform Service Tests', () => { }); it("should process only files in app folder when preparing for iOS 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"); - + // Add platform specific files to app and app1 folders let platformSpecificFiles = [ "test1.ios.js", "test1-ios-js", "test2.android.js", "test2-android-js" ]; - + let destinationDirectories = [appFolderPath, app1FolderPath]; - + _.each(destinationDirectories, directoryPath => { _.each(platformSpecificFiles, filePath => { let fileFullPath = path.join(directoryPath, filePath); fs.writeFile(fileFullPath, "testData").wait(); }); }); - + let platformsData = testInjector.resolve("platformsData"); - platformsData.platformsNames = ["ios", "android"]; + platformsData.platformsNames = ["ios", "android"]; platformsData.getPlatformData = (platform: string) => { return { appDestinationDirectoryPath: appDestFolderPath, @@ -222,50 +222,50 @@ describe('Platform Service Tests', () => { } }; }; - + let projectData = testInjector.resolve("projectData"); projectData.projectDir = tempFolder; - + platformService = testInjector.resolve("platformService"); platformService.preparePlatform("ios").wait(); - + // Asserts that the files in app folder are process as platform specific assert.isTrue(fs.exists(path.join(appDestFolderPath, "app" , "test1.js")).wait()); assert.isFalse(fs.exists(path.join(appDestFolderPath, "app", "test1-js")).wait()); assert.isFalse(fs.exists(path.join(appDestFolderPath, "app", "test2.js")).wait()); assert.isFalse(fs.exists(path.join(appDestFolderPath, "app", "test2-js")).wait()); - + // Asserts that the files in app1 folder aren't process as platform specific 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"); - + // Add platform specific files to app and app1 folders let platformSpecificFiles = [ "test1.ios.js", "test1-ios-js", "test2.android.js", "test2-android-js" ]; - + let destinationDirectories = [appFolderPath, app1FolderPath]; - + _.each(destinationDirectories, directoryPath => { _.each(platformSpecificFiles, filePath => { let fileFullPath = path.join(directoryPath, filePath); fs.writeFile(fileFullPath, "testData").wait(); }); }); - + let platformsData = testInjector.resolve("platformsData"); - platformsData.platformsNames = ["ios", "android"]; + platformsData.platformsNames = ["ios", "android"]; platformsData.getPlatformData = (platform: string) => { return { appDestinationDirectoryPath: appDestFolderPath, @@ -278,21 +278,21 @@ describe('Platform Service Tests', () => { interpolateData: (projectRoot: string) => Future.fromResult(), afterCreateProject: (projectRoot: string) => Future.fromResult() } - }; + }; }; - + let projectData = testInjector.resolve("projectData"); projectData.projectDir = tempFolder; - + platformService = testInjector.resolve("platformService"); platformService.preparePlatform("android").wait(); - + // Asserts that the files in app folder are process as platform specific assert.isTrue(fs.exists(path.join(appDestFolderPath, "app" , "test2.js")).wait()); assert.isFalse(fs.exists(path.join(appDestFolderPath, "app", "test2-js")).wait()); assert.isFalse(fs.exists(path.join(appDestFolderPath, "app", "test1.js")).wait()); assert.isFalse(fs.exists(path.join(appDestFolderPath, "app", "test1-js")).wait()); - + // Asserts that the files in app1 folder aren't process as platform specific assert.isFalse(fs.exists(path.join(appDestFolderPath, "app1")).wait()); }); diff --git a/test/plugins-service.ts b/test/plugins-service.ts index d6bedebc9c..741e32ca1b 100644 --- a/test/plugins-service.ts +++ b/test/plugins-service.ts @@ -28,11 +28,11 @@ import * as path from "path"; import * as temp from "temp"; temp.track(); -let isErrorThrown = false; +let isErrorThrown = false; function createTestInjector() { let testInjector = new Yok(); - + testInjector.register("npm", NodePackageManager); testInjector.register("fs", FileSystem); testInjector.register("projectData", ProjectData); @@ -45,7 +45,7 @@ function createTestInjector() { testInjector.register("devicesServices", {}); testInjector.register("projectDataService", ProjectDataService); testInjector.register("prompter", {}); - testInjector.register("resources", ResourceLoader); + testInjector.register("resources", ResourceLoader); testInjector.register("broccoliBuilder", {}); testInjector.register("options", Options); testInjector.register("errors", Errors); @@ -59,7 +59,7 @@ function createTestInjector() { testInjector.register("hostInfo", HostInfo); testInjector.register("lockfile", { }); testInjector.register("projectHelper", ProjectHelper); - + testInjector.register("pluginsService", PluginsService); testInjector.register("analyticsService", { trackException: () => { return future.fromResult(); }, @@ -67,15 +67,15 @@ function createTestInjector() { trackFeature: () => { return future.fromResult(); } }); testInjector.register("projectFilesManager", ProjectFilesManager); - + return testInjector; } function createProjectFile(testInjector: IInjector): string { - let tempFolder = temp.mkdirSync("pluginsService"); + let tempFolder = temp.mkdirSync("pluginsService"); let options = testInjector.resolve("options"); - options.path = tempFolder; - + options.path = tempFolder; + let packageJsonData = { "name": "testModuleName", "version": "0.1.0", @@ -86,7 +86,7 @@ function createProjectFile(testInjector: IInjector): string { } } }; - + testInjector.resolve("fs").writeJson(path.join(tempFolder, "package.json"), packageJsonData).wait(); return tempFolder; } @@ -107,9 +107,9 @@ function mockBeginCommand(testInjector: IInjector, expectedErrorMessage: string) function addPluginWhenExpectingToFail(testInjector: IInjector, plugin: string, expectedErrorMessage: string) { createProjectFile(testInjector); - + let pluginsService = testInjector.resolve("pluginsService"); - pluginsService.getAllInstalledPlugins = () => { + pluginsService.getAllInstalledPlugins = () => { return (() => { return [{ name: "" @@ -119,10 +119,10 @@ function addPluginWhenExpectingToFail(testInjector: IInjector, plugin: string, e pluginsService.ensureAllDependenciesAreInstalled = () => { return future.fromResult(); }; - - mockBeginCommand(testInjector, "Exception: " + expectedErrorMessage); - - isErrorThrown = false; + + mockBeginCommand(testInjector, "Exception: " + expectedErrorMessage); + + isErrorThrown = false; let commandsService = testInjector.resolve(CommandsService); commandsService.tryExecuteCommand("plugin|add", [plugin]).wait(); @@ -131,23 +131,23 @@ function addPluginWhenExpectingToFail(testInjector: IInjector, plugin: string, e function createAndroidManifestFile(projectFolder: string, fs:IFileSystem): void { let manifest = '' + - '' + + '' + '' + '' + '' + '' + - '' + + '' + '' + '' + '' + - '' + - '' + + '' + + '' + '' + - '' + - '' + - '' + + '' + + '' + + '' + ''; - + fs.createDirectory(path.join(projectFolder, "platforms")).wait(); fs.createDirectory(path.join(projectFolder, "platforms", "android")).wait(); fs.writeFile(path.join(projectFolder, "platforms", "android", "AndroidManifest.xml"), manifest).wait(); @@ -159,11 +159,11 @@ describe("Plugins service", () => { testInjector = createTestInjector(); testInjector.registerCommand("plugin|add", AddPluginCommand); }); - + describe("plugin add", () => { it("fails when no param is specified to plugin add command", () => { addPluginWhenExpectingToFail(testInjector, null, "You must specify plugin name."); - }); + }); it("fails when invalid nativescript plugin name is specified", () => { addPluginWhenExpectingToFail(testInjector, "lodash", "lodash is not a valid NativeScript plugin. Verify that the plugin package.json file contains a nativescript key and try again."); }); @@ -171,36 +171,36 @@ describe("Plugins service", () => { let pluginName = "plugin1"; let projectFolder = createProjectFile(testInjector); let fs = testInjector.resolve("fs"); - - // Add plugin + + // Add plugin let projectFilePath = path.join(projectFolder, "package.json"); let projectData = require(projectFilePath); projectData.dependencies = { }; projectData.dependencies[pluginName] = "^1.0.0"; fs.writeJson(projectFilePath, projectData).wait(); - + let pluginsService = testInjector.resolve("pluginsService"); - pluginsService.getAllInstalledPlugins = () => { + pluginsService.getAllInstalledPlugins = () => { return (() => { return [{ name: "plugin1" }]; }).future()(); }; - - mockBeginCommand(testInjector, "Exception: " + 'Plugin "plugin1" is already installed.'); - - isErrorThrown = false; + + mockBeginCommand(testInjector, "Exception: " + 'Plugin "plugin1" is already installed.'); + + isErrorThrown = false; let commandsService = testInjector.resolve(CommandsService); commandsService.tryExecuteCommand("plugin|add", [pluginName]).wait(); - + assert.isTrue(isErrorThrown); }); it("fails when the plugin does not support the installed framework", () => { let isWarningMessageShown = false; let expectedWarningMessage = "mySamplePlugin 1.0.1 for android is not compatible with the currently installed framework version 1.0.0."; - - // Creates plugin in temp folder + + // Creates plugin in temp folder let pluginName = "mySamplePlugin"; let projectFolder = createProjectFile(testInjector); let pluginFolderPath = path.join(projectFolder, pluginName); @@ -215,28 +215,28 @@ describe("Plugins service", () => { }; let fs = testInjector.resolve("fs"); fs.writeJson(path.join(pluginFolderPath, "package.json"), pluginJsonData).wait(); - + // Adds android platform fs.createDirectory(path.join(projectFolder, "platforms")).wait(); fs.createDirectory(path.join(projectFolder, "platforms", "android")).wait(); - + // Mock logger.warn let logger = testInjector.resolve("logger"); logger.warn = (message: string) => { assert.equal(message, expectedWarningMessage); isWarningMessageShown = true; }; - + // Mock pluginsService let pluginsService = testInjector.resolve("pluginsService"); - pluginsService.getAllInstalledPlugins = () => { + pluginsService.getAllInstalledPlugins = () => { return (() => { return [{ name: "" }]; }).future()(); }; - + // Mock platformsData let platformsData = testInjector.resolve("platformsData"); platformsData.getPlatformData = (platform: string) => { @@ -245,41 +245,41 @@ describe("Plugins service", () => { frameworkPackageName: "tns-android" }; }; - + pluginsService.add(pluginFolderPath).wait(); - + assert.isTrue(isWarningMessageShown); }); it("adds plugin by name", () => { let pluginName = "plugin1"; let projectFolder = createProjectFile(testInjector); - + let pluginsService = testInjector.resolve("pluginsService"); - pluginsService.getAllInstalledPlugins = () => { + pluginsService.getAllInstalledPlugins = () => { return (() => { return [{ name: "" }]; }).future()(); }; - + let commandsService = testInjector.resolve(CommandsService); commandsService.tryExecuteCommand("plugin|add", [pluginName]).wait(); - + let fs = testInjector.resolve("fs"); - + // Asserts that the all plugin's content is successfully added to node_modules folder let nodeModulesFolderPath = path.join(projectFolder, "node_modules"); assert.isTrue(fs.exists(nodeModulesFolderPath).wait()); - + let pluginFolderPath = path.join(nodeModulesFolderPath, pluginName); assert.isTrue(fs.exists(pluginFolderPath).wait()); - + let pluginFiles = ["injex.js", "main.js", "package.json"]; _.each(pluginFiles, pluginFile => { assert.isTrue(fs.exists(path.join(pluginFolderPath, pluginFile)).wait()); }); - + // Asserts that the plugin is added in package.json file let packageJsonContent = fs.readJson(path.join(projectFolder, "package.json")).wait(); let actualDependencies = packageJsonContent.dependencies; @@ -290,33 +290,33 @@ describe("Plugins service", () => { it("adds plugin by name and version", () => { let pluginName = "plugin1"; let projectFolder = createProjectFile(testInjector); - + let pluginsService = testInjector.resolve("pluginsService"); - pluginsService.getAllInstalledPlugins = () => { + pluginsService.getAllInstalledPlugins = () => { return (() => { return [{ name: "" }]; }).future()(); }; - + let commandsService = testInjector.resolve(CommandsService); commandsService.tryExecuteCommand("plugin|add", [pluginName+"@1.0.0"]).wait(); - + let fs = testInjector.resolve("fs"); - + // Assert that the all plugin's content is successfully added to node_modules folder let nodeModulesFolderPath = path.join(projectFolder, "node_modules"); assert.isTrue(fs.exists(nodeModulesFolderPath).wait()); - + let pluginFolderPath = path.join(nodeModulesFolderPath, pluginName); assert.isTrue(fs.exists(pluginFolderPath).wait()); - + let pluginFiles = ["injex.js", "main.js", "package.json"]; _.each(pluginFiles, pluginFile => { assert.isTrue(fs.exists(path.join(pluginFolderPath, pluginFile)).wait()); }); - + // Assert that the plugin is added in package.json file let packageJsonContent = fs.readJson(path.join(projectFolder, "package.json")).wait(); let actualDependencies = packageJsonContent.dependencies; @@ -334,30 +334,30 @@ describe("Plugins service", () => { "version": "0.0.1", "nativescript": { "platforms": { - + } }, }; let fs = testInjector.resolve("fs"); fs.writeJson(path.join(pluginFolderPath, "package.json"), pluginJsonData).wait(); - + let pluginsService = testInjector.resolve("pluginsService"); - pluginsService.getAllInstalledPlugins = () => { + pluginsService.getAllInstalledPlugins = () => { return (() => { return [{ name: "" }]; }).future()(); }; - + let commandsService = testInjector.resolve(CommandsService); commandsService.tryExecuteCommand("plugin|add", [pluginFolderPath]).wait(); - + // Assert that the all plugin's content is successfully added to node_modules folder let nodeModulesFolderPath = path.join(projectFolder, "node_modules"); assert.isTrue(fs.exists(nodeModulesFolderPath).wait()); assert.isTrue(fs.exists(path.join(nodeModulesFolderPath, pluginName)).wait()); - + let pluginFiles = ["package.json"]; _.each(pluginFiles, pluginFile => { assert.isTrue(fs.exists(path.join(nodeModulesFolderPath, pluginName, pluginFile)).wait()); @@ -376,7 +376,7 @@ describe("Plugins service", () => { "version": "0.0.1", "nativescript": { "platforms": { - + } }, "devDependencies": { @@ -385,23 +385,23 @@ describe("Plugins service", () => { }; let fs = testInjector.resolve("fs"); fs.writeJson(path.join(pluginFolderPath, "package.json"), pluginJsonData).wait(); - + let pluginsService = testInjector.resolve("pluginsService"); - pluginsService.getAllInstalledPlugins = () => { + pluginsService.getAllInstalledPlugins = () => { return (() => { return [{ name: "" }]; }).future()(); }; - + // Mock options let options = testInjector.resolve("options"); options.production = true; - + let commandsService = testInjector.resolve(CommandsService); commandsService.tryExecuteCommand("plugin|add", [pluginFolderPath]).wait(); - + let nodeModulesFolderPath = path.join(projectFolder, "node_modules"); assert.isFalse(fs.exists(path.join(nodeModulesFolderPath, pluginName, "node_modules", "grunt")).wait()); }); @@ -415,7 +415,7 @@ describe("Plugins service", () => { "version": "0.0.1", "nativescript": { "platforms": { - + } }, "dependencies": { @@ -427,25 +427,25 @@ describe("Plugins service", () => { }; let fs = testInjector.resolve("fs"); fs.writeJson(path.join(pluginFolderPath, "package.json"), pluginJsonData).wait(); - + let pluginsService = testInjector.resolve("pluginsService"); - pluginsService.getAllInstalledPlugins = () => { + pluginsService.getAllInstalledPlugins = () => { return (() => { return [{ name: "" }]; }).future()(); }; - + // Mock options let options = testInjector.resolve("options"); options.production = false; - + let commandsService = testInjector.resolve(CommandsService); commandsService.tryExecuteCommand("plugin|add", [pluginFolderPath]).wait(); }); }); - + describe("merge xmls tests", () => { beforeEach(() => { testInjector = createTestInjector(); @@ -466,22 +466,22 @@ describe("Plugins service", () => { }; let fs = testInjector.resolve("fs"); fs.writeJson(path.join(pluginFolderPath, "package.json"), pluginJsonData).wait(); - + // Adds AndroidManifest.xml file in platforms/android folder - createAndroidManifestFile(projectFolder, fs); - + createAndroidManifestFile(projectFolder, fs); + // Mock plugins service let pluginsService = testInjector.resolve("pluginsService"); - pluginsService.getAllInstalledPlugins = () => { + pluginsService.getAllInstalledPlugins = () => { return (() => { return [{ name: "" }]; }).future()(); }; - + let appDestinationDirectoryPath = path.join(projectFolder, "platforms", "android"); - + // Mock platformsData let platformsData = testInjector.resolve("platformsData"); platformsData.getPlatformData = (platform: string) => { @@ -491,26 +491,26 @@ describe("Plugins service", () => { configurationFileName: "AndroidManifest.xml" }; }; - + // Ensure the pluginDestinationPath folder exists let pluginPlatformsDirPath = path.join(appDestinationDirectoryPath, "app", "tns_modules", pluginName, "platforms", "android"); fs.ensureDirectoryExists(pluginPlatformsDirPath).wait(); - + // Creates invalid plugin's AndroidManifest.xml file let xml = '' + - '' + + '' + ''; let pluginConfigurationFilePath = path.join(pluginPlatformsDirPath, "AndroidManifest.xml"); fs.writeFile(pluginConfigurationFilePath, xml).wait(); - + // Expected error message. The assertion happens in mockBeginCommand - let expectedErrorMessage = `Exception: Invalid xml file ${pluginConfigurationFilePath}. Additional technical information: element parse error: Exception: Invalid xml file ` + - `${pluginConfigurationFilePath}. Additional technical information: unclosed xml attribute` + - `\n@#[line:1,col:39].` + + let expectedErrorMessage = `Exception: Invalid xml file ${pluginConfigurationFilePath}. Additional technical information: element parse error: Exception: Invalid xml file ` + + `${pluginConfigurationFilePath}. Additional technical information: unclosed xml attribute` + + `\n@#[line:1,col:39].` + `\n@#[line:1,col:39].`; - mockBeginCommand(testInjector, expectedErrorMessage); - - let commandsService = testInjector.resolve(CommandsService); + mockBeginCommand(testInjector, expectedErrorMessage); + + let commandsService = testInjector.resolve(CommandsService); commandsService.tryExecuteCommand("plugin|add", [pluginFolderPath]).wait(); }); it("merges AndroidManifest.xml and produces correct xml", () => { @@ -528,22 +528,22 @@ describe("Plugins service", () => { }; let fs = testInjector.resolve("fs"); fs.writeJson(path.join(pluginFolderPath, "package.json"), pluginJsonData).wait(); - + // Adds AndroidManifest.xml file in platforms/android folder - createAndroidManifestFile(projectFolder, fs); - + createAndroidManifestFile(projectFolder, fs); + // Mock plugins service let pluginsService = testInjector.resolve("pluginsService"); - pluginsService.getAllInstalledPlugins = () => { + pluginsService.getAllInstalledPlugins = () => { return (() => { return [{ name: "" }]; }).future()(); }; - + let appDestinationDirectoryPath = path.join(projectFolder, "platforms", "android"); - + // Mock platformsData let platformsData = testInjector.resolve("platformsData"); platformsData.getPlatformData = (platform: string) => { @@ -558,29 +558,29 @@ describe("Plugins service", () => { } }; }; - + // Ensure the pluginDestinationPath folder exists let pluginPlatformsDirPath = path.join(appDestinationDirectoryPath, "app", "tns_modules", pluginName, "platforms", "android"); fs.ensureDirectoryExists(pluginPlatformsDirPath).wait(); - + // Creates valid plugin's AndroidManifest.xml file let xml = '' + - '' + - '' + + '' + + '' + ''; let pluginConfigurationFilePath = path.join(pluginPlatformsDirPath, "AndroidManifest.xml"); fs.writeFile(pluginConfigurationFilePath, xml).wait(); - + pluginsService.add(pluginFolderPath).wait(); - + let expectedXml = ''; expectedXml = helpers.stringReplaceAll(expectedXml, EOL, ""); expectedXml = helpers.stringReplaceAll(expectedXml, " ", ""); - + let actualXml = fs.readText(path.join(appDestinationDirectoryPath, "AndroidManifest.xml")).wait(); actualXml = helpers.stringReplaceAll(actualXml, "\n", ""); actualXml = helpers.stringReplaceAll(actualXml, " ", ""); - + assert.equal(expectedXml, actualXml); }); }); diff --git a/test/project-files-manager.ts b/test/project-files-manager.ts index 9f6780d6ed..f859fb422b 100644 --- a/test/project-files-manager.ts +++ b/test/project-files-manager.ts @@ -23,17 +23,17 @@ function createTestInjector() { testInjector.register("platformsData", { platformsNames: ["ios", "android"] }); - + return testInjector; } function createFiles(testInjector: IInjector, filesToCreate: string[]): IFuture { return (() => { let fs = testInjector.resolve("fs"); - let directoryPath = temp.mkdirSync("Project Files Manager Tests"); - + let directoryPath = temp.mkdirSync("Project Files Manager Tests"); + _.each(filesToCreate, file => fs.writeFile(path.join(directoryPath, file), "").wait()); - + return directoryPath; }).future()(); } @@ -47,9 +47,9 @@ describe('Project Files Manager Tests', () => { it("filters android specific files", () => { let files = ["test.ios.x", "test.android.x"]; let directoryPath = createFiles(testInjector, files).wait(); - + projectFilesManager.processPlatformSpecificFiles(directoryPath, "android").wait(); - + let fs = testInjector.resolve("fs"); assert.isFalse(fs.exists(path.join(directoryPath, "test.ios.x")).wait()); assert.isTrue(fs.exists(path.join(directoryPath, "test.x")).wait()); @@ -58,9 +58,9 @@ describe('Project Files Manager Tests', () => { it("filters ios specific files", () => { let files = ["index.ios.html", "index1.android.html", "a.test"]; let directoryPath = createFiles(testInjector, files).wait(); - + projectFilesManager.processPlatformSpecificFiles(directoryPath, "ios").wait(); - + let fs = testInjector.resolve("fs"); assert.isFalse(fs.exists(path.join(directoryPath, "index1.android.html")).wait()); assert.isFalse(fs.exists(path.join(directoryPath, "index1.html")).wait()); @@ -69,10 +69,10 @@ describe('Project Files Manager Tests', () => { }); it("doesn't filter non platform specific files", () => { let files = ["index1.js", "index2.js", "index3.js"]; - let directoryPath = createFiles(testInjector, files).wait(); - + let directoryPath = createFiles(testInjector, files).wait(); + projectFilesManager.processPlatformSpecificFiles(directoryPath, "ios").wait(); - + let fs = testInjector.resolve("fs"); assert.isTrue(fs.exists(path.join(directoryPath, "index1.js")).wait()); assert.isTrue(fs.exists(path.join(directoryPath, "index2.js")).wait()); diff --git a/test/project-service.ts b/test/project-service.ts index 2e48204a37..682ab35749 100644 --- a/test/project-service.ts +++ b/test/project-service.ts @@ -103,7 +103,7 @@ class ProjectIntegrationTest { private createTestInjector(): void { this.testInjector = new yok.Yok(); - this.testInjector.register("childProcess", ChildProcessLib.ChildProcess); + this.testInjector.register("childProcess", ChildProcessLib.ChildProcess); this.testInjector.register("errors", stubs.ErrorsStub); this.testInjector.register('logger', stubs.LoggerStub); this.testInjector.register("projectService", ProjectServiceLib.ProjectService); @@ -120,7 +120,7 @@ class ProjectIntegrationTest { this.testInjector.register("httpClient", HttpClientLib.HttpClient); this.testInjector.register("config", {}); this.testInjector.register("lockfile", stubs.LockFile); - + this.testInjector.register("options", optionsLib.Options); this.testInjector.register("hostInfo", hostInfoLib.HostInfo); } @@ -158,7 +158,7 @@ describe("Project Service Tests", () => { function createTestInjector() { let testInjector = new yok.Yok(); - + testInjector.register("errors", stubs.ErrorsStub); testInjector.register('logger', stubs.LoggerStub); testInjector.register("projectService", ProjectServiceLib.ProjectService); @@ -168,7 +168,7 @@ function createTestInjector() { testInjector.register("fs", fsLib.FileSystem); testInjector.register("projectDataService", ProjectDataServiceLib.ProjectDataService); - + testInjector.register("staticConfig", StaticConfigLib.StaticConfig); testInjector.register("npmInstallationManager", NpmInstallationManagerLib.NpmInstallationManager); @@ -177,11 +177,11 @@ function createTestInjector() { testInjector.register("lockfile", stubs.LockFile); testInjector.register("childProcess", ChildProcessLib.ChildProcess); - + testInjector.register('projectData', ProjectDataLib.ProjectData); testInjector.register("options", optionsLib.Options); testInjector.register("hostInfo", hostInfoLib.HostInfo); - + return testInjector; } @@ -192,7 +192,7 @@ describe("project upgrade procedure tests", () => { let options = testInjector.resolve("options"); options.path = tempFolder; let isErrorThrown = false; - + try { testInjector.resolve("projectData"); // This should trigger upgrade procedure } catch(err) { @@ -200,45 +200,45 @@ describe("project upgrade procedure tests", () => { let expectedErrorMessage = "No project found at or above '%s' and neither was a --path specified.," + tempFolder; assert.equal(expectedErrorMessage, err.toString()); } - + assert.isTrue(isErrorThrown); }); it("should upgrade project when .tnsproject file exists but package.json file doesn't exist", () => { let testInjector = createTestInjector(); let fs: IFileSystem = testInjector.resolve("fs"); - - let tempFolder = temp.mkdirSync("projectUpgradeTest2"); + + let tempFolder = temp.mkdirSync("projectUpgradeTest2"); let options = testInjector.resolve("options"); - options.path = tempFolder; + options.path = tempFolder; let tnsProjectData = { "id": "org.nativescript.Test", "tns-ios": { "version": "1.0.0" - } + } }; let tnsProjectFilePath = path.join(tempFolder, ".tnsproject"); fs.writeJson(tnsProjectFilePath, tnsProjectData).wait(); - + testInjector.resolve("projectData"); // This should trigger upgrade procedure - + let packageJsonFilePath = path.join(tempFolder, "package.json"); let packageJsonFileContent = require(packageJsonFilePath); assert.isTrue(fs.exists(packageJsonFilePath).wait()); assert.isFalse(fs.exists(tnsProjectFilePath).wait()); assert.deepEqual(tnsProjectData, packageJsonFileContent["nativescript"]); - }); + }); it("should upgrade project when .tnsproject and package.json exist but nativescript key is not presented in package.json file", () => { let testInjector = createTestInjector(); let fs: IFileSystem = testInjector.resolve("fs"); - - let tempFolder = temp.mkdirSync("projectUpgradeTest3"); + + let tempFolder = temp.mkdirSync("projectUpgradeTest3"); let options = testInjector.resolve("options"); - options.path = tempFolder; + options.path = tempFolder; let tnsProjectData = { "id": "org.nativescript.Test", "tns-ios": { "version": "1.0.1" - } + } }; let packageJsonData = { "name": "testModuleName", @@ -249,12 +249,12 @@ describe("project upgrade procedure tests", () => { }; let tnsProjectFilePath = path.join(tempFolder, ".tnsproject"); fs.writeJson(tnsProjectFilePath, tnsProjectData).wait(); - + let packageJsonFilePath = path.join(tempFolder, "package.json"); fs.writeJson(packageJsonFilePath, packageJsonData).wait(); - + testInjector.resolve("projectData"); // This should trigger upgrade procedure - + let packageJsonFileContent = require(packageJsonFilePath); let expectedPackageJsonContent: any = packageJsonData; expectedPackageJsonContent["nativescript"] = tnsProjectData; @@ -263,12 +263,12 @@ describe("project upgrade procedure tests", () => { it("shouldn't upgrade project when .tnsproject and package.json exist and nativescript key is presented in package.json file", () => { let testInjector = createTestInjector(); let fs: IFileSystem = testInjector.resolve("fs"); - - let tempFolder = temp.mkdirSync("projectUpgradeTest4"); + + let tempFolder = temp.mkdirSync("projectUpgradeTest4"); let options = testInjector.resolve("options"); - options.path = tempFolder; + options.path = tempFolder; let tnsProjectData = { - + }; let packageJsonData = { "name": "testModuleName", @@ -280,17 +280,17 @@ describe("project upgrade procedure tests", () => { "id": "org.nativescript.Test", "tns-ios": { "version": "1.0.2" - } + } } }; - + fs.writeJson(path.join(tempFolder, ".tnsproject"), tnsProjectData).wait(); fs.writeJson(path.join(tempFolder, "package.json"), packageJsonData).wait(); testInjector.resolve("projectData"); // This should trigger upgrade procedure - + let packageJsonFilePath = path.join(tempFolder, "package.json"); let packageJsonFileContent = require(packageJsonFilePath); - + assert.deepEqual(packageJsonData, packageJsonFileContent); }); }); diff --git a/test/stubs.ts b/test/stubs.ts index 87e4b45eef..bf2bfc9439 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -162,7 +162,7 @@ export class FileSystemStub implements IFileSystem { export class ErrorsStub implements IErrors { constructor() { - new (require("../lib/common/errors").Errors)(); // we need the side effect of require'ing errors + new (require("../lib/common/errors").Errors)(); // we need the side effect of require'ing errors } fail(formatStr:string, ...args: any[]): void; @@ -321,7 +321,7 @@ export class PlatformProjectServiceStub implements IPlatformProjectService { } afterPrepareAllPlugins(): IFuture { return Future.fromResult(); - } + } } export class ProjectDataService implements IProjectDataService { diff --git a/tslint.json b/tslint.json index 716eaaa3bf..40b9f253e1 100644 --- a/tslint.json +++ b/tslint.json @@ -16,13 +16,15 @@ "no-empty": true, "no-eval": true, "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, "no-unreachable": true, "no-unused-expression": true, "no-unused-variable": true, "no-use-before-declare": true, "no-var-keyword": true, + "no-var-requires": false, "one-line": [ - false, + true, "check-open-brace", "check-catch", "check-else" @@ -42,11 +44,6 @@ "check-separator", "check-type", "check-typecast" - ], - - - - "no-var-requires": false, - "no-trailing-whitespace": false + ] } } \ No newline at end of file