summaryrefslogtreecommitdiff
path: root/tasks/update_embedded.py
diff options
context:
space:
mode:
authorBernát Gábor <bgabor8@bloomberg.net>2020-01-10 15:35:38 +0000
committerBernat Gabor <bgabor8@bloomberg.net>2020-01-10 15:38:01 +0000
commitd47ab61dc274b84c616f81ff740d1ee369a18871 (patch)
treece94ff619eb3980a296d39f4fc4a582aed3a37ea /tasks/update_embedded.py
downloadvirtualenv-d47ab61dc274b84c616f81ff740d1ee369a18871.tar.gz
Stat rewrite - POC
Signed-off-by: Bernat Gabor <bgabor8@bloomberg.net>
Diffstat (limited to 'tasks/update_embedded.py')
-rwxr-xr-xtasks/update_embedded.py89
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)