Skip to content

Commit dab0364

Browse files
committed
Merge pull request #1083 from NativeScript/fatme/fix-info-plist-merge
Fix failed ios build after second info-plist merge
2 parents 31b2621 + 2daee31 commit dab0364

12 files changed

+130
-72
lines changed

lib/definitions/npm.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,10 @@ declare module "npm" {
33
var commands: { [index: string]: any };
44
var prefix: string;
55
function load(config: Object, callback: (err: any, data: any) => void): void;
6+
module config {
7+
var loaded: boolean;
8+
module sources {
9+
var cli: { data: Object };
10+
}
11+
}
612
}

lib/definitions/platform.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ interface IPlatformData {
3636
targetedOS?: string[];
3737
configurationFileName?: string;
3838
configurationFilePath?: string;
39+
relativeToFrameworkConfigurationFilePath: string;
3940
mergeXmlConfig?: any[];
4041
}
4142

lib/definitions/project.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ interface IPlatformProjectService {
3636
platformData: IPlatformData;
3737
validate(): IFuture<void>;
3838
createProject(frameworkDir: string, frameworkVersion: string): IFuture<void>;
39-
interpolateData(projectRoot: string): IFuture<void>;
39+
interpolateData(): IFuture<void>;
40+
interpolateConfigurationFile(configurationFilePath?: string): IFuture<void>;
4041
afterCreateProject(projectRoot: string): IFuture<void>;
4142
buildProject(projectRoot: string, buildConfig?: IBuildConfig): IFuture<void>;
4243
prepareProject(): IFuture<void>;

lib/node-package-manager.ts

+17-8
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,24 @@ export class NodePackageManager implements INodePackageManager {
1919
}
2020

2121
public load(config?: any): IFuture<void> {
22-
let future = new Future<void>();
23-
npm.load(config, (err: Error) => {
24-
if(err) {
25-
future.throw(err);
26-
} else {
27-
future.return();
22+
if (npm.config.loaded) {
23+
let data = npm.config.sources.cli.data;
24+
Object.keys(data).forEach(k => delete data[k]);
25+
if (config) {
26+
_.assign(data, config);
2827
}
29-
});
30-
return future;
28+
return Future.fromResult();
29+
} else {
30+
let future = new Future<void>();
31+
npm.load(config, (err: Error) => {
32+
if(err) {
33+
future.throw(err);
34+
} else {
35+
future.return();
36+
}
37+
});
38+
return future;
39+
}
3140
}
3241

3342
public install(packageName: string, pathToSave: string, config?: any): IFuture<any> {

lib/services/android-project-service.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as semver from "semver";
88
import * as projectServiceBaseLib from "./platform-project-service-base";
99
import * as androidDebugBridgePath from "../common/mobile/android/android-debug-bridge";
1010

11-
class AndroidProjectService extends projectServiceBaseLib.PlatformProjectServiceBase implements IPlatformProjectService {
11+
export class AndroidProjectService extends projectServiceBaseLib.PlatformProjectServiceBase implements IPlatformProjectService {
1212
private static VALUES_DIRNAME = "values";
1313
private static VALUES_VERSION_DIRNAME_PREFIX = AndroidProjectService.VALUES_DIRNAME + "-v";
1414
private static ANDROID_PLATFORM_NAME = "android";
@@ -57,6 +57,7 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
5757
frameworkFilesExtensions: [".jar", ".dat", ".so"],
5858
configurationFileName: "AndroidManifest.xml",
5959
configurationFilePath: path.join(projectRoot, "src", "main", "AndroidManifest.xml"),
60+
relativeToFrameworkConfigurationFilePath: path.join("src", "main", "AndroidManifest.xml"),
6061
mergeXmlConfig: [{ "nodename": "manifest", "attrname": "*" }, {"nodename": "application", "attrname": "*"}]
6162
};
6263
}
@@ -133,18 +134,24 @@ class AndroidProjectService extends projectServiceBaseLib.PlatformProjectService
133134
}).future<void>()();
134135
}
135136

136-
public interpolateData(projectRoot: string): IFuture<void> {
137+
public interpolateData(): IFuture<void> {
137138
return (() => {
138-
// Interpolate the activity name and package
139-
let manifestPath = this.platformData.configurationFilePath;
140-
shell.sed('-i', /__PACKAGE__/, this.$projectData.projectId, manifestPath);
139+
// Interpolate the apilevel and package
140+
this.interpolateConfigurationFile().wait();
141141

142142
let stringsFilePath = path.join(this.getAppResourcesDestinationDirectoryPath().wait(), 'values', 'strings.xml');
143143
shell.sed('-i', /__NAME__/, this.$projectData.projectName, stringsFilePath);
144144
shell.sed('-i', /__TITLE_ACTIVITY__/, this.$projectData.projectName, stringsFilePath);
145145

146146
let gradleSettingsFilePath = path.join(this.platformData.projectRoot, "settings.gradle");
147147
shell.sed('-i', /__PROJECT_NAME__/, this.getProjectNameFromId(), gradleSettingsFilePath);
148+
}).future<void>()();
149+
}
150+
151+
public interpolateConfigurationFile(): IFuture<void> {
152+
return (() => {
153+
let manifestPath = this.platformData.configurationFilePath;
154+
shell.sed('-i', /__PACKAGE__/, this.$projectData.projectId, manifestPath);
148155
shell.sed('-i', /__APILEVEL__/, this.$options.sdk || this.$androidToolsInfo.getToolsInfo().wait().compileSdkVersion.toString(), manifestPath);
149156
}).future<void>()();
150157
}

lib/services/ios-project-service.ts

+15-7
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
6161
targetedOS: ['darwin'],
6262
configurationFileName: "Info.plist",
6363
configurationFilePath: path.join(projectRoot, this.$projectData.projectName, this.$projectData.projectName+"-Info.plist"),
64+
relativeToFrameworkConfigurationFilePath: path.join("__PROJECT_NAME__", "__PROJECT_NAME__-Info.plist"),
6465
mergeXmlConfig: [{ "nodename": "plist", "attrname": "*" }, {"nodename": "dict", "attrname": "*"}]
6566
};
6667
}
@@ -119,20 +120,27 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
119120
}).future<void>()();
120121
}
121122

122-
public interpolateData(projectRoot: string): IFuture<void> {
123+
public interpolateData(): IFuture<void> {
123124
return (() => {
124-
let infoPlistFilePath = path.join(projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, util.format("%s-%s", IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, "Info.plist"));
125-
shell.sed('-i', "__CFBUNDLEIDENTIFIER__", this.$projectData.projectId, infoPlistFilePath);
125+
let infoPlistFilePath = path.join(this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, util.format("%s-%s", IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, "Info.plist"));
126+
this.interpolateConfigurationFile(infoPlistFilePath).wait();
126127

127-
this.replaceFileName("-Info.plist", path.join(projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER)).wait();
128-
this.replaceFileName("-Prefix.pch", path.join(projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER)).wait();
129-
this.replaceFileName(IOSProjectService.XCODE_PROJECT_EXT_NAME, projectRoot).wait();
128+
let projectRootFilePath = path.join(this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER);
129+
this.replaceFileName("-Info.plist", projectRootFilePath).wait();
130+
this.replaceFileName("-Prefix.pch", projectRootFilePath).wait();
131+
this.replaceFileName(IOSProjectService.XCODE_PROJECT_EXT_NAME, this.platformData.projectRoot).wait();
130132

131-
let pbxprojFilePath = path.join(projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj");
133+
let pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj");
132134
this.replaceFileContent(pbxprojFilePath).wait();
133135
}).future<void>()();
134136
}
135137

138+
public interpolateConfigurationFile(configurationFilePath?: string): IFuture<void> {
139+
return (() => {
140+
shell.sed('-i', "__CFBUNDLEIDENTIFIER__", this.$projectData.projectId, configurationFilePath || this.platformData.configurationFilePath);
141+
}).future<void>()();
142+
}
143+
136144
public afterCreateProject(projectRoot: string): IFuture<void> {
137145
return (() => {
138146
this.$fs.rename(path.join(projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER),

lib/services/platform-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export class PlatformService implements IPlatformService {
102102
this.$fs.deleteDirectory(path.join(frameworkDir, "../../")).wait();
103103
}
104104

105-
platformData.platformProjectService.interpolateData(platformData.projectRoot).wait();
105+
platformData.platformProjectService.interpolateData().wait();
106106
platformData.platformProjectService.afterCreateProject(platformData.projectRoot).wait();
107107

108108
this.$projectDataService.initialize(this.$projectData.projectDir);

lib/services/plugins-service.ts

+33-37
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,6 @@ export class PluginsService implements IPluginsService {
6666

6767
public remove(pluginName: string): IFuture<void> {
6868
return (() => {
69-
let isUninstallCommandExecuted = false;
70-
71-
let executeUninstallCommand = () => {
72-
return (() => {
73-
if(!isUninstallCommandExecuted) {
74-
this.executeNpmCommand(PluginsService.UNINSTALL_COMMAND_NAME, pluginName).wait();
75-
isUninstallCommandExecuted = true;
76-
}
77-
}).future<void>()();
78-
};
79-
8069
let removePluginNativeCodeAction = (modulesDestinationPath: string, platform: string, platformData: IPlatformData) => {
8170
return (() => {
8271
let pluginData = this.convertToPluginData(this.getNodeModuleData(pluginName).wait());
@@ -86,25 +75,7 @@ export class PluginsService implements IPluginsService {
8675
// Remove the plugin and call merge for another plugins that have configuration file
8776
let pluginConfigurationFilePath = this.getPluginConfigurationFilePath(pluginData, platformData);
8877
if(this.$fs.exists(pluginConfigurationFilePath).wait()) {
89-
let tnsModulesDestinationPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.TNS_MODULES_FOLDER_NAME);
90-
let nodeModules = this.$broccoliBuilder.getChangedNodeModules(tnsModulesDestinationPath, platform).wait();
91-
92-
_(nodeModules)
93-
.map(nodeModule => this.getNodeModuleData(pluginName).wait())
94-
.map(nodeModuleData => this.convertToPluginData(nodeModuleData))
95-
.filter(data => data.isPlugin && this.$fs.exists(this.getPluginConfigurationFilePath(data, platformData)).wait())
96-
.forEach((data, index) => {
97-
executeUninstallCommand().wait();
98-
99-
if(index === 0) {
100-
this.initializeConfigurationFileFromCache(platformData).wait();
101-
}
102-
103-
if(data.name !== pluginName) {
104-
this.merge(data, platformData).wait();
105-
}
106-
})
107-
.value();
78+
this.merge(pluginData, platformData, (data: IPluginData) => data.name !== pluginData.name).wait();
10879
}
10980

11081
if(pluginData.pluginVariables) {
@@ -114,7 +85,7 @@ export class PluginsService implements IPluginsService {
11485
};
11586
this.executeForAllInstalledPlatforms(removePluginNativeCodeAction).wait();
11687

117-
executeUninstallCommand().wait();
88+
this.executeNpmCommand(PluginsService.UNINSTALL_COMMAND_NAME, pluginName).wait();
11889

11990
let showMessage = true;
12091
let action = (modulesDestinationPath: string, platform: string, platformData: IPlatformData) => {
@@ -137,15 +108,17 @@ export class PluginsService implements IPluginsService {
137108
return (() => {
138109
this.$projectDataService.initialize(this.$projectData.projectDir);
139110
let frameworkVersion = this.$projectDataService.getValue(platformData.frameworkPackageName).wait().version;
140-
this.$npm.cache(platformData.frameworkPackageName, frameworkVersion).wait();
141111

142-
let relativeConfigurationFilePath = path.relative(platformData.projectRoot, platformData.configurationFilePath);
143112
// We need to resolve this manager here due to some restrictions from npm api and in order to load PluginsService.NPM_CONFIG config
144113
let npmInstallationManager: INpmInstallationManager = this.$injector.resolve("npmInstallationManager");
114+
npmInstallationManager.addToCache(platformData.frameworkPackageName, frameworkVersion).wait();
115+
145116
let cachedPackagePath = npmInstallationManager.getCachedPackagePath(platformData.frameworkPackageName, frameworkVersion);
146-
let cachedConfigurationFilePath = path.join(cachedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME, relativeConfigurationFilePath);
117+
let cachedConfigurationFilePath = 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();
147120

148-
shelljs.cp("-f", cachedConfigurationFilePath, path.dirname(platformData.configurationFilePath));
121+
platformData.platformProjectService.interpolateConfigurationFile().wait();
149122
}).future<void>()();
150123
}
151124

@@ -164,7 +137,6 @@ export class PluginsService implements IPluginsService {
164137
shelljs.cp("-Rf", pluginData.fullPath, pluginDestinationPath);
165138

166139
let pluginConfigurationFilePath = this.getPluginConfigurationFilePath(pluginData, platformData);
167-
168140
if(this.$fs.exists(pluginConfigurationFilePath).wait()) {
169141
this.merge(pluginData, platformData).wait();
170142
}
@@ -347,7 +319,7 @@ export class PluginsService implements IPluginsService {
347319
doc.parseFromString(xml, 'text/xml');
348320
}
349321

350-
private merge(pluginData: IPluginData, platformData: IPlatformData): IFuture<void> {
322+
private mergeCore(pluginData: IPluginData, platformData: IPlatformData): IFuture<void> {
351323
return (() => {
352324
let pluginConfigurationFilePath = this.getPluginConfigurationFilePath(pluginData, platformData);
353325
let configurationFilePath = platformData.configurationFilePath;
@@ -368,6 +340,30 @@ export class PluginsService implements IPluginsService {
368340
}).future<void>()();
369341
}
370342

343+
private merge(pluginData: IPluginData, platformData: IPlatformData, mergeCondition?: (_pluginData: IPluginData) => boolean): IFuture<void> {
344+
return (() => {
345+
let tnsModulesDestinationPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.TNS_MODULES_FOLDER_NAME);
346+
let nodeModules = this.$broccoliBuilder.getChangedNodeModules(tnsModulesDestinationPath, platformData.normalizedPlatformName.toLowerCase()).wait();
347+
348+
_(nodeModules)
349+
.keys()
350+
.map(nodeModule => this.getNodeModuleData(path.join(nodeModule, "package.json")).wait())
351+
.map(nodeModuleData => this.convertToPluginData(nodeModuleData))
352+
.filter(data => data.isPlugin && this.$fs.exists(this.getPluginConfigurationFilePath(data, platformData)).wait())
353+
.forEach((data, index) => {
354+
if(index === 0) {
355+
this.initializeConfigurationFileFromCache(platformData).wait();
356+
}
357+
358+
if(!mergeCondition || (mergeCondition && mergeCondition(data))) {
359+
this.mergeCore(data, platformData).wait();
360+
}
361+
})
362+
.value();
363+
364+
}).future<void>()();
365+
}
366+
371367
private getPluginConfigurationFilePath(pluginData: IPluginData, platformData: IPlatformData): string {
372368
let pluginPlatformsFolderPath = pluginData.pluginPlatformsFolderPath(platformData.normalizedPlatformName.toLowerCase());
373369
let pluginConfigurationFilePath = path.join(pluginPlatformsFolderPath, platformData.configurationFileName);

lib/tools/broccoli/builder.ts

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ let through = require("through2");
1212

1313
export class Builder implements IBroccoliBuilder {
1414
constructor(private $fs: IFileSystem,
15-
private $nodeModulesTree: INodeModulesTree,
1615
private $projectData: IProjectData,
1716
private $projectDataService: IProjectDataService,
1817
private $injector: IInjector,

test/platform-commands.ts

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class PlatformData implements IPlatformData {
2828
frameworkVersion = "";
2929
appDestinationDirectoryPath = "";
3030
appResourcesDestinationDirectoryPath = "";
31+
relativeToFrameworkConfigurationFilePath = "";
3132
}
3233

3334
class ErrorsNoFailStub implements IErrors {

0 commit comments

Comments
 (0)