-
Notifications
You must be signed in to change notification settings - Fork 202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add mercurial repository support. #979
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,7 +75,7 @@ class GitRepository(FileRepository): | |
def __init__(self, *args): | ||
""" | ||
Initialize git client to None (will be set later) | ||
All the real logic is in the setupRepo and createWorkingCopy methods | ||
All the real logic is in the setup_repo and create_wroking_copy methods | ||
""" | ||
self.client = None | ||
FileRepository.__init__(self, *args) | ||
|
@@ -84,10 +84,8 @@ def setup_repo(self): | |
""" | ||
Set up git repository. | ||
""" | ||
try: | ||
git.GitCommandError | ||
except NameError, err: | ||
self.log.exception("It seems like GitPython is not available: %s" % err) | ||
if not HAVE_GIT: | ||
self.log.error("It seems like GitPython is not available, which is required for Git support.") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this point ever be reached? Will the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. true, then again, the uses of logger makes it hard to use this outside EB (as I noticed in the clean up script). |
||
|
||
self.wc = tempfile.mkdtemp(prefix='git-wc-') | ||
|
||
|
@@ -103,7 +101,7 @@ def create_working_copy(self): | |
client.clone(self.repo) | ||
reponame = os.listdir(self.wc)[0] | ||
self.log.debug("rep name is %s" % reponame) | ||
except git.GitCommandError, err: | ||
except (git.GitCommandError, OSError), err: | ||
# it might already have existed | ||
self.log.warning("Git local repo initialization failed, it might already exist: %s" % err) | ||
|
||
|
@@ -120,7 +118,7 @@ def create_working_copy(self): | |
res = self.client.pull() | ||
self.log.debug("pulled succesfully to %s in %s" % (res, self.wc)) | ||
except (git.GitCommandError, OSError), err: | ||
self.log.exception("pull in working copy %s went wrong: %s" % (self.wc, err)) | ||
self.log.error("pull in working copy %s went wrong: %s" % (self.wc, err)) | ||
|
||
def add_easyconfig(self, cfg, name, version, stats, append): | ||
""" | ||
|
@@ -139,10 +137,9 @@ def commit(self, msg=None): | |
Commit working copy to git repository | ||
""" | ||
self.log.debug("committing in git: %s" % msg) | ||
completemsg = "EasyBuild-commit from %s (time: %s, user: %s) \n%s" % (socket.gethostname(), | ||
time.strftime("%Y-%m-%d_%H-%M-%S"), | ||
getpass.getuser(), | ||
msg) | ||
tup = (socket.gethostname(), time.strftime("%Y-%m-%d_%H-%M-%S"), getpass.getuser(), msg) | ||
completemsg = "EasyBuild-commit from %s (time: %s, user: %s) \n%s" % tup | ||
|
||
self.log.debug("git status: %s" % self.client.status()) | ||
try: | ||
self.client.commit('-am "%s"' % completemsg) | ||
|
@@ -153,10 +150,8 @@ def commit(self, msg=None): | |
info = self.client.push() | ||
self.log.debug("push info: %s " % info) | ||
except GitCommandError, err: | ||
self.log.warning("Push from working copy %s to remote %s (msg: %s) failed: %s" % (self.wc, | ||
self.repo, | ||
msg, | ||
err)) | ||
tup = (self.wc, self.repo, msg, err) | ||
self.log.warning("Push from working copy %s to remote %s (msg: %s) failed: %s" % tup) | ||
|
||
def cleanup(self): | ||
""" | ||
|
@@ -166,4 +161,4 @@ def cleanup(self): | |
self.wc = os.path.dirname(self.wc) | ||
rmtree2(self.wc) | ||
except IOError, err: | ||
self.log.exception("Can't remove working copy %s: %s" % (self.wc, err)) | ||
self.log.error("Can't remove working copy %s: %s" % (self.wc, err)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
# # | ||
# Copyright 2009-2014 Ghent University | ||
# | ||
# This file is part of EasyBuild, | ||
# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), | ||
# with support of Ghent University (http://ugent.be/hpc), | ||
# the Flemish Supercomputer Centre (VSC) (https://vscentrum.be/nl/en), | ||
# the Hercules foundation (http://www.herculesstichting.be/in_English) | ||
# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). | ||
# | ||
# http://github.com/hpcugent/easybuild | ||
# | ||
# EasyBuild is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation v2. | ||
# | ||
# EasyBuild is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with EasyBuild. If not, see <http://www.gnu.org/licenses/>. | ||
# # | ||
""" | ||
Repository tools | ||
|
||
Mercurial repository | ||
|
||
@author: Stijn De Weirdt (Ghent University) | ||
@author: Dries Verdegem (Ghent University) | ||
@author: Kenneth Hoste (Ghent University) | ||
@author: Pieter De Baets (Ghent University) | ||
@author: Jens Timmerman (Ghent University) | ||
@author: Toon Willems (Ghent University) | ||
@author: Ward Poelmans (Ghent University) | ||
@author: Fotis Georgatos (University of Luxembourg) | ||
@author: Cedric Clerget (University of Franche-Comte) | ||
""" | ||
import getpass | ||
import socket | ||
import tempfile | ||
import time | ||
from vsc.utils import fancylogger | ||
|
||
from easybuild.tools.filetools import rmtree2 | ||
from easybuild.tools.repository.filerepo import FileRepository | ||
|
||
_log = fancylogger.getLogger('hgrepo', fname=False) | ||
|
||
# optional Python packages, these might be missing | ||
# failing imports are just ignored | ||
# a NameError should be catched where these are used | ||
|
||
# python-hglib | ||
try: | ||
import hglib | ||
from hglib.error import CapabilityError as HgCapabilityError | ||
from hglib.error import CommandError as HgCommandError | ||
from hglib.error import ResponseError as HgResponseError | ||
from hglib.error import ServerError as HgServerError | ||
HAVE_HG = True | ||
except ImportError: | ||
_log.debug('Failed to import hglib module') | ||
HAVE_HG = False | ||
|
||
|
||
class HgRepository(FileRepository): | ||
""" | ||
Class for hg repositories. | ||
""" | ||
DESCRIPTION = ("A non-empty mercurial repository (created with 'hg init' or 'hg clone'). " | ||
"The 1st argument contains the mercurial repository location, which can be a directory or an URL. " | ||
"The 2nd argument is ignored.") | ||
|
||
USABLE = HAVE_HG | ||
|
||
def __init__(self, *args): | ||
""" | ||
Initialize mercurial client to None (will be set later) | ||
All the real logic is in the setup_repo and create_working_copy methods | ||
""" | ||
self.client = None | ||
FileRepository.__init__(self, *args) | ||
|
||
def setup_repo(self): | ||
""" | ||
Set up mercurial repository. | ||
""" | ||
if not HAVE_HG: | ||
self.log.error("The python-hglib Python module is not available, which is required for Mercurial support.") | ||
|
||
self.wc = tempfile.mkdtemp(prefix='hg-wc-') | ||
|
||
def create_working_copy(self): | ||
""" | ||
Create mercurial working copy. | ||
""" | ||
|
||
# try to get a copy of | ||
try: | ||
client = hglib.clone(self.repo, self.wc) | ||
self.log.debug("repo %s cloned in %s" % (self.repo, self.wc)) | ||
except (HgCommandError, OSError), err: | ||
# it might already have existed | ||
self.log.warning("Mercurial local repo initialization failed, it might already exist: %s" % err) | ||
|
||
# local repo should now exist, let's connect to it again | ||
try: | ||
self.log.debug("connection to mercurial repo in %s" % self.wc) | ||
self.client = hglib.open(self.wc) | ||
except HgServerError, err: | ||
self.log.error("Could not connect to local mercurial repo: %s" % err) | ||
except (HgCapabilityError, HgResponseError), err: | ||
self.log.error("Server response: %s", err) | ||
except (OSError, ValueError), err: | ||
self.log.error("Could not create a local mercurial repo in wc %s: %s" % (self.wc, err)) | ||
|
||
# try to get the remote data in the local repo | ||
try: | ||
self.client.pull() | ||
self.log.debug("pulled succesfully in %s" % self.wc) | ||
except (HgCommandError, HgServerError, HgResponseError, OSError, ValueError), err: | ||
self.log.error("pull in working copy %s went wrong: %s" % (self.wc, err)) | ||
|
||
def add_easyconfig(self, cfg, name, version, stats, append): | ||
""" | ||
Add easyconfig to mercurial repository. | ||
""" | ||
dest = FileRepository.add_easyconfig(self, cfg, name, version, stats, append) | ||
# add it to version control | ||
if dest: | ||
try: | ||
self.client.add(dest) | ||
except (HgCommandError, HgServerError, HgResponseError, ValueError), err: | ||
self.log.warning("adding %s to mercurial repository failed: %s" % (dest, err)) | ||
|
||
def commit(self, msg=None): | ||
""" | ||
Commit working copy to mercurial repository | ||
""" | ||
user = getpass.getuser() | ||
self.log.debug("%s committing in mercurial repository: %s" % (user, msg)) | ||
tup = (socket.gethostname(), time.strftime("%Y-%m-%d_%H-%M-%S"), user, msg) | ||
completemsg = "EasyBuild-commit from %s (time: %s, user: %s) \n%s" % tup | ||
|
||
self.log.debug("hg status: %s" % self.client.status()) | ||
try: | ||
self.client.commit('"%s"' % completemsg, user=user) | ||
self.log.debug("succesfull commit") | ||
except (HgCommandError, HgServerError, HgResponseError, ValueError), err: | ||
self.log.warning("Commit from working copy %s (msg: %s) failed, empty commit?\n%s" % (self.wc, msg, err)) | ||
try: | ||
if self.client.push(): | ||
info = "pushed" | ||
else: | ||
info = "nothing to push" | ||
self.log.debug("push info: %s " % info) | ||
except (HgCommandError, HgServerError, HgResponseError, ValueError), err: | ||
tup = (self.wc, self.repo, msg, err) | ||
self.log.warning("Push from working copy %s to remote %s (msg: %s) failed: %s" % tup) | ||
|
||
def cleanup(self): | ||
""" | ||
Clean up mercurial working copy. | ||
""" | ||
try: | ||
rmtree2(self.wc) | ||
except IOError, err: | ||
self.log.error("Can't remove working copy %s: %s" % (self.wc, err)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought the catching exception was used to make sure git/svn binary was present on system and I was wrong. What you think about an additional check on binary presence ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say that's the job of the respective Python packages being used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes and only git and hglib module are concerned. Just apply a minor fix to catch OSError exception for cloning step.