aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--cgitize/cgit.py39
-rw-r--r--cgitize/git.py48
-rw-r--r--cgitize/utils.py22
3 files changed, 72 insertions, 37 deletions
diff --git a/cgitize/cgit.py b/cgitize/cgit.py
index 167456f..7c6e6f6 100644
--- a/cgitize/cgit.py
+++ b/cgitize/cgit.py
@@ -3,49 +3,14 @@
# For details, see https://github.com/egor-tensin/cgitize.
# Distributed under the MIT License.
-from contextlib import contextmanager
import logging
import os
-import os.path
import shutil
-import stat
from cgitize.git import Git
from cgitize.utils import chdir
-@contextmanager
-def setup_git_auth(repo):
- if not repo.url_auth:
- yield
- return
- config_path = os.path.expanduser('~/.gitconfig')
- exists = os.path.exists(config_path)
- if exists:
- old_permissions = stat.S_IMODE(os.stat(config_path).st_mode)
- new_permissions = stat.S_IRUSR | stat.S_IWUSR # 0x600
- os.chmod(config_path, new_permissions)
- with open(config_path, encoding='utf-8', mode='r') as fd:
- old_contents = fd.read()
- else:
- old_contents = ''
- new_contents = f'''{old_contents}
-[url "{repo.clone_url_with_auth}"]
- insteadOf = {repo.clone_url}
-'''
- with open(config_path, encoding='utf-8', mode='w') as fd:
- fd.write(new_contents)
- try:
- yield
- finally:
- if exists:
- with open(config_path, encoding='utf-8', mode='w') as fd:
- fd.write(old_contents)
- os.chmod(config_path, old_permissions)
- else:
- os.unlink(config_path)
-
-
class CGitServer:
def __init__(self, clone_url):
self.clone_url = clone_url
@@ -150,14 +115,14 @@ class CGitRepositories:
except Exception as e:
logging.exception(e)
return False
- with setup_git_auth(repo):
+ with Git.setup_auth(repo):
return Git.check('clone', '--mirror', '--quiet', repo.clone_url, repo_dir)
def _update_existing(self, repo):
logging.info("Updating repository '%s'", repo.repo_id)
repo_dir = self.get_repo_dir(repo)
with chdir(repo_dir):
- with setup_git_auth(repo):
+ with Git.setup_auth(repo):
if not Git.check('remote', 'update', '--prune'):
return False
# In case the local repository is not a bare repository, but a
diff --git a/cgitize/git.py b/cgitize/git.py
index 87554dd..a2be8df 100644
--- a/cgitize/git.py
+++ b/cgitize/git.py
@@ -3,6 +3,7 @@
# For details, see https://github.com/egor-tensin/cgitize.
# Distributed under the MIT License.
+from contextlib import contextmanager
import os
import cgitize.utils as utils
@@ -12,6 +13,33 @@ GIT_ENV = os.environ.copy()
GIT_ENV['GIT_SSH_COMMAND'] = 'ssh -oBatchMode=yes -oLogLevel=QUIET -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null'
+class Config:
+ def __init__(self, path):
+ self.path = path
+
+ def exists(self):
+ return os.path.exists(self.path)
+
+ def open(self, mode='r'):
+ return open(self.path, mode=mode, encoding='utf-8')
+
+ def read(self):
+ with self.open(mode='r') as fd:
+ return fd.read()
+
+ def write(self, contents):
+ with self.open(mode='w') as fd:
+ fd.write(contents)
+
+ @contextmanager
+ def backup(self):
+ old_contents = self.read()
+ try:
+ yield old_contents
+ finally:
+ self.write(old_contents)
+
+
class Git:
EXE = 'git'
@@ -22,3 +50,23 @@ class Git:
@staticmethod
def capture(*args, **kwargs):
return utils.try_run_capture(Git.EXE, *args, env=GIT_ENV, **kwargs)
+
+ @staticmethod
+ def get_global_config():
+ return Config(os.path.expanduser('~/.gitconfig'))
+
+ @staticmethod
+ @contextmanager
+ def setup_auth(repo):
+ if not repo.url_auth:
+ yield
+ return
+ config = Git.get_global_config()
+ with utils.protected_file(config.path):
+ with config.backup() as old_contents:
+ new_contents = f'''{old_contents}
+[url "{repo.clone_url_with_auth}"]
+ insteadOf = {repo.clone_url}
+'''
+ config.write(new_contents)
+ yield
diff --git a/cgitize/utils.py b/cgitize/utils.py
index 0bfa855..152684f 100644
--- a/cgitize/utils.py
+++ b/cgitize/utils.py
@@ -6,6 +6,7 @@
from contextlib import contextmanager
import logging
import os
+import stat
import subprocess
import sys
@@ -69,3 +70,24 @@ def chdir(new_cwd):
yield
finally:
os.chdir(old_cwd)
+
+
+@contextmanager
+def protected_file(path):
+ # 0600:
+ new_permissions = stat.S_IRUSR | stat.S_IWUSR
+ if os.path.exists(path):
+ old_permissions = stat.S_IMODE(os.stat(path).st_mode)
+ os.chmod(path, new_permissions)
+ try:
+ yield
+ finally:
+ os.chmod(path, old_permissions)
+ else:
+ with open(path, mode='w'):
+ pass
+ os.chmod(path, new_permissions)
+ try:
+ yield
+ finally:
+ os.unlink(path)