summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Scott <barry@barrys-emacs.org>2016-05-28 12:05:23 +0100
committerBarry Scott <barry@barrys-emacs.org>2016-05-28 12:05:23 +0100
commitb4492c7965cd8e3c5faaf28b2a6414b04984720b (patch)
tree201c035534ac5809a3ef2436bdf7826775d195b5
parentbed46300fe5dcb376d43da56bbcd448d73bb2ea0 (diff)
downloadgitpython-b4492c7965cd8e3c5faaf28b2a6414b04984720b.tar.gz
The progress arg to push, pull, fetch and clone is now a python callable.
This simplifies the API and removes the parser, RemoteProgres, from the API as RemoteProgress is an internal detail of the implementation. progress is accepted as: * None - drop progress messages * callable (function etc) - call the function with the same args as update * object - assume its RemoteProgress derived as use as before RemoteProgress takes an optional progress_function argument. It will call the progress function if not None otherwise call self.update as it used to.
-rw-r--r--git/remote.py47
-rw-r--r--git/repo/base.py5
-rw-r--r--git/util.py12
3 files changed, 54 insertions, 10 deletions
diff --git a/git/remote.py b/git/remote.py
index e430abf5..320d4e56 100644
--- a/git/remote.py
+++ b/git/remote.py
@@ -57,6 +57,22 @@ def add_progress(kwargs, git, progress):
#} END utilities
+def progress_object(progress):
+ """Given the 'progress' return a suitable object derived from
+ RemoteProgress().
+ """
+ # new API only needs progress as a function
+ if callable(progress):
+ return RemoteProgress(progress)
+
+ # where None is passed create a parser that eats the progress
+ elif progress is None:
+ return RemoteProgress()
+
+ # assume its the old API with an instance of RemoteProgress.
+ else:
+ return progress
+
class PushInfo(object):
@@ -535,7 +551,10 @@ class Remote(LazyMixin, Iterable):
self.repo.git.remote(scmd, self.name, **kwargs)
return self
+
def _get_fetch_info_from_stderr(self, proc, progress):
+ progress = progress_object(progress)
+
# skip first line as it is some remote info we are not interested in
output = IterableList('name')
@@ -580,6 +599,8 @@ class Remote(LazyMixin, Iterable):
return output
def _get_push_info(self, proc, progress):
+ progress = progress_object(progress)
+
# read progress information from stderr
# we hope stdout can hold all the data, it should ...
# read the lines manually as it will use carriage returns between the messages
@@ -654,7 +675,7 @@ class Remote(LazyMixin, Iterable):
proc = self.repo.git.fetch(self, *args, as_process=True, with_stdout=False, v=True,
**kwargs)
- res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress())
+ res = self._get_fetch_info_from_stderr(proc, progress)
if hasattr(self.repo.odb, 'update_cache'):
self.repo.odb.update_cache()
return res
@@ -672,7 +693,7 @@ class Remote(LazyMixin, Iterable):
self._assert_refspec()
kwargs = add_progress(kwargs, self.repo.git, progress)
proc = self.repo.git.pull(self, refspec, with_stdout=False, as_process=True, v=True, **kwargs)
- res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress())
+ res = self._get_fetch_info_from_stderr(proc, progress)
if hasattr(self.repo.odb, 'update_cache'):
self.repo.odb.update_cache()
return res
@@ -682,10 +703,26 @@ class Remote(LazyMixin, Iterable):
:param refspec: see 'fetch' method
:param progress:
- Instance of type RemoteProgress allowing the caller to receive
- progress information until the method returns.
If None, progress information will be discarded
+ No further progress information is returned after push returns.
+
+ A function (callable) that is called with the progress infomation:
+
+ progress( op_code, cur_count, max_count=None, message='' )
+
+ op_code is a bit mask of values defined in git.RemoteProgress
+
+ cur_count and max_count are float values.
+
+ max_count is None if there is no max_count
+
+ messages is '' if there is no additon message.
+
+ Deprecated: Pass in a class derived from git.RemoteProgres that
+ overrides the update() function.
+
+
:param kwargs: Additional arguments to be passed to git-push
:return:
IterableList(PushInfo, ...) iterable list of PushInfo instances, each
@@ -697,7 +734,7 @@ class Remote(LazyMixin, Iterable):
be null."""
kwargs = add_progress(kwargs, self.repo.git, progress)
proc = self.repo.git.push(self, refspec, porcelain=True, as_process=True, **kwargs)
- return self._get_push_info(proc, progress or RemoteProgress())
+ return self._get_push_info(proc, progress)
@property
def config_reader(self):
diff --git a/git/repo/base.py b/git/repo/base.py
index bc5a7c35..9ba2b1d2 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -32,7 +32,8 @@ from git.index import IndexFile
from git.config import GitConfigParser
from git.remote import (
Remote,
- add_progress
+ add_progress,
+ progress_object
)
from git.db import GitCmdObjectDB
@@ -872,6 +873,8 @@ class Repo(object):
@classmethod
def _clone(cls, git, url, path, odb_default_type, progress, **kwargs):
+ progress = progress_object(progress)
+
# special handling for windows for path at which the clone should be
# created.
# tilde '~' will be expanded to the HOME no matter where the ~ occours. Hence
diff --git a/git/util.py b/git/util.py
index a267f183..9b86b191 100644
--- a/git/util.py
+++ b/git/util.py
@@ -174,11 +174,16 @@ class RemoteProgress(object):
DONE_TOKEN = 'done.'
TOKEN_SEPARATOR = ', '
- __slots__ = ("_cur_line", "_seen_ops")
+ __slots__ = ("_cur_line", "_seen_ops", "__progress_function")
re_op_absolute = re.compile(r"(remote: )?([\w\s]+):\s+()(\d+)()(.*)")
re_op_relative = re.compile(r"(remote: )?([\w\s]+):\s+(\d+)% \((\d+)/(\d+)\)(.*)")
- def __init__(self):
+ def __init__(self, progress_function=None):
+ if progress_function is not None:
+ self.__progress_function = progress_function
+ else:
+ self.__progress_function = self.update
+
self._seen_ops = list()
self._cur_line = None
@@ -267,7 +272,7 @@ class RemoteProgress(object):
# END end message handling
message = message.strip(self.TOKEN_SEPARATOR)
- self.update(op_code,
+ self.__progress_function(op_code,
cur_count and float(cur_count),
max_count and float(max_count),
message)
@@ -314,7 +319,6 @@ class RemoteProgress(object):
You may read the contents of the current line in self._cur_line"""
pass
-
class Actor(object):
"""Actors hold information about a person acting on the repository. They