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

platform-specific after_prepare hooks don't run after restoring #940

Open
3 tasks done
dpogue opened this issue Dec 9, 2024 · 4 comments
Open
3 tasks done

platform-specific after_prepare hooks don't run after restoring #940

dpogue opened this issue Dec 9, 2024 · 4 comments

Comments

@dpogue
Copy link
Member

dpogue commented Dec 9, 2024

Bug Report

Problem

Include cordova-plugin-androidx-adapter in package.json, along with cordova-ios and cordova-android.

With no platforms or plugins directories, run cordova prepare.

What is expected to happen?

The after_prepare hook of cordova-plugin-androidx-adapter should be invoked at the end of the prepare, because the Android platform and the plugin have just been restored.

What does actually happen?

The after_prepare hook never fires, cordova-lib verbose output indicates that no hook scripts were found.

Information

What happens is that the ScriptsFinder tries to look up scripts in plugins for the provided list of platforms:

const scriptElements = plugin.pluginInfo.getHookScripts(hook, platforms);

That list of platforms comes from the options of the HooksRunner:

scripts = scripts.concat(getPluginScriptFiles(currentPluginOptions, hook, opts.cordova.platforms));

The HooksRunner sets its list of platforms to a provided option, or falls back to querying for the installed platforms:

opts.cordova.platforms = opts.cordova.platforms || opts.platforms || cordovaUtil.listPlatforms(opts.projectRoot);
opts.cordova.platforms = opts.cordova.platforms.map(function (platform) { return platform.split('@')[0]; });

In the case of prepare, if a platform is not manually specified, we set that list of platforms to an empty array:

options = options || { verbose: false, platforms: [], options: {} };

The end result is that after restoring all the platforms and plugins, the HooksRunner still tries to find hook scripts with an empty platforms list, and the Android-specific hook never runs.

Suggested fix

HooksRunner should maybe check if the platforms array is empty and then still fallback to querying the installed platforms, rather than taking the empty input and running with it.

Version information

Was seeing this in an older project using Cordova CLI 10, but having looked at the code it seems like it's probably still an issue today.

Checklist

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above
@erisu
Copy link
Member

erisu commented Dec 10, 2024

Maybe try the following.

const platformList = cordova_util.listPlatforms(projectRoot);
options = options || { verbose: false, platforms: platformList, options: {} }; 

cordova_util is already required and projectRoot is also already defined.

@dpogue
Copy link
Member Author

dpogue commented Dec 10, 2024

If you mean doing that in prepare.js, I think it will be too early. That line to set the initial options runs before any platforms are restored, so it would still end up being an empty array.

@dpogue
Copy link
Member Author

dpogue commented Dec 10, 2024

Now I'm confused because util.preProcessOptions looks like it should be adding the platforms if the array is empty...

if (result.platforms.length === 0) {
result.platforms = projectPlatforms;
}

I'll try to do some more testing tomorrow to see what going on with that...

@dpogue
Copy link
Member Author

dpogue commented Dec 10, 2024

Okay, the root cause is this line:

opts.cordova.platforms = opts.cordova.platforms || opts.platforms || cordovaUtil.listPlatforms(opts.projectRoot);

When it initially runs, options.platforms is an empty array, so it sets options.cordova.platforms to an empty array. Then, preProcessOptions ends up filling options.platforms with the right values, but because options.cordova.platforms is already set to a non-falsey value (an empty array), it never gets updated to reflect the updated list of platforms.

I'm not sure why the hooks runner needs a separate list of platforms and plugins nested under a cordova key, but we should probably update that assignment to update that array every time if it is empty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants