diff options
author | Bernát Gábor <bgabor8@bloomberg.net> | 2020-01-10 15:35:38 +0000 |
---|---|---|
committer | Bernat Gabor <bgabor8@bloomberg.net> | 2020-01-10 15:38:01 +0000 |
commit | d47ab61dc274b84c616f81ff740d1ee369a18871 (patch) | |
tree | ce94ff619eb3980a296d39f4fc4a582aed3a37ea /tasks/update_embedded.py | |
download | virtualenv-d47ab61dc274b84c616f81ff740d1ee369a18871.tar.gz |
Stat rewrite - POC
Signed-off-by: Bernat Gabor <bgabor8@bloomberg.net>
Diffstat (limited to 'tasks/update_embedded.py')
-rwxr-xr-x | tasks/update_embedded.py | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/tasks/update_embedded.py b/tasks/update_embedded.py new file mode 100755 index 0000000..8144559 --- /dev/null +++ b/tasks/update_embedded.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +""" +Helper script to rebuild virtualenv.py from virtualenv_support +""" +from __future__ import print_function, unicode_literals + +import codecs +import os +import re +import sys +from zlib import crc32 as _crc32 + +if sys.version_info < (3,): + print("requires Python 3 (use tox from Python 3 if invoked via tox)") + raise SystemExit(1) + + +def crc32(data): + """Python version idempotent""" + return _crc32(data.encode()) & 0xFFFFFFFF + + +here = os.path.realpath(os.path.dirname(__file__)) +script = os.path.realpath(os.path.join(here, "..", "src", "virtualenv.py")) + +gzip = codecs.lookup("zlib") +b64 = codecs.lookup("base64") + +file_regex = re.compile(r'# file (.*?)\n([a-zA-Z][a-zA-Z0-9_]+) = convert\(\n {4}"""\n(.*?)"""\n\)', re.S) +file_template = '# file {filename}\n{variable} = convert(\n """\n{data}"""\n)' + + +def rebuild(script_path): + with open(script_path, "rt") as current_fh: + script_content = current_fh.read() + script_parts = [] + match_end = 0 + next_match = None + _count, did_update = 0, False + for _count, next_match in enumerate(file_regex.finditer(script_content)): + script_parts += [script_content[match_end : next_match.start()]] + match_end = next_match.end() + filename, variable_name, previous_encoded = next_match.group(1), next_match.group(2), next_match.group(3) + differ, content = handle_file(next_match.group(0), filename, variable_name, previous_encoded) + script_parts.append(content) + if differ: + did_update = True + + script_parts += [script_content[match_end:]] + new_content = "".join(script_parts) + + report(1 if not _count or did_update else 0, new_content, next_match, script_content, script_path) + + +def handle_file(previous_content, filename, variable_name, previous_encoded): + print("Found file {}".format(filename)) + current_path = os.path.realpath(os.path.join(here, "..", "src", "virtualenv_embedded", filename)) + _, file_type = os.path.splitext(current_path) + keep_line_ending = file_type in (".bat",) + with open(current_path, "rt", encoding="utf-8", newline="" if keep_line_ending else None) as current_fh: + current_text = current_fh.read() + current_crc = crc32(current_text) + current_encoded = b64.encode(gzip.encode(current_text.encode())[0])[0].decode() + if current_encoded == previous_encoded: + print(" File up to date (crc: {:08x})".format(current_crc)) + return False, previous_content + # Else: content has changed + previous_text = gzip.decode(b64.decode(previous_encoded.encode())[0])[0].decode() + previous_crc = crc32(previous_text) + print(" Content changed (crc: {:08x} -> {:08x})".format(previous_crc, current_crc)) + new_part = file_template.format(filename=filename, variable=variable_name, data=current_encoded) + return True, new_part + + +def report(exit_code, new, next_match, current, script_path): + if new != current: + print("Content updated; overwriting... ", end="") + with open(script_path, "wt") as current_fh: + current_fh.write(new) + print("done.") + else: + print("No changes in content") + if next_match is None: + print("No variables were matched/found") + raise SystemExit(exit_code) + + +if __name__ == "__main__": + rebuild(script) |