From b7ded6f98b6a1353d7a2fe6a66c11b84c4fae5c4 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Thu, 2 Jul 2020 15:41:25 +0200 Subject: [PATCH] release.py: order symbols list, preserve old symbols Part-of: --- scripts/release.py | 97 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/scripts/release.py b/scripts/release.py index ca13ebba3d..d963244578 100644 --- a/scripts/release.py +++ b/scripts/release.py @@ -5,6 +5,89 @@ import shutil import sys import tarfile +from collections.abc import MutableSet +import json + + +# Recipe from http://code.activestate.com/recipes/576694/ + + +class OrderedSet(MutableSet): + def __init__(self, iterable=None): + self.end = end = [] + end += [None, end, end] # sentinel node for doubly linked list + self.map = {} # key --> [key, prev, next] + if iterable is not None: + self |= iterable + + def __len__(self): + return len(self.map) + + def __contains__(self, key): + return key in self.map + + # pylint: disable=arguments-differ + def add(self, key): + if key not in self.map: + end = self.end + curr = end[1] + curr[2] = end[1] = self.map[key] = [key, curr, end] + + def __getstate__(self): + if not self: + # The state can't be an empty list. + # We need to return a truthy value, or else + # __setstate__ won't be run. + # + # This could have been done more gracefully by always putting + # the state in a tuple, but this way is backwards- and forwards- + # compatible with previous versions of OrderedSet. + return (None,) + return list(self) + + def __setstate__(self, state): + if state == (None,): + self.__init__([]) + else: + self.__init__(state) + + def discard(self, key): + if key in self.map: + key, prev, nxt = self.map.pop(key) + prev[2] = nxt + nxt[1] = prev + + def __iter__(self): + end = self.end + curr = end[2] + while curr is not end: + yield curr[0] + curr = curr[2] + + def __reversed__(self): + end = self.end + curr = end[1] + while curr is not end: + yield curr[0] + curr = curr[1] + + def pop(self, last=True): + if not self: + raise KeyError('set is empty') + key = self.end[1][0] if last else self.end[2][0] + self.discard(key) + return key + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, list(self)) + + def __eq__(self, other): + if isinstance(other, OrderedSet): + return len(self) == len(other) and list(self) == list(other) + return set(self) == set(other) + HERE = os.path.realpath(os.path.dirname(__file__)) @@ -32,10 +115,18 @@ if __name__ == "__main__": print("Updating symbols to new major version %s" % version_major_minor, file=sys.stderr) symbol_index_file = os.path.join(symbols_index_dir, 'symbol_index.json') - shutil.copyfile(os.path.join(builddir, "hotdoc-private-GStreamer", "symbol_index.json"), - symbol_index_file) + with open(symbol_index_file, 'r', encoding='utf-8') as _: + symbols = OrderedSet(json.load(_)) + + with open(os.path.join(builddir, "hotdoc-private-GStreamer", "symbol_index.json"), 'r', encoding='utf-8') as _: + new_symbols = OrderedSet(sorted(json.load(_))) + + with open(symbol_index_file, 'w', encoding='utf-8') as _: + json.dump(sorted(list(symbols | new_symbols)), _, indent=2) + with open(symbols_version_file, 'w') as sv: sv.write(version_major_minor) + print("NOTE: YOU SHOULD COMMIT THE FOLLOWING FILES BEFORE PUBLISHING THE RELEASE:", file=sys.stderr) print(" - " + symbol_index_file, file=sys.stderr) print(" - " + symbols_version_file, file=sys.stderr) @@ -47,4 +138,4 @@ if __name__ == "__main__": tar.add(files, release_name) os.chdir(os.path.dirname(readme)) tar.add(os.path.basename(readme), os.path.join(release_name, os.path.basename(readme))) - tar.close() \ No newline at end of file + tar.close()