From e01022369c28bb5e034a55157e55cc30f76ada5e Mon Sep 17 00:00:00 2001 From: Fatme Havaluova Date: Mon, 19 Oct 2015 17:03:15 +0300 Subject: [PATCH 1/4] Fixes https://github.com/NativeScript/nativescript-cli/issues/1066 --- lib/definitions/platform.d.ts | 1 + lib/definitions/project.d.ts | 3 +- lib/services/android-project-service.ts | 21 ++++++++--- lib/services/ios-project-service.ts | 21 +++++++---- lib/services/platform-service.ts | 2 +- lib/services/plugins-service.ts | 50 +++++++++++++------------ lib/tools/broccoli/builder.ts | 1 - test/platform-commands.ts | 1 + test/plugins-service.ts | 39 ++++++++++++++----- test/stubs.ts | 9 ++++- 10 files changed, 98 insertions(+), 50 deletions(-) diff --git a/lib/definitions/platform.d.ts b/lib/definitions/platform.d.ts index 2e3d1e73da..a8b8584e11 100644 --- a/lib/definitions/platform.d.ts +++ b/lib/definitions/platform.d.ts @@ -36,6 +36,7 @@ interface IPlatformData { targetedOS?: string[]; configurationFileName?: string; configurationFilePath?: string; + relativeToFrameworkConfigurationFilePath: string; mergeXmlConfig?: any[]; } diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index 809bf76318..7008fcbd84 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -36,7 +36,8 @@ interface IPlatformProjectService { platformData: IPlatformData; validate(): IFuture; createProject(frameworkDir: string, frameworkVersion: string): IFuture; - interpolateData(projectRoot: string): IFuture; + interpolateData(): IFuture; + interpolateConfigurationFile(configurationFilePath?: string): IFuture; afterCreateProject(projectRoot: string): IFuture; buildProject(projectRoot: string, buildConfig?: IBuildConfig): IFuture; prepareProject(): IFuture; diff --git a/lib/services/android-project-service.ts b/lib/services/android-project-service.ts index 76fbe4eb03..1d99d28e24 100644 --- a/lib/services/android-project-service.ts +++ b/lib/services/android-project-service.ts @@ -8,7 +8,7 @@ import * as semver from "semver"; import * as projectServiceBaseLib from "./platform-project-service-base"; import * as androidDebugBridgePath from "../common/mobile/android/android-debug-bridge"; -class AndroidProjectService extends projectServiceBaseLib.PlatformProjectServiceBase implements IPlatformProjectService { +export class AndroidProjectService extends projectServiceBaseLib.PlatformProjectServiceBase implements IPlatformProjectService { private static VALUES_DIRNAME = "values"; private static VALUES_VERSION_DIRNAME_PREFIX = AndroidProjectService.VALUES_DIRNAME + "-v"; private static ANDROID_PLATFORM_NAME = "android"; @@ -57,6 +57,7 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService frameworkFilesExtensions: [".jar", ".dat", ".so"], configurationFileName: "AndroidManifest.xml", configurationFilePath: path.join(projectRoot, "src", "main", "AndroidManifest.xml"), + relativeToFrameworkConfigurationFilePath: path.join("src", "main", "AndroidManifest.xml"), mergeXmlConfig: [{ "nodename": "manifest", "attrname": "*" }, {"nodename": "application", "attrname": "*"}] }; } @@ -134,11 +135,10 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService }).future()(); } - public interpolateData(projectRoot: string): IFuture { + public interpolateData(): IFuture { return (() => { - // Interpolate the activity name and package - let manifestPath = this.platformData.configurationFilePath; - shell.sed('-i', /__PACKAGE__/, this.$projectData.projectId, manifestPath); + // Interpolate the apilevel and package + this.interpolateConfigurationFile().wait(); let stringsFilePath = path.join(this.getAppResourcesDestinationDirectoryPath().wait(), 'values', 'strings.xml'); shell.sed('-i', /__NAME__/, this.$projectData.projectName, stringsFilePath); @@ -146,6 +146,17 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService let gradleSettingsFilePath = path.join(this.platformData.projectRoot, "settings.gradle"); shell.sed('-i', /__PROJECT_NAME__/, this.getProjectNameFromId(), gradleSettingsFilePath); + }).future()(); + } + + public interpolateConfigurationFile(): IFuture { + return (() => { + let manifestPath = this.platformData.configurationFilePath; + + console.log("ANDROID MANIFEST FILE PATH!!!!"); + console.log(manifestPath); + + shell.sed('-i', /__PACKAGE__/, this.$projectData.projectId, manifestPath); shell.sed('-i', /__APILEVEL__/, this.$options.sdk || this.$androidToolsInfo.getToolsInfo().wait().compileSdkVersion.toString(), manifestPath); }).future()(); } diff --git a/lib/services/ios-project-service.ts b/lib/services/ios-project-service.ts index 550791e1d0..3319be9810 100644 --- a/lib/services/ios-project-service.ts +++ b/lib/services/ios-project-service.ts @@ -60,6 +60,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ targetedOS: ['darwin'], configurationFileName: "Info.plist", configurationFilePath: path.join(projectRoot, this.$projectData.projectName, this.$projectData.projectName+"-Info.plist"), + relativeToFrameworkConfigurationFilePath: path.join("__PROJECT_NAME__", "__PROJECT_NAME__-Info.plist"), mergeXmlConfig: [{ "nodename": "plist", "attrname": "*" }, {"nodename": "dict", "attrname": "*"}] }; } @@ -118,20 +119,26 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ }).future()(); } - public interpolateData(projectRoot: string): IFuture { + public interpolateData(): IFuture { return (() => { - let infoPlistFilePath = path.join(projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, util.format("%s-%s", IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, "Info.plist")); - shell.sed('-i', "__CFBUNDLEIDENTIFIER__", this.$projectData.projectId, infoPlistFilePath); + let infoPlistFilePath = path.join(this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, util.format("%s-%s", IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, "Info.plist")); + this.interpolateConfigurationFile(infoPlistFilePath).wait(); - this.replaceFileName("-Info.plist", path.join(projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER)).wait(); - this.replaceFileName("-Prefix.pch", path.join(projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER)).wait(); - this.replaceFileName(IOSProjectService.XCODE_PROJECT_EXT_NAME, projectRoot).wait(); + this.replaceFileName("-Info.plist", path.join(this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER)).wait(); + this.replaceFileName("-Prefix.pch", path.join(this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER)).wait(); + this.replaceFileName(IOSProjectService.XCODE_PROJECT_EXT_NAME, this.platformData.projectRoot).wait(); - let pbxprojFilePath = path.join(projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj"); + let pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj"); this.replaceFileContent(pbxprojFilePath).wait(); }).future()(); } + public interpolateConfigurationFile(configurationFilePath?: string): IFuture { + return (() => { + shell.sed('-i', "__CFBUNDLEIDENTIFIER__", this.$projectData.projectId, configurationFilePath || this.platformData.configurationFilePath); + }).future()(); + } + public afterCreateProject(projectRoot: string): IFuture { return (() => { this.$fs.rename(path.join(projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER), diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index caae4c28a7..6b31503d7d 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -102,7 +102,7 @@ export class PlatformService implements IPlatformService { this.$fs.deleteDirectory(path.join(frameworkDir, "../../")).wait(); } - platformData.platformProjectService.interpolateData(platformData.projectRoot).wait(); + platformData.platformProjectService.interpolateData().wait(); platformData.platformProjectService.afterCreateProject(platformData.projectRoot).wait(); this.$projectDataService.initialize(this.$projectData.projectDir); diff --git a/lib/services/plugins-service.ts b/lib/services/plugins-service.ts index 37b639993c..270b2a1a20 100644 --- a/lib/services/plugins-service.ts +++ b/lib/services/plugins-service.ts @@ -86,25 +86,7 @@ export class PluginsService implements IPluginsService { // Remove the plugin and call merge for another plugins that have configuration file let pluginConfigurationFilePath = this.getPluginConfigurationFilePath(pluginData, platformData); if(this.$fs.exists(pluginConfigurationFilePath).wait()) { - let tnsModulesDestinationPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.TNS_MODULES_FOLDER_NAME); - let nodeModules = this.$broccoliBuilder.getChangedNodeModules(tnsModulesDestinationPath, platform).wait(); - - _(nodeModules) - .map(nodeModule => this.getNodeModuleData(pluginName).wait()) - .map(nodeModuleData => this.convertToPluginData(nodeModuleData)) - .filter(data => data.isPlugin && this.$fs.exists(this.getPluginConfigurationFilePath(data, platformData)).wait()) - .forEach((data, index) => { - executeUninstallCommand().wait(); - - if(index === 0) { - this.initializeConfigurationFileFromCache(platformData).wait(); - } - - if(data.name !== pluginName) { - this.merge(data, platformData).wait(); - } - }) - .value(); + this.merge(pluginData, platformData).wait(); } if(pluginData.pluginVariables) { @@ -139,13 +121,14 @@ export class PluginsService implements IPluginsService { let frameworkVersion = this.$projectDataService.getValue(platformData.frameworkPackageName).wait().version; this.$npm.cache(platformData.frameworkPackageName, frameworkVersion).wait(); - let relativeConfigurationFilePath = path.relative(platformData.projectRoot, platformData.configurationFilePath); // We need to resolve this manager here due to some restrictions from npm api and in order to load PluginsService.NPM_CONFIG config let npmInstallationManager: INpmInstallationManager = this.$injector.resolve("npmInstallationManager"); let cachedPackagePath = npmInstallationManager.getCachedPackagePath(platformData.frameworkPackageName, frameworkVersion); - let cachedConfigurationFilePath = path.join(cachedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME, relativeConfigurationFilePath); + let cachedConfigurationFilePath = path.join(cachedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME, platformData.relativeToFrameworkConfigurationFilePath); + let cachedConfigurationFileContent = this.$fs.readText(cachedConfigurationFilePath).wait(); + this.$fs.writeFile(platformData.configurationFilePath, cachedConfigurationFileContent).wait(); - shelljs.cp("-f", cachedConfigurationFilePath, path.dirname(platformData.configurationFilePath)); + platformData.platformProjectService.interpolateConfigurationFile().wait(); }).future()(); } @@ -347,7 +330,7 @@ export class PluginsService implements IPluginsService { doc.parseFromString(xml, 'text/xml'); } - private merge(pluginData: IPluginData, platformData: IPlatformData): IFuture { + private mergeCore(pluginData: IPluginData, platformData: IPlatformData): IFuture { return (() => { let pluginConfigurationFilePath = this.getPluginConfigurationFilePath(pluginData, platformData); let configurationFilePath = platformData.configurationFilePath; @@ -368,6 +351,27 @@ export class PluginsService implements IPluginsService { }).future()(); } + private merge(pluginData: IPluginData, platformData: IPlatformData): IFuture { + return (() => { + let tnsModulesDestinationPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.TNS_MODULES_FOLDER_NAME); + let nodeModules = this.$broccoliBuilder.getChangedNodeModules(tnsModulesDestinationPath, platformData.normalizedPlatformName.toLowerCase()).wait(); + + _(_.keys(nodeModules)) + .map(nodeModule => this.getNodeModuleData(path.join(nodeModule, "package.json")).wait()) + .map(nodeModuleData => this.convertToPluginData(nodeModuleData)) + .filter(data => data.isPlugin && this.$fs.exists(this.getPluginConfigurationFilePath(data, platformData)).wait()) + .forEach((data, index) => { + if(index === 0) { + this.initializeConfigurationFileFromCache(platformData).wait(); + } + + this.mergeCore(data, platformData).wait(); + }) + .value(); + + }).future()(); + } + private getPluginConfigurationFilePath(pluginData: IPluginData, platformData: IPlatformData): string { let pluginPlatformsFolderPath = pluginData.pluginPlatformsFolderPath(platformData.normalizedPlatformName.toLowerCase()); let pluginConfigurationFilePath = path.join(pluginPlatformsFolderPath, platformData.configurationFileName); diff --git a/lib/tools/broccoli/builder.ts b/lib/tools/broccoli/builder.ts index 6a78eb89bf..868d135d4b 100644 --- a/lib/tools/broccoli/builder.ts +++ b/lib/tools/broccoli/builder.ts @@ -12,7 +12,6 @@ let through = require("through2"); export class Builder implements IBroccoliBuilder { constructor(private $fs: IFileSystem, - private $nodeModulesTree: INodeModulesTree, private $projectData: IProjectData, private $projectDataService: IProjectDataService, private $injector: IInjector, diff --git a/test/platform-commands.ts b/test/platform-commands.ts index 25f70ba733..90c7ac0ead 100644 --- a/test/platform-commands.ts +++ b/test/platform-commands.ts @@ -28,6 +28,7 @@ class PlatformData implements IPlatformData { frameworkVersion = ""; appDestinationDirectoryPath = ""; appResourcesDestinationDirectoryPath = ""; + relativeToFrameworkConfigurationFilePath = ""; } class ErrorsNoFailStub implements IErrors { diff --git a/test/plugins-service.ts b/test/plugins-service.ts index 9abd0d25b3..5f691983d4 100644 --- a/test/plugins-service.ts +++ b/test/plugins-service.ts @@ -5,6 +5,7 @@ import {Yok} from '../lib/common/yok'; import future = require("fibers/future"); import * as stubs from './stubs'; import {NodePackageManager} from "../lib/node-package-manager"; +import {NpmInstallationManager} from "../lib/npm-installation-manager"; import {FileSystem} from "../lib/common/file-system"; import {ProjectData} from "../lib/project-data"; import {ChildProcess} from "../lib/common/child-process"; @@ -23,6 +24,9 @@ import {ResourceLoader} from "../lib/common/resource-loader"; import {EOL} from "os"; import {PluginsService} from "../lib/services/plugins-service"; import {AddPluginCommand} from "../lib/commands/plugin/add-plugin"; +import {Builder} from "../lib/tools/broccoli/builder"; +import {AndroidProjectService} from "../lib/services/android-project-service"; +import {AndroidToolsInfo} from "../lib/android-tools-info"; import {assert} from "chai"; import * as path from "path"; import * as temp from "temp"; @@ -40,13 +44,17 @@ function createTestInjector() { testInjector.register("childProcess", ChildProcess); testInjector.register("platformService", PlatformService); testInjector.register("platformsData", PlatformsData); - testInjector.register("androidProjectService", {}); + testInjector.register("androidEmulatorServices", {}); + testInjector.register("androidToolsInfo", AndroidToolsInfo); + testInjector.register("sysInfo", {}); + testInjector.register("mobileHelper", {}); + testInjector.register("androidProjectService", AndroidProjectService); testInjector.register("iOSProjectService", {}); testInjector.register("devicesServices", {}); testInjector.register("projectDataService", ProjectDataService); testInjector.register("prompter", {}); testInjector.register("resources", ResourceLoader); - testInjector.register("broccoliBuilder", {}); + testInjector.register("broccoliBuilder", Builder); testInjector.register("options", Options); testInjector.register("errors", Errors); testInjector.register("logger", stubs.LoggerStub); @@ -71,7 +79,7 @@ function createTestInjector() { savePluginVariablesInProjectFile: (pluginData: IPluginData) => future.fromResult(), interpolatePluginVariables: (pluginData: IPluginData, pluginConfigurationFileContent: string) => future.fromResult(pluginConfigurationFileContent) }); - testInjector.register("npmInstallationManager", {}); + testInjector.register("npmInstallationManager", NpmInstallationManager); return testInjector; } @@ -87,7 +95,7 @@ function createProjectFile(testInjector: IInjector): string { "nativescript": { "id": "org.nativescript.Test", "tns-android": { - "version": "1.0.0" + "version": "1.4.0" } } }; @@ -203,7 +211,7 @@ describe("Plugins service", () => { }); 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."; + let expectedWarningMessage = "mySamplePlugin 1.5.0 for android is not compatible with the currently installed framework version 1.4.0."; // Creates plugin in temp folder let pluginName = "mySamplePlugin"; @@ -214,7 +222,7 @@ describe("Plugins service", () => { "version": "0.0.1", "nativescript": { "platforms": { - "android": "1.0.1" + "android": "1.5.0" } }, }; @@ -557,23 +565,34 @@ describe("Plugins service", () => { // Mock platformsData let platformsData = testInjector.resolve("platformsData"); platformsData.getPlatformData = (platform: string) => { + let androidProjectService = testInjector.resolve("androidProjectService"); + return { appDestinationDirectoryPath: appDestinationDirectoryPath, frameworkPackageName: "tns-android", configurationFileName: "AndroidManifest.xml", - configurationFilePath: path.join(appDestinationDirectoryPath, "AndroidManifest.xml"), + configurationFilePath: path.join(appDestinationDirectoryPath, "src", "main", "AndroidManifest.xml"), + relativeToFrameworkConfigurationFilePath: path.join("src", "main", "AndroidManifest.xml"), mergeXmlConfig: [{ "nodename": "manifest", "attrname": "*" }], platformProjectService: { - preparePluginNativeCode: (pluginData: IPluginData) => future.fromResult() + preparePluginNativeCode: (pluginData: IPluginData) => future.fromResult(), + interpolateConfigurationFile: () => androidProjectService.interpolateConfigurationFile() }, normalizedPlatformName: "Android" }; }; + // Mock projectData + let projectData = testInjector.resolve("projectData"); + projectData.projectId = "com.example.android.basiccontactables"; + // Ensure the pluginDestinationPath folder exists let pluginPlatformsDirPath = path.join(projectFolder, "node_modules", pluginName, "platforms", "android"); fs.ensureDirectoryExists(pluginPlatformsDirPath).wait(); + let shelljs = require("shelljs"); + shelljs.cp("-R", path.join(pluginFolderPath, "*"), path.join(projectFolder, "node_modules", pluginName)); + // Creates valid plugin's AndroidManifest.xml file let xml = '' + '' + @@ -584,11 +603,11 @@ describe("Plugins service", () => { pluginsService.prepare(pluginJsonData).wait(); - let expectedXml = ''; + let expectedXml = ''; expectedXml = helpers.stringReplaceAll(expectedXml, EOL, ""); expectedXml = helpers.stringReplaceAll(expectedXml, " ", ""); - let actualXml = fs.readText(path.join(appDestinationDirectoryPath, "AndroidManifest.xml")).wait(); + let actualXml = fs.readText(path.join(appDestinationDirectoryPath, "src", "main", "AndroidManifest.xml")).wait(); actualXml = helpers.stringReplaceAll(actualXml, "\n", ""); actualXml = helpers.stringReplaceAll(actualXml, " ", ""); diff --git a/test/stubs.ts b/test/stubs.ts index 904a583dd6..806d9c361a 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -258,6 +258,7 @@ export class PlatformsDataStub implements IPlatformsData { frameworkFilesExtensions: [], frameworkVersion: "", appDestinationDirectoryPath: "", + relativeToFrameworkConfigurationFilePath: "", preparePluginNativeCode: () => Future.fromResult(), removePluginNativeCode: () => Future.fromResult(), afterPrepareAllPlugins: () => Future.fromResult() @@ -281,7 +282,8 @@ export class PlatformProjectServiceStub implements IPlatformProjectService { validPackageNamesForDevice: [], frameworkFilesExtensions: [], frameworkVersion: "", - appDestinationDirectoryPath: "" + appDestinationDirectoryPath: "", + relativeToFrameworkConfigurationFilePath: "" }; } getAppResourcesDestinationDirectoryPath(): IFuture{ @@ -293,7 +295,10 @@ export class PlatformProjectServiceStub implements IPlatformProjectService { createProject(projectRoot: string, frameworkDir: string): IFuture { return Future.fromResult(); } - interpolateData(projectRoot: string): IFuture { + interpolateData(): IFuture { + return Future.fromResult(); + } + interpolateConfigurationFile(): IFuture { return Future.fromResult(); } afterCreateProject(projectRoot: string): IFuture { From aae1c98a626126bdf17b65eac728cb10397b6b2d Mon Sep 17 00:00:00 2001 From: Fatme Havaluova Date: Mon, 19 Oct 2015 17:14:22 +0300 Subject: [PATCH 2/4] Cherrypick the fix that allows $npm to be used with different configurations --- lib/definitions/npm.d.ts | 6 ++++++ lib/node-package-manager.ts | 25 +++++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/definitions/npm.d.ts b/lib/definitions/npm.d.ts index 9cb8c86d6b..4de36a8be6 100644 --- a/lib/definitions/npm.d.ts +++ b/lib/definitions/npm.d.ts @@ -3,4 +3,10 @@ declare module "npm" { var commands: { [index: string]: any }; var prefix: string; function load(config: Object, callback: (err: any, data: any) => void): void; + module config { + var loaded: boolean; + module sources { + var cli: { data: Object }; + } + } } \ No newline at end of file diff --git a/lib/node-package-manager.ts b/lib/node-package-manager.ts index 79ed92e7d2..47cce4927b 100644 --- a/lib/node-package-manager.ts +++ b/lib/node-package-manager.ts @@ -19,15 +19,24 @@ export class NodePackageManager implements INodePackageManager { } public load(config?: any): IFuture { - let future = new Future(); - npm.load(config, (err: Error) => { - if(err) { - future.throw(err); - } else { - future.return(); + if (npm.config.loaded) { + let data = npm.config.sources.cli.data; + Object.keys(data).forEach(k => delete data[k]); + if (config) { + _.assign(data, config); } - }); - return future; + return Future.fromResult(); + } else { + let future = new Future(); + npm.load(config, (err: Error) => { + if(err) { + future.throw(err); + } else { + future.return(); + } + }); + return future; + } } public install(packageName: string, pathToSave: string, config?: any): IFuture { From bca245ad898d32fe2861bc873a457d15272972cc Mon Sep 17 00:00:00 2001 From: Fatme Havaluova Date: Mon, 19 Oct 2015 17:14:38 +0300 Subject: [PATCH 3/4] Remove the unneeded code from plugin.remove function and from android-project-service --- lib/services/android-project-service.ts | 4 ---- lib/services/plugins-service.ts | 17 +++-------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/lib/services/android-project-service.ts b/lib/services/android-project-service.ts index 1d99d28e24..810104bdb3 100644 --- a/lib/services/android-project-service.ts +++ b/lib/services/android-project-service.ts @@ -152,10 +152,6 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject public interpolateConfigurationFile(): IFuture { return (() => { let manifestPath = this.platformData.configurationFilePath; - - console.log("ANDROID MANIFEST FILE PATH!!!!"); - console.log(manifestPath); - shell.sed('-i', /__PACKAGE__/, this.$projectData.projectId, manifestPath); shell.sed('-i', /__APILEVEL__/, this.$options.sdk || this.$androidToolsInfo.getToolsInfo().wait().compileSdkVersion.toString(), manifestPath); }).future()(); diff --git a/lib/services/plugins-service.ts b/lib/services/plugins-service.ts index 270b2a1a20..f28469f310 100644 --- a/lib/services/plugins-service.ts +++ b/lib/services/plugins-service.ts @@ -66,17 +66,6 @@ export class PluginsService implements IPluginsService { public remove(pluginName: string): IFuture { return (() => { - let isUninstallCommandExecuted = false; - - let executeUninstallCommand = () => { - return (() => { - if(!isUninstallCommandExecuted) { - this.executeNpmCommand(PluginsService.UNINSTALL_COMMAND_NAME, pluginName).wait(); - isUninstallCommandExecuted = true; - } - }).future()(); - }; - let removePluginNativeCodeAction = (modulesDestinationPath: string, platform: string, platformData: IPlatformData) => { return (() => { let pluginData = this.convertToPluginData(this.getNodeModuleData(pluginName).wait()); @@ -96,7 +85,7 @@ export class PluginsService implements IPluginsService { }; this.executeForAllInstalledPlatforms(removePluginNativeCodeAction).wait(); - executeUninstallCommand().wait(); + this.executeNpmCommand(PluginsService.UNINSTALL_COMMAND_NAME, pluginName).wait(); let showMessage = true; let action = (modulesDestinationPath: string, platform: string, platformData: IPlatformData) => { @@ -119,10 +108,11 @@ export class PluginsService implements IPluginsService { return (() => { this.$projectDataService.initialize(this.$projectData.projectDir); let frameworkVersion = this.$projectDataService.getValue(platformData.frameworkPackageName).wait().version; - this.$npm.cache(platformData.frameworkPackageName, frameworkVersion).wait(); // We need to resolve this manager here due to some restrictions from npm api and in order to load PluginsService.NPM_CONFIG config let npmInstallationManager: INpmInstallationManager = this.$injector.resolve("npmInstallationManager"); + npmInstallationManager.addToCache(platformData.frameworkPackageName, frameworkVersion).wait(); + let cachedPackagePath = npmInstallationManager.getCachedPackagePath(platformData.frameworkPackageName, frameworkVersion); let cachedConfigurationFilePath = path.join(cachedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME, platformData.relativeToFrameworkConfigurationFilePath); let cachedConfigurationFileContent = this.$fs.readText(cachedConfigurationFilePath).wait(); @@ -147,7 +137,6 @@ export class PluginsService implements IPluginsService { shelljs.cp("-Rf", pluginData.fullPath, pluginDestinationPath); let pluginConfigurationFilePath = this.getPluginConfigurationFilePath(pluginData, platformData); - if(this.$fs.exists(pluginConfigurationFilePath).wait()) { this.merge(pluginData, platformData).wait(); } From 2daee3103ce214fe6b0ff55cdd41557e1ec575c2 Mon Sep 17 00:00:00 2001 From: Fatme Havaluova Date: Tue, 20 Oct 2015 09:43:12 +0300 Subject: [PATCH 4/4] Fix plugin remove, mock interpolateConfigurationFile and address some PR comments --- lib/services/ios-project-service.ts | 5 +++-- lib/services/plugins-service.ts | 11 +++++++---- test/plugins-service.ts | 24 +++++++++++++++--------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/lib/services/ios-project-service.ts b/lib/services/ios-project-service.ts index 3319be9810..6edfdde827 100644 --- a/lib/services/ios-project-service.ts +++ b/lib/services/ios-project-service.ts @@ -124,8 +124,9 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ let infoPlistFilePath = path.join(this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, util.format("%s-%s", IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, "Info.plist")); this.interpolateConfigurationFile(infoPlistFilePath).wait(); - this.replaceFileName("-Info.plist", path.join(this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER)).wait(); - this.replaceFileName("-Prefix.pch", path.join(this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER)).wait(); + let projectRootFilePath = path.join(this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER); + this.replaceFileName("-Info.plist", projectRootFilePath).wait(); + this.replaceFileName("-Prefix.pch", projectRootFilePath).wait(); this.replaceFileName(IOSProjectService.XCODE_PROJECT_EXT_NAME, this.platformData.projectRoot).wait(); let pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj"); diff --git a/lib/services/plugins-service.ts b/lib/services/plugins-service.ts index f28469f310..90314c499f 100644 --- a/lib/services/plugins-service.ts +++ b/lib/services/plugins-service.ts @@ -75,7 +75,7 @@ export class PluginsService implements IPluginsService { // Remove the plugin and call merge for another plugins that have configuration file let pluginConfigurationFilePath = this.getPluginConfigurationFilePath(pluginData, platformData); if(this.$fs.exists(pluginConfigurationFilePath).wait()) { - this.merge(pluginData, platformData).wait(); + this.merge(pluginData, platformData, (data: IPluginData) => data.name !== pluginData.name).wait(); } if(pluginData.pluginVariables) { @@ -340,12 +340,13 @@ export class PluginsService implements IPluginsService { }).future()(); } - private merge(pluginData: IPluginData, platformData: IPlatformData): IFuture { + private merge(pluginData: IPluginData, platformData: IPlatformData, mergeCondition?: (_pluginData: IPluginData) => boolean): IFuture { return (() => { let tnsModulesDestinationPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.TNS_MODULES_FOLDER_NAME); let nodeModules = this.$broccoliBuilder.getChangedNodeModules(tnsModulesDestinationPath, platformData.normalizedPlatformName.toLowerCase()).wait(); - _(_.keys(nodeModules)) + _(nodeModules) + .keys() .map(nodeModule => this.getNodeModuleData(path.join(nodeModule, "package.json")).wait()) .map(nodeModuleData => this.convertToPluginData(nodeModuleData)) .filter(data => data.isPlugin && this.$fs.exists(this.getPluginConfigurationFilePath(data, platformData)).wait()) @@ -354,7 +355,9 @@ export class PluginsService implements IPluginsService { this.initializeConfigurationFileFromCache(platformData).wait(); } - this.mergeCore(data, platformData).wait(); + if(!mergeCondition || (mergeCondition && mergeCondition(data))) { + this.mergeCore(data, platformData).wait(); + } }) .value(); diff --git a/test/plugins-service.ts b/test/plugins-service.ts index 5f691983d4..c4d995fac7 100644 --- a/test/plugins-service.ts +++ b/test/plugins-service.ts @@ -562,35 +562,41 @@ describe("Plugins service", () => { let appDestinationDirectoryPath = path.join(projectFolder, "platforms", "android"); fs.ensureDirectoryExists(path.join(appDestinationDirectoryPath, "app")).wait(); + // Mock projectData + let projectData = testInjector.resolve("projectData"); + projectData.projectId = "com.example.android.basiccontactables"; + + let configurationFilePath = path.join(appDestinationDirectoryPath, "src", "main", "AndroidManifest.xml"); + + let shelljs = require("shelljs"); + // Mock platformsData let platformsData = testInjector.resolve("platformsData"); platformsData.getPlatformData = (platform: string) => { - let androidProjectService = testInjector.resolve("androidProjectService"); - return { appDestinationDirectoryPath: appDestinationDirectoryPath, frameworkPackageName: "tns-android", configurationFileName: "AndroidManifest.xml", - configurationFilePath: path.join(appDestinationDirectoryPath, "src", "main", "AndroidManifest.xml"), + configurationFilePath: configurationFilePath, relativeToFrameworkConfigurationFilePath: path.join("src", "main", "AndroidManifest.xml"), mergeXmlConfig: [{ "nodename": "manifest", "attrname": "*" }], platformProjectService: { preparePluginNativeCode: (pluginData: IPluginData) => future.fromResult(), - interpolateConfigurationFile: () => androidProjectService.interpolateConfigurationFile() + interpolateConfigurationFile: () => { + return (() => { + shelljs.sed('-i', /__PACKAGE__/, projectData.projectId, configurationFilePath); + shelljs.sed('-i', /__APILEVEL__/, "23", configurationFilePath); + }).future()(); + } }, normalizedPlatformName: "Android" }; }; - // Mock projectData - let projectData = testInjector.resolve("projectData"); - projectData.projectId = "com.example.android.basiccontactables"; - // Ensure the pluginDestinationPath folder exists let pluginPlatformsDirPath = path.join(projectFolder, "node_modules", pluginName, "platforms", "android"); fs.ensureDirectoryExists(pluginPlatformsDirPath).wait(); - let shelljs = require("shelljs"); shelljs.cp("-R", path.join(pluginFolderPath, "*"), path.join(projectFolder, "node_modules", pluginName)); // Creates valid plugin's AndroidManifest.xml file