Skip to content

Commit

Permalink
feat: modify package.swift on update and sync (#7042)
Browse files Browse the repository at this point in the history
  • Loading branch information
markemer authored Nov 8, 2023
1 parent 0ac019a commit 24573fb
Show file tree
Hide file tree
Showing 102 changed files with 172 additions and 105,965 deletions.
24 changes: 22 additions & 2 deletions cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Option, program } from 'commander';
import { resolve } from 'path';

import c from './colors';
import { checkExternalConfig, loadConfig } from './config';
Expand All @@ -10,6 +11,10 @@ import { telemetryAction } from './telemetry';
import { wrapAction } from './util/cli';
import { emoji as _e } from './util/emoji';

type Writable<T> = T extends object
? { -readonly [K in keyof T]: Writable<T[K]> }
: T;

process.on('unhandledRejection', error => {
console.error(c.failure('[fatal]'), error);
});
Expand Down Expand Up @@ -263,12 +268,27 @@ export function runProgram(config: Config): void {
program
.command('add [platform]')
.description('add a native platform project')
.option(
'--packagemanager <packageManager>',
'The package manager to use for dependency installs (SPM, Cocoapods)',
)
.action(
wrapAction(
telemetryAction(config, async platform => {
telemetryAction(config, async (platform, { packagemanager }) => {
checkExternalConfig(config.app);
const { addCommand } = await import('./tasks/add');
await addCommand(config, platform);

const configWritable: Writable<Config> = config as Writable<Config>;
if (packagemanager === 'SPM') {
configWritable.cli.assets.ios.platformTemplateArchive =
'ios-spm-template.tar.gz';
configWritable.cli.assets.ios.platformTemplateArchiveAbs = resolve(
configWritable.cli.assetsDirAbs,
configWritable.cli.assets.ios.platformTemplateArchive,
);
}

await addCommand(configWritable as Config, platform);
}),
),
);
Expand Down
8 changes: 7 additions & 1 deletion cli/src/ios/open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ import open from 'open';

import { wait } from '../common';
import type { Config } from '../definitions';
import { checkPackageManager } from '../util/spm';

export async function openIOS(config: Config): Promise<void> {
await open(await config.ios.nativeXcodeWorkspaceDirAbs, { wait: false });
if ((await checkPackageManager(config)) == 'SPM') {
await open(config.ios.nativeXcodeProjDirAbs, { wait: false });
} else {
await open(await config.ios.nativeXcodeWorkspaceDirAbs, { wait: false });
}

await wait(3000);
}
13 changes: 13 additions & 0 deletions cli/src/ios/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import type { Plugin } from '../plugin';
import { copy as copyTask } from '../tasks/copy';
import { convertToUnixPath } from '../util/fs';
import { resolveNode } from '../util/node';
import { checkPackageManager, generatePackageFile } from '../util/spm';
import { runCommand, isInstalled } from '../util/subprocess';
import { extractTemplate } from '../util/template';

Expand All @@ -49,8 +50,20 @@ export async function updateIOS(
p => getPluginType(p, platform) === PluginType.Core,
);

if ((await checkPackageManager(config)) === 'SPM') {
await generatePackageFile(config, capacitorPlugins);
} else {
await updateIOSCocoaPods(config, plugins, deployment);
}

printPlugins(capacitorPlugins, 'ios');
}

async function updateIOSCocoaPods(
config: Config,
plugins: Plugin[],
deployment: boolean,
) {
await removePluginsNativeFiles(config);
const cordovaPlugins = plugins.filter(
p => getPluginType(p, platform) === PluginType.Cordova,
Expand Down
113 changes: 113 additions & 0 deletions cli/src/util/spm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { existsSync, readFileSync, writeFileSync } from '@ionic/utils-fs';
import { relative, resolve } from 'path';

import type { Config } from '../definitions';
import { logger } from '../log';
import type { Plugin } from '../plugin';

export interface SwiftPlugin {
name: string;
path: string;
}

export async function findPackageSwiftFile(config: Config): Promise<string> {
const packageDirectory = resolve(
config.ios.nativeProjectDirAbs,
'CapApp-SPM',
);
return resolve(packageDirectory, 'Package.swift');
}

function readSwiftPackage(packageLine: string): string | null {
const packageRegex = RegExp(/.package\(\s*name:\s*"([A-Za-z0-9_-]+)"/);
const lineMatch = packageLine.match(packageRegex);
if (lineMatch === null) {
return null;
}

return lineMatch[1];
}

export async function generatePackageFile(
config: Config,
plugins: Plugin[],
): Promise<void> {
const swiftPluginList: string[] = [];

for (const plugin of plugins) {
const relPath = relative(config.ios.nativeXcodeProjDirAbs, plugin.rootPath);
const pluginStatement = `.package(name: "${plugin.ios?.name}", path: "${relPath}"),`;
swiftPluginList.push(pluginStatement);
}

const packageSwiftFile = await findPackageSwiftFile(config);

try {
if (!existsSync(packageSwiftFile)) {
logger.error(
`Unable to find ${packageSwiftFile}. Try updating it manually`,
);
}
const packageSwiftText = readFileSync(packageSwiftFile, 'utf-8');
const packageSwiftTextLines = packageSwiftText.split('\n');

let textToWrite = '';
const packages: string[] = [];
for (const lineIndex in packageSwiftTextLines) {
const line = packageSwiftTextLines;
const index = parseInt(lineIndex);

if (
line[index].includes('dependencies: [') &&
line[index + 1].includes(
'.package(url: "https://github.com/ionic-team/capacitor6-spm-test.git", branch: "main")',
)
) {
let tempIndex = index + 1;
while (!line[tempIndex].includes('],')) {
const swiftPack = readSwiftPackage(line[tempIndex]);
if (swiftPack !== null) {
packages.push(swiftPack);
}
tempIndex++;
}
}

if (
line[index].includes(
'.package(url: "https://github.com/ionic-team/capacitor6-spm-test.git", branch: "main")',
)
) {
if (line[index].endsWith(',')) {
textToWrite += line[index] + '\n';
} else {
textToWrite += line[index] + ',\n';
}

for (const swiftPlugin of swiftPluginList) {
const name = readSwiftPackage(swiftPlugin) ?? '';
if (!packages.includes(name)) {
textToWrite += ' ' + swiftPlugin + '\n';
}
}
} else {
textToWrite += line[index] + '\n';
}
}

writeFileSync(packageSwiftFile, textToWrite);
} catch (err) {
logger.error(
`Unable to read ${packageSwiftFile}. Verify it is not already open. ${err}`,
);
}
}

export async function checkPackageManager(config: Config): Promise<string> {
const iosDirectory = config.ios.nativeProjectDirAbs;
if (existsSync(resolve(iosDirectory, 'CapApp-SPM'))) {
return 'SPM';
}

return 'Cocoapods';
}
15 changes: 13 additions & 2 deletions ios-spm-template/App/App.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; };
4D22ABE92AF431CB00220026 /* CapApp-SPM in Frameworks */ = {isa = PBXBuildFile; productRef = 4D22ABE82AF431CB00220026 /* CapApp-SPM */; };
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; };
504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; };
504EC30D1FED79650016851F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30B1FED79650016851F /* Main.storyboard */; };
Expand Down Expand Up @@ -36,6 +37,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4D22ABE92AF431CB00220026 /* CapApp-SPM in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -108,6 +110,9 @@
dependencies = (
);
name = App;
packageProductDependencies = (
4D22ABE82AF431CB00220026 /* CapApp-SPM */,
);
productName = App;
productReference = 504EC3041FED79650016851F /* App.app */;
productType = "com.apple.product-type.application";
Expand Down Expand Up @@ -306,7 +311,6 @@
};
504EC3171FED79650016851F /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
Expand All @@ -329,7 +333,6 @@
};
504EC3181FED79650016851F /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
Expand Down Expand Up @@ -378,6 +381,14 @@
relativePath = "CapApp-SPM";
};
/* End XCLocalSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
4D22ABE82AF431CB00220026 /* CapApp-SPM */ = {
isa = XCSwiftPackageProductDependency;
package = D4C12C0A2AAA248700AAC8A2 /* XCLocalSwiftPackageReference "CapApp-SPM" */;
productName = "CapApp-SPM";
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 504EC2FC1FED79650016851F /* Project object */;
}
6 changes: 3 additions & 3 deletions ios-spm-template/App/CapApp-SPM/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ let package = Package(
targets: ["CapApp-SPM"])
],
dependencies: [
.package(name: "Capacitor", path: "../../../node_modules/@capacitor/ios")
.package(url: "https://github.com/ionic-team/capacitor6-spm-test.git", branch: "main")
],
targets: [
.target(
name: "CapApp-SPM",
dependencies: [
.product(name: "Capacitor", package: "Capacitor"),
.product(name: "Cordova", package: "Capacitor")
.product(name: "Capacitor", package: "capacitor6-spm-test"),
.product(name: "Cordova", package: "capacitor6-spm-test")
]
)
]
Expand Down
48 changes: 0 additions & 48 deletions ios/Frameworks/Capacitor.xcframework/Info.plist

This file was deleted.

Binary file not shown.

This file was deleted.

Loading

0 comments on commit 24573fb

Please sign in to comment.