mirror of
https://github.com/IEEE-SB-Passau/pelican-deployment-system.git
synced 2017-09-06 16:35:38 +02:00
move to homegrown git wrapper
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from git import Repo, InvalidGitRepositoryError, NoSuchPathError
|
from pelican_deploy.gittool import Repo
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from threading import RLock
|
from threading import RLock
|
||||||
@@ -47,55 +47,45 @@ class DeploymentRunner:
|
|||||||
self._build_lock = RLock()
|
self._build_lock = RLock()
|
||||||
|
|
||||||
def update_build_repository(self):
|
def update_build_repository(self):
|
||||||
try:
|
repo = Repo(str(self.build_repo_path))
|
||||||
build_repo = Repo(str(self.build_repo_path))
|
if not repo.is_repo():
|
||||||
|
|
||||||
except (InvalidGitRepositoryError, NoSuchPathError) as e:
|
|
||||||
if self.build_repo_path.is_dir() and \
|
if self.build_repo_path.is_dir() and \
|
||||||
next(self.build_repo_path.iterdir(), None) is not None:
|
next(self.build_repo_path.iterdir(), None) is not None:
|
||||||
log.error(
|
log.error(
|
||||||
"non-empty %s exists but not a valid git repository!",
|
"non-empty %s exists but not a valid git repository!",
|
||||||
self.build_repo_path)
|
self.build_repo_path)
|
||||||
raise
|
raise RuntimeException(("non-empty {} exists but not a"
|
||||||
|
"valid git repository!").format(self.build_repo_path))
|
||||||
else:
|
else:
|
||||||
log.info("Build repository %s not there, cloneing", e)
|
log.info("Build repository %s not there, cloneing", e)
|
||||||
build_repo = Repo.clone_from(self.clone_url,
|
result = repo.clone("--branch", "self.git_branch",
|
||||||
str(self.build_repo_path),
|
"--depth", "1", self.clone_url, ".")
|
||||||
branch=self.git_branch)
|
|
||||||
|
|
||||||
if build_repo.remotes.origin.url != self.clone_url:
|
origin_url = repo.config_get("remote.origin.url")
|
||||||
|
if origin_url != self.clone_url:
|
||||||
log.info("%s build_repo: URL of git origin changed (`%s` --> `%s`),\
|
log.info("%s build_repo: URL of git origin changed (`%s` --> `%s`),\
|
||||||
adjusting...", self.name, build_repo.remotes.origin.url,
|
adjusting...", self.name, origin_url, self.clone_url)
|
||||||
self.clone_url)
|
repo.config("remote.origin.url", self.clone_url)
|
||||||
cw = build_repo.remotes.origin.config_writer
|
|
||||||
cw.set("url", self.clone_url)
|
|
||||||
cw.release()
|
|
||||||
|
|
||||||
build_repo.head.reference = build_repo.create_head(self.git_branch)
|
|
||||||
assert not build_repo.head.is_detached
|
|
||||||
|
|
||||||
# deinit submodules to avoid removed ones dangling around later
|
# deinit submodules to avoid removed ones dangling around later
|
||||||
# they should stay around in .git, so reinit should be fast
|
# they should stay around in .git, so reinit should be fast
|
||||||
build_repo.git.submodule("deinit", ".")
|
repo.submodule("deinit", ".")
|
||||||
|
|
||||||
|
log.info("%s build_repo: reset it hard!", self.name)
|
||||||
|
repo.reset("--hard")
|
||||||
|
|
||||||
log.info("%s build_repo: pulling changes from origin", self.name)
|
log.info("%s build_repo: pulling changes from origin", self.name)
|
||||||
build_repo.remotes.origin.pull(
|
refspec = "+{b}:{b}".format(b=self.git_branch)
|
||||||
force=True,
|
repo.pull("--force", "--no-edit", "--recurse-submodules", "--depth",
|
||||||
no_edit=True,
|
"1", "origin", refspec)
|
||||||
refspec="+{b}:{b}".format(b=self.git_branch),
|
|
||||||
recurse_submodules="yes")
|
|
||||||
|
|
||||||
log.info("%s build_repo: resetting the working tree", self.name)
|
|
||||||
# forcefully reset the working tree
|
|
||||||
build_repo.head.reset(index=True, working_tree=True)
|
|
||||||
try:
|
try:
|
||||||
build_repo.git.clean(force=True, d=True, x=True)
|
repo.clean("--force", "-d", "-x")
|
||||||
except:
|
except:
|
||||||
log.warning("git clean failed!", exc_info=True)
|
log.warning("git clean failed!", exc_info=True)
|
||||||
|
|
||||||
# update the submodules
|
# update the submodules
|
||||||
log.info("%s build_repo: update submodules", self.name)
|
log.info("%s build_repo: update submodules", self.name)
|
||||||
build_repo.git.submodule("update", "--init", "--force", "--recursive")
|
repo.submodule("update", "--init", "--force", "--recursive")
|
||||||
|
|
||||||
def build(self, abort_running=False):
|
def build(self, abort_running=False):
|
||||||
with self._build_lock:
|
with self._build_lock:
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ from subprocess import Popen, PIPE
|
|||||||
|
|
||||||
CmdResult = namedtuple("CmdResult", "status stdout stderr")
|
CmdResult = namedtuple("CmdResult", "status stdout stderr")
|
||||||
|
|
||||||
|
class GitCommandError(Exception):
|
||||||
|
def __init__(self, message, result, *args, **kwargs):
|
||||||
|
super().__init__(message, result, *args, **kwargs)
|
||||||
|
self.result = result
|
||||||
|
|
||||||
|
|
||||||
class Repo:
|
class Repo:
|
||||||
def __init__(self, repo_dir, git_cmd="git", default_timeout=None):
|
def __init__(self, repo_dir, git_cmd="git", default_timeout=None):
|
||||||
self.repo_dir = repo_dir
|
self.repo_dir = repo_dir
|
||||||
@@ -18,20 +24,29 @@ class Repo:
|
|||||||
return self.cmd(*((self.git_cmd, name) + tuple(cmdargs)), **kwargs)
|
return self.cmd(*((self.git_cmd, name) + tuple(cmdargs)), **kwargs)
|
||||||
return cmdcaller
|
return cmdcaller
|
||||||
|
|
||||||
def cmd(self, *args, timeout=None, env=None):
|
def cmd(self, *args, timeout=None, env=None, universal_newlines=True,
|
||||||
timeout = timeout if timeout else default_timeout
|
errors_raise=True):
|
||||||
|
timeout = timeout if timeout else self.default_timeout
|
||||||
proc = self.popen_cmd(*args, env=env)
|
proc = self.popen_cmd(*args, env=env)
|
||||||
outs, errs = proc.communicate(timeout=timeout)
|
outs, errs = proc.communicate(timeout=timeout)
|
||||||
status = proc.wait()
|
status = proc.wait()
|
||||||
|
res = CmdResult(status, outs, errs)
|
||||||
|
if status != 0 and errors_raise:
|
||||||
|
raise GitCommandError("git failed: {}".format(args), res)
|
||||||
return CmdResult(status, outs, errs)
|
return CmdResult(status, outs, errs)
|
||||||
|
|
||||||
def popen_cmd(self, *args, env=None):
|
def popen_cmd(self, *args, env=None, universal_newlines=True):
|
||||||
return Popen(args, stdout=PIPE, stderr=PIPE, cwd=self.repo_dir, env=env)
|
return Popen(args, stdout=PIPE, stderr=PIPE, cwd=self.repo_dir, env=env,
|
||||||
|
universal_newlines=universal_newlines)
|
||||||
|
|
||||||
def is_bare(self):
|
def is_bare(self):
|
||||||
result = self.rev_parse("--is-bare-repository")
|
result = self.rev_parse("--is-bare-repository")
|
||||||
return result.stdout.startswith(b"true")
|
return result.stdout.startswith("true")
|
||||||
|
|
||||||
def is_repo(self):
|
def is_repo(self):
|
||||||
return self.rev_parse("--git-dir").status == 0
|
return self.rev_parse("--git-dir", errors_raise=False).status == 0
|
||||||
|
|
||||||
|
def config_get(self, key):
|
||||||
|
res = self.config("--get", key)
|
||||||
|
return res.stdout.rstrip("\r\n")
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
bottle
|
bottle
|
||||||
GitPython
|
|
||||||
apscheduler
|
apscheduler
|
||||||
tox
|
tox
|
||||||
|
|||||||
Reference in New Issue
Block a user