Skip to content

Commit 4354c81

Browse files
committed
fix: remove duplicated platforms from project's podfile
fixes #3604
1 parent e9d98ee commit 4354c81

File tree

5 files changed

+221
-1
lines changed

5 files changed

+221
-1
lines changed

lib/definitions/project.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,8 @@ interface ICocoaPodsService {
540540
* @param opts
541541
*/
542542
mergePodXcconfigFile(projectData: IProjectData, platformData: IPlatformData, opts: IRelease): Promise<void>;
543+
544+
removeDuplicatedPlatfomsFromProjectPodFile(projectRoot: string): Promise<void>;
543545
}
544546

545547
interface IRubyFunction {

lib/services/cocoapods-service.ts

+43-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { EOL } from "os";
22
import * as path from "path";
33
import { PluginNativeDirNames, PODFILE_NAME, NS_BASE_PODFILE } from "../constants";
4+
import * as semver from "semver";
45

56
export class CocoaPodsService implements ICocoaPodsService {
67
private static PODFILE_POST_INSTALL_SECTION_NAME = "post_install";
@@ -98,7 +99,6 @@ export class CocoaPodsService implements ICocoaPodsService {
9899
}
99100

100101
public removePodfileFromProject(moduleName: string, podfilePath: string, projectData: IProjectData, projectRoot: string): void {
101-
102102
if (this.$fs.exists(this.getProjectPodfilePath(projectRoot))) {
103103
let projectPodFileContent = this.$fs.readText(this.getProjectPodfilePath(projectRoot));
104104
// Remove the data between #Begin Podfile and #EndPodfile
@@ -124,6 +124,48 @@ export class CocoaPodsService implements ICocoaPodsService {
124124
return pluginPodFilePath;
125125
}
126126

127+
public async removeDuplicatedPlatfomsFromProjectPodFile(projectRoot: string): Promise<void> {
128+
const projectPodfilePath = this.getProjectPodfilePath(projectRoot);
129+
if (this.$fs.exists(projectPodfilePath)) {
130+
let projectPodfileContent = this.$fs.readText(projectPodfilePath);
131+
const appResourcesRegExp = new RegExp(`# Begin Podfile - [\\S]*?\/App_Resources\/iOS\/Podfile[\\s\\S]*?platform[\\s\\S]*?# End Podfile`, "mg");
132+
let selectedPodfileWithPlatform = (projectPodfileContent.match(appResourcesRegExp) || [])[0];
133+
134+
const regExp = new RegExp(`# Begin Podfile - [\\s\\S]*?platform[\\s\\S]*?# End Podfile`, "mg");
135+
const podfilesWithPlatform = (projectPodfileContent.match(regExp) || [])
136+
.filter(podfileContent => podfileContent.split(EOL)[0].split(" - ")[1].indexOf('App_Resources/iOS/Podfile') < 0);
137+
138+
if (!selectedPodfileWithPlatform) {
139+
const podfilePlatformVersion: string = null;
140+
_.each(podfilesWithPlatform, podfileContent => {
141+
const platformLine = podfileContent.split(EOL).find(line => line.startsWith('platform'));
142+
const rawPlatformVersion = platformLine.split(", '")[1];
143+
if (!rawPlatformVersion) {
144+
selectedPodfileWithPlatform = podfileContent;
145+
return false;
146+
}
147+
148+
const platformVersion = rawPlatformVersion.substr(0, rawPlatformVersion.length - 1);
149+
if (!podfilePlatformVersion || semver.gt(semver.coerce(platformVersion), semver.coerce(podfilePlatformVersion))) {
150+
selectedPodfileWithPlatform = podfileContent;
151+
}
152+
});
153+
}
154+
155+
if (selectedPodfileWithPlatform) {
156+
podfilesWithPlatform
157+
.filter(podfileContent => podfileContent !== selectedPodfileWithPlatform)
158+
.map(podfileContent => {
159+
const podfilePath = podfileContent.split(EOL)[0].split(" - ")[1];
160+
const contentWithoutPlatform = podfileContent.replace(new RegExp(`^platform.*$`, "mg"), "");
161+
projectPodfileContent = projectPodfileContent.replace(new RegExp(`# Begin Podfile - ${podfilePath}[\\s\\S]*?# End Podfile`, 'mg'), contentWithoutPlatform);
162+
});
163+
}
164+
165+
this.$fs.writeFile(projectPodfilePath, projectPodfileContent);
166+
}
167+
}
168+
127169
private addPostInstallHook(replacedFunctions: IRubyFunction[], finalPodfileContent: string, pluginPodfileContent: string): string {
128170
const postInstallHookStart = this.getPostInstallHookHeader();
129171
let postInstallHookContent = "";

lib/services/ios-project-service.ts

+1
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
978978

979979
const projectPodfilePath = this.$cocoapodsService.getProjectPodfilePath(platformData.projectRoot);
980980
if (this.$fs.exists(projectPodfilePath)) {
981+
await this.$cocoapodsService.removeDuplicatedPlatfomsFromProjectPodFile(platformData.projectRoot);
981982
await this.$cocoapodsService.executePodInstall(platformData.projectRoot, this.$xcprojService.getXcodeprojPath(projectData, platformData));
982983
// The `pod install` command adds a new target to the .pbxproject. This target adds additional build phases to xcodebuild.
983984
// Some of these phases relies on env variables (like PODS_PODFILE_DIR_PATH or PODS_ROOT).

test/cocoapods-service.ts

+174
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { CocoaPodsService } from "../lib/services/cocoapods-service";
44
import { EOL } from "os";
55
import { LoggerStub, ErrorsStub } from "./stubs";
66
import { XcconfigService } from "../lib/services/xcconfig-service";
7+
import * as path from "path";
78

89
interface IMergePodfileHooksTestCase {
910
input: string;
@@ -905,4 +906,177 @@ end`
905906

906907
});
907908
});
909+
910+
describe("removeDuplicatedPlatfomsFromProjectPodFile", () => {
911+
const projectRoot = "my/project/platforms/ios";
912+
const projectPodfilePath = path.join(projectRoot, "testProjectPodfilePath");
913+
const testCases = [
914+
{
915+
name: "should not change the Podfile when no platform",
916+
projectPodfileContent: `use_frameworks!
917+
target "projectName" do
918+
919+
# Begin Podfile - pluginPlatformsFolderPath1/Podfile
920+
921+
pod 'Firebase', '~> 3.1'
922+
# End Podfile`,
923+
expectedProjectPodfileContent: `use_frameworks!
924+
target "projectName" do
925+
926+
# Begin Podfile - pluginPlatformsFolderPath1/Podfile
927+
928+
pod 'Firebase', '~> 3.1'
929+
# End Podfile`
930+
},
931+
{
932+
name: "should not change the Podfile when there is only one platform",
933+
projectPodfileContent: `use_frameworks!
934+
target "projectName" do
935+
936+
# Begin Podfile - pluginPlatformsFolderPath1/Podfile
937+
938+
platform :ios, '9.0'
939+
# End Podfile`,
940+
expectedProjectPodfileContent: `use_frameworks!
941+
target "projectName" do
942+
943+
# Begin Podfile - pluginPlatformsFolderPath1/Podfile
944+
945+
platform :ios, '9.0'
946+
# End Podfile`
947+
},
948+
{
949+
name: "should select the platform from Podfile in App_Resources",
950+
projectPodfileContent: `use_frameworks!
951+
target "projectName" do
952+
953+
# Begin Podfile - ${projectRoot}/App_Resources/iOS/Podfile
954+
955+
platform :ios, '9.0'
956+
# End Podfile
957+
958+
# Begin Podfile - node_modules/myPluginWithPlatform/Podfile
959+
960+
platform :ios, '10.0'
961+
# End Podfile
962+
963+
# Begin Podfile - node_modules/myPluginWithoutPlatform/Podfile
964+
myPod ~> 0.3.4
965+
# End Podfile`,
966+
expectedProjectPodfileContent: `use_frameworks!
967+
target "projectName" do
968+
969+
# Begin Podfile - ${projectRoot}/App_Resources/iOS/Podfile
970+
971+
platform :ios, '9.0'
972+
# End Podfile
973+
974+
# Begin Podfile - node_modules/myPluginWithPlatform/Podfile
975+
976+
977+
# End Podfile
978+
979+
# Begin Podfile - node_modules/myPluginWithoutPlatform/Podfile
980+
myPod ~> 0.3.4
981+
# End Podfile`
982+
},
983+
{
984+
name: "should select the platform with highest version from plugins",
985+
projectPodfileContent: `use_frameworks!
986+
target "projectName" do
987+
988+
# Begin Podfile - node_modules/myFirstPluginWithPlatform/Podfile
989+
990+
platform :ios, '9.0'
991+
# End Podfile
992+
993+
# Begin Podfile - node_modules/mySecondPluginWithPlatform/Podfile
994+
995+
platform :ios, '10.0'
996+
# End Podfile
997+
998+
# Begin Podfile - node_modules/myPluginWithoutPlatform/Podfile
999+
myPod ~> 0.3.4
1000+
# End Podfile`,
1001+
expectedProjectPodfileContent: `use_frameworks!
1002+
target "projectName" do
1003+
1004+
# Begin Podfile - node_modules/myFirstPluginWithPlatform/Podfile
1005+
1006+
1007+
# End Podfile
1008+
1009+
# Begin Podfile - node_modules/mySecondPluginWithPlatform/Podfile
1010+
1011+
platform :ios, '10.0'
1012+
# End Podfile
1013+
1014+
# Begin Podfile - node_modules/myPluginWithoutPlatform/Podfile
1015+
myPod ~> 0.3.4
1016+
# End Podfile`
1017+
},
1018+
{
1019+
name: "should select the platform without version when no Podfile in App_Resources",
1020+
projectPodfileContent: `use_frameworks!
1021+
target "projectName" do
1022+
1023+
# Begin Podfile - node_modules/myFirstPluginWithPlatform/Podfile
1024+
1025+
platform :ios
1026+
# End Podfile
1027+
1028+
# Begin Podfile - node_modules/mySecondPluginWithPlatform/Podfile
1029+
1030+
platform :ios, '10.0'
1031+
# End Podfile
1032+
1033+
# Begin Podfile - node_modules/myPluginWithoutPlatform/Podfile
1034+
myPod ~> 0.3.4
1035+
# End Podfile`,
1036+
expectedProjectPodfileContent: `use_frameworks!
1037+
target "projectName" do
1038+
1039+
# Begin Podfile - node_modules/myFirstPluginWithPlatform/Podfile
1040+
1041+
platform :ios
1042+
# End Podfile
1043+
1044+
# Begin Podfile - node_modules/mySecondPluginWithPlatform/Podfile
1045+
1046+
1047+
# End Podfile
1048+
1049+
# Begin Podfile - node_modules/myPluginWithoutPlatform/Podfile
1050+
myPod ~> 0.3.4
1051+
# End Podfile`
1052+
}
1053+
];
1054+
1055+
beforeEach(() => {
1056+
cocoapodsService.getProjectPodfilePath = () => projectPodfilePath;
1057+
});
1058+
1059+
_.each(testCases, testCase => {
1060+
it(testCase.name, async () => {
1061+
let actualPodfileContent = "";
1062+
1063+
const fs = testInjector.resolve("fs");
1064+
fs.exists = (filePath: string) => projectPodfilePath === filePath;
1065+
fs.readText = (filePath: string) => {
1066+
if (filePath === projectPodfilePath) {
1067+
return testCase.projectPodfileContent;
1068+
}
1069+
};
1070+
fs.writeFile = (filePath: string, fileContent: string) => {
1071+
if (filePath === projectPodfilePath) {
1072+
actualPodfileContent = fileContent;
1073+
}
1074+
};
1075+
1076+
await cocoapodsService.removeDuplicatedPlatfomsFromProjectPodFile(projectRoot);
1077+
1078+
assert.deepEqual(actualPodfileContent, testCase.expectedProjectPodfileContent);
1079+
});
1080+
});
1081+
});
9081082
});

test/ios-project-service.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,7 @@ describe("handleNativeDependenciesChange", () => {
13861386
cocoapodsService.executePodInstall = async () => executedCocoapodsMethods.push("podInstall");
13871387
cocoapodsService.mergePodXcconfigFile = async () => executedCocoapodsMethods.push("podMerge");
13881388
cocoapodsService.applyPodfileFromAppResources = async () => ({});
1389+
cocoapodsService.removeDuplicatedPlatfomsFromProjectPodFile = async () => ({});
13891390
cocoapodsService.getProjectPodfilePath = () => projectPodfilePath;
13901391

13911392
const fs = testInjector.resolve("fs");

0 commit comments

Comments
 (0)