Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(326)

Unified Diff: third_party/logilab/logilab/common/changelog.py

Issue 1920403002: [content/test/gpu] Run pylint check of gpu tests in unittest instead of PRESUBMIT (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update path to LICENSE.txt of logilab/README.chromium Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/logilab/logilab/common/cache.py ('k') | third_party/logilab/logilab/common/clcommands.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/logilab/logilab/common/changelog.py
diff --git a/third_party/logilab/logilab/common/changelog.py b/third_party/logilab/logilab/common/changelog.py
new file mode 100644
index 0000000000000000000000000000000000000000..2fff2ed6505838e781151cecb76d0ae151ecc4d4
--- /dev/null
+++ b/third_party/logilab/logilab/common/changelog.py
@@ -0,0 +1,238 @@
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of logilab-common.
+#
+# logilab-common is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option) any
+# later version.
+#
+# logilab-common 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 Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with logilab-common. If not, see <http://www.gnu.org/licenses/>.
+"""Manipulation of upstream change log files.
+
+The upstream change log files format handled is simpler than the one
+often used such as those generated by the default Emacs changelog mode.
+
+Sample ChangeLog format::
+
+ Change log for project Yoo
+ ==========================
+
+ --
+ * add a new functionality
+
+ 2002-02-01 -- 0.1.1
+ * fix bug #435454
+ * fix bug #434356
+
+ 2002-01-01 -- 0.1
+ * initial release
+
+
+There is 3 entries in this change log, one for each released version and one
+for the next version (i.e. the current entry).
+Each entry contains a set of messages corresponding to changes done in this
+release.
+All the non empty lines before the first entry are considered as the change
+log title.
+"""
+
+__docformat__ = "restructuredtext en"
+
+import sys
+from stat import S_IWRITE
+
+from six import string_types
+
+BULLET = '*'
+SUBBULLET = '-'
+INDENT = ' ' * 4
+
+class NoEntry(Exception):
+ """raised when we are unable to find an entry"""
+
+class EntryNotFound(Exception):
+ """raised when we are unable to find a given entry"""
+
+class Version(tuple):
+ """simple class to handle soft version number has a tuple while
+ correctly printing it as X.Y.Z
+ """
+ def __new__(cls, versionstr):
+ if isinstance(versionstr, string_types):
+ versionstr = versionstr.strip(' :') # XXX (syt) duh?
+ parsed = cls.parse(versionstr)
+ else:
+ parsed = versionstr
+ return tuple.__new__(cls, parsed)
+
+ @classmethod
+ def parse(cls, versionstr):
+ versionstr = versionstr.strip(' :')
+ try:
+ return [int(i) for i in versionstr.split('.')]
+ except ValueError as ex:
+ raise ValueError("invalid literal for version '%s' (%s)"%(versionstr, ex))
+
+ def __str__(self):
+ return '.'.join([str(i) for i in self])
+
+# upstream change log #########################################################
+
+class ChangeLogEntry(object):
+ """a change log entry, i.e. a set of messages associated to a version and
+ its release date
+ """
+ version_class = Version
+
+ def __init__(self, date=None, version=None, **kwargs):
+ self.__dict__.update(kwargs)
+ if version:
+ self.version = self.version_class(version)
+ else:
+ self.version = None
+ self.date = date
+ self.messages = []
+
+ def add_message(self, msg):
+ """add a new message"""
+ self.messages.append(([msg], []))
+
+ def complete_latest_message(self, msg_suite):
+ """complete the latest added message
+ """
+ if not self.messages:
+ raise ValueError('unable to complete last message as there is no previous message)')
+ if self.messages[-1][1]: # sub messages
+ self.messages[-1][1][-1].append(msg_suite)
+ else: # message
+ self.messages[-1][0].append(msg_suite)
+
+ def add_sub_message(self, sub_msg, key=None):
+ if not self.messages:
+ raise ValueError('unable to complete last message as there is no previous message)')
+ if key is None:
+ self.messages[-1][1].append([sub_msg])
+ else:
+ raise NotImplementedError("sub message to specific key are not implemented yet")
+
+ def write(self, stream=sys.stdout):
+ """write the entry to file """
+ stream.write('%s -- %s\n' % (self.date or '', self.version or ''))
+ for msg, sub_msgs in self.messages:
+ stream.write('%s%s %s\n' % (INDENT, BULLET, msg[0]))
+ stream.write(''.join(msg[1:]))
+ if sub_msgs:
+ stream.write('\n')
+ for sub_msg in sub_msgs:
+ stream.write('%s%s %s\n' % (INDENT * 2, SUBBULLET, sub_msg[0]))
+ stream.write(''.join(sub_msg[1:]))
+ stream.write('\n')
+
+ stream.write('\n\n')
+
+class ChangeLog(object):
+ """object representation of a whole ChangeLog file"""
+
+ entry_class = ChangeLogEntry
+
+ def __init__(self, changelog_file, title=''):
+ self.file = changelog_file
+ self.title = title
+ self.additional_content = ''
+ self.entries = []
+ self.load()
+
+ def __repr__(self):
+ return '<ChangeLog %s at %s (%s entries)>' % (self.file, id(self),
+ len(self.entries))
+
+ def add_entry(self, entry):
+ """add a new entry to the change log"""
+ self.entries.append(entry)
+
+ def get_entry(self, version='', create=None):
+ """ return a given changelog entry
+ if version is omitted, return the current entry
+ """
+ if not self.entries:
+ if version or not create:
+ raise NoEntry()
+ self.entries.append(self.entry_class())
+ if not version:
+ if self.entries[0].version and create is not None:
+ self.entries.insert(0, self.entry_class())
+ return self.entries[0]
+ version = self.version_class(version)
+ for entry in self.entries:
+ if entry.version == version:
+ return entry
+ raise EntryNotFound()
+
+ def add(self, msg, create=None):
+ """add a new message to the latest opened entry"""
+ entry = self.get_entry(create=create)
+ entry.add_message(msg)
+
+ def load(self):
+ """ read a logilab's ChangeLog from file """
+ try:
+ stream = open(self.file)
+ except IOError:
+ return
+ last = None
+ expect_sub = False
+ for line in stream.readlines():
+ sline = line.strip()
+ words = sline.split()
+ # if new entry
+ if len(words) == 1 and words[0] == '--':
+ expect_sub = False
+ last = self.entry_class()
+ self.add_entry(last)
+ # if old entry
+ elif len(words) == 3 and words[1] == '--':
+ expect_sub = False
+ last = self.entry_class(words[0], words[2])
+ self.add_entry(last)
+ # if title
+ elif sline and last is None:
+ self.title = '%s%s' % (self.title, line)
+ # if new entry
+ elif sline and sline[0] == BULLET:
+ expect_sub = False
+ last.add_message(sline[1:].strip())
+ # if new sub_entry
+ elif expect_sub and sline and sline[0] == SUBBULLET:
+ last.add_sub_message(sline[1:].strip())
+ # if new line for current entry
+ elif sline and last.messages:
+ last.complete_latest_message(line)
+ else:
+ expect_sub = True
+ self.additional_content += line
+ stream.close()
+
+ def format_title(self):
+ return '%s\n\n' % self.title.strip()
+
+ def save(self):
+ """write back change log"""
+ # filetutils isn't importable in appengine, so import locally
+ from logilab.common.fileutils import ensure_fs_mode
+ ensure_fs_mode(self.file, S_IWRITE)
+ self.write(open(self.file, 'w'))
+
+ def write(self, stream=sys.stdout):
+ """write changelog to stream"""
+ stream.write(self.format_title())
+ for entry in self.entries:
+ entry.write(stream)
+
« no previous file with comments | « third_party/logilab/logilab/common/cache.py ('k') | third_party/logilab/logilab/common/clcommands.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698