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 ...@@ -40,6 +40,7 @@ from Products.CMFCore.utils import getToolByName
from Products.PythonScripts.PythonScript import PythonScript from Products.PythonScripts.PythonScript import PythonScript
from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
from Products.ERP5Type.Cache import transactional_cached from Products.ERP5Type.Cache import transactional_cached
from Products.ERP5Type.Message import translateString
from Products.ERP5Type.Utils import readLocalDocument, \ from Products.ERP5Type.Utils import readLocalDocument, \
writeLocalDocument, \ writeLocalDocument, \
importLocalDocument, \ importLocalDocument, \
...@@ -5479,12 +5480,16 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -5479,12 +5480,16 @@ Business Template is a set of definitions, such as skins, portal types and categ
if os.path.isdir(bt_path): if os.path.isdir(bt_path):
return bt_path return bt_path
@transactional_cached(lambda self, vcs=None, path=None: (self, vcs, path)) @transactional_cached(lambda self, vcs=None, path=None, restricted=False:
def getVcsTool(self, vcs=None, path=None): (self, vcs, path, restricted))
def _getVcsTool(self, vcs=None, path=None, restricted=False):
from Products.ERP5VCS.WorkingCopy import getVcsTool from Products.ERP5VCS.WorkingCopy import getVcsTool
if not (path or vcs): if not (path or vcs):
path = self.getExportPath() 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): def isVcsType(self, *vcs):
# could be moved to Products.ERP5.Base.Base # 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 ...@@ -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() prop_dict[pid[:-5]] = (value or '').splitlines()
self._edit(**prop_dict) 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() self.storeTemplateItemData()
# Create temporary modules/classes for classes defined by this BT. # Create temporary modules/classes for classes defined by this BT.
......
...@@ -315,6 +315,11 @@ class Git(WorkingCopy): ...@@ -315,6 +315,11 @@ class Git(WorkingCopy):
#except AttributeError: #except AttributeError:
# pass # 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=()): def commit(self, changelog, added=(), modified=(), removed=()):
context = self.aq_parent context = self.aq_parent
request = context.REQUEST request = context.REQUEST
......
...@@ -65,10 +65,17 @@ class Subversion(WorkingCopy): ...@@ -65,10 +65,17 @@ class Subversion(WorkingCopy):
_login_cookie_name = 'erp5_subversion_login' _login_cookie_name = 'erp5_subversion_login'
_ssl_trust_cookie_name = 'erp5_subversion_ssl_trust' _ssl_trust_cookie_name = 'erp5_subversion_ssl_trust'
def __init__(self, path): def __init__(self, *args, **kw):
WorkingCopy.__init__(self, path) WorkingCopy.__init__(self, *args, **kw)
if path and not os.path.exists(os.path.join(self.working_copy, '.svn')): try:
raise NotAWorkingCopyError(self.working_copy) 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): def setLogin(self, realm, user, password):
"""Set login information. """Set login information.
...@@ -159,6 +166,12 @@ class Subversion(WorkingCopy): ...@@ -159,6 +166,12 @@ class Subversion(WorkingCopy):
def getRemoteComment(self): def getRemoteComment(self):
return 'r%s' % self.info()['revision'] 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): def export(self, path, url):
return self._getClient().export(path, url) return self._getClient().export(path, url)
......
...@@ -90,9 +90,9 @@ class WorkingCopy(Implicit): ...@@ -90,9 +90,9 @@ class WorkingCopy(Implicit):
if cls.reference: if cls.reference:
cls._registry.append((cls.reference, cls)) cls._registry.append((cls.reference, cls))
def __init__(self, path=None): def __init__(self, path=None, restricted=False):
if path: if path:
self.working_copy = self.checkWorkingPath(path) self.working_copy = self.checkWorkingPath(path, restricted)
def getWorkingCopyList(self): def getWorkingCopyList(self):
working_copy_list = [] working_copy_list = []
...@@ -112,7 +112,7 @@ class WorkingCopy(Implicit): ...@@ -112,7 +112,7 @@ class WorkingCopy(Implicit):
os.mkdir(path) os.mkdir(path)
self.working_copy = path self.working_copy = path
def checkWorkingPath(self, path): def checkWorkingPath(self, path, restricted):
# First remove any '..' to prevent escaping. # First remove any '..' to prevent escaping.
# Note that 'normpath' ignore symlinks so it would not do it correctly. # Note that 'normpath' ignore symlinks so it would not do it correctly.
parts = path.split(os.sep) parts = path.split(os.sep)
...@@ -125,11 +125,14 @@ class WorkingCopy(Implicit): ...@@ -125,11 +125,14 @@ class WorkingCopy(Implicit):
# Allow symlinks inside instance home. # Allow symlinks inside instance home.
path = os.path.normpath(path) path = os.path.normpath(path)
real_path = os.path.realpath(path) real_path = os.path.realpath(path)
for allowed in getConfiguration().instancehome, gettempdir(): if restricted and not any(
if issubdir(allowed, path) or issubdir(allowed, real_path): issubdir(allowed, path) or issubdir(allowed, real_path)
return real_path for allowed in (getConfiguration().instancehome, gettempdir())):
raise Unauthorized("Unauthorized access to path %r." raise Unauthorized("Unauthorized access to path %r."
" It is NOT in your Zope home instance." % path) " 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): def _getCookie(self, name, default=None):
try: try:
...@@ -329,16 +332,16 @@ class WorkingCopy(Implicit): ...@@ -329,16 +332,16 @@ class WorkingCopy(Implicit):
installed_bt.reinstall(object_to_update=object_to_update, force=0) 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: if vcs:
for x in WorkingCopy._registry: for x in WorkingCopy._registry:
if x[0] == vcs: if x[0] == vcs:
return x[1](path) return x[1](path, restricted)
raise ValueError("Unsupported Version Control System: %s" % vcs) raise ValueError("Unsupported Version Control System: %s" % vcs)
elif path: elif path:
for x in WorkingCopy._registry: for x in WorkingCopy._registry:
try: try:
return x[1](path) return x[1](path, restricted)
except NotAWorkingCopyError: except NotAWorkingCopyError:
pass pass
raise NotAWorkingCopyError(path) 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