nope/py-helpers/prepare_code/main.py

260 lines
8.0 KiB
Python
Raw Normal View History

2022-07-17 20:24:55 +00:00
import argparse
2022-07-21 21:31:19 +00:00
from msilib.schema import Error
2022-07-17 20:24:55 +00:00
import os
import re
import multiprocessing as mp
2022-07-23 05:39:56 +00:00
from . import get_logger, ts, js, post_process
2022-07-17 20:24:55 +00:00
MAX_CPU = mp.cpu_count()
if MAX_CPU <= 4:
2022-07-21 21:31:19 +00:00
MAX_CPU = 1
else:
MAX_CPU = MAX_CPU - 2
func = {
"ts": ts,
"js": js
}
2022-07-17 20:24:55 +00:00
def worker(opt):
""" Helper function, which will be called during a multiprocess. Converts the input.
Args:
opt: packed options
"""
2022-07-23 05:39:56 +00:00
type = opt[0]
2022-07-21 21:31:19 +00:00
return parse(func[type].get_parser(), *opt)
2022-07-17 20:24:55 +00:00
2022-07-23 05:39:56 +00:00
def parse(parser, type, logger, input_path, output_path, name, path_to_file, dir_path, debug):
""" Function to generate the python-code
2022-07-17 20:24:55 +00:00
Args:
2022-07-23 05:39:56 +00:00
parser (_type_): The Parser to use (js/ts)
logger (_type_): The Logger
input_path (_type_): path of the folder to readin
output_path (_type_): main path of the output
name (_type_): name of the file
path_to_file (_type_): path to the file
dir_path (_type_): directory of the file
debug (_type_): Flag to enable debugging
2022-07-17 20:24:55 +00:00
Returns:
2022-07-23 05:39:56 +00:00
(
(
str | False, # Directory of the PY-File, where it should be stored. False in the case of an error
str | False, # Filename of the PY-File or False in the case of an error
str | False # Python-Code or False in the case of an error
), (
err | False, # The Error or False, if everything was fine
str | False # Filepointer to the error if parsing using lark failed (clickable pointer for the editor)
)
)
2022-07-17 20:24:55 +00:00
2022-07-23 05:39:56 +00:00
"""
2022-07-21 21:31:19 +00:00
2022-07-17 20:24:55 +00:00
try:
2022-07-21 21:31:19 +00:00
python_name = name.replace(".ts", ".py").replace(".js", ".py")
2022-07-17 20:24:55 +00:00
rel_path = dir_path[len(input_path) + 1:]
logger.debug(f"determined the following rel-path = {rel_path}")
pytho_path_to_file = os.path.join(output_path,rel_path,python_name)
try:
2022-07-23 05:39:56 +00:00
code = func[type].transform(
parser.parse(open(path_to_file, encoding="utf-8").read()),
debug
2022-07-21 21:31:19 +00:00
)
2022-07-23 05:39:56 +00:00
logger.debug(f"converted {path_to_file}")
code = post_process(code)
logger.info(f"processed-file: '{path_to_file}'")
2022-07-17 20:24:55 +00:00
return (
2022-07-23 05:39:56 +00:00
(os.path.join(output_path,rel_path), pytho_path_to_file , code),
2022-07-17 20:24:55 +00:00
(False ,False)
)
except Exception as err:
ptr_to_err = path_to_file
try:
m = re.search('(?<=line )\d+', str(err))
line = int(m.group(0))
m = re.search('(?<=col )\d+', str(err))
col = int(m.group(0))
ptr_to_err = path_to_file+":"+str(line)+":"+str(col)
except:
pass
logger.error(f"Failed to convert {ptr_to_err}")
2022-07-21 21:31:19 +00:00
2022-07-23 05:39:56 +00:00
if debug:
2022-07-21 21:31:19 +00:00
logger.error(err)
else:
logger.error(str(err).split("\n")[0])
2022-07-17 20:24:55 +00:00
return (
2022-07-21 21:31:19 +00:00
(False, False, False),
2022-07-17 20:24:55 +00:00
(str(err), ptr_to_err)
)
except Exception as err:
# An unknown Error has been found
logger.error(err)
return (
2022-07-21 21:31:19 +00:00
(False, False,False),
2022-07-17 20:24:55 +00:00
(str(err), False)
)
def main():
""" The main routine.
"""
parser = argparse.ArgumentParser(
description='Tython. A tool to convert the typescript file to the given python files.')
parser.add_argument('--input', type=str, default="./", dest='inputFolder',
help='Defines the Folder with the Files, being search.')
parser.add_argument('--output', type=str, default="./out/", dest='outputFolder',
help='Defines the Files, which should be looked for. Possible Values are "ts" | "js"')
parser.add_argument('--type', type=str, default="ts", dest='type',
help='Defines the Folder where the converted files should be stored.')
parser.add_argument('--debug', dest='debug', action='store_true',
help='Shows debug related output')
parser.add_argument('--cores', type=int, default=MAX_CPU, dest='cores',
help='The Amount of cores, which must be use')
# Create a Logger:
logger = get_logger("nope-py-prepare")
args = parser.parse_args()
files_to_ignore ={
2022-07-21 21:31:19 +00:00
"js": lambda name: name.endswith(".js") and not (name.endswith(".spec.js") or "index" in name or "\\types\\" in name or "/types/" in name),
2022-07-17 20:24:55 +00:00
"ts": lambda name: name.endswith(".ts") and not (name.endswith(".spec.ts") or "index" in name),
}
if not args.type in ("ts","js"):
logger.error("Please use the correct type")
logger.error(f"Determined type: '{args.type}'")
return
logger.warn(f"Working wiht '{args.type}' file-ending.")
# Define the Input Path
input_path = os.path.join(os.getcwd(), args.inputFolder)
typescript_files = []
logger.info(f"Checking dir: '{input_path}'")
2022-07-18 05:53:42 +00:00
2022-07-21 21:31:19 +00:00
if os.path.isdir(input_path):
# Get all relevant Files.
for dir_path, directories, files in os.walk(input_path):
for file_name in files:
# Generate the Path of files.
path_to_file = os.path.join(dir_path, file_name)
if files_to_ignore[args.type](path_to_file):
# Show a log message
logger.debug(f"Found file: '{file_name}' at '{dir_path}'")
# Add the file-name, path to the file and the dir path
typescript_files.append((file_name, path_to_file, dir_path))
elif os.path.isfile(input_path):
# Generate the Path of files.
path_to_file = input_path
if files_to_ignore[args.type](path_to_file):
dir_path = os.path.dirname(path_to_file)
file_name = path_to_file[len(dir_path) + 1 :]
# Show a log message
logger.debug(f"Found file: '{file_name}' at '{dir_path}'")
# Add the file-name, path to the file and the dir path
typescript_files.append((file_name, path_to_file, dir_path))
else:
raise Error("Failed to load the file")
2022-07-17 20:24:55 +00:00
# Define the Destination
output_path = os.path.join(os.getcwd(), args.outputFolder)
cores_to_use = max(1, min(MAX_CPU, args.cores))
logger.info(f"Founf {len(typescript_files)} files. Starting multiprocess with {cores_to_use} cores.")
# Create Pool.
pool = mp.Pool(cores_to_use)
results = pool.map(worker, [
(
2022-07-23 05:39:56 +00:00
args.type,
2022-07-17 20:24:55 +00:00
logger, # The Logger
input_path, # The Input Folder
output_path, # The Output Path
file_name, # Name of the File
path_to_file, # Path to the File
2022-07-21 21:31:19 +00:00
dir_path, # Path of the Directory.
2022-07-23 05:39:56 +00:00
args.debug
2022-07-17 20:24:55 +00:00
) for file_name, path_to_file, dir_path in typescript_files
]
)
# Close the Pool
pool.close()
# Wait to finish all.
pool.join()
success = []
failed = []
2022-07-21 21:31:19 +00:00
for (path, py_file_name,content),(err, org_file_name) in results:
2022-07-17 20:24:55 +00:00
if py_file_name and content:
success.append(py_file_name)
2022-07-21 21:31:19 +00:00
os.makedirs(path, exist_ok=True)
with open(py_file_name, "w") as file:
file.write(content)
2022-07-17 20:24:55 +00:00
else:
2022-07-23 05:39:56 +00:00
failed.append((org_file_name, err))
2022-07-17 20:24:55 +00:00
2022-07-21 21:31:19 +00:00
if len(failed):
logger.warn(f"The following files failed ({len(failed)}):")
2022-07-23 05:39:56 +00:00
for (idx, (file_name, err)) in enumerate(failed):
print("\t", idx+1, ".\t", file_name)
print("\t\t\t->",str(err).split("\n")[0])
2022-07-17 20:24:55 +00:00
if (args.debug):
print("\n"*2)
print(f"Created the following files ({len(success)}):")
for file_name in success:
print("\t- ", file_name)
print("\n"*2)
logger.info(f"Parsed {len(success)} of {len(typescript_files)} files ({(len(success)/len(typescript_files))*100:.2f} %).")
if __name__ == "__main__":
main()