| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- from src.parser import Parser, ParseException, parse_environment
- from jinja2 import Template
- import argparse
- import sys
- import os
- _here = os.path.dirname(os.path.realpath(__file__))
- class ListFormalisms(argparse.Action):
- def __init__(self, option_strings,
- dest=argparse.SUPPRESS,
- default=argparse.SUPPRESS, **kwargs):
- super().__init__(
- option_strings=option_strings,
- dest=dest,
- default=default,
- nargs=0,
- **kwargs)
- def __call__(self, parser, namespace, values, option_string=None):
- print("The following formalisms are available for generation "
- "('ENV' identifies which environment variables are available):")
- self.list()
- print("\nUse the -F/--formalism flag to specify which one you want to use.")
- parser.exit()
- @staticmethod
- def list():
- contents = os.listdir(os.path.join(_here, "formalisms"))
- for file in contents:
- path = os.path.join(_here, "formalisms", file)
- if os.path.isdir(path) and "__init__.py" in os.listdir(path):
- _local = {}
- with open(os.path.join(path, "__init__.py")) as F:
- exec(F.read(), {}, _local)
- print(" -", "{:<10}".format(file), "ENV:", _local["setup"]["generator"]["environment"])
- # Read commandline variables
- argprs = argparse.ArgumentParser(description='Create model/simulation files from draw.io/diagrams.net XML files.')
- argprs.add_argument('input', type=str, help="The input file to convert.")
- argprs.add_argument("-F", "--formalism", required=True,
- help="The formalism for which files must be generated. "
- "Use -L or --list to show the available formalisms.")
- argprs.add_argument("-e", "--entry", default='', help="The topmost class to use in the simulation.")
- argprs.add_argument("-t", "--time", default=10, type=float, help="Total simulation time. (default: 10)")
- argprs.add_argument('-L', '--list', action=ListFormalisms, help="Lists the available formalisms.")
- argprs.add_argument('-s', '--skip', action='store_true',
- help="When set, empty blocks will be skipped in the generation, otherwise they are created.")
- argprs.add_argument('-d', '--directory', default='./', help="Directory of where the files must be generated. (default: ./)")
- argprs.add_argument('-f', '--force', action='store_true', help="Force generation of the experiment file.")
- argprs.add_argument('-a', '--all', action='store_true', help="Generate all files associated to the formalism.")
- argprs.add_argument('-v', '--verbose', action='store_true', help="Output generation information.")
- argprs.add_argument('-E', '--environment', help="Optional parameters to add to the generation; "
- "as comma-separated key-value list. See -L/--list for more info.")
- args = argprs.parse_args()
- if args.verbose:
- print("[ DEBUG ] Loading Formalism...")
- # Load correct formalism setup file
- form = args.formalism
- contents = os.listdir(os.path.join(_here, "formalisms"))
- if form not in contents:
- print(f"[ ERROR ] Could not find formalism '{form}'. Try one of:")
- ListFormalisms.list()
- sys.exit(1)
- try:
- with open(os.path.join(_here, "formalisms", form, "__init__.py"), 'r') as file:
- _locals = {}
- exec(file.read(), {}, _locals)
- setup = _locals["setup"]
- default_setup_parser = {
- "input class": "InputPort",
- "output class": "OutputPort",
- "class object xpath": ".//object/mxCell/mxGeometry/mxRectangle/../../..[@class_name]",
- "special object xpath": ".//object/mxCell/mxGeometry/../..[@role]"
- }
- setup_parser = setup.get("parser", {})
- setup_parser = {**default_setup_parser, **setup_parser}
- default_setup_generator = {
- "verify": [],
- "ignore": [],
- "environment": [],
- "templates": []
- }
- setup_generator = setup.get("generator", {})
- setup_generator = {**default_setup_generator, **setup_generator}
- except Exception as e:
- print("[ ERROR ] Could not load formalism.")
- print(e)
- sys.exit(1)
- if args.verbose:
- print("[ DEBUG ] Parsing DrawIO File...")
- # Parse the drawio file
- parser = Parser(args.input, setup_parser, args.skip)
- nodes = list(parser.parse())
- for ver in setup_generator["verify"]:
- if not ver["function"](nodes):
- raise ParseException(ver["error"])
- # Create the files
- fields = {
- "command": " ".join(sys.argv),
- "nodes": nodes,
- "ignore": setup_generator["ignore"],
- "time": args.time,
- "imports": parser.get_imports()
- }
- for blueprint in setup_generator["templates"]:
- if blueprint.get("auto", True) or args.all:
- loc = os.path.join(args.directory, blueprint["filename"])
- if os.path.isfile(loc) and not blueprint.get("overwrite", True) and not args.force:
- print(f"[ WARNING ] File '{loc}' already exists. Use -f/--force to regenerate this file.")
- continue
- path = os.path.join(_here, "formalisms", form, blueprint["filename"] + ".jinja")
- with open(path, 'r') as file:
- template = Template(file.read(), trim_blocks=True, lstrip_blocks=True)
- env = parse_environment(args.environment)
- a = {}
- if blueprint.get("entry", False):
- if args.entry == '':
- print(f"[ WARNING ] Could not generate '{loc}' file. -e/--entry missing.")
- continue
- a["entry"] = args.entry
- contents = template.render(**fields, **a, **env)
- with open(loc, 'w') as file:
- file.write(contents)
- if args.verbose:
- print(f"[ DEBUG ] Generated '{loc}'.")
- if args.verbose:
- print("[ DEBUG ] Done.")
|