diff --git a/utils/credits_git_gen.py b/utils/credits_git_gen.py index 96dd579eb8094fc718a9443164e74bef30ca6034..a947cd808ca1caaa19d959f0d537b7287d35c4c4 100644 --- a/utils/credits_git_gen.py +++ b/utils/credits_git_gen.py @@ -24,137 +24,8 @@ import os import subprocess -# ----------------------------------------------------------------------------- -# Generic git read-only classes for extracting info - -class GitCommit: - __slots__ = ( - "sha1", - # to extract more info - "_git_dir", - - # cached values - "_author", - "_date", - "_body", - "_files", - "_files_status", - ) - - def __init__(self, sha1, git_dir): - self.sha1 = sha1 - self._git_dir = git_dir - - self._author = \ - self._date = \ - self._body = \ - self._files = \ - self._files_status = \ - None - - def _log_format(self, format, args=()): - # sha1 = self.sha1.decode('ascii') - cmd = ( - "git", - "--git-dir", - self._git_dir, - "log", - "-1", # only this rev - self.sha1, - "--format=" + format, - ) + args - # print(" ".join(cmd)) - - p = subprocess.Popen( - cmd, - stdout=subprocess.PIPE, - ) - return p.stdout.read() - - @property - def author(self): - ret = self._author - if ret is None: - content = self._log_format("%an")[:-1] - ret = content.decode("utf8", errors="ignore") - self._author = ret - return ret - - @property - def date(self): - ret = self._date - if ret is None: - import datetime - ret = datetime.datetime.fromtimestamp(int(self._log_format("%ct"))) - self._date = ret - return ret - - @property - def body(self): - ret = self._body - if ret is None: - content = self._log_format("%B")[:-1] - ret = content.decode("utf8", errors="ignore") - self._body = ret - return ret - - @property - def files(self): - ret = self._files - if ret is None: - ret = [f for f in self._log_format("format:", args=("--name-only",)).split(b"\n") if f] - self._files = ret - return ret - - @property - def files_status(self): - ret = self._files_status - if ret is None: - ret = [f.split(None, 1) for f in self._log_format("format:", args=("--name-status",)).split(b"\n") if f] - self._files_status = ret - return ret - - -class GitCommitIter: - __slots__ = ( - "_path", - "_git_dir", - "_sha1_range", - "_process", - ) - - def __init__(self, path, sha1_range): - self._path = path - self._git_dir = os.path.join(path, ".git") - self._sha1_range = sha1_range - self._process = None - - def __iter__(self): - cmd = ( - "git", - "--git-dir", - self._git_dir, - "log", - self._sha1_range, - "--format=%H", - ) - # print(" ".join(cmd)) - - self._process = subprocess.Popen( - cmd, - stdout=subprocess.PIPE, - ) - return self - - def __next__(self): - sha1 = self._process.stdout.readline()[:-1] - if sha1: - return GitCommit(sha1, self._git_dir) - else: - raise StopIteration - - -if 0 and __name__ == "__main__": +from git_log import GitCommit, GitCommitIter +if 1 and __name__ == "__main__": for c in GitCommitIter("/src/blender", "HEAD~10..HEAD"): print(c.sha1, c.author, c.date) print(c.body) diff --git a/utils/git_log.py b/utils/git_log.py new file mode 100644 index 0000000000000000000000000000000000000000..1fe9b3a4c8eee7876ad124da5893ed3ebba10024 --- /dev/null +++ b/utils/git_log.py @@ -0,0 +1,152 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +# Simple module for inspecting git commits + +import os +import subprocess + + +class GitCommit: + __slots__ = ( + "sha1", + # to extract more info + "_git_dir", + + # cached values + "_author", + "_date", + "_body", + "_files", + "_files_status", + ) + + def __init__(self, sha1, git_dir): + self.sha1 = sha1 + self._git_dir = git_dir + + self._author = \ + self._date = \ + self._body = \ + self._files = \ + self._files_status = \ + None + + def _log_format(self, format, args=()): + # sha1 = self.sha1.decode('ascii') + cmd = ( + "git", + "--git-dir", + self._git_dir, + "log", + "-1", # only this rev + self.sha1, + "--format=" + format, + ) + args + # print(" ".join(cmd)) + + p = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + ) + return p.stdout.read() + + @property + def author(self): + ret = self._author + if ret is None: + content = self._log_format("%an")[:-1] + ret = content.decode("utf8", errors="ignore") + self._author = ret + return ret + + @property + def date(self): + ret = self._date + if ret is None: + import datetime + ret = datetime.datetime.fromtimestamp(int(self._log_format("%ct"))) + self._date = ret + return ret + + @property + def body(self): + ret = self._body + if ret is None: + content = self._log_format("%B")[:-1] + ret = content.decode("utf8", errors="ignore") + self._body = ret + return ret + + @property + def files(self): + ret = self._files + if ret is None: + ret = [f for f in self._log_format("format:", args=("--name-only",)).split(b"\n") if f] + self._files = ret + return ret + + @property + def files_status(self): + ret = self._files_status + if ret is None: + ret = [f.split(None, 1) for f in self._log_format("format:", args=("--name-status",)).split(b"\n") if f] + self._files_status = ret + return ret + + +class GitCommitIter: + __slots__ = ( + "_path", + "_git_dir", + "_sha1_range", + "_process", + ) + + def __init__(self, path, sha1_range): + self._path = path + self._git_dir = os.path.join(path, ".git") + self._sha1_range = sha1_range + self._process = None + + def __iter__(self): + cmd = ( + "git", + "--git-dir", + self._git_dir, + "log", + self._sha1_range, + "--format=%H", + ) + # print(" ".join(cmd)) + + self._process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + ) + return self + + def __next__(self): + sha1 = self._process.stdout.readline()[:-1] + if sha1: + return GitCommit(sha1, self._git_dir) + else: + raise StopIteration +