-
Notifications
You must be signed in to change notification settings - Fork 1.2k
chore(cli): migrate changes for Capacitor 9 #8521
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
base: next
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| import { writeFileSync, readFileSync, existsSync } from 'fs-extra'; | ||
| import { join } from 'path'; | ||
| import rimraf from 'rimraf'; | ||
| import { rimraf } from 'rimraf'; | ||
| import { coerce, gte, lt } from 'semver'; | ||
|
|
||
| import c from '../colors'; | ||
|
|
@@ -43,8 +43,8 @@ const plugins = [ | |
| '@capacitor/text-zoom', | ||
| '@capacitor/toast', | ||
| ]; | ||
| const coreVersion = '^8.0.0'; | ||
| const pluginVersion = '^8.0.0'; | ||
| const coreVersion = 'next'; | ||
| const pluginVersion = 'next'; | ||
| const gradleVersion = '9.5.1'; | ||
| const iOSVersion = '16'; | ||
| const kotlinVersion = '2.4.0'; | ||
|
|
@@ -56,14 +56,14 @@ export async function migrateCommand(config: Config, noprompt: boolean, packagem | |
| } | ||
|
|
||
| const capMajor = await checkCapacitorMajorVersion(config); | ||
| if (capMajor < 7) { | ||
| fatal('Migrate can only be used on Capacitor 7, please use the CLI in Capacitor 7 to upgrade to 7 first'); | ||
| if (capMajor < 8) { | ||
| fatal('Migrate can only be used on Capacitor 8, please use the CLI in Capacitor 8 to upgrade to 8 first'); | ||
| } | ||
|
|
||
| const jdkMajor = await checkJDKMajorVersion(); | ||
|
|
||
| if (jdkMajor < 21) { | ||
| logger.warn('Capacitor 8 requires JDK 21 or higher. Some steps may fail.'); | ||
| logger.warn('Capacitor 9 requires JDK 21 or higher. Some steps may fail.'); | ||
| } | ||
|
|
||
| const variablesAndClasspaths: | ||
|
|
@@ -84,13 +84,13 @@ export async function migrateCommand(config: Config, noprompt: boolean, packagem | |
| }; | ||
|
|
||
| const monorepoWarning = | ||
| 'Please note this tool is not intended for use in a mono-repo environment, you should migrate manually instead. Refer to https://capacitorjs.com/docs/next/updating/8-0'; | ||
| 'Please note this tool is not intended for use in a mono-repo environment, you should migrate manually instead. Refer to https://capacitorjs.com/docs/next/updating/9-0'; | ||
|
|
||
| logger.info(monorepoWarning); | ||
|
|
||
| const { migrateconfirm } = noprompt | ||
| ? { migrateconfirm: 'y' } | ||
| : await logPrompt(`Capacitor 8 sets a deployment target of iOS ${iOSVersion} and Android 17 (SDK 37). \n`, { | ||
| : await logPrompt(`Capacitor 9 sets a deployment target of iOS ${iOSVersion} and Android 17 (SDK 37). \n`, { | ||
| type: 'text', | ||
| name: 'migrateconfirm', | ||
| message: `Are you sure you want to migrate? (Y/n)`, | ||
|
|
@@ -175,6 +175,10 @@ export async function migrateCommand(config: Config, noprompt: boolean, packagem | |
| } else { | ||
| logger.warn('Skipped updating deployment target'); | ||
| } | ||
|
|
||
| await runTask(`Migrating AppDelegate.swift`, () => { | ||
| return updateAppDelegate(join(config.ios.nativeTargetDirAbs, 'AppDelegate.swift')); | ||
| }); | ||
| } | ||
|
|
||
| if (!installFailed) { | ||
|
|
@@ -228,6 +232,23 @@ export async function migrateCommand(config: Config, noprompt: boolean, packagem | |
| return updateAppBuildGradle(join(config.android.appDirAbs, 'build.gradle')); | ||
| }); | ||
|
|
||
| // settings.gradle | ||
| await runTask(`Migrating settings.gradle file.`, () => { | ||
| return (async (): Promise<void> => { | ||
| const settingsPath = join(config.android.platformDirAbs, 'settings.gradle'); | ||
| let txt = readFile(settingsPath); | ||
| if (!txt) { | ||
| return; | ||
| } | ||
| txt = txt.replace(`include ':capacitor-cordova-android-plugins'\n`, ''); | ||
| txt = txt.replace( | ||
| `project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/')\n`, | ||
| '', | ||
| ); | ||
| writeFileSync(settingsPath, txt, { encoding: 'utf-8' }); | ||
| })(); | ||
| }); | ||
|
|
||
| // Variables gradle | ||
| await runTask(`Migrating variables.gradle file.`, () => { | ||
| return (async (): Promise<void> => { | ||
|
|
@@ -336,14 +357,14 @@ async function installLatestLibs(dependencyManager: string, runInstall: boolean, | |
| for (const devDepKey of Object.keys(pkgJson['devDependencies'] || {})) { | ||
| if (libs.includes(devDepKey)) { | ||
| pkgJson['devDependencies'][devDepKey] = coreVersion; | ||
| } else if (plugins.includes(devDepKey)) { | ||
| } else if (plugins.includes(devDepKey) && !pkgJson['devDependencies'][devDepKey].startsWith('file:')) { | ||
| pkgJson['devDependencies'][devDepKey] = pluginVersion; | ||
| } | ||
| } | ||
| for (const depKey of Object.keys(pkgJson['dependencies'] || {})) { | ||
| if (libs.includes(depKey)) { | ||
| pkgJson['dependencies'][depKey] = coreVersion; | ||
| } else if (plugins.includes(depKey)) { | ||
| } else if (plugins.includes(depKey) && !pkgJson['dependencies'][depKey].startsWith('file:')) { | ||
| pkgJson['dependencies'][depKey] = pluginVersion; | ||
| } | ||
| } | ||
|
|
@@ -366,18 +387,7 @@ async function installLatestLibs(dependencyManager: string, runInstall: boolean, | |
| } | ||
|
|
||
| async function writeBreakingChanges() { | ||
| const breaking = [ | ||
| '@capacitor/action-sheet', | ||
| '@capacitor/barcode-scanner', | ||
| '@capacitor/browser', | ||
| '@capacitor/camera', | ||
| '@capacitor/geolocation', | ||
| '@capacitor/google-maps', | ||
| '@capacitor/push-notifications', | ||
| '@capacitor/screen-orientation', | ||
| '@capacitor/splash-screen', | ||
| '@capacitor/status-bar', | ||
| ]; | ||
| const breaking = ['@capacitor/push-notifications', '@capacitor/splash-screen']; | ||
| const broken = []; | ||
| for (const lib of breaking) { | ||
| if (allDependencies[lib]) { | ||
|
|
@@ -386,7 +396,7 @@ async function writeBreakingChanges() { | |
| } | ||
| if (broken.length > 0) { | ||
| logger.info( | ||
| `IMPORTANT: Review https://capacitorjs.com/docs/next/updating/8-0#plugins for breaking changes in these plugins that you use: ${broken.join( | ||
| `IMPORTANT: Review https://capacitorjs.com/docs/next/updating/9-0#plugins for breaking changes in these plugins that you use: ${broken.join( | ||
| ', ', | ||
| )}.`, | ||
| ); | ||
|
|
@@ -518,14 +528,19 @@ async function updateAppBuildGradle(filename: string) { | |
| } | ||
| let replaced = txt; | ||
|
|
||
| const gradlePproperties = ['compileSdk', 'namespace', 'ignoreAssetsPattern']; | ||
| for (const prop of gradlePproperties) { | ||
| // Use updated Groovy DSL syntax with " = " assignment | ||
| const regex = new RegExp(`(^\\s*${prop})\\s+(?!=)(.+)$`, 'gm'); | ||
| replaced = replaced.replace(regex, (_match, key, value) => { | ||
| return `${key} = ${value.trim()}`; | ||
| }); | ||
| } | ||
| replaced = replaced.replace(`proguard-android.txt`, `proguard-android-optimize.txt`); | ||
| replaced = replaced.replace(' targetSdkVersion rootProject.ext.targetSdkVersion\n', ''); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In AGP 9, users can change the behavior of targetSDK by setting I don't know why anyone would do this voluntarily, but they could if they want to. What seems more likely to happen is users that migrated to AGP 9 while in Capacitor 8 - So the way to overcome this issue would be one of or a combination of:
Let me know if this makes sense, and if you have a preference on the approach (only 1., only 2., both, other...) |
||
| replaced = replaced.replace(` implementation project(':capacitor-cordova-android-plugins')\n`, ''); | ||
| replaced = replaced.replace( | ||
| `repositories { | ||
| flatDir{ | ||
| dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs' | ||
| } | ||
| } | ||
|
|
||
| `, | ||
| '', | ||
| ); | ||
| writeFileSync(filename, replaced, 'utf-8'); | ||
| } | ||
|
|
||
|
|
@@ -622,3 +637,21 @@ async function updateAndroidManifest(filename: string) { | |
| writeFileSync(filename, replaced, 'utf-8'); | ||
| } | ||
| } | ||
|
|
||
| async function updateAppDelegate(filename: string) { | ||
| const txt = readFile(filename); | ||
| if (!txt) { | ||
| return; | ||
| } | ||
|
|
||
| if (txt.includes('@main')) { | ||
| return; // Probably already updated | ||
| } | ||
| // Since navigation was an optional change in Capacitor 7, attempting to add density and/or navigation | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment seems out of place? It sounds it's referring to changes in Android Manifest but this is AppDelegate. |
||
| const replaced = txt.replace('@UIApplicationMain', '@main'); | ||
| if (!replaced.includes('@main')) { | ||
| logger.error(`Unable to replace @UIApplicationMain to @main in ${filename}. Try replacing it manually`); | ||
| } else { | ||
| writeFileSync(filename, replaced, 'utf-8'); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we no longer be replacing kotlin version for
classpath, and instead remove it? Because it's now bundled in AGP 9?We added it in Capacitor 8 to fix an issue related to an app declaring the kotlin version in root
build.gradleand it differing from the one Capacitor / Plugins use. Internal Slack Thread. But AGP bundles kotlin gradle plugin it's probably better to not have it in the app, and instead remove it altogether perhaps?But also, we are using Kotlin 2.4.0 here and AGP 9.2 uses 2.3.10. But since it's a minor version change it should be ok (where last year it was a major version).
If you think this is better left to a separate task / PR let me know, but just wanted to highlight it.