Skip to content

Commit c1f934f

Browse files
Fatme HavaluovaFatme Havaluova
Fatme Havaluova
authored and
Fatme Havaluova
committed
Implements #1026
Removes the unneeded logic that merges configuration files
1 parent d6d17c4 commit c1f934f

10 files changed

+93
-231
lines changed

lib/definitions/platform.d.ts

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ interface IPlatformData {
3939
configurationFileName?: string;
4040
configurationFilePath?: string;
4141
relativeToFrameworkConfigurationFilePath: string;
42-
mergeXmlConfig?: any[];
4342
fastLivesyncFileExtensions: string[];
4443
}
4544

lib/definitions/plugins.d.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,20 @@ interface IPluginVariablesService {
4343
/**
4444
* Replaces all plugin variables with their corresponding values.
4545
* @param {IPluginData} pluginData for the plugin.
46-
* @param {pluginConfigurationFileContent} pluginConfigurationFileContent for the plugin.
47-
* @return {IFuture<string>} returns the changed plugin configuration file content.
46+
* @param {pluginConfigurationFilePath} pluginConfigurationFilePath for the plugin.
47+
* @return {IFuture<void>}
48+
*/
49+
interpolatePluginVariables(pluginData: IPluginData, pluginConfigurationFilePath: string): IFuture<void>;
50+
/**
51+
* Replaces {nativescript.id} expression with the application identifier from package.json.
52+
* @param {pluginConfigurationFilePath} pluginConfigurationFilePath for the plugin.
53+
* @return {IFuture<void>}
54+
*/
55+
interpolateAppIdentifier(pluginConfigurationFilePath: string): IFuture<void>;
56+
/**
57+
* Replaces both plugin variables and appIdentifier
4858
*/
49-
interpolatePluginVariables(pluginData: IPluginData, pluginConfigurationFileContent: string): IFuture<string>;
59+
interpolate(pluginData: IPluginData, pluginConfigurationFilePath: string): IFuture<void>;
5060
/**
5161
* Returns the
5262
* @param {IPluginData} pluginData for the plugin.

lib/services/android-project-service.ts

+11-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
2828
$projectDataService: IProjectDataService,
2929
private $sysInfo: ISysInfo,
3030
private $mobileHelper: Mobile.IMobileHelper,
31-
private $injector: IInjector) {
31+
private $injector: IInjector,
32+
private $pluginVariablesService: IPluginVariablesService) {
3233
super($fs, $projectData, $projectDataService);
3334
this._androidProjectPropertiesManagers = Object.create(null);
3435
}
@@ -56,7 +57,6 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
5657
configurationFileName: "AndroidManifest.xml",
5758
configurationFilePath: path.join(projectRoot, "src", "main", "AndroidManifest.xml"),
5859
relativeToFrameworkConfigurationFilePath: path.join("src", "main", "AndroidManifest.xml"),
59-
mergeXmlConfig: [{ "nodename": "manifest", "attrname": "*" }, {"nodename": "application", "attrname": "*"}],
6060
fastLivesyncFileExtensions: [".jpg", ".gif", ".png", ".bmp", ".webp"] // http://developer.android.com/guide/appendix/media-formats.html
6161
};
6262
}
@@ -284,27 +284,32 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
284284
public preparePluginNativeCode(pluginData: IPluginData): IFuture<void> {
285285
return (() => {
286286
let pluginPlatformsFolderPath = this.getPluginPlatformsFolderPath(pluginData, AndroidProjectService.ANDROID_PLATFORM_NAME);
287-
this.processResourcesFromPlugin(pluginData.name, pluginPlatformsFolderPath).wait();
287+
this.processResourcesFromPlugin(pluginData, pluginPlatformsFolderPath).wait();
288288
}).future<void>()();
289289
}
290290

291291
public processConfigurationFilesFromAppResources(): IFuture<void> {
292292
return Future.fromResult();
293293
}
294294

295-
private processResourcesFromPlugin(pluginName: string, pluginPlatformsFolderPath: string): IFuture<void> {
295+
private processResourcesFromPlugin(pluginData: IPluginData, pluginPlatformsFolderPath: string): IFuture<void> {
296296
return (() => {
297297
let configurationsDirectoryPath = path.join(this.platformData.projectRoot, "configurations");
298298
this.$fs.ensureDirectoryExists(configurationsDirectoryPath).wait();
299299

300-
let pluginConfigurationDirectoryPath = path.join(configurationsDirectoryPath, pluginName);
300+
let pluginConfigurationDirectoryPath = path.join(configurationsDirectoryPath, pluginData.name);
301301
if (this.$fs.exists(pluginPlatformsFolderPath).wait()) {
302302
this.$fs.ensureDirectoryExists(pluginConfigurationDirectoryPath).wait();
303303

304304
// Copy all resources from plugin
305-
let resourcesDestinationDirectoryPath = path.join(this.platformData.projectRoot, "src", pluginName);
305+
let resourcesDestinationDirectoryPath = path.join(this.platformData.projectRoot, "src", pluginData.name);
306306
this.$fs.ensureDirectoryExists(resourcesDestinationDirectoryPath).wait();
307307
shell.cp("-Rf", path.join(pluginPlatformsFolderPath, "*"), resourcesDestinationDirectoryPath);
308+
309+
let pluginConfigurationFilePath = path.join(resourcesDestinationDirectoryPath, this.platformData.configurationFileName);
310+
if (this.$fs.exists(pluginConfigurationFilePath).wait()) {
311+
this.$pluginVariablesService.interpolate(pluginData, pluginConfigurationFilePath).wait();
312+
}
308313
}
309314

310315
// Copy include.gradle file

lib/services/ios-project-service.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
3737
private $config: IConfiguration,
3838
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
3939
private $devicesService: Mobile.IDevicesService,
40-
private $mobileHelper: Mobile.IMobileHelper) {
40+
private $mobileHelper: Mobile.IMobileHelper,
41+
private $pluginVariablesService: IPluginVariablesService) {
4142
super($fs, $projectData, $projectDataService);
4243
}
4344

@@ -66,7 +67,6 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
6667
configurationFileName: "Info.plist",
6768
configurationFilePath: path.join(projectRoot, this.$projectData.projectName, this.$projectData.projectName+"-Info.plist"),
6869
relativeToFrameworkConfigurationFilePath: path.join("__PROJECT_NAME__", "__PROJECT_NAME__-Info.plist"),
69-
mergeXmlConfig: [{ "nodename": "plist", "attrname": "*" }, {"nodename": "dict", "attrname": "*"}],
7070
fastLivesyncFileExtensions: [".tiff", ".tif", ".jpg", "jpeg", "gif", ".png", ".bmp", ".BMPf", ".ico", ".cur", ".xbm"] // https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/
7171
};
7272
}
@@ -396,6 +396,10 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
396396
public processConfigurationFilesFromAppResources(): IFuture<void> {
397397
return (() => {
398398
this.mergeInfoPlists().wait();
399+
_(this.getAllInstalledPlugins().wait())
400+
.map(pluginData => this.$pluginVariablesService.interpolatePluginVariables(pluginData, this.platformData.configurationFilePath).wait())
401+
.value();
402+
this.$pluginVariablesService.interpolateAppIdentifier(this.platformData.configurationFilePath).wait();
399403
}).future<void>()();
400404
}
401405

@@ -405,7 +409,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
405409
let infoPlistPath = path.join(projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME, this.platformData.normalizedPlatformName, this.platformData.configurationFileName);
406410

407411
if (!this.$fs.exists(infoPlistPath).wait()) {
408-
// The project is missing Info.plist, try to populate it from the project tempalte.
412+
// The project is missing Info.plist, try to populate it from the project template.
409413
let projectTemplateService: IProjectTemplatesService = this.$injector.resolve("projectTemplatesService");
410414
let defaultTemplatePath = projectTemplateService.defaultTemplatePath.wait();
411415
let templateInfoPlist = path.join(defaultTemplatePath, constants.APP_RESOURCES_FOLDER_NAME, this.$devicePlatformsConstants.iOS, this.platformData.configurationFileName);
@@ -438,7 +442,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
438442
});
439443
};
440444

441-
let allPlugins: IPluginData[] = (<IPluginsService>this.$injector.resolve("pluginsService")).getAllInstalledPlugins().wait();
445+
let allPlugins = this.getAllInstalledPlugins().wait();
442446
for (let plugin of allPlugins) {
443447
let pluginInfoPlistPath = path.join(plugin.pluginPlatformsFolderPath(IOSProjectService.IOS_PLATFORM_NAME), this.platformData.configurationFileName);
444448
makePatch(pluginInfoPlistPath);
@@ -469,6 +473,10 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
469473
}).future<void>()();
470474
}
471475

476+
private getAllInstalledPlugins(): IFuture<IPluginData[]> {
477+
return (<IPluginsService>this.$injector.resolve("pluginsService")).getAllInstalledPlugins();
478+
}
479+
472480
private get projectPodFilePath(): string {
473481
return path.join(this.platformData.projectRoot, "Podfile");
474482
}

lib/services/plugin-variables-service.ts

+26-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ export class PluginVariablesService implements IPluginVariablesService {
1010
private $pluginVariablesHelper: IPluginVariablesHelper,
1111
private $projectData: IProjectData,
1212
private $projectDataService: IProjectDataService,
13-
private $prompter: IPrompter) { }
13+
private $prompter: IPrompter,
14+
private $fs: IFileSystem) { }
1415

1516
public getPluginVariablePropertyName(pluginData: IPluginData): string {
1617
return `${pluginData.name}-${PluginVariablesService.PLUGIN_VARIABLES_KEY}`;
@@ -38,15 +39,35 @@ export class PluginVariablesService implements IPluginVariablesService {
3839
return this.$projectDataService.removeProperty(this.getPluginVariablePropertyName(pluginData));
3940
}
4041

41-
public interpolatePluginVariables(pluginData: IPluginData, pluginConfigurationFileContent: string): IFuture<string> {
42+
public interpolatePluginVariables(pluginData: IPluginData, pluginConfigurationFilePath: string): IFuture<void> {
4243
return (() => {
44+
let pluginConfigurationFileContent = this.$fs.readText(pluginConfigurationFilePath).wait();
4345
this.executeForAllPluginVariables(pluginData, (pluginVariableData: IPluginVariableData) =>
4446
(() => {
4547
this.ensurePluginVariableValue(pluginVariableData.value, `Unable to find the value for ${pluginVariableData.name} plugin variable into project package.json file. Verify that your package.json file is correct and try again.`);
46-
pluginConfigurationFileContent = pluginConfigurationFileContent.replace(new RegExp(`{${pluginVariableData.name}}`, "gi"), pluginVariableData.value);
48+
pluginConfigurationFileContent = this.interpolateCore(pluginVariableData.name, pluginVariableData.value, pluginConfigurationFileContent);
4749
}).future<void>()()).wait();
48-
return pluginConfigurationFileContent;
49-
}).future<string>()();
50+
this.$fs.writeFile(pluginConfigurationFilePath, pluginConfigurationFileContent).wait();
51+
}).future<void>()();
52+
}
53+
54+
public interpolateAppIdentifier(pluginConfigurationFilePath: string): IFuture<void> {
55+
return (() => {
56+
let pluginConfigurationFileContent = this.$fs.readText(pluginConfigurationFilePath).wait();
57+
let newContent = this.interpolateCore("nativescript.id", this.$projectData.projectId, pluginConfigurationFileContent);
58+
this.$fs.writeFile(pluginConfigurationFilePath, newContent).wait();
59+
}).future<void>()();
60+
}
61+
62+
public interpolate(pluginData: IPluginData, pluginConfigurationFilePath: string): IFuture<void> {
63+
return (() => {
64+
this.interpolatePluginVariables(pluginData, pluginConfigurationFilePath).wait();
65+
this.interpolateAppIdentifier(pluginConfigurationFilePath).wait();
66+
}).future<void>()();
67+
}
68+
69+
private interpolateCore(name: string, value: string, content: string): string {
70+
return content.replace(new RegExp(`{${name}}`, "gi"), value);
5071
}
5172

5273
private ensurePluginVariableValue(pluginVariableValue: string, errorMessage: string): void {

lib/services/plugins-service.ts

-110
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import * as path from "path";
44
import * as shelljs from "shelljs";
55
import * as semver from "semver";
6-
import Future = require("fibers/future");
76
import * as constants from "../constants";
8-
let xmlmerge = require("xmlmerge-js");
9-
let DOMParser = require('xmldom').DOMParser;
107

118
export class PluginsService implements IPluginsService {
129
private static INSTALL_COMMAND_NAME = "install";
@@ -72,12 +69,6 @@ export class PluginsService implements IPluginsService {
7269

7370
platformData.platformProjectService.removePluginNativeCode(pluginData).wait();
7471

75-
// Remove the plugin and call merge for another plugins that have configuration file
76-
let pluginConfigurationFilePath = this.getPluginConfigurationFilePath(pluginData, platformData);
77-
if(this.$fs.exists(pluginConfigurationFilePath).wait()) {
78-
this.merge(pluginData, platformData, (data: IPluginData) => data.name !== pluginData.name).wait();
79-
}
80-
8172
if(pluginData.pluginVariables) {
8273
this.$pluginVariablesService.removePluginVariablesFromProjectFile(pluginData).wait();
8374
}
@@ -104,24 +95,6 @@ export class PluginsService implements IPluginsService {
10495
}).future<void>()();
10596
}
10697

107-
private initializeConfigurationFileFromCache(platformData: IPlatformData): IFuture<void> {
108-
return (() => {
109-
this.$projectDataService.initialize(this.$projectData.projectDir);
110-
let frameworkVersion = this.$projectDataService.getValue(platformData.frameworkPackageName).wait().version;
111-
112-
// We need to resolve this manager here due to some restrictions from npm api and in order to load PluginsService.NPM_CONFIG config
113-
let npmInstallationManager: INpmInstallationManager = this.$injector.resolve("npmInstallationManager");
114-
npmInstallationManager.addToCache(platformData.frameworkPackageName, frameworkVersion).wait();
115-
116-
let cachedPackagePath = npmInstallationManager.getCachedPackagePath(platformData.frameworkPackageName, frameworkVersion);
117-
let cachedConfigurationFilePath = this.$options.baseConfig ? path.resolve(this.$options.baseConfig) : path.join(cachedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME, platformData.relativeToFrameworkConfigurationFilePath);
118-
let cachedConfigurationFileContent = this.$fs.readText(cachedConfigurationFilePath).wait();
119-
this.$fs.writeFile(platformData.configurationFilePath, cachedConfigurationFileContent).wait();
120-
121-
platformData.platformProjectService.interpolateConfigurationFile().wait();
122-
}).future<void>()();
123-
}
124-
12598
public prepare(dependencyData: IDependencyData, platform: string): IFuture<void> {
12699
return (() => {
127100
platform = platform.toLowerCase();
@@ -137,12 +110,6 @@ export class PluginsService implements IPluginsService {
137110
this.$fs.ensureDirectoryExists(pluginDestinationPath).wait();
138111
shelljs.cp("-Rf", pluginData.fullPath, pluginDestinationPath);
139112

140-
let pluginConfigurationFilePath = this.getPluginConfigurationFilePath(pluginData, platformData);
141-
142-
if(this.$fs.exists(pluginConfigurationFilePath).wait()) {
143-
this.merge(pluginData, platformData).wait();
144-
}
145-
146113
this.$projectFilesManager.processPlatformSpecificFiles(pluginDestinationPath, platform).wait();
147114

148115
pluginData.pluginPlatformsFolderPath = (_platform: string) => path.join(pluginData.fullPath, "platforms", _platform);
@@ -290,83 +257,6 @@ export class PluginsService implements IPluginsService {
290257
}).future<string>()();
291258
}
292259

293-
private mergeXml(xml1: string, xml2: string, config: any[]): IFuture<string> {
294-
let future = new Future<string>();
295-
296-
try {
297-
xmlmerge.merge(xml1, xml2, config, (mergedXml: string) => {
298-
future.return(mergedXml);
299-
});
300-
} catch(err) {
301-
future.throw(err);
302-
}
303-
304-
return future;
305-
}
306-
307-
private validateXml(xml: string, xmlFilePath?: string): void {
308-
let doc = new DOMParser({
309-
locator: {},
310-
errorHandler: (level: any, msg: string) => {
311-
let errorMessage = xmlFilePath ? `Invalid xml file ${xmlFilePath}.` : `Invalid xml ${xml}.`;
312-
this.$errors.fail(errorMessage + ` Additional technical information: ${msg}.` );
313-
}
314-
});
315-
doc.parseFromString(xml, 'text/xml');
316-
}
317-
318-
private mergeCore(pluginData: IPluginData, platformData: IPlatformData): IFuture<void> {
319-
return (() => {
320-
let pluginConfigurationFilePath = this.getPluginConfigurationFilePath(pluginData, platformData);
321-
let configurationFilePath = platformData.configurationFilePath;
322-
323-
// Validate plugin configuration file
324-
let pluginConfigurationFileContent = this.$fs.readText(pluginConfigurationFilePath).wait();
325-
pluginConfigurationFileContent = this.$pluginVariablesService.interpolatePluginVariables(pluginData, pluginConfigurationFileContent).wait();
326-
this.validateXml(pluginConfigurationFileContent, pluginConfigurationFilePath);
327-
328-
// Validate configuration file
329-
let configurationFileContent = this.$fs.readText(configurationFilePath).wait();
330-
this.validateXml(configurationFileContent, configurationFilePath);
331-
332-
// Merge xml
333-
let resultXml = this.mergeXml(configurationFileContent, pluginConfigurationFileContent, platformData.mergeXmlConfig || []).wait();
334-
this.validateXml(resultXml);
335-
this.$fs.writeFile(configurationFilePath, resultXml).wait();
336-
}).future<void>()();
337-
}
338-
339-
private merge(pluginData: IPluginData, platformData: IPlatformData, mergeCondition?: (_pluginData: IPluginData) => boolean): IFuture<void> {
340-
return (() => {
341-
let tnsModulesDestinationPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.TNS_MODULES_FOLDER_NAME);
342-
let nodeModules = this.$broccoliBuilder.getChangedNodeModules(tnsModulesDestinationPath, platformData.normalizedPlatformName.toLowerCase()).wait();
343-
344-
_(nodeModules)
345-
.keys()
346-
.filter(nodeModule => this.$fs.exists(path.join(nodeModule, "package.json")).wait())
347-
.map(nodeModule => this.getNodeModuleData(path.join(nodeModule, "package.json")).wait())
348-
.map(nodeModuleData => this.convertToPluginData(nodeModuleData))
349-
.filter(data => data.isPlugin && this.$fs.exists(this.getPluginConfigurationFilePath(data, platformData)).wait())
350-
.forEach((data, index) => {
351-
if(index === 0) {
352-
this.initializeConfigurationFileFromCache(platformData).wait();
353-
}
354-
355-
if(!mergeCondition || (mergeCondition && mergeCondition(data))) {
356-
this.mergeCore(data, platformData).wait();
357-
}
358-
})
359-
.value();
360-
361-
}).future<void>()();
362-
}
363-
364-
private getPluginConfigurationFilePath(pluginData: IPluginData, platformData: IPlatformData): string {
365-
let pluginPlatformsFolderPath = pluginData.pluginPlatformsFolderPath(platformData.normalizedPlatformName.toLowerCase());
366-
let pluginConfigurationFilePath = path.join(pluginPlatformsFolderPath, platformData.configurationFileName);
367-
return pluginConfigurationFilePath;
368-
}
369-
370260
private isPluginDataValidForPlatform(pluginData: IPluginData, platform: string): IFuture<boolean> {
371261
return (() => {
372262
let isValid = true;

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@
7878
"xcode": "https://github.com/NativeScript/node-xcode/archive/1.4.0.tar.gz",
7979
"xmldom": "0.1.21",
8080
"xmlhttprequest": "https://github.com/telerik/node-XMLHttpRequest/tarball/master",
81-
"xmlmerge-js": "0.2.4",
8281
"yargs": "3.15.0"
8382
},
8483
"analyze": true,

test/ios-project-service.ts

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import {LoggingLevels} from "../lib/common/mobile/logging-levels";
2222
import {DeviceDiscovery} from "../lib/common/mobile/mobile-core/device-discovery";
2323
import {IOSDeviceDiscovery} from "../lib/common/mobile/mobile-core/ios-device-discovery";
2424
import {AndroidDeviceDiscovery} from "../lib/common/mobile/mobile-core/android-device-discovery";
25+
import {PluginVariablesService} from "../lib/services/plugin-variables-service";
26+
import {PluginVariablesHelper} from "../lib/common/plugin-variables-helper";
2527
import {Utils} from "../lib/common/utils";
2628
import { assert } from "chai";
2729
import temp = require("temp");
@@ -73,6 +75,8 @@ function createTestInjector(projectPath: string, projectName: string): IInjector
7375
testInjector.register("loggingLevels", LoggingLevels);
7476
testInjector.register("utils", Utils);
7577
testInjector.register("iTunesValidator", {});
78+
testInjector.register("pluginVariablesService", PluginVariablesService);
79+
testInjector.register("pluginVariablesHelper", PluginVariablesHelper);
7680
return testInjector;
7781
}
7882

0 commit comments

Comments
 (0)