Missing or incomplete platform or plugin folders are ignored by Cordova and result in incomplete builds
Bug Report
Problem
When I run a cordova build on a fresh git cloned project, after npm install, the following error occurs:
Failed to install 'cordova-plugin-statusbar':
Error: C:\path-to-app\platforms\android\cdv-gradle-config.json: ENOENT: no such file or directory,
open 'C:\path-to-app\platforms\android\cdv-gradle-config.json'
My workaround, is adding a pre build script which adds the platform again:
if (!existsSync('platforms/android/android.json')) {
const cordovaAndroidVersion = devDependencies['cordova-android'];
execSync(`cordova platform add android@${cordovaAndroidVersion}`, { stdio: 'inherit' });
}
But then, sometimes the following error appears:
CordovaError: Platform android already added.
at C:\path-to-app\node_modules\cordova-lib\src\cordova\platform\addHelper.js:120:35
Command or Code
cordova build android --release
I think we should ensure that the platform incl. folder structure exists on npm i or cordova build. Because it's already defined in package.json.
Environment, Platform, Device
Windows 11, Node 20.14, cordova-android 13
Checklist
- [x] I searched for existing GitHub issues
- [x] I updated all Cordova tooling to most recent version
- [x] I included all the necessary information above
I think we should ensure that the platform incl. folder structure exists on npm i or cordova build. Because it's already defined in package.json.
Just because platform exists in package.json doesn't mean it should be added. There are several instances where a workstation only wants to work with subset of supported platforms (be it a CI build, or perhaps the project supports the iOS platform but is operating on a non-mac workstation). Therefore it definitely can't be implicitly added on npm install.
I'm not sure if Cordova ever supported the ability to build a platform that hasn't been added so I'm not sure if this would be a bug, and I'm not sure if I'd support it checking and adding the platform implicitly if it hasn't been added, it would depend on the code complexity... I'm not sure how easy it would be to make the build/prepare command check for and add the platform if it doesn't already exists.
Naturally the prebuild hook written will fail since you can't add a platform that is already added, and after the first build, it will be added. If you wanted to use that as a workaround, you'll need to check if the platforms/android directory exists (which should be something that is gitignored) before you attempt to add the platform.
Generally speaking a workflow would look something like:
git clone cordova-projectnpm installcordova platform add androidcordova build/run android
The workaround to add platforms generally works great. But sometimes on a fresh cloned repo, it throws the "already added" error. Maybe I have to remove before adding.
if (!existsSync('platforms/android/android.json')) {
const cordovaAndroidVersion = devDependencies['cordova-android'];
execSync(`cordova platform remove android`, { stdio: 'inherit' });
execSync(`cordova platform add android@${cordovaAndroidVersion}`, { stdio: 'inherit' });
}
This works better. No error so far. So we need the following steps:
- Check if
androidfolder exists. If not continue... - Get and hold the
cordova-androidversion from package.json. cordova platform remove androidcordova platform add android@{version}
Btw. when an error occurs during the build or add platform, the build will not include all plugins etc. when you start the build again. It just build successfully, no error. Then you have a incomplete abb/apk which may either not run correctly, or miss e.g. a plugin which you may not detetect. Not funny when you release an incomplete app.
I wonder, why Cordova is not ensuring this since, it should know the platforms from e.g. package.json:
{
"cordova": {
"plugins": {"...": {}},
"platforms": [
"android"
]
}
}
And I wonder why incomplete builds are possible. It seems Cordova does not ensure all platforms and plugin data are complete. This is also specified in package.json cordova node. I think about writing a script to ensure that stuff. But shouldn't that be Cordova's job? Otherwise, it's too risky to release incomplete builds. I just reported it as bug, because this is an unexpected behavior and causes broken apps (without errors). Turning this into improvement or feature request is also ok. I just want that Cordova handle this by ensure complete builds or throws an error if not.
TL;DR: If the initialization of the platform or plugins failed, subsequent build attempts will succeed and produce an incomplete app. Even if the folders are incomplete. Cordova should ensure that everything needed exists or throw an error! Since all information exist, it should be possible to do that.