diff --git a/py-helpers/.gitignore b/py-helpers/.gitignore new file mode 100644 index 0000000..a8944f1 --- /dev/null +++ b/py-helpers/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +*.egg-info +dist/ +build/ \ No newline at end of file diff --git a/py-helpers/00-install.sh b/py-helpers/00-install.sh new file mode 100755 index 0000000..e461915 --- /dev/null +++ b/py-helpers/00-install.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +echo "The script you are running has basename $( basename -- "$0"; ), dirname $( dirname -- "$0"; )"; +echo "The present working directory is $( pwd; )"; + +cd "$( dirname -- "$0"; )" + +pip install . \ No newline at end of file diff --git a/py-helpers/01-prepare-ts.sh b/py-helpers/01-prepare-ts.sh new file mode 100755 index 0000000..3138fd1 --- /dev/null +++ b/py-helpers/01-prepare-ts.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +echo "The script you are running has basename $( basename -- "$0"; ), dirname $( dirname -- "$0"; )"; +echo "The present working directory is $( pwd; )"; + +cd "$( dirname -- "$0"; )" +cd .. + +nope-py-prepare-code --input lib --output temp --type ts \ No newline at end of file diff --git a/py-helpers/02-prepare-js.sh b/py-helpers/02-prepare-js.sh new file mode 100755 index 0000000..c90ff52 --- /dev/null +++ b/py-helpers/02-prepare-js.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +echo "The script you are running has basename $( basename -- "$0"; ), dirname $( dirname -- "$0"; )"; +echo "The present working directory is $( pwd; )"; + +cd "$( dirname -- "$0"; )" +cd .. + +rm -rf temp +nope-py-prepare-code --input dist-nodejs --output temp --type js \ No newline at end of file diff --git a/py-helpers/LICENSE b/py-helpers/LICENSE new file mode 100644 index 0000000..ce7dcbc --- /dev/null +++ b/py-helpers/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 M.Karkowski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/py-helpers/MANIFEST.in b/py-helpers/MANIFEST.in new file mode 100644 index 0000000..cd53039 --- /dev/null +++ b/py-helpers/MANIFEST.in @@ -0,0 +1,4 @@ +include *.py +incluce README.md +include *.lark +recursive-include prepare_code * \ No newline at end of file diff --git a/py-helpers/README.md b/py-helpers/README.md new file mode 100644 index 0000000..9aa1849 --- /dev/null +++ b/py-helpers/README.md @@ -0,0 +1,3 @@ +Helper to prepare the code in python. + +This tools tries to transpile the ts - code to python code \ No newline at end of file diff --git a/py-helpers/prepare_code/__init__.py b/py-helpers/prepare_code/__init__.py new file mode 100644 index 0000000..c7ef851 --- /dev/null +++ b/py-helpers/prepare_code/__init__.py @@ -0,0 +1,9 @@ +__title__ = 'prepare_code' +__author__ = 'M.Karkowski' +__license__ = 'MIT' +__copyright__ = 'Copyright 2022 M.Karkowski' +__version__ = '0.1.0' + +from .parser import get_parser +from .main import main +from .logger import get_logger \ No newline at end of file diff --git a/py-helpers/prepare_code/grammar.lark b/py-helpers/prepare_code/grammar.lark new file mode 100644 index 0000000..4e30f68 --- /dev/null +++ b/py-helpers/prepare_code/grammar.lark @@ -0,0 +1,454 @@ +%import common.WS +%import common.DIGIT +%import common.INT + +MULTI_LINE_COMMENT: "/**" /(.|\n)*?/ "*/\n" +COMMENT: "//" /.*/ +STR: /(`.*?`)|(".*?")|(\'.*?\')/ +%ignore MULTI_LINE_COMMENT +%ignore COMMENT +%ignore WS +// Ignore Exports +%ignore "export" "*" "from" STR ";" +%ignore "export" "*" "as" /w+/ "from" STR ";" +%ignore "export" /(?<=export)(.|\n)+?(?=})/ "}" "from" STR ";" +%ignore "export" /(?<=export)(.|\n)+?(?=})/ "}" ";" + +// -------------------------------------------------------------------------- +// Summary: +// -------------------------------------------------------------------------- + +start: statement+ + +// we have to define, what is a valid return type + +ret_expr: id + | str + | str_multi_line + | num + | bool + | null + | undefined + | instanceof + | typeof + | increment + | decrease + | invert + | list + | dict + | descruct_dict + | reassign + | await + | delete + | reg_ex + | throw + | sum + | product + | boolean_operation + | accessor + | function + | arrow_function + | function_call + | inline_if + | new_class + | break + | continue + | ret_expr ("as" type)+ + | "(" ret_expr ")" + | continue + | break + | return + +// Now we ar able to provide this expressions wiht a terminator. + +ret_expr_with_terminator: ret_expr terminator + +return: "return" [ret_expr] + +statement: ret_expr_with_terminator + | declare + | declare_type + | declare_var + | declare_var_not_initialized + | declare_var_descructed + | import_stmt + | for + | while + | do_while + | if + | switch + | interface + | class + | decorated_class + | function + | try_catch + + +// -------------------------------------------------------------------------- +// -------------------------------------------------------------------------- + +// Default Terminator: +terminator: ";" + +// Default ID: +id: /[a-zA-Z_$][a-zA-Z0-9_$]*/ -> identifier + +// We define valid import statements: + +import_stmt: "import" str terminator + | "import" id "from" str terminator + | "import" "*" "as" id "from" str terminator + | "import" "{" import_names "}" "from" str terminator + +// we may import multiple items: +import_names: import_name ("," import_name)* + +// The import name might include multiple lines +import_name: id + | id "as" id -> import_as_name + | /\n/ +// Lets define a string; +str: /(`.*?`)|(".*?")|(\'.*?\')/ +str_multi_line: /(`(\\`|.|\n)*?`)/ + +// Lets define a number; +num: INT ["." INT] | "." INT + +// Define a boolean; +bool: "false" | "true" + +null: "null" +undefined: "undefined" + +increment: accessor "++" + | "++" accessor +decrease: accessor "--" + | "--" accessor +invert: "!" ret_expr +instanceof: id "instanceof" id_typed +typeof: "typeof" accessor + +delete: "delete" accessor + +await: "await" ret_expr + +reg_ex: "/" /(?<=\/).+(?=\/\w)/ "/" [/\w/] + +?sum: product + | sum "+" product -> add + | sum "-" product -> min + | id "+=" product + | id "-=" product + +?product: atom + | product "*" atom -> mul + | product "/" atom -> div + | id "*=" atom + | id "/=" atom + +boolean_operation: boolean_input boolean_operator boolean_input + +boolean_operator: ">" + | "<" + | "<=" + | ">=" + | "==" + | "===" + | "!=" + | "!==" + | "&&" + | "||" + | "in" + +boolean_input: ret_expr + +?atom: ret_expr + | id + | "-" atom -> negative_types_repr + | "(" sum ")" + +// Define Lists. +list: "[" [list_items] "]" +list_items: (list_item [","])+ +list_item: ret_expr + | "..." ret_expr + +descruct_list: "[" ((id | | ("..." id)) [","])* "]" "=" ret_expr + +// Define Objects +dict: "{" dict_items? "}" +dict_items: (dict_item [","] )+ +dict_item: (id | num | str) ":" ret_expr + | id "(" func_args? ")" func_body + | "..." ret_expr + | id + +descruct_dict: "{" ((id | (id ":" id) | ("..." id)) [","])* "}" "=" ret_expr + + +// -------------------------------------------------------------------------- +// Lets enable defining variables: +// -------------------------------------------------------------------------- + +export: "export" +declare: "declare" declare_var_type implicit_or_typed terminator +declare_type: [export] "type" id_typed "=" type terminator +declare_var: [export] declare_var_type implicit_or_typed "=" ret_expr_with_terminator +declare_var_not_initialized: [export] declare_var_type implicit_or_typed terminator +declare_var_descructed: declare_var_type descruct_dict terminator + | declare_var_type descruct_list terminator + +// Valid defintions of variables. + +declare_var_type: "let" + | "var" + | "const" + +// -------------------------------------------------------------------------- +// Acess Variables: +// -------------------------------------------------------------------------- + +// To access some vars +// We may want to convert them to +// specific types. + +simple_access: id | str | num | ret_expr + +accessor: simple_access + | accessor ["as" type]+ + | "(" accessor ["as" type]+ ")" + | accessor ["?"] "." accessor + | accessor ["?"] "[" ret_expr "]" + | function_call + +// -------------------------------------------------------------------------- +// Reassignment: +// -------------------------------------------------------------------------- + +// lets define a reassingment: + +reassign: accessor "=" ret_expr + + +// -------------------------------------------------------------------------- +// Functions: +// These may contain: +// - Async Functions +// - Sync Functions +// They might be defined as `arrow_function`. +// +// In General, a function is name with an valid id, may be typed, +// may receives a custom amount of arguments and normally provides a +// function body; +// -------------------------------------------------------------------------- + +function_helper: ["<" type ("," type)* ">"] "(" func_args? ")" [":" type] func_body + +function: [export] ["async"] "function" [id] ["<" type ("," type)* ">"] "(" func_args? ")" [":" type] func_body + +arrow_function: [export] ["async"] ["<" type ("," type)* ">"] (( "(" func_args? ")" [":" type] ) | func_arg ) "=>" arrow_func_body + +arrow_function_type: ["<" type ("," type)* ">"] "(" func_args? ")" [":" type] "=>" type + +// Now we have to define the valid arguments: +// The function may receives multiple arguments +// which are typed or implicit (-> any) + +func_args: func_arg ("," func_arg)* + +func_arg: implicit_or_typed + | "..." implicit_or_typed + | implicit_or_typed "=" ret_expr + | dict | list + +implicit_or_typed: id + | id ["?"] ":" type + +// Define the Function Body: +// This consists of the brackets and the statements in the function + +func_body: "{" [func_statements] "}" +func_statements: func_statement+ +func_statement: statement + +arrow_func_body: func_body + | ret_expr + +// And now we define, which elements are allowed to be included +// in a function. in our case these are more or less all statements +// Additionally, we have ot make shure, that we are able to +// "return" something. + + +// -------------------------------------------------------------------------- +// -------------------------------------------------------------------------- + +// The Defintion of how a function could be called. +// In here we consider sync as well as async calls. + +function_call: ret_expr ["<" type ("," type)* ">"] "(" call_args? ")" + +// We define our call args: + +call_args: call_arg ("," call_arg)* + +call_arg: ret_expr + | "..." ret_expr + +type: basic_type + | enhanced_type + | "(" type ")" + +basic_type: id + | "any" + | "string" -> string + | "boolean" -> boolean + | "number" -> number + | ["|"] str ("|" str)* // Typess like `const a: "hello" | "world" = "world" + | arrow_function_type // arrow functions + + +enhanced_type: "|" type // Leading type. + | id "in" type + | id ("<" type ("," type)* ">") // Typess like `Map + | "[" type ("," type)* "]" // Typess like `Array<[string,boolean]> + | "{" ( id ["?"] ":" type [";"] )* "}" // Dynamic type like + | "{" "[" id (":" | "in") type "]" ":" type [";"]"}" // Dynamic type like `{ [index: string]: INopeDescriptor }` + | type "extends"? "keyof"? "typeof"? type // Types consisting of keyof , typeof etc + | type ("[" (type | num) "]")+ // Partial type of the Element + | type ("[" "]")+ // Array type + | type ("&" type)+ // Combinded type using & + | type ("|" type)+ // Types which might be + | type "=" type // Types which are assigned with a default type. + | accessor + + +// Definition for a Nested Type. +id_typed: id | enhanced_type + +// -------------------------------------------------------------------------- +// Loops +// -------------------------------------------------------------------------- + +// Define a For - Statement +for: "for" "(" declare_var_type for_iter_var ("of" | "in") ret_expr ")" iter_body + | "for" "(" declare_var_type "[" (for_iter_var [","])+ "]" ("of" | "in") ret_expr ")" iter_body + | "for" "(" declare_var_type id "=" ret_expr ";" ret_expr ";" ret_expr ")" iter_body + +for_iter_var: id | dict | list + +while: "while" "(" ret_expr ")" iter_body + +do_while: "do" iter_body "while" "(" ret_expr ")" terminator + +iter_body: "{" iter_statements "}" | iter_statement +iter_statements: iter_statement* +iter_statement: statement + +continue: "continue" +break: "break" + +// -------------------------------------------------------------------------- +// IF-Statements +// -------------------------------------------------------------------------- + +// Define a If - Statement +// We have to consider "if" "else if" and "else" +if: "if" "(" ret_expr ")" if_body ("else" "if" "(" ret_expr ")" if_body)* ["else" if_body] + +if_body: "{" statement* "}" + | ret_expr_with_terminator + +inline_if: ret_expr "?" ret_expr ":" ret_expr + +// -------------------------------------------------------------------------- +// switch-case +// -------------------------------------------------------------------------- + +switch: "switch" "(" ret_expr ")" switch_body +switch_body: "{" ((switch_case)* [switch_default])* "}" +switch_case: "case" ret_expr ":" [switch_case_body] +switch_default: "default" ":" [switch_case_body] + +switch_case_body: ("{" switch_case_statements "}") | switch_case_statements + +switch_case_statements: switch_case_statement* +switch_case_statement: statement + | break + +// -------------------------------------------------------------------------- +// Error Handling +// -------------------------------------------------------------------------- + +try_catch: "try" try_catch_body "catch" "(" id ")" try_catch_body ["finally" try_catch_body] + +try_catch_body: "{" statement* "}" + +throw: "throw" ret_expr + +// -------------------------------------------------------------------------- +// interfaces +// -------------------------------------------------------------------------- + +interface: [export] "interface" id_typed ["extends" implementing_interfaces] interface_body + +extending_interfaces: id_typed ("," id_typed)* + +interface_body: "{" interface_declarations* "}" + +interface_declarations: interface_declaration + +// Interfaces contains implicit or typed attributes or methods + +interface_declaration: [readonly] implicit_or_typed terminator + | id ["<" type ("," type)* ">"] "(" func_args? ")" [":" type ] terminator + +// -------------------------------------------------------------------------- +// classes +// -------------------------------------------------------------------------- + + +class: [export] "class" id_typed ["extends" id_typed] ["implements" implementing_interfaces] class_body +decorated_class: ("@" function_call) class + +implementing_interfaces: id_typed ("," id_typed)* + +class_body: "{" class_declarations* "}" + +class_declarations: constructor + | property_defintion + | property_assigned + | decorated_property_assigned + | decorated_property_defintion + | getter + | setter + | method + | async_method + | decorated_method + | decorated_async_method + +constructor: ["public"] "constructor" "(" constructor_args? ")" func_body +constructor_args: constructor_arg ("," constructor_arg)* +constructor_arg: ["@" function_call] [visibility] [readonly] func_arg + +visibility: "private" + | "protected" + | "public" + +readonly: "readonly" + +property_defintion: [visibility] [readonly] implicit_or_typed terminator +property_assigned: [visibility] [readonly] implicit_or_typed "=" ret_expr_with_terminator +decorated_property_defintion: ("@" function_call) property_defintion +decorated_property_assigned: ("@" function_call) property_assigned + +getter: [visibility] "get" id "("")" [":" type] func_body +setter: [visibility] "set" id "(" func_arg ")" [":" "void"] func_body + +method: [visibility] id ["<" type ("," type)* ">"] "(" func_args? ")" [":" type] func_body +async_method: [visibility] "async" id ["<" type ("," type)* ">"] "(" func_args? ")" [":" type] func_body +decorated_method: ("@" function_call) method +decorated_async_method: ("@" function_call) async_method + +// Types for a new Class +new_class: "new" id_typed "(" call_args? ")" \ No newline at end of file diff --git a/py-helpers/prepare_code/logger.py b/py-helpers/prepare_code/logger.py new file mode 100644 index 0000000..5c6c171 --- /dev/null +++ b/py-helpers/prepare_code/logger.py @@ -0,0 +1,31 @@ +import logging +import sys + + +def get_logger(name: str, level=logging.INFO): + """ Creates a Logger for the Tool. + + Args: + name (str): Name of the logger + level: The logging Level. Defaults to logging.INFO. + + Returns: + a. logger + """ + _logger = logging.getLogger(name) + # Define a Logging Format + _format = _format = logging.Formatter( + '%(levelname)s - %(message)s') + # Create Console Output + _handler = logging.StreamHandler(sys.stdout) + # Add the Format to the Handler + _handler.setFormatter(_format) + # Set Loglevel to the Desired One. + _handler.setLevel(level) + + # Finally add the Handler to the Logger: + _logger.addHandler(_handler) + + # Set the Log Level of the Logger. + _logger.setLevel(level) + return _logger \ No newline at end of file diff --git a/py-helpers/prepare_code/main.py b/py-helpers/prepare_code/main.py new file mode 100644 index 0000000..55fc441 --- /dev/null +++ b/py-helpers/prepare_code/main.py @@ -0,0 +1,193 @@ +import argparse +import os +import re +import multiprocessing as mp + +from .parser import get_parser +from .logger import get_logger + +MAX_CPU = mp.cpu_count() + +if MAX_CPU <= 4: + MAX_CPU = 2 + +def worker(opt): + """ Helper function, which will be called during a multiprocess. Converts the input. + + Args: + opt: packed options + """ + return parse(get_parser(), *opt) + +def parse(parser, logger, input_path, output_path, name, path_to_file, dir_path): + """ Function to parse the corresponding + + Args: + parser (_type_): _description_ + logger (_type_): _description_ + input_path (_type_): _description_ + output_path (_type_): _description_ + name (_type_): _description_ + path_to_file (_type_): _description_ + dir_path (_type_): _description_ + + Returns: + str: _description_ + """ + + try: + + python_name = name.replace(".ts", ".py") + 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: + content = parser.parse(open(path_to_file, encoding="utf-8").read()) + logger.info(f"converted {path_to_file}") + return ( + (pytho_path_to_file , content), + (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}") + logger.error(str(err).split("\n")[0]) + + return ( + (False, False), + (str(err), ptr_to_err) + ) + + except Exception as err: + # An unknown Error has been found + logger.error(err) + return ( + (False,False), + (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 ={ + "js": lambda name: name.endswith(".js") and not (name.endswith(".spec.js") or "index" in name), + "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}'") + + # Get all relevant Files. + for dir_path, directories, files in os.walk(input_path): + for file_name in files: + if files_to_ignore[args.type](file_name): + # Generate the Path of files. + path_to_file = os.path.join(dir_path, file_name) + # 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)) + + + # 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, [ + ( + 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 + dir_path # Path of the Directory. + ) for file_name, path_to_file, dir_path in typescript_files + ] + ) + # Close the Pool + pool.close() + # Wait to finish all. + pool.join() + + success = [] + failed = [] + for (py_file_name,content),(err, org_file_name) in results: + if py_file_name and content: + success.append(py_file_name) + else: + failed.append(org_file_name) + + + logger.warn(f"The following files failed ({len(failed)}):") + for (idx, file_name) in enumerate(failed): + print("\t", idx, ".\t", file_name) + + 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() diff --git a/py-helpers/prepare_code/parser.py b/py-helpers/prepare_code/parser.py new file mode 100644 index 0000000..842f04c --- /dev/null +++ b/py-helpers/prepare_code/parser.py @@ -0,0 +1,14 @@ +from lark import Lark +from pathlib import Path + +# Define the Grammar File. +grammar_file_path = Path(__file__).parent.joinpath('grammar.lark') + + +def get_parser(): + """ Helper, to generate a parser. + + Returns: + A lark parser + """ + return Lark.open(grammar_file_path,debug = True, maybe_placeholders=True) \ No newline at end of file diff --git a/py-helpers/requirements.txt b/py-helpers/requirements.txt new file mode 100644 index 0000000..2f583ad --- /dev/null +++ b/py-helpers/requirements.txt @@ -0,0 +1,2 @@ +astor==0.8.1 +lark-parser>=0.8.1 diff --git a/py-helpers/setup.py b/py-helpers/setup.py new file mode 100644 index 0000000..984d38b --- /dev/null +++ b/py-helpers/setup.py @@ -0,0 +1,31 @@ +from setuptools import setup,find_packages +import re + +with open('requirements.txt') as f: + requirements = f.read().splitlines() + +with open('prepare_code/__init__.py') as f: + version = re.search("__version__ = '(.+)'", f.read()).group(1) + +with open('README.md', encoding='utf-8') as f: + readme = f.read() + +setup( + name='prepare_code', + author='M.Karkowski', + python_requires='>=3.6.0', + version=version, + packages=['prepare_code'], + license='MIT', + description='A simple TypeScript to Python transpiler. Helps the user to simplify the code.', + long_description=readme, + long_description_content_type='text/markdown', + include_package_data=True, + install_requires=requirements, + classifiers=[], + entry_points={ + 'console_scripts': [ + 'nope-py-prepare-code = prepare_code.main:main', + ], + } +) \ No newline at end of file