Mercurial > wikked
changeset 117:b07cdd68de70
Added partial Git support:
* New Git source control file, with only support for querying state.
* Auto-detect repo type during initialization.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 19 Nov 2013 13:14:05 -0800 |
parents | b7950fa699f7 |
children | 7c8543878b47 |
files | wikked/resources/defaults.cfg wikked/scm.py wikked/wiki.py |
diffstat | 3 files changed, 95 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/wikked/resources/defaults.cfg Mon Nov 18 17:16:24 2013 -0800 +++ b/wikked/resources/defaults.cfg Tue Nov 19 13:14:05 2013 -0800 @@ -1,4 +1,3 @@ [wiki] -scm=hg auto_update=False default_extension=md
--- a/wikked/scm.py Mon Nov 18 17:16:24 2013 -0800 +++ b/wikked/scm.py Tue Nov 19 13:14:05 2013 -0800 @@ -6,6 +6,12 @@ import tempfile import subprocess +try: + import pygit2 + SUPPORTS_GIT = True +except ImportError: + SUPPORTS_GIT = False + STATE_COMMITTED = 0 STATE_MODIFIED = 1 @@ -88,7 +94,7 @@ if not os.path.isfile(ignore_path): self.logger.info("Creating `.hgignore` file.") with open(ignore_path, 'w') as f: - f.write('.cache') + f.write('.wiki') self._run('add', ignore_path) self._run('commit', ignore_path, '-m', 'Created .hgignore.') @@ -307,3 +313,75 @@ else: self.client.revert(all=True, clean=True) + +class GitBaseSourceControl(SourceControl): + def __init__(self, root, logger=None): + SourceControl.__init__(self, logger) + self.root = root + + def initRepo(self): + # Make a Git repo if there's none. + if not os.path.isdir(os.path.join(self.root, '.git')): + self.logger.info("Creating Git repository at: " + self.root) + self._initRepo(self.root) + + # Create a `.gitignore` file there's none. + ignore_path = os.path.join(self.root, '.gitignore') + if not os.path.isfile(ignore_path): + self.logger.info("Creating `.gitignore` file.") + with open(ignore_path, 'w') as f: + f.write('.wiki') + self._add(ignore_path) + self._commit('Created .gitignore.', [ignore_path]) + + def getSpecialFilenames(self): + specials = ['.git', '.gitignore'] + return [os.path.join(self.root, d) for d in specials] + + def getState(self, path): + return self._status(path) + + def _run(self, cmd, *args, **kwargs): + exe = [self.git] + if 'norepo' not in kwargs or not kwargs['norepo']: + exe.append('--git-dir="%s"' % self.root) + exe.append(cmd) + exe += args + self.logger.debug("Running Git: " + str(exe)) + return subprocess.check_output(exe) + + +class GitLibSourceControl(GitBaseSourceControl): + def __init__(self, root, logger=None): + if not SUPPORTS_GIT: + raise Exception("Can't support Git because pygit2 is not available.") + GitBaseSourceControl.__init__(self, root, logger) + + def initRepo(self): + GitBaseSourceControl.initRepo(self) + self.repo = pygit2.Repository(self.root) + + def _initRepo(self, path): + pygit2.init_repository(path, False) + + def _add(self, paths): + pass + + def _commit(self, message, paths): + pass + + def _status(self, path): + flags = self.repo.status_file(self._getRepoPath(path)) + if flags == pygit2.GIT_STATUS_CURRENT: + return STATE_COMMITTED + if (flags & pygit2.GIT_STATUS_WT_MODIFIED or + flags & pygit2.GIT_STATUS_INDEX_MODIFIED): + return STATE_MODIFIED + if (flags & pygit2.GIT_STATUS_WT_NEW or + flags & pygit2.GIT_STATUS_INDEX_NEW): + return STATE_NEW + raise Exception("Unsupported status flag combination: %s" % flags) + + def _getRepoPath(self, path): + return os.path.relpath(path, self.root).replace('\\', '/') +
--- a/wikked/wiki.py Mon Nov 18 17:16:24 2013 -0800 +++ b/wikked/wiki.py Tue Nov 19 13:14:05 2013 -0800 @@ -4,11 +4,11 @@ import logging import itertools import importlib -from ConfigParser import SafeConfigParser +from ConfigParser import SafeConfigParser, NoOptionError from page import DatabasePage, FileSystemPage from fs import FileSystem from db import SQLDatabase -from scm import MercurialCommandServerSourceControl +from scm import MercurialCommandServerSourceControl, GitLibSourceControl from indexer import WhooshWikiIndex from auth import UserManager @@ -54,9 +54,22 @@ return SQLDatabase(self.db_path, logger=self.logger_factory()) def scm_factory(self, config): - scm_type = config.get('wiki', 'scm') + try: + scm_type = config.get('wiki', 'scm') + except NoOptionError: + # Auto-detect + if os.path.isdir(os.path.join(self.root, '.hg')): + scm_type = 'hg' + elif os.path.isdir(os.path.join(self.root, '.git')): + scm_type = 'git' + else: + # Default to Mercurial. Yes. I just decided that myself. + scm_type = 'hg' + if scm_type == 'hg': return MercurialCommandServerSourceControl(self.root, logger=self.logger_factory()) + elif scm_type == 'git': + return GitLibSourceControl(self.root, logger=self.logger_factory()) else: raise InitializationError("No such source control: " + scm_type)