diff --git a/lib/controllers/prepare-controller.ts b/lib/controllers/prepare-controller.ts index f491745072..273a254dbf 100644 --- a/lib/controllers/prepare-controller.ts +++ b/lib/controllers/prepare-controller.ts @@ -3,7 +3,7 @@ import { hook } from "../common/helpers"; import { performanceLog, cache } from "../common/decorators"; import { EventEmitter } from "events"; import * as path from "path"; -import { PREPARE_READY_EVENT_NAME, WEBPACK_COMPILATION_COMPLETE, PACKAGE_JSON_FILE_NAME, PLATFORMS_DIR_NAME, TrackActionNames, AnalyticsEventLabelDelimiter } from "../constants"; +import { PREPARE_READY_EVENT_NAME, WEBPACK_COMPILATION_COMPLETE, PACKAGE_JSON_FILE_NAME, PLATFORMS_DIR_NAME, TrackActionNames, AnalyticsEventLabelDelimiter, CONFIG_NS_FILE_NAME } from "../constants"; interface IPlatformWatcherData { hasWebpackCompilerProcess: boolean; nativeFilesWatcher: choki.FSWatcher; @@ -189,6 +189,7 @@ export class PrepareController extends EventEmitter { const patterns = [ path.join(projectData.projectDir, PACKAGE_JSON_FILE_NAME), + path.join(projectData.projectDir, CONFIG_NS_FILE_NAME), path.join(projectData.getAppDirectoryPath(), PACKAGE_JSON_FILE_NAME), path.join(projectData.getAppResourcesRelativeDirectoryPath(), platformData.normalizedPlatformName), ] diff --git a/lib/definitions/platform.d.ts b/lib/definitions/platform.d.ts index e5ec3a2ba4..be07ae0a15 100644 --- a/lib/definitions/platform.d.ts +++ b/lib/definitions/platform.d.ts @@ -46,7 +46,12 @@ interface IPlatformsDataService { } interface INodeModulesBuilder { - prepareNodeModules(platformData: IPlatformData, projectData: IProjectData): Promise; + prepareNodeModules(prepareNodeModulesData: IPrepareNodeModulesData): Promise; +} + +interface IPrepareNodeModulesData { + platformData: IPlatformData; + projectData: IProjectData; } interface INodeModulesDependenciesBuilder { diff --git a/lib/definitions/plugins.d.ts b/lib/definitions/plugins.d.ts index c1a7d55727..7435a1cacc 100644 --- a/lib/definitions/plugins.d.ts +++ b/lib/definitions/plugins.d.ts @@ -12,11 +12,17 @@ interface IPluginsService { * @returns {IPackageJsonDepedenciesResult} */ getDependenciesFromPackageJson(projectDir: string): IPackageJsonDepedenciesResult; - preparePluginNativeCode(pluginData: IPluginData, platform: string, projectData: IProjectData): Promise; + preparePluginNativeCode(preparePluginNativeCodeData: IPreparePluginNativeCodeData): Promise; convertToPluginData(cacheData: any, projectDir: string): IPluginData; isNativeScriptPlugin(pluginPackageJsonPath: string): boolean; } +interface IPreparePluginNativeCodeData { + pluginData: IPluginData; + platform: string; + projectData: IProjectData; +} + interface IPackageJsonDepedenciesResult { dependencies: IBasePluginData[], devDependencies?: IBasePluginData[] diff --git a/lib/definitions/project-changes.d.ts b/lib/definitions/project-changes.d.ts index e799efbb5d..e0965ac3c5 100644 --- a/lib/definitions/project-changes.d.ts +++ b/lib/definitions/project-changes.d.ts @@ -17,6 +17,7 @@ interface IProjectChangesInfo extends IAddedNativePlatform { configChanged: boolean; nativeChanged: boolean; signingChanged: boolean; + nsConfigChanged: boolean; readonly hasChanges: boolean; readonly changesRequireBuild: boolean; diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index aae148252b..51eb52fc99 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -75,6 +75,7 @@ interface INsConfig { appResourcesPath?: string; shared?: boolean; previewAppSchema?: string; + overridePods?: string } interface IProjectData extends ICreateProjectData { @@ -406,10 +407,10 @@ interface ICocoaPodsService { * @param {string} moduleName The module which the Podfile is from. * @param {string} podfilePath The path to the podfile. * @param {IProjectData} projectData Information about the project. - * @param {string} nativeProjectPath Path to the native Xcode project. + * @param {IPlatformData} platformData Information about the platform. * @returns {Promise} */ - applyPodfileToProject(moduleName: string, podfilePath: string, projectData: IProjectData, nativeProjectPath: string): Promise; + applyPodfileToProject(moduleName: string, podfilePath: string, projectData: IProjectData, platformData: IPlatformData): Promise; /** * Gives the path to the plugin's Podfile. diff --git a/lib/services/cocoapods-service.ts b/lib/services/cocoapods-service.ts index e4868f3571..8c8bae7935 100644 --- a/lib/services/cocoapods-service.ts +++ b/lib/services/cocoapods-service.ts @@ -1,12 +1,12 @@ import { EOL } from "os"; import * as path from "path"; import { PluginNativeDirNames, PODFILE_NAME, NS_BASE_PODFILE } from "../constants"; -import { regExpEscape } from "../common/helpers"; +import { regExpEscape, getHash } from "../common/helpers"; export class CocoaPodsService implements ICocoaPodsService { private static PODFILE_POST_INSTALL_SECTION_NAME = "post_install"; private static INSTALLER_BLOCK_PARAMETER_NAME = "installer"; - + private getCocoaPodsFromPodfile: Function; constructor( private $cocoaPodsPlatformManager: ICocoaPodsPlatformManager, private $fs: IFileSystem, @@ -14,7 +14,9 @@ export class CocoaPodsService implements ICocoaPodsService { private $errors: IErrors, private $logger: ILogger, private $config: IConfiguration, - private $xcconfigService: IXcconfigService) { } + private $xcconfigService: IXcconfigService) { + this.getCocoaPodsFromPodfile = _.memoize(this._getCocoaPodsFromPodfile, getHash); + } public getPodfileHeader(targetName: string): string { return `use_frameworks!${EOL}${EOL}target "${targetName}" do${EOL}`; @@ -35,7 +37,11 @@ export class CocoaPodsService implements ICocoaPodsService { const podInstallResult = await this.$childProcess.spawnFromEvent(podTool, ["install"], "close", { cwd: projectRoot, stdio: ['pipe', process.stdout, process.stdout] }, { throwError: false }); if (podInstallResult.exitCode !== 0) { - this.$errors.fail(`'${podTool} install' command failed.${podInstallResult.stderr ? " Error is: " + podInstallResult.stderr : ""}`); + // https://github.com/CocoaPods/CocoaPods/blob/92aaf0f1120d32f3487960b485fb69fcaf61486c/lib/cocoapods/resolver.rb#L498 + // TODO add article + const versionResolutionHint = podInstallResult.exitCode === 31 ? `For more information on resolving CocoaPod issues in NativeScript read.` : ""; + this.$errors.fail(`'${podTool} install' command failed.${podInstallResult.stderr ? " Error is: " + podInstallResult.stderr : ""} +${versionResolutionHint}`); } return podInstallResult; @@ -59,17 +65,18 @@ export class CocoaPodsService implements ICocoaPodsService { const mainPodfilePath = path.join(projectData.appResourcesDirectoryPath, normalizedPlatformName, PODFILE_NAME); const projectPodfilePath = this.getProjectPodfilePath(projectRoot); if (this.$fs.exists(projectPodfilePath) || this.$fs.exists(mainPodfilePath)) { - await this.applyPodfileToProject(NS_BASE_PODFILE, mainPodfilePath, projectData, projectRoot); + await this.applyPodfileToProject(NS_BASE_PODFILE, mainPodfilePath, projectData, platformData); } } - public async applyPodfileToProject(moduleName: string, podfilePath: string, projectData: IProjectData, nativeProjectPath: string): Promise { + public async applyPodfileToProject(moduleName: string, podfilePath: string, projectData: IProjectData, platformData: IPlatformData): Promise { + const nativeProjectPath = platformData.projectRoot; if (!this.$fs.exists(podfilePath)) { this.removePodfileFromProject(moduleName, podfilePath, projectData, nativeProjectPath); return; } - const { podfileContent, replacedFunctions, podfilePlatformData } = this.buildPodfileContent(podfilePath, moduleName); + const { podfileContent, replacedFunctions, podfilePlatformData } = this.buildPodfileContent(podfilePath, moduleName, projectData, platformData); const pathToProjectPodfile = this.getProjectPodfilePath(nativeProjectPath); const projectPodfileContent = this.$fs.exists(pathToProjectPodfile) ? this.$fs.readText(pathToProjectPodfile).trim() : ""; @@ -222,10 +229,16 @@ export class CocoaPodsService implements ICocoaPodsService { return `${CocoaPodsService.PODFILE_POST_INSTALL_SECTION_NAME} do |${CocoaPodsService.INSTALLER_BLOCK_PARAMETER_NAME}|${EOL}`; } - private buildPodfileContent(pluginPodFilePath: string, pluginName: string): { podfileContent: string, replacedFunctions: IRubyFunction[], podfilePlatformData: IPodfilePlatformData } { + private buildPodfileContent(pluginPodFilePath: string, pluginName: string, projectData: IProjectData, platformData: IPlatformData): { podfileContent: string, replacedFunctions: IRubyFunction[], podfilePlatformData: IPodfilePlatformData } { const pluginPodfileContent = this.$fs.readText(pluginPodFilePath); const data = this.replaceHookContent(CocoaPodsService.PODFILE_POST_INSTALL_SECTION_NAME, pluginPodfileContent, pluginName); - const { replacedContent, podfilePlatformData } = this.$cocoaPodsPlatformManager.replacePlatformRow(data.replacedContent, pluginPodFilePath); + const cocoapodsData = this.$cocoaPodsPlatformManager.replacePlatformRow(data.replacedContent, pluginPodFilePath); + const podfilePlatformData = cocoapodsData.podfilePlatformData; + let replacedContent = cocoapodsData.replacedContent; + + if (projectData.nsConfig && projectData.nsConfig.overridePods && !this.isMainPodFile(pluginPodFilePath, projectData, platformData)) { + replacedContent = this.overridePodsFromFile(replacedContent, projectData, platformData); + } return { podfileContent: `${this.getPluginPodfileHeader(pluginPodFilePath)}${EOL}${replacedContent}${EOL}${this.getPluginPodfileEnd()}`, @@ -234,6 +247,43 @@ export class CocoaPodsService implements ICocoaPodsService { }; } + private getMainPodFilePath(projectData: IProjectData, platformData: IPlatformData): string { + return path.join(projectData.appResourcesDirectoryPath, platformData.normalizedPlatformName, PODFILE_NAME); + } + + private isMainPodFile(podFilePath: string, projectData: IProjectData, platformData: IPlatformData): boolean { + const mainPodfilePath = this.getMainPodFilePath(projectData, platformData); + + return podFilePath === mainPodfilePath; + } + + private overridePodsFromFile(podfileContent: string, projectData: IProjectData, platformData: IPlatformData): string { + const mainPodfilePath = this.getMainPodFilePath(projectData, platformData); + const mainPodfileContent = this.$fs.readText(mainPodfilePath); + const pods = this.getCocoaPodsFromPodfile(mainPodfileContent); + _.forEach(pods, pod => { + podfileContent = podfileContent.replace(new RegExp(`^[ ]*pod\\s*["']${pod}['"].*$`, "gm"), '#$&'); + }); + + return podfileContent; + } + + private _getCocoaPodsFromPodfile(podfileContent: string): Array { + const pods = []; + const podsRegex = /^\s*pod\s*["'](.*?)['"].*$/gm; + + let match = podsRegex.exec(podfileContent); + while (match != null) { + const podName: string = match[1]; + if (podName) { + pods.push(podName); + } + + match = podsRegex.exec(podfileContent); + } + + return pods; + } } $injector.register("cocoapodsService", CocoaPodsService); diff --git a/lib/services/ios-project-service.ts b/lib/services/ios-project-service.ts index 6d1f3f1b73..32e0bd2ca2 100644 --- a/lib/services/ios-project-service.ts +++ b/lib/services/ios-project-service.ts @@ -495,9 +495,6 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ await this.prepareResources(pluginPlatformsFolderPath, pluginData, projectData); await this.prepareFrameworks(pluginPlatformsFolderPath, pluginData, projectData); await this.prepareStaticLibs(pluginPlatformsFolderPath, pluginData, projectData); - - const projectRoot = this.getPlatformData(projectData).projectRoot; - await this.$cocoapodsService.applyPodfileToProject(pluginData.name, this.$cocoapodsService.getPluginPodfilePath(pluginData), projectData, projectRoot); } public async removePluginNativeCode(pluginData: IPluginData, projectData: IProjectData): Promise { @@ -513,8 +510,10 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ public async handleNativeDependenciesChange(projectData: IProjectData, opts: IRelease): Promise { const platformData = this.getPlatformData(projectData); - + const pluginsData = await this.getAllInstalledPlugins(projectData); this.setProductBundleIdentifier(projectData); + + await this.applyPluginsCocoaPods(pluginsData, projectData, platformData); await this.$cocoapodsService.applyPodfileFromAppResources(projectData, platformData); const projectPodfilePath = this.$cocoapodsService.getProjectPodfilePath(platformData.projectRoot); @@ -529,7 +528,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ const pbxProjPath = this.getPbxProjPath(projectData); this.$iOSExtensionsService.removeExtensions({ pbxProjPath }); - await this.addExtensions(projectData); + await this.addExtensions(projectData, pluginsData); } public beforePrepareAllPlugins(): Promise { @@ -642,7 +641,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ this.savePbxProj(project, projectData); } - private async addExtensions(projectData: IProjectData): Promise { + private async addExtensions(projectData: IProjectData, pluginsData: IPluginData[]): Promise { const resorcesExtensionsPath = path.join( projectData.getAppResourcesDirectoryPath(), this.getPlatformData(projectData).normalizedPlatformName, constants.NATIVE_EXTENSION_FOLDER @@ -650,10 +649,9 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ const platformData = this.getPlatformData(projectData); const pbxProjPath = this.getPbxProjPath(projectData); const addedExtensionsFromResources = await this.$iOSExtensionsService.addExtensionsFromPath({ extensionsFolderPath: resorcesExtensionsPath, projectData, platformData, pbxProjPath }); - const plugins = await this.getAllInstalledPlugins(projectData); let addedExtensionsFromPlugins = false; - for (const pluginIndex in plugins) { - const pluginData = plugins[pluginIndex]; + for (const pluginIndex in pluginsData) { + const pluginData = pluginsData[pluginIndex]; const pluginPlatformsFolderPath = pluginData.pluginPlatformsFolderPath(IOSProjectService.IOS_PLATFORM_NAME); const extensionPath = path.join(pluginPlatformsFolderPath, constants.NATIVE_EXTENSION_FOLDER); @@ -829,6 +827,15 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ this.$logger.warn("[WARNING]: The CFBundleIdentifier key inside the 'Info.plist' will be overriden by the 'id' inside 'package.json'."); } } + + private async applyPluginsCocoaPods(pluginsData: IPluginData[], projectData: IProjectData, platformData: IPlatformData) { + for (const pluginIndex in pluginsData) { + const pluginData = pluginsData[pluginIndex]; + if (this.$fs.exists(pluginData.pluginPlatformsFolderPath(platformData.normalizedPlatformName))) { + await this.$cocoapodsService.applyPodfileToProject(pluginData.name, this.$cocoapodsService.getPluginPodfilePath(pluginData), projectData, platformData); + } + } + } } $injector.register("iOSProjectService", IOSProjectService); diff --git a/lib/services/platform/prepare-native-platform-service.ts b/lib/services/platform/prepare-native-platform-service.ts index 1a9276beee..c70a93cd1b 100644 --- a/lib/services/platform/prepare-native-platform-service.ts +++ b/lib/services/platform/prepare-native-platform-service.ts @@ -37,7 +37,7 @@ export class PrepareNativePlatformService implements IPrepareNativePlatformServi } if (hasNativeModulesChange) { - await this.$nodeModulesBuilder.prepareNodeModules(platformData, projectData); + await this.$nodeModulesBuilder.prepareNodeModules({platformData, projectData}); } if (hasNativeModulesChange || hasConfigChange) { diff --git a/lib/services/plugins-service.ts b/lib/services/plugins-service.ts index 5b3d156d6d..943687ac4f 100644 --- a/lib/services/plugins-service.ts +++ b/lib/services/plugins-service.ts @@ -114,7 +114,7 @@ export class PluginsService implements IPluginsService { } } - public async preparePluginNativeCode(pluginData: IPluginData, platform: string, projectData: IProjectData): Promise { + public async preparePluginNativeCode({pluginData, platform, projectData}: IPreparePluginNativeCodeData): Promise { const platformData = this.$platformsDataService.getPlatformData(platform, projectData); pluginData.pluginPlatformsFolderPath = (_platform: string) => path.join(pluginData.fullPath, "platforms", _platform.toLowerCase()); diff --git a/lib/services/project-changes-service.ts b/lib/services/project-changes-service.ts index 55ce723b97..c31e349fd6 100644 --- a/lib/services/project-changes-service.ts +++ b/lib/services/project-changes-service.ts @@ -1,5 +1,5 @@ import * as path from "path"; -import { NativePlatformStatus, PACKAGE_JSON_FILE_NAME, APP_GRADLE_FILE_NAME, BUILD_XCCONFIG_FILE_NAME, PLATFORMS_DIR_NAME } from "../constants"; +import { NativePlatformStatus, PACKAGE_JSON_FILE_NAME, APP_GRADLE_FILE_NAME, BUILD_XCCONFIG_FILE_NAME, PLATFORMS_DIR_NAME, CONFIG_NS_FILE_NAME } from "../constants"; import { getHash, hook } from "../common/helpers"; const prepareInfoFileName = ".nsprepareinfo"; @@ -8,6 +8,7 @@ class ProjectChangesInfo implements IProjectChangesInfo { public appResourcesChanged: boolean; public configChanged: boolean; + public nsConfigChanged: boolean; public nativeChanged: boolean; public signingChanged: boolean; public nativePlatformStatus: NativePlatformStatus; @@ -70,6 +71,10 @@ export class ProjectChangesService implements IProjectChangesService { this._changesInfo.nativeChanged = this.isProjectFileChanged(projectData.projectDir, platformData); } + // If this causes too much rebuilds of the plugins or uncecessary builds for Android, move overrideCocoapods to prepareInfo. + this._changesInfo.nsConfigChanged = this.filesChanged([path.join(projectData.projectDir, CONFIG_NS_FILE_NAME)]); + this._changesInfo.nativeChanged = this._changesInfo.nativeChanged || this._changesInfo.nsConfigChanged; + this.$logger.trace(`Set nativeChanged to ${this._changesInfo.nativeChanged}.`); if (platformData.platformNameLowerCase === this.$devicePlatformsConstants.iOS.toLowerCase()) { @@ -183,6 +188,7 @@ export class ProjectChangesService implements IProjectChangesService { this._changesInfo.appResourcesChanged = true; this._changesInfo.configChanged = true; this._changesInfo.nativeChanged = true; + this._changesInfo.nsConfigChanged = true; return true; } diff --git a/lib/tools/node-modules/node-modules-builder.ts b/lib/tools/node-modules/node-modules-builder.ts index a42d8df47d..cbda44a9a2 100644 --- a/lib/tools/node-modules/node-modules-builder.ts +++ b/lib/tools/node-modules/node-modules-builder.ts @@ -5,7 +5,7 @@ export class NodeModulesBuilder implements INodeModulesBuilder { private $pluginsService: IPluginsService ) { } - public async prepareNodeModules(platformData: IPlatformData, projectData: IProjectData): Promise { + public async prepareNodeModules({platformData , projectData}: IPrepareNodeModulesData): Promise { const dependencies = this.$nodeModulesDependenciesBuilder.getProductionDependencies(projectData.projectDir); if (_.isEmpty(dependencies)) { return; @@ -19,7 +19,7 @@ export class NodeModulesBuilder implements INodeModulesBuilder { if (isPlugin) { this.$logger.debug(`Successfully prepared plugin ${dependency.name} for ${platformData.normalizedPlatformName.toLowerCase()}.`); const pluginData = this.$pluginsService.convertToPluginData(dependency, projectData.projectDir); - await this.$pluginsService.preparePluginNativeCode(pluginData, platformData.normalizedPlatformName.toLowerCase(), projectData); + await this.$pluginsService.preparePluginNativeCode({pluginData, platform: platformData.normalizedPlatformName.toLowerCase(), projectData}); } } } diff --git a/test/cocoapods-service.ts b/test/cocoapods-service.ts index 52ff704b3b..5bb7f1f030 100644 --- a/test/cocoapods-service.ts +++ b/test/cocoapods-service.ts @@ -47,14 +47,23 @@ describe("Cocoapods service", () => { }; const mockProjectData: any = { projectDir: "projectDir", - projectName: "projectName" + projectName: "projectName", + appResourcesDirectoryPath: "my/full/path/to/app/App_Resources", + nsConfig: { + overridePods: false + } + }; + + const mockPlatformData: any = { + projectRoot: "nativeProjectRoot", + normalizedPlatformName: "iOS" }; let testInjector: IInjector; let cocoapodsService: ICocoaPodsService; let newPodfileContent = ""; - const mockFileSystem = (injector: IInjector, podfileContent: string, projectPodfileContent?: string): void => { + const mockFileSystem = (injector: IInjector, podfileContent: string, projectPodfileContent?: string, appResourcesPodfileContent?: string): void => { const fs: IFileSystem = injector.resolve("fs"); fs.exists = () => true; @@ -63,6 +72,10 @@ describe("Cocoapods service", () => { return podfileContent; } + if (file.indexOf("App_Resources") !== -1) { + return appResourcesPodfileContent; + } + return newPodfileContent || projectPodfileContent || ""; }; @@ -515,7 +528,7 @@ end`, it(testCase.testCaseDescription, async () => { mockFileSystem(testInjector, testCase.input, testCase.projectPodfileContent); - await cocoapodsService.applyPodfileToProject(testCase.pluginData ? testCase.pluginData.name : mockPluginData.name, cocoapodsService.getPluginPodfilePath(testCase.pluginData || mockPluginData), mockProjectData, nativeProjectPath); + await cocoapodsService.applyPodfileToProject(testCase.pluginData ? testCase.pluginData.name : mockPluginData.name, cocoapodsService.getPluginPodfilePath(testCase.pluginData || mockPluginData), mockProjectData, mockPlatformData); assert.deepEqual(changeNewLineCharacter(newPodfileContent), changeNewLineCharacter(testCase.output)); }); @@ -821,11 +834,15 @@ end` projectPodfileContent = ""; }); - function setupMocks(pods: any[]): { projectData: IProjectData } { + function setupMocks(pods: any[]): { projectData: IProjectData, platformData: any } { const podsPaths = pods.map(p => p.path); const projectData = testInjector.resolve("projectData"); projectData.getAppResourcesDirectoryPath = () => "my/full/path/to/app/App_Resources"; + projectData.appResourcesDirectoryPath = "my/full/path/to/app/App_Resources"; projectData.projectName = "projectName"; + projectData.nsConfig = { + overridePods: false + }; const fs = testInjector.resolve("fs"); fs.exists = (filePath: string) => projectPodfilePath === filePath || _.includes(podsPaths, filePath); @@ -846,7 +863,9 @@ end` }; fs.deleteFile = () => ({}); - return { projectData }; + const platformData = { normalizedPlatformName: "iOS", projectRoot }; + + return { projectData, platformData }; } const testCasesWithApplyAndRemove = [ @@ -921,10 +940,10 @@ end` _.each(testCasesWithApplyAndRemove, testCase => { it(testCase.name, async () => { - const { projectData } = setupMocks(testCase.pods); + const { projectData, platformData } = setupMocks(testCase.pods); for (const pod of testCase.pods) { - await cocoapodsService.applyPodfileToProject(pod.name, pod.path, projectData, projectPodfilePath); + await cocoapodsService.applyPodfileToProject(pod.name, pod.path, projectData, platformData); } assert.deepEqual(projectPodfileContent, testCase.expectedProjectPodfileContentAfterApply); @@ -1160,11 +1179,11 @@ end` _.each(testCases, testCase => { it(testCase.name, async () => { - const { projectData } = setupMocks(testCase.pods); + const { projectData, platformData } = setupMocks(testCase.pods); cocoapodsService.removePodfileFromProject = () => ({}); for (const pod of testCase.pods) { - await cocoapodsService.applyPodfileToProject(pod.name, pod.path, projectData, projectPodfilePath); + await cocoapodsService.applyPodfileToProject(pod.name, pod.path, projectData, platformData); } assert.deepEqual(projectPodfileContent, testCase.expectedProjectPodfileContent); diff --git a/test/ios-project-service.ts b/test/ios-project-service.ts index fd1b2ed35c..cdf15f5aa7 100644 --- a/test/ios-project-service.ts +++ b/test/ios-project-service.ts @@ -79,7 +79,10 @@ function createTestInjector(projectPath: string, projectName: string, xCode?: IX projectDir: "", appDirectoryPath: "", appResourcesDirectoryPath: "", - getAppResourcesDirectoryPath: () => "" + getAppResourcesDirectoryPath: () => "", + nsConfig: { + overridePods: false + } }); projectData.projectDir = temp.mkdirSync("projectDir"); projectData.appDirectoryPath = join(projectData.projectDir, "app"); @@ -241,7 +244,7 @@ describe("Cocoapods support", () => { projectData.podfilePath = basePodfilePath; - await cocoapodsService.applyPodfileToProject(basePodfileModuleName, basePodfilePath, projectData, iOSProjectService.getPlatformData(projectData).projectRoot); + await cocoapodsService.applyPodfileToProject(basePodfileModuleName, basePodfilePath, projectData, iOSProjectService.getPlatformData(projectData)); const projectPodfilePath = join(platformsFolderPath, "Podfile"); assert.isTrue(fs.exists(projectPodfilePath), `File ${projectPodfilePath} must exist as we have already applied Podfile to it.`); @@ -265,7 +268,7 @@ describe("Cocoapods support", () => { fs.deleteFile(basePodfilePath); - await cocoapodsService.applyPodfileToProject(basePodfileModuleName, basePodfilePath, projectData, iOSProjectService.getPlatformData(projectData).projectRoot); + await cocoapodsService.applyPodfileToProject(basePodfileModuleName, basePodfilePath, projectData, iOSProjectService.getPlatformData(projectData)); assert.isFalse(fs.exists(projectPodfilePath), `The projectPodfilePath (${projectPodfilePath}) must not exist when all Podfiles have been deleted and project is prepared again. (i.e. CLI should delete the project Podfile in this case)`); }); @@ -315,11 +318,18 @@ describe("Cocoapods support", () => { const samplePluginData = { pluginPlatformsFolderPath(platform: string): string { return samplePluginPlatformsFolderPath; - } + }, + name: "somePlugin" }; const projectData: IProjectData = testInjector.resolve("projectData"); + const pluginsService = testInjector.resolve("pluginsService"); + pluginsService.getAllInstalledPlugins = () => { + return [samplePluginData]; + }; + const cocoapodsService = testInjector.resolve("cocoapodsService"); + cocoapodsService.executePodInstall = async () => { /* */ }; - await iOSProjectService.preparePluginNativeCode(samplePluginData, projectData); + await iOSProjectService.handleNativeDependenciesChange(projectData); const projectPodfilePath = join(platformsFolderPath, "Podfile"); assert.isTrue(fs.exists(projectPodfilePath)); @@ -400,8 +410,14 @@ describe("Cocoapods support", () => { fullPath: "fullPath" }; const projectData: IProjectData = testInjector.resolve("projectData"); + const pluginsService = testInjector.resolve("pluginsService"); + pluginsService.getAllInstalledPlugins = () => { + return [samplePluginData]; + }; + const cocoapodsService = testInjector.resolve("cocoapodsService"); + cocoapodsService.executePodInstall = async () => { /* */ }; - await iOSProjectService.preparePluginNativeCode(samplePluginData, projectData); + await iOSProjectService.handleNativeDependenciesChange(projectData); const projectPodfilePath = join(platformsFolderPath, "Podfile"); assert.isTrue(fs.exists(projectPodfilePath)); diff --git a/test/plugins-service.ts b/test/plugins-service.ts index cb44b1436f..c055aea6ee 100644 --- a/test/plugins-service.ts +++ b/test/plugins-service.ts @@ -570,7 +570,7 @@ describe("Plugins service", () => { `\n@#[line:1,col:39].` + `\n@#[line:1,col:39].`; mockBeginCommand(testInjector, expectedErrorMessage); - await pluginsService.preparePluginNativeCode(pluginsService.convertToPluginData(pluginJsonData, projectData.projectDir), "android", projectData); + await pluginsService.preparePluginNativeCode({pluginData: pluginsService.convertToPluginData(pluginJsonData, projectData.projectDir), platform: "android", projectData}); }); }); @@ -590,7 +590,8 @@ describe("Plugins service", () => { preparePluginNativeCode: async (pluginData: IPluginData, projData: IProjectData) => { testData.isPreparePluginNativeCodeCalled = true; } - } + }, + normalizedPlatformName: "iOS" }) }); @@ -643,21 +644,21 @@ describe("Plugins service", () => { it("does not prepare the files when plugin does not have platforms dir", async () => { const testData = setupTest({ hasPluginPlatformsDir: false }); - await testData.pluginsService.preparePluginNativeCode(testData.pluginData, platform, projectData); + await testData.pluginsService.preparePluginNativeCode({pluginData: testData.pluginData, platform, projectData}); assert.isFalse(testData.isPreparePluginNativeCodeCalled); }); it("prepares the files when plugin has platforms dir and has not been built before", async () => { const newPluginHashes = { "file": "hash" }; const testData = setupTest({ newPluginHashes, hasPluginPlatformsDir: true }); - await testData.pluginsService.preparePluginNativeCode(testData.pluginData, platform, projectData); + await testData.pluginsService.preparePluginNativeCode({pluginData: testData.pluginData, platform, projectData}); assert.isTrue(testData.isPreparePluginNativeCodeCalled); assert.deepEqual(testData.dataPassedToWriteJson, { [testData.pluginData.name]: newPluginHashes }); }); it("does not prepare the files when plugin has platforms dir and files have not changed since then", async () => { const testData = setupTest({ hasChangesInShasums: false, buildDataFileExists: true, hasPluginPlatformsDir: true }); - await testData.pluginsService.preparePluginNativeCode(testData.pluginData, platform, projectData); + await testData.pluginsService.preparePluginNativeCode({pluginData: testData.pluginData, platform, projectData}); assert.isFalse(testData.isPreparePluginNativeCodeCalled); }); });