Repository: plone/Products.CMFPlone

Issue:
Please, re-introduce install.py support on Plone 5
Plone 5 will be the most problematic Plone release for add-ons (probably more complex than Plone 2.0 -> 2.1).

Things to be done to make add-ons compatible to both Plone 4.3 and 5.0 are _a lot_ and the simpler (and, let me say, more pythonic) way to handle that unavoidable mess _was_ the old good guy `Extensions/install.py` script, where we can pilot which/when generic setup profiles are run.

I don't know the reason why it's has been removed from Plone 5, but I think it is a mistake that is not giving nothing good back.
- The way Plone "choose" a profile to be run when installing (alphabetical order) has always been something opinable.
- we still need `install.py` for uninstall.
- `install.py/install` method it's still supported when running installation from ZMI/portal_quickinstaller so the behavior in not coherent with Plone UI.

This lack force add-ons developers to:
- drop Plone 4.3 support, which will be an epic fail
- support two different branch for Plone 4.3 and Plone 5, which often leads to different releases (bug not fixed in one version)
- invent some super complex way to fix this, like: running stuff inside `import_steps.xml`, which is complex, needs more boilerplate and is not exactly the scope it's intended to be.

This complexity is totally useless IMHO.



Discussion:
@keul Is it really true that install.py support is removed and you are not simply missing `<five:registerPackage package="." />` from your add-on?

I think dropping support for Install.py probably happened inadvertently when the add-ons control panel was rewritten as a z3c.form form instead of the old skin template. I agree re-adding it would be useful.

Agreed.

+1 to adding it back
On Apr 18, 2015 7:43 PM, "Asko Soukka" notifications@github.com wrote:

> Agreed.
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/plone/Products.CMFPlone/issues/443#issuecomment-94186901
> .

The switch to the old behavior should be quite easy, but the Plone 5 
code seem to have a clear intent to drop support for QuickInstaller and 
go GS only. It's just that only install has been implemented, while 
unininstall and reinstall continue to rely on QI.

Does anyone remember the discussion about this?

@keul Nowadays (also in Plone 4) you can register "volatile" GS steps in 
zcml, which makes it relatively easy to execute custom code during 
profile import (the only issue being the need for checking the existence 
of your "marker" file).

Yet, GS has never had real "uninstall" feature, and "uninstall profile" 
is just a convention. Simple add-ons may still have relied on the magic 
of QI (which does not cover the newst tech like p.a.registry).

I guess, because there's no clear winner solution, it's safest to keep 
backwards compatibility to QI.

Nathan Van Gheem wrote:

> +1 to adding it back
> On Apr 18, 2015 7:43 PM, "Asko Soukka" notifications@github.com wrote:
> 
> > Agreed.
> > 
> > —
> > Reply to this email directly or view it on GitHub
> > 
> > https://github.com/plone/Products.CMFPlone/issues/443#issuecomment-94186901
> > .
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/plone/Products.CMFPlone/issues/443#issuecomment-94196467.


Resolving patch:
diff --git a/Products/CMFPlone/controlpanel/browser/quickinstaller.py b/Products/CMFPlone/controlpanel/browser/quickinstaller.py
--- a/Products/CMFPlone/controlpanel/browser/quickinstaller.py
+++ b/Products/CMFPlone/controlpanel/browser/quickinstaller.py
@@ -203,20 +203,14 @@ def __call__(self):
 class InstallProductsView(BrowserView):
 
     def __call__(self):
-        """
-        Install products by running the default import steps
-        XXX: is this running all profiles?
-        """
-        setupTool = getToolByName(self.context, 'portal_setup')
-        profiles = self.request.get('install_products')
+        qi = getToolByName(self.context, 'portal_quickinstaller')
+        products = self.request.get('install_products')
         msg_type = 'info'
-        if profiles:
+        if products:
             messages = IStatusMessage(self.request)
-            for profile in profiles:
-                # TODO: find out where this is and don't run already
-                # activated profiles
-                setupTool.runAllImportStepsFromProfile(profile)
-                msg = _(u'Installed ${product}!', mapping={'product': profile})
+            for product in products:
+                qi.installProducts(products=[product, ])
+                msg = _(u'Installed ${product}!', mapping={'product': product})
                 messages.addStatusMessage(msg, type=msg_type)
 
         purl = getToolByName(self.context, 'portal_url')()
@@ -225,7 +219,6 @@ def __call__(self):
 
 class UninstallProductsView(BrowserView):
     def __call__(self):
-        # XXX: Need to call the uninstall profile
         qi = getToolByName(self.context, 'portal_quickinstaller')
         products = self.request.get('uninstall_products')
         msg_type = 'info'


Test patch: