From c09a611ea8aab0c1718496c80c59ab246339a419 Mon Sep 17 00:00:00 2001 From: Marat Dukhan Date: Sat, 4 Mar 2017 20:16:26 -0500 Subject: [PATCH] Fall back to git executable if pygit2 is not working --- confu/__main__.py | 2 - confu/git.py | 73 ++++++++++++++++++++++------ install_deps.sh => install_pygit2.sh | 0 setup.py | 2 +- 4 files changed, 59 insertions(+), 18 deletions(-) rename install_deps.sh => install_pygit2.sh (100%) diff --git a/confu/__main__.py b/confu/__main__.py index d996403..23d8eb4 100644 --- a/confu/__main__.py +++ b/confu/__main__.py @@ -8,8 +8,6 @@ def setup_deps(options, unparsed_args): - import pygit2 - import confu.recipes import types builtin_recipes = [name for name in confu.recipes.__dict__ diff --git a/confu/git.py b/confu/git.py index 897f81e..be34538 100644 --- a/confu/git.py +++ b/confu/git.py @@ -1,27 +1,70 @@ import logging -import pygit2 - - logger = logging.getLogger("confu") +try: + import pygit2 + if not(pygit2.features & pygit2.GIT_FEATURE_HTTPS) or not(pygit2.features & pygit2.GIT_FEATURE_SSH): + logger.warning("pygit2 is built without HTTPS or SSH support, fall back to using git executable") + pygit2 = None +except ImportError: + pygit2 = None + failed_certificate_hosts = set() -class RemoteCallbacks(pygit2.RemoteCallbacks): - def __init__(self, credentials=None, certificate=None): - super(RemoteCallbacks, self).__init__(credentials, certificate) +if pygit2 is not None: + class RemoteCallbacks(pygit2.RemoteCallbacks): + def __init__(self, credentials=None, certificate=None): + super(RemoteCallbacks, self).__init__(credentials, certificate) + + def certificate_check(self, certificate, valid, host): + if not valid: + # Do not complain twice about the same host + if host not in failed_certificate_hosts: + logger.warning("could not validate certificate for {host}".format(host=host)) + failed_certificate_hosts.add(host) + + return True +else: + class Repo: + def __init__(self, root_dir): + self.root_dir = root_dir + + @staticmethod + def clone(url, path, checkout_branch=None): + import subprocess + args = ["git", "clone", "--quiet", url] + if checkout_branch is not None: + args += ["-b", checkout_branch] + args.append(path) + + import os + env = os.environ.copy() + env["LC_ALL"] = "C" + + git = subprocess.Popen(args, env=env) + git.communicate() + assert git.returncode == 0 + + return Repo(path) + + def checkout(self, refname): + import subprocess + args = ["git", "checkout", "--quiet", refname] - def certificate_check(self, certificate, valid, host): - if not valid: - # Do not complain twice about the same host - if host not in failed_certificate_hosts: - logger.warning("could not validate certificate for {host}".format(host=host)) - failed_certificate_hosts.add(host) + import os + env = os.environ.copy() + env["LC_ALL"] = "C" - return True + git = subprocess.Popen(args, cwd=self.root_dir, env=env) + git.communicate() + assert git.returncode == 0 def clone(url, path, checkout_branch=None): - remote_callbacks = RemoteCallbacks() - return pygit2.clone_repository(url, path, checkout_branch=checkout_branch, callbacks=remote_callbacks) + if pygit2 is not None: + remote_callbacks = RemoteCallbacks() + return pygit2.clone_repository(url, path, checkout_branch=checkout_branch, callbacks=remote_callbacks) + else: + return Repo.clone(url, path, checkout_branch=checkout_branch) diff --git a/install_deps.sh b/install_pygit2.sh similarity index 100% rename from install_deps.sh rename to install_pygit2.sh diff --git a/setup.py b/setup.py index 271d31b..7c4641a 100755 --- a/setup.py +++ b/setup.py @@ -28,4 +28,4 @@ "Topic :: Software Development :: Build Tools" ], setup_requires=["six"], - install_requires=["six", "pygit2", "ninja_syntax>=1.7.2"]) + install_requires=["six", "PyYAML", "ninja_syntax>=1.7.2"])