Commit db6a2d07 authored by Julien Muchembled's avatar Julien Muchembled

BT: when downloading from VCS, add a history comment with revision information

parent 5558216e
......@@ -40,6 +40,7 @@ from Products.CMFCore.utils import getToolByName
from Products.PythonScripts.PythonScript import PythonScript
from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
from Products.ERP5Type.Cache import transactional_cached
from Products.ERP5Type.Message import translateString
from Products.ERP5Type.Utils import readLocalDocument, \
writeLocalDocument, \
importLocalDocument, \
......@@ -5479,12 +5480,16 @@ Business Template is a set of definitions, such as skins, portal types and categ
if os.path.isdir(bt_path):
return bt_path
@transactional_cached(lambda self, vcs=None, path=None: (self, vcs, path))
def getVcsTool(self, vcs=None, path=None):
@transactional_cached(lambda self, vcs=None, path=None, restricted=False:
(self, vcs, path, restricted))
def _getVcsTool(self, vcs=None, path=None, restricted=False):
from Products.ERP5VCS.WorkingCopy import getVcsTool
if not (path or vcs):
path = self.getExportPath()
return getVcsTool(vcs=vcs, path=path).__of__(self)
return getVcsTool(vcs, path, restricted).__of__(self)
def getVcsTool(self, vcs=None, path=None):
return self._getVcsTool(vcs, path, True)
def isVcsType(self, *vcs):
# could be moved to Products.ERP5.Base.Base
......@@ -5562,6 +5567,20 @@ Business Template is a set of definitions, such as skins, portal types and categ
prop_dict[pid[:-5]] = (value or '').splitlines()
self._edit(**prop_dict)
from Products.ERP5VCS.WorkingCopy import NotAWorkingCopyError
try:
vcs_tool = self._getVcsTool(path=path)
except NotAWorkingCopyError:
pass
else:
comment = translateString(
'Downloaded from ${type} repository at revision ${revision}',
mapping={'type': vcs_tool.title,
'revision': vcs_tool.getRevision(True)})
workflow_tool = self.getPortalObject().portal_workflow
workflow_tool.business_template_building_workflow.notifyWorkflowMethod(
self, 'edit', kw={'comment': comment})
self.storeTemplateItemData()
# Create temporary modules/classes for classes defined by this BT.
......
......@@ -315,6 +315,11 @@ class Git(WorkingCopy):
#except AttributeError:
# pass
def getRevision(self, dirty=False):
if dirty and self._git('diff-index', '--quiet', 'HEAD').wait():
return self.git('rev-parse', '--short', 'HEAD') + '+'
return self.git('rev-parse', 'HEAD')
def commit(self, changelog, added=(), modified=(), removed=()):
context = self.aq_parent
request = context.REQUEST
......
......@@ -65,10 +65,17 @@ class Subversion(WorkingCopy):
_login_cookie_name = 'erp5_subversion_login'
_ssl_trust_cookie_name = 'erp5_subversion_ssl_trust'
def __init__(self, path):
WorkingCopy.__init__(self, path)
if path and not os.path.exists(os.path.join(self.working_copy, '.svn')):
raise NotAWorkingCopyError(self.working_copy)
def __init__(self, *args, **kw):
WorkingCopy.__init__(self, *args, **kw)
try:
path = self.working_copy
except AttributeError:
return
from pysvn import ClientError
try:
self.getRevision()
except (ClientError, KeyError):
raise NotAWorkingCopyError(path)
def setLogin(self, realm, user, password):
"""Set login information.
......@@ -159,6 +166,12 @@ class Subversion(WorkingCopy):
def getRemoteComment(self):
return 'r%s' % self.info()['revision']
def getRevision(self, dirty=False):
r = self.info()['commit_revision']
if dirty and self._getClient().status(self.working_copy, get_all=False):
return "%s+" % r
return r
def export(self, path, url):
return self._getClient().export(path, url)
......
......@@ -90,9 +90,9 @@ class WorkingCopy(Implicit):
if cls.reference:
cls._registry.append((cls.reference, cls))
def __init__(self, path=None):
def __init__(self, path=None, restricted=False):
if path:
self.working_copy = self.checkWorkingPath(path)
self.working_copy = self.checkWorkingPath(path, restricted)
def getWorkingCopyList(self):
working_copy_list = []
......@@ -112,7 +112,7 @@ class WorkingCopy(Implicit):
os.mkdir(path)
self.working_copy = path
def checkWorkingPath(self, path):
def checkWorkingPath(self, path, restricted):
# First remove any '..' to prevent escaping.
# Note that 'normpath' ignore symlinks so it would not do it correctly.
parts = path.split(os.sep)
......@@ -125,11 +125,14 @@ class WorkingCopy(Implicit):
# Allow symlinks inside instance home.
path = os.path.normpath(path)
real_path = os.path.realpath(path)
for allowed in getConfiguration().instancehome, gettempdir():
if issubdir(allowed, path) or issubdir(allowed, real_path):
return real_path
raise Unauthorized("Unauthorized access to path %r."
" It is NOT in your Zope home instance." % path)
if restricted and not any(
issubdir(allowed, path) or issubdir(allowed, real_path)
for allowed in (getConfiguration().instancehome, gettempdir())):
raise Unauthorized("Unauthorized access to path %r."
" It is NOT in your Zope home instance." % path)
if os.path.isdir(real_path):
return real_path
raise NotAWorkingCopyError(real_path)
def _getCookie(self, name, default=None):
try:
......@@ -329,16 +332,16 @@ class WorkingCopy(Implicit):
installed_bt.reinstall(object_to_update=object_to_update, force=0)
def getVcsTool(vcs=None, path=None):
def getVcsTool(vcs=None, path=None, restricted=False):
if vcs:
for x in WorkingCopy._registry:
if x[0] == vcs:
return x[1](path)
return x[1](path, restricted)
raise ValueError("Unsupported Version Control System: %s" % vcs)
elif path:
for x in WorkingCopy._registry:
try:
return x[1](path)
return x[1](path, restricted)
except NotAWorkingCopyError:
pass
raise NotAWorkingCopyError(path)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment