89 lines
3.2 KiB
Python
Executable file
89 lines
3.2 KiB
Python
Executable file
#!/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)
|