[FIX] script transform python to code writer: improve generated code
- Remove indent when no need - Generate the same end of file space - Support beautiful multiple end line - Add automatic test - Support """ into string like this " """ "
This commit is contained in:
parent
24a15c57f5
commit
218e17a16a
2 changed files with 173 additions and 16 deletions
114
script/code_generator/test_transform_python_to_code_writer.py
Normal file
114
script/code_generator/test_transform_python_to_code_writer.py
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
|
||||
def get_config():
|
||||
"""Parse command line arguments, extracting the config file name,
|
||||
returning the union of config file and command line arguments
|
||||
|
||||
:return: dict of config file settings and command line arguments
|
||||
"""
|
||||
# TODO update description
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""\
|
||||
Transform a python file in code writer format python file, will generate it in temp file and compare difference.
|
||||
""",
|
||||
epilog="""\
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--debug", action="store_true", help="Show debug information."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--format", action="store_true", help="Format file before test."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--file",
|
||||
dest="file",
|
||||
required=True,
|
||||
help="Path of file to transform to code_writer.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
if config.format:
|
||||
result = subprocess.run(
|
||||
[
|
||||
"bash",
|
||||
"./script/maintenance/format_python.sh",
|
||||
config.file,
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
with tempfile.NamedTemporaryFile() as temp_file:
|
||||
# Generate the generator
|
||||
file = temp_file.name
|
||||
result = subprocess.run(
|
||||
[
|
||||
"python",
|
||||
"./script/code_generator/transform_python_to_code_writer.py",
|
||||
"-f",
|
||||
config.file,
|
||||
"-o",
|
||||
file,
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
# if config.debug:
|
||||
# print("-- show the generator --")
|
||||
# print(result.stdout)
|
||||
# print("-- end show the generator --")
|
||||
# Execute the generator
|
||||
result_generator = subprocess.run(
|
||||
["python", file], capture_output=True, text=True
|
||||
)
|
||||
if result_generator.returncode != 0:
|
||||
raise Exception(result_generator.stderr)
|
||||
if config.debug:
|
||||
print("-- show the generator result --")
|
||||
print(result_generator.stdout)
|
||||
print("-- end show the generator result --")
|
||||
# Test the generator output
|
||||
fd, temp_file_path = tempfile.mkstemp()
|
||||
with os.fdopen(fd, "w+") as temp_file_test:
|
||||
temp_file_test.write(result_generator.stdout)
|
||||
temp_file_test.seek(0)
|
||||
# Compare the output of the generator with original
|
||||
result = subprocess.run(
|
||||
["diff", config.file, temp_file_path],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if config.debug or result.stdout:
|
||||
print("-- show diff --")
|
||||
print(result.stdout)
|
||||
print("-- end show diff --")
|
||||
if result.stdout:
|
||||
print("FAIL")
|
||||
result_wc = subprocess.run(
|
||||
["wc", "-m", config.file], capture_output=True, text=True
|
||||
)
|
||||
if result_wc.returncode == 0:
|
||||
line_count = int(result_wc.stdout.split()[0])
|
||||
print(f"{line_count} VS {len(result_generator.stdout)}")
|
||||
else:
|
||||
print(f"Error with command 'wc -m {config.file}'")
|
||||
return -1
|
||||
else:
|
||||
print("PASS")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
#!./.venv/bin/python
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import uuid
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
|
@ -88,6 +87,7 @@ def main():
|
|||
|
||||
cw.emit("from code_writer import CodeWriter")
|
||||
cw.emit("cw = CodeWriter()")
|
||||
unique_str = f"#{uuid.uuid4().hex}#"
|
||||
|
||||
no_line = 1
|
||||
with open(config.file, "r") as file:
|
||||
|
|
@ -95,7 +95,13 @@ def main():
|
|||
nb_tab, nb_space = count_space_tab(line)
|
||||
diff_tab = nb_tab - last_nb_tab
|
||||
new_line = line.strip()
|
||||
|
||||
# Support \, because with cw.emit("\") this will break
|
||||
new_line = new_line.replace("\\", "\\\\")
|
||||
# Support " into string
|
||||
new_line = new_line.replace('"', '\\"')
|
||||
# Fix """
|
||||
new_line = new_line.replace('\\"\\"\\"', unique_str)
|
||||
|
||||
status_no_tab = add_line(
|
||||
cw, new_line, no_line, nb_tab, no_tab, no_tab, nb_space
|
||||
|
|
@ -105,7 +111,16 @@ def main():
|
|||
|
||||
last_nb_tab = nb_tab
|
||||
no_line += 1
|
||||
cw.emit("print(cw.render())")
|
||||
argument_print = ""
|
||||
if line[-1] != "\n":
|
||||
# Remove last endline if missing
|
||||
argument_print = ", end=''"
|
||||
# Ignore last character, it's an empty space
|
||||
# TODO find another technique to support """, instead of using uuid
|
||||
cw.emit(
|
||||
f"print(cw.render()[:-1].replace('{unique_str}',"
|
||||
f' \'"""\'){argument_print})'
|
||||
)
|
||||
|
||||
output = cw.render()
|
||||
if config.output:
|
||||
|
|
@ -116,7 +131,14 @@ def main():
|
|||
|
||||
|
||||
def add_line(
|
||||
cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space
|
||||
cw,
|
||||
line,
|
||||
no_line,
|
||||
nb_indent,
|
||||
no_indent,
|
||||
init_no_intend,
|
||||
nb_space,
|
||||
deindent=False,
|
||||
):
|
||||
"""
|
||||
Recursive check indent and write line
|
||||
|
|
@ -135,22 +157,27 @@ def add_line(
|
|||
sys.exit(-1)
|
||||
|
||||
if nb_indent == -1:
|
||||
cw.emit('cw.emit("")')
|
||||
return 0
|
||||
if no_indent > 0:
|
||||
cw.emit_raw(" " * no_indent * 4 + f"cw.emit()\n")
|
||||
return no_indent
|
||||
else:
|
||||
cw.emit("cw.emit()")
|
||||
return 0
|
||||
elif nb_indent == no_indent:
|
||||
if nb_indent == 0:
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
return 0
|
||||
elif nb_indent == 1:
|
||||
if no_indent != init_no_intend:
|
||||
if no_indent != init_no_intend and not deindent:
|
||||
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
|
||||
with cw.indent():
|
||||
cw.emit(f'cw.emit("{line}")')
|
||||
elif nb_indent == 2:
|
||||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
# TODO support indent with cw.emit_raw
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
if no_indent != init_no_intend and not deindent:
|
||||
cw.emit(
|
||||
f"with cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
)
|
||||
|
|
@ -163,7 +190,7 @@ def add_line(
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
if no_indent != init_no_intend and not deindent:
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
|
|
@ -180,7 +207,7 @@ def add_line(
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
if no_indent != init_no_intend and not deindent:
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
|
|
@ -200,7 +227,7 @@ def add_line(
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
if no_indent != init_no_intend and not deindent:
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
|
|
@ -223,7 +250,10 @@ def add_line(
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
if (
|
||||
no_indent != init_no_intend
|
||||
and not deindent
|
||||
):
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
|
|
@ -249,7 +279,10 @@ def add_line(
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
if (
|
||||
no_indent != init_no_intend
|
||||
and not deindent
|
||||
):
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
|
|
@ -278,7 +311,10 @@ def add_line(
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
if (
|
||||
no_indent != init_no_intend
|
||||
and not deindent
|
||||
):
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
|
|
@ -310,7 +346,10 @@ def add_line(
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
if (
|
||||
no_indent != init_no_intend
|
||||
and not deindent
|
||||
):
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
|
|
@ -345,7 +384,10 @@ def add_line(
|
|||
if nb_indent - 1 > init_no_intend:
|
||||
cw.emit(f"with cw.indent():")
|
||||
with cw.indent():
|
||||
if no_indent != init_no_intend:
|
||||
if (
|
||||
no_indent != init_no_intend
|
||||
and not deindent
|
||||
):
|
||||
cw.emit(
|
||||
"with"
|
||||
f" cw.indent({4 + nb_space if nb_space else ''}):"
|
||||
|
|
@ -1137,6 +1179,7 @@ def add_line(
|
|||
no_indent - 1,
|
||||
init_no_intend,
|
||||
nb_space,
|
||||
deindent=True,
|
||||
)
|
||||
else:
|
||||
# indent
|
||||
|
|
|
|||
Loading…
Reference in a new issue