diff --git a/rhodecode/model/scm.py b/rhodecode/model/scm.py --- a/rhodecode/model/scm.py +++ b/rhodecode/model/scm.py @@ -23,14 +23,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os +import re import time import traceback import logging import cStringIO +import pkg_resources +from os.path import dirname as dn, join as jn from sqlalchemy import func from pylons.i18n.translation import _ +import rhodecode from rhodecode.lib.vcs import get_backend from rhodecode.lib.vcs.exceptions import RepositoryError from rhodecode.lib.vcs.utils.lazy import LazyProperty @@ -545,3 +549,49 @@ class ScmModel(BaseModel): choices.extend([x[0] for x in tags_group[0]]) return choices, hist_l + + def install_git_hook(self, repo, force_create=False): + """ + Creates a rhodecode hook inside a git repository + + :param repo: Instance of VCS repo + :param force_create: Create even if same name hook exists + """ + + loc = jn(repo.path, 'hooks') + if not repo.bare: + loc = jn(repo.path, '.git', 'hooks') + if not os.path.isdir(loc): + os.makedirs(loc) + + tmpl = pkg_resources.resource_string( + 'rhodecode', jn('config', 'post_receive_tmpl.py') + ) + + _hook_file = jn(loc, 'post-receive') + _rhodecode_hook = False + log.debug('Installing git hook in repo %s' % repo) + if os.path.exists(_hook_file): + # let's take a look at this hook, maybe it's rhodecode ? + log.debug('hook exists, checking if it is from rhodecode') + _HOOK_VER_PAT = re.compile(r'^RC_HOOK_VER') + with open(_hook_file, 'rb') as f: + data = f.read() + matches = re.compile(r'(?:%s)\s*=\s*(.*)' + % 'RC_HOOK_VER').search(data) + if matches: + try: + ver = matches.groups()[0] + log.debug('got %s it is rhodecode' % (ver)) + _rhodecode_hook = True + except: + log.error(traceback.format_exc()) + + if _rhodecode_hook or force_create: + log.debug('writing hook file !') + with open(_hook_file, 'wb') as f: + tmpl = tmpl.replace('_TMPL_', rhodecode.__version__) + f.write(tmpl) + os.chmod(_hook_file, 0755) + else: + log.debug('skipping writing hook file') \ No newline at end of file