Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(extensions): add extension podfile and setup extension with provision #5751

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ export type SupportedPlatform = PlatformTypes.ios | PlatformTypes.android;

export const PODFILE_NAME = "Podfile";

export const EXTENSION_PROVISIONING_FILENAME = "provisioning.json";

export class IosProjectConstants {
public static XcodeProjExtName = ".xcodeproj";
public static XcodeSchemeExtName = ".xcscheme";
Expand Down
4 changes: 4 additions & 0 deletions lib/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,10 @@ interface IProvision {
provision: string;
}

interface IProvisioningJSON {
[identifier: string]: string;
}

interface ITeamIdentifier {
teamId: string;
}
Expand Down
5 changes: 5 additions & 0 deletions lib/definitions/project.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,11 @@ interface ICocoaPodsService {
platformData: IPlatformData
): Promise<void>;

applyPodfileFromExtensions(
projectData: IProjectData,
platformData: IPlatformData
): Promise<void>;

/**
* Prepares the Podfile content of a plugin and merges it in the project's Podfile.
* @param {string} moduleName The module which the Podfile is from.
Expand Down
115 changes: 97 additions & 18 deletions lib/services/cocoapods-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from "../common/declarations";
import { injector } from "../common/yok";
import { XcodeSelectService } from "../common/services/xcode-select-service";
import * as constants from "../constants";

export class CocoaPodsService implements ICocoaPodsService {
private static PODFILE_POST_INSTALL_SECTION_NAME = "post_install";
Expand Down Expand Up @@ -121,9 +122,10 @@ ${versionResolutionHint}`);
);
const podFolder = path.join(platformData.projectRoot, podFilesRootDirName);
if (this.$fs.exists(podFolder)) {
const pluginsXcconfigFilePaths = this.$xcconfigService.getPluginsXcconfigFilePaths(
platformData.projectRoot
);
const pluginsXcconfigFilePaths =
this.$xcconfigService.getPluginsXcconfigFilePaths(
platformData.projectRoot
);
for (const configuration in pluginsXcconfigFilePaths) {
const pluginsXcconfigFilePath = pluginsXcconfigFilePaths[configuration];
const podXcconfigFilePath = path.join(
Expand Down Expand Up @@ -199,6 +201,71 @@ end`.trim();
this.$fs.deleteFile(exclusionsPodfile);
}

public async applyPodfileFromExtensions(
projectData: IProjectData,
platformData: IPlatformData
) {
const extensionFolderPath = path.join(
projectData.getAppResourcesDirectoryPath(),
constants.iOSAppResourcesFolderName,
constants.NATIVE_EXTENSION_FOLDER
);
const projectPodfilePath = this.getProjectPodfilePath(
platformData.projectRoot
);

if (
!this.$fs.exists(extensionFolderPath) ||
!this.$fs.exists(projectPodfilePath)
) {
return;
}

let projectPodFileContent = this.$fs.readText(projectPodfilePath);

const extensionsPodfile = this.$fs
.readDirectory(extensionFolderPath)
.filter((name) => {
const extensionPath = path.join(extensionFolderPath, name);
const stats = this.$fs.getFsStats(extensionPath);
return stats.isDirectory() && !name.startsWith(".");
})
.map((name) => ({
targetName: name,
podfilePath: path.join(
extensionFolderPath,
name,
constants.PODFILE_NAME
),
}));

extensionsPodfile.forEach(({ targetName, podfilePath }) => {
// Remove the data between #Begin Podfile and #EndPodfile
const regExpToRemove = new RegExp(
`${this.getExtensionPodfileHeader(
podfilePath,
targetName
)}[\\s\\S]*?${this.getExtensionPodfileEnd()}`,
"mg"
);
projectPodFileContent = projectPodFileContent.replace(regExpToRemove, "");

if (this.$fs.exists(podfilePath)) {
const podfileContentWithoutTarget = this.$fs.readText(podfilePath);
const podFileContent =
this.getExtensionPodfileHeader(podfilePath, targetName) +
EOL +
podfileContentWithoutTarget +
EOL +
this.getExtensionPodfileEnd();

projectPodFileContent += EOL + podFileContent;
}
});

this.$fs.writeFile(projectPodfilePath, projectPodFileContent);
}

public async applyPodfileToProject(
moduleName: string,
podfilePath: string,
Expand All @@ -216,16 +283,13 @@ end`.trim();
return;
}

const {
podfileContent,
replacedFunctions,
podfilePlatformData,
} = this.buildPodfileContent(
podfilePath,
moduleName,
projectData,
platformData
);
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()
Expand Down Expand Up @@ -297,11 +361,12 @@ end`.trim();
moduleName,
projectPodFileContent
);
projectPodFileContent = this.$cocoaPodsPlatformManager.removePlatformSection(
moduleName,
projectPodFileContent,
podfilePath
);
projectPodFileContent =
this.$cocoaPodsPlatformManager.removePlatformSection(
moduleName,
projectPodFileContent,
podfilePath
);

const defaultPodfileBeginning = this.getPodfileHeader(
projectData.projectName
Expand Down Expand Up @@ -496,6 +561,20 @@ end`.trim();
return `# End Podfile${EOL}`;
}

private getExtensionPodfileHeader(
extensionPodFilePath: string,
targetName: string
): string {
const targetHeader = `target "${targetName.trim()}" do`;
return `${this.getPluginPodfileHeader(
extensionPodFilePath
)}${EOL}${targetHeader}`;
}

private getExtensionPodfileEnd(): string {
return `end${EOL}${this.getPluginPodfileEnd()}`;
}

private getPostInstallHookHeader() {
return `${CocoaPodsService.PODFILE_POST_INSTALL_SECTION_NAME} do |${CocoaPodsService.INSTALLER_BLOCK_PARAMETER_NAME}|${EOL}`;
}
Expand Down
57 changes: 29 additions & 28 deletions lib/services/ios-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,14 +259,13 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
return;
}

const checkEnvironmentRequirementsOutput = await this.$platformEnvironmentRequirements.checkEnvironmentRequirements(
{
const checkEnvironmentRequirementsOutput =
await this.$platformEnvironmentRequirements.checkEnvironmentRequirements({
platform: this.getPlatformData(projectData).normalizedPlatformName,
projectDir: projectData.projectDir,
options,
notConfiguredEnvOptions,
}
);
});

if (
checkEnvironmentRequirementsOutput &&
Expand Down Expand Up @@ -567,6 +566,12 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
): Promise<void> {
const projectRoot = path.join(projectData.platformsDir, "ios");
const platformData = this.getPlatformData(projectData);

const pluginsData = this.getAllProductionPlugins(projectData);
const pbxProjPath = this.getPbxProjPath(projectData);
this.$iOSExtensionsService.removeExtensions({ pbxProjPath });
await this.addExtensions(projectData, pluginsData);

const resourcesDirectoryPath = projectData.getAppResourcesDirectoryPath();

const provision = prepareData && prepareData.provision;
Expand Down Expand Up @@ -653,7 +658,6 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
);
}

const pbxProjPath = this.getPbxProjPath(projectData);
this.$iOSWatchAppService.removeWatchApp({ pbxProjPath });
const addedWatchApp = await this.$iOSWatchAppService.addWatchAppFromPath({
watchAppFolderPath: path.join(
Expand All @@ -677,9 +681,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
const projectAppResourcesPath = projectData.getAppResourcesDirectoryPath(
projectData.projectDir
);
const platformsAppResourcesPath = this.getAppResourcesDestinationDirectoryPath(
projectData
);
const platformsAppResourcesPath =
this.getAppResourcesDestinationDirectoryPath(projectData);

this.$fs.deleteDirectory(platformsAppResourcesPath);
this.$fs.ensureDirectoryExists(platformsAppResourcesPath);
Expand Down Expand Up @@ -959,6 +962,10 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
projectData,
platformData
);
await this.$cocoapodsService.applyPodfileFromExtensions(
projectData,
platformData
);

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

await this.$spmService.applySPMPackages(platformData, projectData);

const pbxProjPath = this.getPbxProjPath(projectData);
this.$iOSExtensionsService.removeExtensions({ pbxProjPath });
await this.addExtensions(projectData, pluginsData);
}

public beforePrepareAllPlugins(
Expand Down Expand Up @@ -1031,9 +1034,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
if (hasTeamId) {
if (signing && signing.style === "Automatic") {
if (signing.team !== teamId) {
const teamIdsForName = await this.$iOSProvisionService.getTeamIdsWithName(
teamId
);
const teamIdsForName =
await this.$iOSProvisionService.getTeamIdsWithName(teamId);
if (!teamIdsForName.some((id) => id === signing.team)) {
changesInfo.signingChanged = true;
}
Expand Down Expand Up @@ -1179,14 +1181,13 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
);
const platformData = this.getPlatformData(projectData);
const pbxProjPath = this.getPbxProjPath(projectData);
const addedExtensionsFromResources = await this.$iOSExtensionsService.addExtensionsFromPath(
{
const addedExtensionsFromResources =
await this.$iOSExtensionsService.addExtensionsFromPath({
extensionsFolderPath: resorcesExtensionsPath,
projectData,
platformData,
pbxProjPath,
}
);
});
let addedExtensionsFromPlugins = false;
for (const pluginIndex in pluginsData) {
const pluginData = pluginsData[pluginIndex];
Expand All @@ -1198,14 +1199,13 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
pluginPlatformsFolderPath,
constants.NATIVE_EXTENSION_FOLDER
);
const addedExtensionFromPlugin = await this.$iOSExtensionsService.addExtensionsFromPath(
{
const addedExtensionFromPlugin =
await this.$iOSExtensionsService.addExtensionsFromPath({
extensionsFolderPath: extensionPath,
projectData,
platformData,
pbxProjPath,
}
);
});
addedExtensionsFromPlugins =
addedExtensionsFromPlugins || addedExtensionFromPlugin;
}
Expand Down Expand Up @@ -1460,9 +1460,10 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
tempEntitlementsDir,
"set-entitlements.xcconfig"
);
const entitlementsRelativePath = this.$iOSEntitlementsService.getPlatformsEntitlementsRelativePath(
projectData
);
const entitlementsRelativePath =
this.$iOSEntitlementsService.getPlatformsEntitlementsRelativePath(
projectData
);
this.$fs.writeFile(
tempEntitlementsFilePath,
`CODE_SIGN_ENTITLEMENTS = ${entitlementsRelativePath}${EOL}`
Expand Down Expand Up @@ -1491,8 +1492,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
this.getPlatformData(projectData).normalizedPlatformName,
this.getPlatformData(projectData).configurationFileName
);
const mergedPlistPath = this.getPlatformData(projectData)
.configurationFilePath;
const mergedPlistPath =
this.getPlatformData(projectData).configurationFilePath;

if (!this.$fs.exists(infoPlistPath) || !this.$fs.exists(mergedPlistPath)) {
return;
Expand Down
8 changes: 3 additions & 5 deletions lib/services/ios/export-options-plist-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IFileSystem } from "../../common/declarations";
import { injector } from "../../common/yok";
import { ITempService } from "../../definitions/temp-service";
import * as constants from "../../constants";
import { IProvisioningJSON } from "../../declarations";

export class ExportOptionsPlistService implements IExportOptionsPlistService {
constructor(
Expand All @@ -16,17 +17,14 @@ export class ExportOptionsPlistService implements IExportOptionsPlistService {
private getExtensionProvisions() {
const provisioningJSONPath = path.join(
this.$projectData.getAppResourcesDirectoryPath(),
"iOS",
constants.iOSAppResourcesFolderName,
constants.NATIVE_EXTENSION_FOLDER,
"provisioning.json"
constants.EXTENSION_PROVISIONING_FILENAME
);
if (!this.$fs.exists(provisioningJSONPath)) {
return "";
}

interface IProvisioningJSON {
[identifier: string]: string;
}
const provisioningJSON = this.$fs.readJson(
provisioningJSONPath
) as IProvisioningJSON;
Expand Down
Loading