Skip to content

Commit 554fc8b

Browse files
committed
feat: add expansion, first step
1 parent 836e003 commit 554fc8b

File tree

6 files changed

+170
-2
lines changed

6 files changed

+170
-2
lines changed

.envrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export ACTIVE_BIGBANG=True
2+
export ACTIVE_BIGBANG_EXPANSION=True

buildout.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[buildout]
22

33
extends =
4-
test_plone-6.0.cfg
4+
test_plone-6.1.cfg

src/collective/big/bang/configure.zcml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
xmlns="http://namespaces.zope.org/zope"
33
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
44
xmlns:i18n="http://namespaces.zope.org/i18n"
5+
xmlns:browser="http://namespaces.zope.org/browser"
56
xmlns:plone="http://namespaces.plone.org/plone"
67
i18n_domain="collective.big.bang"
78
>
@@ -16,5 +17,21 @@
1617
handler=".big.bang"
1718
/>
1819

20+
<!--for="zope.processlifetime.IDatabaseOpenedWithRoot"-->
21+
<subscriber
22+
for="zope.processlifetime.IDatabaseOpenedWithRoot"
23+
handler=".expansion.started"
24+
/>
25+
26+
27+
<include package="Products.CMFCore" file="permissions.zcml" />
28+
29+
<browser:page
30+
for="plone.base.interfaces.IPloneSiteRoot"
31+
name="expansion"
32+
permission="cmf.ManagePortal"
33+
class=".expansion.ExpansionView"
34+
/>
35+
1936

2037
</configure>
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
from Products.Five.browser import BrowserView
2+
from Products.GenericSetup.upgrade import _upgrade_registry
3+
from Testing.makerequest import makerequest
4+
from zope.globalrequest import setRequest
5+
6+
# from zope.interface import Interface
7+
# from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
8+
9+
import os
10+
import logging
11+
import transaction
12+
import Zope2
13+
14+
logger = logging.getLogger("collective.big.bang.expansion")
15+
16+
# class IMyView(Interface):
17+
# """Marker Interface for IMyView"""
18+
19+
20+
def started(event):
21+
is_expansion_active = os.getenv("ACTIVE_BIGBANG_EXPANSION", False)
22+
if is_expansion_active == "True":
23+
app = Zope2.app()
24+
app = makerequest(app)
25+
app.REQUEST["PARENTS"] = [app]
26+
setRequest(app.REQUEST)
27+
container = app.unrestrictedTraverse("/")
28+
29+
site_id = os.getenv("SITE_ID", "Plone")
30+
oids = container.objectIds()
31+
if site_id in oids and "/" not in site_id:
32+
site = getattr(app, site_id, None)
33+
portal_setup = site.portal_setup
34+
upgrade_all_profiles(portal_setup)
35+
36+
37+
class ExpansionView(BrowserView):
38+
# If you want to define a template here, please remove the template attribute from
39+
# the configure.zcml registration of this view.
40+
# template = ViewPageTemplateFile('my_view.pt')
41+
42+
def __call__(self):
43+
# your code here
44+
45+
# render the template
46+
return self.index()
47+
48+
49+
def upgrade_all_profiles(portal_setup):
50+
"""Upgrade the profiles."""
51+
upgrade_profiles = portal_setup.listProfilesWithPendingUpgrades()
52+
for upgrade_profile in upgrade_profiles:
53+
upgrade_one_profile(portal_setup, upgrade_profile)
54+
55+
56+
def upgrade_one_profile(setup, profile_id):
57+
upgrades = list_upgrades(setup, profile_id)
58+
if not upgrades:
59+
logger.info("Nothing to upgrade for profile {0}".format(profile_id))
60+
return
61+
while upgrades:
62+
do_upgrades(setup, profile_id, upgrades)
63+
upgrades = list_upgrades(setup, profile_id)
64+
else:
65+
logger.info("Finished upgrading {1} profile".format(profile_id))
66+
67+
68+
def list_upgrades(setup, profile_id):
69+
"""Return only the upgrade steps needed to get to the next version."""
70+
all_upgrades = list(flatten_upgrades(setup, profile_id))
71+
if not all_upgrades:
72+
return all_upgrades
73+
dest = all_upgrades[0]["dest"]
74+
upgrades = []
75+
for info in all_upgrades:
76+
if info["dest"] != dest:
77+
break
78+
upgrades.append(info)
79+
return upgrades
80+
81+
82+
def flatten_upgrades(setup, profile_id):
83+
for info in setup.listUpgrades(profile_id):
84+
if isinstance(info, list):
85+
for subinfo in info:
86+
yield subinfo
87+
else:
88+
yield info
89+
90+
91+
def do_upgrades(setup, profile_id, steps_to_run):
92+
"""Perform all selected upgrade steps."""
93+
step = None
94+
if steps_to_run:
95+
logger.info(
96+
"Upgrading profile {0} to {1}".format(profile_id, steps_to_run[0]["sdest"])
97+
)
98+
for info in steps_to_run:
99+
step = _upgrade_registry.getUpgradeStep(profile_id, info["id"])
100+
if step is not None:
101+
msg = "profile {0} from {ssource} to {sdest}: {title}".format(
102+
profile_id, **info
103+
)
104+
logger.info("Running upgrade step for {0}.".format(msg))
105+
step.doStep(setup)
106+
logger.info("Finished upgrade step for {0}.".format(msg))
107+
108+
# We update the profile version to the last one we have reached
109+
# with running an upgrade step.
110+
if step and step.dest is not None and step.checker is None:
111+
setup.setLastVersionForProfile(profile_id, step.dest)
112+
else:
113+
raise ValueError(
114+
"Upgrade steps {0} finished for profile {1} "
115+
"but no new version {2} recorded.".format(
116+
steps_to_run, profile_id, ".".join(step.dest)
117+
)
118+
)
119+
120+
transaction.commit()

src/collective/big/bang/setuphandlers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# -*- coding: utf-8 -*-
2-
from Products.CMFPlone.interfaces import INonInstallable
2+
from plone.base.interfaces import INonInstallable
33
from zope.interface import implementer
44

55

test_scripts/upgrade_steps.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from collective.big.bang.big import create_plone_site
2+
from collective.big.bang.expansion import upgrade_all_profiles
3+
4+
import os
5+
import transaction
6+
7+
8+
def main(app):
9+
site_id = os.getenv("SITE_ID", "Plone")
10+
create_plone_site(app, site_id)
11+
assert site_id in app.objectIds(), "Plone site not existing"
12+
plone = app.get(site_id)
13+
14+
setup = plone.portal_setup
15+
profile_id = "profile-plone.restapi:default"
16+
restapi_profile_upgrades = setup.listUpgrades(profile_id)
17+
second_to_last_profile_upgrade = sorted(
18+
restapi_profile_upgrades, key=lambda x: x["sdest"], reverse=True
19+
)[1]
20+
step = second_to_last_profile_upgrade.get("step")
21+
setup.setLastVersionForProfile(profile_id, step.dest)
22+
assert "plone.restapi:default" in setup.listProfilesWithPendingUpgrades()
23+
upgrade_all_profiles(setup)
24+
assert [] == setup.listProfilesWithPendingUpgrades()
25+
del app[site_id]
26+
transaction.commit()
27+
28+
29+
main(app) # noqa

0 commit comments

Comments
 (0)