Skip to content

Commit ba3293c

Browse files
authored
feat(extensions): add extension podfile and setup extension with provision (#5751)
1 parent f6a0fdd commit ba3293c

8 files changed

+419
-137
lines changed

lib/constants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ export type SupportedPlatform = PlatformTypes.ios | PlatformTypes.android;
335335

336336
export const PODFILE_NAME = "Podfile";
337337

338+
export const EXTENSION_PROVISIONING_FILENAME = "provisioning.json";
339+
338340
export class IosProjectConstants {
339341
public static XcodeProjExtName = ".xcodeproj";
340342
public static XcodeSchemeExtName = ".xcscheme";

lib/declarations.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,10 @@ interface IProvision {
530530
provision: string;
531531
}
532532

533+
interface IProvisioningJSON {
534+
[identifier: string]: string;
535+
}
536+
533537
interface ITeamIdentifier {
534538
teamId: string;
535539
}

lib/definitions/project.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,11 @@ interface ICocoaPodsService {
652652
platformData: IPlatformData
653653
): Promise<void>;
654654

655+
applyPodfileFromExtensions(
656+
projectData: IProjectData,
657+
platformData: IPlatformData
658+
): Promise<void>;
659+
655660
/**
656661
* Prepares the Podfile content of a plugin and merges it in the project's Podfile.
657662
* @param {string} moduleName The module which the Podfile is from.

lib/services/cocoapods-service.ts

+97-18
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
} from "../common/declarations";
2222
import { injector } from "../common/yok";
2323
import { XcodeSelectService } from "../common/services/xcode-select-service";
24+
import * as constants from "../constants";
2425

2526
export class CocoaPodsService implements ICocoaPodsService {
2627
private static PODFILE_POST_INSTALL_SECTION_NAME = "post_install";
@@ -121,9 +122,10 @@ ${versionResolutionHint}`);
121122
);
122123
const podFolder = path.join(platformData.projectRoot, podFilesRootDirName);
123124
if (this.$fs.exists(podFolder)) {
124-
const pluginsXcconfigFilePaths = this.$xcconfigService.getPluginsXcconfigFilePaths(
125-
platformData.projectRoot
126-
);
125+
const pluginsXcconfigFilePaths =
126+
this.$xcconfigService.getPluginsXcconfigFilePaths(
127+
platformData.projectRoot
128+
);
127129
for (const configuration in pluginsXcconfigFilePaths) {
128130
const pluginsXcconfigFilePath = pluginsXcconfigFilePaths[configuration];
129131
const podXcconfigFilePath = path.join(
@@ -199,6 +201,71 @@ end`.trim();
199201
this.$fs.deleteFile(exclusionsPodfile);
200202
}
201203

204+
public async applyPodfileFromExtensions(
205+
projectData: IProjectData,
206+
platformData: IPlatformData
207+
) {
208+
const extensionFolderPath = path.join(
209+
projectData.getAppResourcesDirectoryPath(),
210+
constants.iOSAppResourcesFolderName,
211+
constants.NATIVE_EXTENSION_FOLDER
212+
);
213+
const projectPodfilePath = this.getProjectPodfilePath(
214+
platformData.projectRoot
215+
);
216+
217+
if (
218+
!this.$fs.exists(extensionFolderPath) ||
219+
!this.$fs.exists(projectPodfilePath)
220+
) {
221+
return;
222+
}
223+
224+
let projectPodFileContent = this.$fs.readText(projectPodfilePath);
225+
226+
const extensionsPodfile = this.$fs
227+
.readDirectory(extensionFolderPath)
228+
.filter((name) => {
229+
const extensionPath = path.join(extensionFolderPath, name);
230+
const stats = this.$fs.getFsStats(extensionPath);
231+
return stats.isDirectory() && !name.startsWith(".");
232+
})
233+
.map((name) => ({
234+
targetName: name,
235+
podfilePath: path.join(
236+
extensionFolderPath,
237+
name,
238+
constants.PODFILE_NAME
239+
),
240+
}));
241+
242+
extensionsPodfile.forEach(({ targetName, podfilePath }) => {
243+
// Remove the data between #Begin Podfile and #EndPodfile
244+
const regExpToRemove = new RegExp(
245+
`${this.getExtensionPodfileHeader(
246+
podfilePath,
247+
targetName
248+
)}[\\s\\S]*?${this.getExtensionPodfileEnd()}`,
249+
"mg"
250+
);
251+
projectPodFileContent = projectPodFileContent.replace(regExpToRemove, "");
252+
253+
if (this.$fs.exists(podfilePath)) {
254+
const podfileContentWithoutTarget = this.$fs.readText(podfilePath);
255+
const podFileContent =
256+
this.getExtensionPodfileHeader(podfilePath, targetName) +
257+
EOL +
258+
podfileContentWithoutTarget +
259+
EOL +
260+
this.getExtensionPodfileEnd();
261+
262+
projectPodFileContent += EOL + podFileContent;
263+
}
264+
});
265+
266+
this.$fs.writeFile(projectPodfilePath, projectPodFileContent);
267+
}
268+
202269
public async applyPodfileToProject(
203270
moduleName: string,
204271
podfilePath: string,
@@ -216,16 +283,13 @@ end`.trim();
216283
return;
217284
}
218285

219-
const {
220-
podfileContent,
221-
replacedFunctions,
222-
podfilePlatformData,
223-
} = this.buildPodfileContent(
224-
podfilePath,
225-
moduleName,
226-
projectData,
227-
platformData
228-
);
286+
const { podfileContent, replacedFunctions, podfilePlatformData } =
287+
this.buildPodfileContent(
288+
podfilePath,
289+
moduleName,
290+
projectData,
291+
platformData
292+
);
229293
const pathToProjectPodfile = this.getProjectPodfilePath(nativeProjectPath);
230294
const projectPodfileContent = this.$fs.exists(pathToProjectPodfile)
231295
? this.$fs.readText(pathToProjectPodfile).trim()
@@ -297,11 +361,12 @@ end`.trim();
297361
moduleName,
298362
projectPodFileContent
299363
);
300-
projectPodFileContent = this.$cocoaPodsPlatformManager.removePlatformSection(
301-
moduleName,
302-
projectPodFileContent,
303-
podfilePath
304-
);
364+
projectPodFileContent =
365+
this.$cocoaPodsPlatformManager.removePlatformSection(
366+
moduleName,
367+
projectPodFileContent,
368+
podfilePath
369+
);
305370

306371
const defaultPodfileBeginning = this.getPodfileHeader(
307372
projectData.projectName
@@ -496,6 +561,20 @@ end`.trim();
496561
return `# End Podfile${EOL}`;
497562
}
498563

564+
private getExtensionPodfileHeader(
565+
extensionPodFilePath: string,
566+
targetName: string
567+
): string {
568+
const targetHeader = `target "${targetName.trim()}" do`;
569+
return `${this.getPluginPodfileHeader(
570+
extensionPodFilePath
571+
)}${EOL}${targetHeader}`;
572+
}
573+
574+
private getExtensionPodfileEnd(): string {
575+
return `end${EOL}${this.getPluginPodfileEnd()}`;
576+
}
577+
499578
private getPostInstallHookHeader() {
500579
return `${CocoaPodsService.PODFILE_POST_INSTALL_SECTION_NAME} do |${CocoaPodsService.INSTALLER_BLOCK_PARAMETER_NAME}|${EOL}`;
501580
}

lib/services/ios-project-service.ts

+29-28
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,13 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
259259
return;
260260
}
261261

262-
const checkEnvironmentRequirementsOutput = await this.$platformEnvironmentRequirements.checkEnvironmentRequirements(
263-
{
262+
const checkEnvironmentRequirementsOutput =
263+
await this.$platformEnvironmentRequirements.checkEnvironmentRequirements({
264264
platform: this.getPlatformData(projectData).normalizedPlatformName,
265265
projectDir: projectData.projectDir,
266266
options,
267267
notConfiguredEnvOptions,
268-
}
269-
);
268+
});
270269

271270
if (
272271
checkEnvironmentRequirementsOutput &&
@@ -567,6 +566,12 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
567566
): Promise<void> {
568567
const projectRoot = path.join(projectData.platformsDir, "ios");
569568
const platformData = this.getPlatformData(projectData);
569+
570+
const pluginsData = this.getAllProductionPlugins(projectData);
571+
const pbxProjPath = this.getPbxProjPath(projectData);
572+
this.$iOSExtensionsService.removeExtensions({ pbxProjPath });
573+
await this.addExtensions(projectData, pluginsData);
574+
570575
const resourcesDirectoryPath = projectData.getAppResourcesDirectoryPath();
571576

572577
const provision = prepareData && prepareData.provision;
@@ -653,7 +658,6 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
653658
);
654659
}
655660

656-
const pbxProjPath = this.getPbxProjPath(projectData);
657661
this.$iOSWatchAppService.removeWatchApp({ pbxProjPath });
658662
const addedWatchApp = await this.$iOSWatchAppService.addWatchAppFromPath({
659663
watchAppFolderPath: path.join(
@@ -677,9 +681,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
677681
const projectAppResourcesPath = projectData.getAppResourcesDirectoryPath(
678682
projectData.projectDir
679683
);
680-
const platformsAppResourcesPath = this.getAppResourcesDestinationDirectoryPath(
681-
projectData
682-
);
684+
const platformsAppResourcesPath =
685+
this.getAppResourcesDestinationDirectoryPath(projectData);
683686

684687
this.$fs.deleteDirectory(platformsAppResourcesPath);
685688
this.$fs.ensureDirectoryExists(platformsAppResourcesPath);
@@ -959,6 +962,10 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
959962
projectData,
960963
platformData
961964
);
965+
await this.$cocoapodsService.applyPodfileFromExtensions(
966+
projectData,
967+
platformData
968+
);
962969

963970
const projectPodfilePath = this.$cocoapodsService.getProjectPodfilePath(
964971
platformData.projectRoot
@@ -983,10 +990,6 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
983990
}
984991

985992
await this.$spmService.applySPMPackages(platformData, projectData);
986-
987-
const pbxProjPath = this.getPbxProjPath(projectData);
988-
this.$iOSExtensionsService.removeExtensions({ pbxProjPath });
989-
await this.addExtensions(projectData, pluginsData);
990993
}
991994

992995
public beforePrepareAllPlugins(
@@ -1031,9 +1034,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
10311034
if (hasTeamId) {
10321035
if (signing && signing.style === "Automatic") {
10331036
if (signing.team !== teamId) {
1034-
const teamIdsForName = await this.$iOSProvisionService.getTeamIdsWithName(
1035-
teamId
1036-
);
1037+
const teamIdsForName =
1038+
await this.$iOSProvisionService.getTeamIdsWithName(teamId);
10371039
if (!teamIdsForName.some((id) => id === signing.team)) {
10381040
changesInfo.signingChanged = true;
10391041
}
@@ -1179,14 +1181,13 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
11791181
);
11801182
const platformData = this.getPlatformData(projectData);
11811183
const pbxProjPath = this.getPbxProjPath(projectData);
1182-
const addedExtensionsFromResources = await this.$iOSExtensionsService.addExtensionsFromPath(
1183-
{
1184+
const addedExtensionsFromResources =
1185+
await this.$iOSExtensionsService.addExtensionsFromPath({
11841186
extensionsFolderPath: resorcesExtensionsPath,
11851187
projectData,
11861188
platformData,
11871189
pbxProjPath,
1188-
}
1189-
);
1190+
});
11901191
let addedExtensionsFromPlugins = false;
11911192
for (const pluginIndex in pluginsData) {
11921193
const pluginData = pluginsData[pluginIndex];
@@ -1198,14 +1199,13 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
11981199
pluginPlatformsFolderPath,
11991200
constants.NATIVE_EXTENSION_FOLDER
12001201
);
1201-
const addedExtensionFromPlugin = await this.$iOSExtensionsService.addExtensionsFromPath(
1202-
{
1202+
const addedExtensionFromPlugin =
1203+
await this.$iOSExtensionsService.addExtensionsFromPath({
12031204
extensionsFolderPath: extensionPath,
12041205
projectData,
12051206
platformData,
12061207
pbxProjPath,
1207-
}
1208-
);
1208+
});
12091209
addedExtensionsFromPlugins =
12101210
addedExtensionsFromPlugins || addedExtensionFromPlugin;
12111211
}
@@ -1460,9 +1460,10 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
14601460
tempEntitlementsDir,
14611461
"set-entitlements.xcconfig"
14621462
);
1463-
const entitlementsRelativePath = this.$iOSEntitlementsService.getPlatformsEntitlementsRelativePath(
1464-
projectData
1465-
);
1463+
const entitlementsRelativePath =
1464+
this.$iOSEntitlementsService.getPlatformsEntitlementsRelativePath(
1465+
projectData
1466+
);
14661467
this.$fs.writeFile(
14671468
tempEntitlementsFilePath,
14681469
`CODE_SIGN_ENTITLEMENTS = ${entitlementsRelativePath}${EOL}`
@@ -1491,8 +1492,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
14911492
this.getPlatformData(projectData).normalizedPlatformName,
14921493
this.getPlatformData(projectData).configurationFileName
14931494
);
1494-
const mergedPlistPath = this.getPlatformData(projectData)
1495-
.configurationFilePath;
1495+
const mergedPlistPath =
1496+
this.getPlatformData(projectData).configurationFilePath;
14961497

14971498
if (!this.$fs.exists(infoPlistPath) || !this.$fs.exists(mergedPlistPath)) {
14981499
return;

lib/services/ios/export-options-plist-service.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { IFileSystem } from "../../common/declarations";
55
import { injector } from "../../common/yok";
66
import { ITempService } from "../../definitions/temp-service";
77
import * as constants from "../../constants";
8+
import { IProvisioningJSON } from "../../declarations";
89

910
export class ExportOptionsPlistService implements IExportOptionsPlistService {
1011
constructor(
@@ -16,17 +17,14 @@ export class ExportOptionsPlistService implements IExportOptionsPlistService {
1617
private getExtensionProvisions() {
1718
const provisioningJSONPath = path.join(
1819
this.$projectData.getAppResourcesDirectoryPath(),
19-
"iOS",
20+
constants.iOSAppResourcesFolderName,
2021
constants.NATIVE_EXTENSION_FOLDER,
21-
"provisioning.json"
22+
constants.EXTENSION_PROVISIONING_FILENAME
2223
);
2324
if (!this.$fs.exists(provisioningJSONPath)) {
2425
return "";
2526
}
2627

27-
interface IProvisioningJSON {
28-
[identifier: string]: string;
29-
}
3028
const provisioningJSON = this.$fs.readJson(
3129
provisioningJSONPath
3230
) as IProvisioningJSON;

0 commit comments

Comments
 (0)