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

CKAN 2.9 changes order in which plugins are returned by PluginImplementations #5731

Closed
amercader opened this issue Nov 9, 2020 · 1 comment · Fixed by #5737
Closed

CKAN 2.9 changes order in which plugins are returned by PluginImplementations #5731

amercader opened this issue Nov 9, 2020 · 1 comment · Fixed by #5737
Assignees

Comments

@amercader
Copy link
Member

amercader commented Nov 9, 2020

Summary

I'm porting a big project from CKAN 2.8 to 2.9. My plugin overrides a template from ckanext-scheming to customize the form. After upgrade, my changes weren't reflected because my custom template wasn't loaded.
Only after changing the ordering of the plugins in ckan.plugins it was picked up.

So on CKAN <= 2.8, in order for plugin abc to override scheming_datasets you needed:

ckan.plugins = abc scheming_datasets 

In CKAN 2.9, you need:

ckan.plugins = scheming_datasets abc

Why it is important

This is pretty significant change, which AFAICT wasn't mentioned in the changelog.

After initial investigation it looks like the issue is not how we parse the config option or load the plugins, but how the PluginImplementations iterator returns them. We use them in all places where we let plugins integrate with CKAN core. For instance in environment.py we call:

      for plugin in p.PluginImplementations(p.IConfigurer):                                                                                                                                                                                                                          
          plugin.update_config(config) 

This is one is relevant to my issue, as it registers template directories from plugins and stores them on a list in config['extra_template_paths']. Order is important, as the first template path found will be used to render.

At this point we get the following behaviour:

  • On CKAN 2.8:
[plugin for plugin in p.PluginImplementations(p.IConfigurer)]

# [<Plugin AbcPlugin 'abc'>, <Plugin SchemingDatasetsPlugin 'scheming_datasets'>]

config['extra_template_paths'].split(',')

# [
#  u'/home/adria/dev/pyenvs/ckan/src/ckanext-abc/ckanext/abc/templates',
#  u'/home/adria/dev/pyenvs/ckan/src/ckanext-scheming/ckanext/scheming/templates',
# ]
  • On CKAN 2.9:
[plugin for plugin in p.PluginImplementations(p.IConfigurer)]

# [<Plugin SchemingDatasetsPlugin 'scheming_datasets'>, <Plugin AbcPlugin 'abc'>]

config['extra_template_paths'].split(',')

# [
#  u'/home/adria/dev/pyenvs/ckan/src/ckanext-scheming/ckanext/scheming/templates',
#  u'/home/adria/dev/pyenvs/ckan/src/ckanext-abc/ckanext/abc/templates',
# ]

Apart from template loading issues this is likely to affect everywhere where the order of plugins is important, eg chained actions, chained auth functions.

Root cause

After looking at ckan/plugins/core.py my current thinking is that this is not related to the loading of the plugins. AFAICT we´ve always loaded them in the order that they are defined in ckan.plugins. It´s the actual iterator returned by PluginImplementations that changed the order of the returned plugins at some point between the two versions (pyutilib.component.core==4.6.4 in CKAN 2.8, PyUtilib==5.7.1 in CKAN 2.9). We are importing this class directly from Pyutillib. The only work done on this code between these two versions was #4886, and I don´t think it should affect the ordering (apart from upgrading the library of course)

What should we do?

My ideas so far:

  1. Change nothing and assume this is the new behaviour, but documenting it in the relevant places (2.9 Changelog, plugins docs, mail to ckan-dev). I don´t think we can leave a change like this undocumented
  2. Create our own PluginImplementations wrapper that restores the old ordering (maybe optionally based on a config option). We would need to override the __iter__() method, not sure how easy that is

Any thoughts or other ideas on what to do? @ckan/core

@Zharktas
Copy link
Member

Personally I think we should try to preserve the order if we can. People don't read change logs or understand them, based on solely on the amount of support requests we've had since 2.9 release.

amercader added a commit that referenced this issue Nov 10, 2020
Fixes #5731

The order in which plugins were returned by `PluginImplementations`
changed between CKAN 2.8 and CKAN 2.9. This has important implications
as plugin ordering affects template overriding, chained actions and auth
functions, etc

This patch overrides the `__iter__()` method of pyutilib's
`ExtensionPoint` to reverse its output before returning it.

Added test to ensure we don't break this again.
alexandru-m-g added a commit to OCHA-DAP/hdx-ckan that referenced this issue Nov 17, 2020
see ckan/ckan#5731

was taking resource_list.html from requestdata instead of hdx_theme
wardi added a commit that referenced this issue Nov 20, 2020
[#5731] Add a PluginImplementations wrapper to maintain ordering
amercader added a commit that referenced this issue Jan 15, 2021
Fixes #5731

The order in which plugins were returned by `PluginImplementations`
changed between CKAN 2.8 and CKAN 2.9. This has important implications
as plugin ordering affects template overriding, chained actions and auth
functions, etc

This patch overrides the `__iter__()` method of pyutilib's
`ExtensionPoint` to reverse its output before returning it.

Added test to ensure we don't break this again.
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

Successfully merging a pull request may close this issue.

2 participants