From 5299c033e58eb5a7d56869b00ebfb3c49b027aee Mon Sep 17 00:00:00 2001
From: wjmcat <1435130236@qq.com>
Date: Fri, 26 Jun 2020 21:51:26 +0800
Subject: [PATCH] complete simple version of code-generator
---
examples/config/base_model.json | 10 ++++++
examples/plugins/base.plugin.jinja2 | 10 ++++++
examples/templates/index.html.jinja2 | 15 ++++++++
plugins/base.plugin.jinja2 | 0
setup.py | 53 ++++++++++++++++++++++++++++
src/code_generator/config.py | 4 ++-
src/code_generator/loader.py | 32 +++++++++++------
src/code_generator/main.py | 43 +++++++++++++++++-----
8 files changed, 148 insertions(+), 19 deletions(-)
create mode 100644 examples/config/base_model.json
create mode 100644 examples/plugins/base.plugin.jinja2
create mode 100644 examples/templates/index.html.jinja2
delete mode 100644 plugins/base.plugin.jinja2
create mode 100644 setup.py
diff --git a/examples/config/base_model.json b/examples/config/base_model.json
new file mode 100644
index 0000000..b567319
--- /dev/null
+++ b/examples/config/base_model.json
@@ -0,0 +1,10 @@
+{
+ "model": "基础模型",
+ "columns": [{
+ "name": "1"
+ },{
+ "name": "22"
+ },{
+ "name": "33"
+ }]
+}
\ No newline at end of file
diff --git a/examples/plugins/base.plugin.jinja2 b/examples/plugins/base.plugin.jinja2
new file mode 100644
index 0000000..075e8ac
--- /dev/null
+++ b/examples/plugins/base.plugin.jinja2
@@ -0,0 +1,10 @@
+{%- macro number_input(column) -%}
+
number_input
+ {{ column.name }}
+{% endmacro -%}
+
+
+{%- macro date_input(column) -%}
+ date_input
+ {{ column.name }}
+{% endmacro -%}
diff --git a/examples/templates/index.html.jinja2 b/examples/templates/index.html.jinja2
new file mode 100644
index 0000000..346be00
--- /dev/null
+++ b/examples/templates/index.html.jinja2
@@ -0,0 +1,15 @@
+{{ model }}
+
+
+{%- for column in columns %}
+ -
+ {%- if column.name == "1" %}
+ {{ number_input(column) }}
+ {%- elif column.name == "22" %}
+ {{ date_input(column) }}
+ {%- else %}
+
ssss
+ {%- endif %}
+
+{%- endfor %}
+
\ No newline at end of file
diff --git a/plugins/base.plugin.jinja2 b/plugins/base.plugin.jinja2
deleted file mode 100644
index e69de29..0000000
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..28b5f5a
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,53 @@
+"""
+Code Generator - https://github.com/wj-Mcat/code-generator
+
+Authors: Jingjing WU (吴京京)
+
+2020-now @ Copyright wj-Mcat
+
+Licensed under the Apache License, Version 2.0 (the 'License');
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an 'AS IS' BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+from setuptools import setup, find_packages
+
+with open("./VERSION", 'r+') as f:
+ VERSION = f.read()
+
+with open('./requirements.txt', 'r+') as f:
+ requirements = f.readlines()
+
+setup(
+ name='code-generator',
+ version=VERSION,
+ description="a simple code generator for ",
+ long_description='a templated code generator for all language, especially '
+ 'for boring code',
+ keywords='code-gen,code-generator,python,code-snippet',
+ author='wj-Mcat',
+ author_email='1435130236@qq.com',
+ license='Apache 2',
+ packages=find_packages('src'),
+ package_dir = {
+ "": "src"
+ },
+ include_package_data=True,
+ package_data = {
+ 'code_generator': ['vue/*', 'flask/*', 'element.css', 'index.js', 'jquery.min.js', 'template.html', 'vue.js']
+ },
+ install_requires=requirements,
+ entry_points={
+ 'console_scripts': [
+ 'code-gen = code_generator.main:main'
+ ]
+ }
+)
\ No newline at end of file
diff --git a/src/code_generator/config.py b/src/code_generator/config.py
index 4112cc2..edabc7e 100644
--- a/src/code_generator/config.py
+++ b/src/code_generator/config.py
@@ -21,11 +21,13 @@ from __future__ import annotations
import logging
+from jinja2 import Template
+
def get_logger():
"""get the logger"""
log_formatter = logging.Formatter(
- fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ fmt='%(asctime)s - %(name)s - %(levelname)s - %(filename)s - %(funcName)s - %(message)s')
logger = logging.getLogger("CodeGenerator")
logger.handlers = []
diff --git a/src/code_generator/loader.py b/src/code_generator/loader.py
index 0a5300f..cbef607 100644
--- a/src/code_generator/loader.py
+++ b/src/code_generator/loader.py
@@ -19,7 +19,7 @@ limitations under the License.
"""
from __future__ import annotations
import os
-from typing import Dict
+from typing import Dict, Optional
from abc import ABCMeta
from jinja2 import Template
@@ -39,7 +39,7 @@ class Loader(metaclass=ABCMeta):
lazy load plugins
"""
self.files: Dict[str, str] = {}
- log.info('load the plugins from : %s', file_or_dir)
+ log.info('load the files from : %s', file_or_dir)
if not os.path.exists(file_or_dir):
log.warning('plugin file/dir doesn"t exist, there are '
'no plugins to load')
@@ -82,11 +82,17 @@ class TemplateLoader(Loader):
def __init__(self, file_or_dir: str = 'templates'):
super(TemplateLoader, self).__init__(file_or_dir)
- def load_templates(self) -> Dict[str, Template]:
+ def load_templates(self, plugins: Optional[str] = None
+ ) -> Dict[str, Template]:
"""load template"""
self._load_files()
templates: Dict[str, Template] = {}
for key, template in self.files.items():
+ if plugins is not None:
+ template = "{plugin}\n{template}".format(
+ plugin=plugins, template=template
+ )
+ log.info(template)
templates[key] = Template(template)
return templates
@@ -102,7 +108,7 @@ class PluginLoader(Loader):
def load_to_file(self) -> str:
files = self._load_plugins()
- return '\n'.join(files)
+ return '\n'.join(files.values())
def load_plugin_descriptions(self) -> Dict[str, str]:
descriptions: Dict[str, str] = {}
@@ -113,12 +119,18 @@ class PluginLoader(Loader):
attrs = dir(module)
macros = [(attr, getattr(module, attr)) for attr in attrs
if isinstance(getattr(module, attr), Macro)]
-
- # find macros description from html node description using bs4
-
-
+ # first we only load the name of plugin
+ for macro_name, macro in macros:
+ if macro_name not in descriptions:
+ descriptions[macro_name] = macro_name
return descriptions
-
-
+ def load_to_module(self):
+ """
+ load plugins to the instance of module type
+ :return:
+ """
+ plugin_content = self.load_to_file()
+ module = Template(plugin_content).module
+ return module
diff --git a/src/code_generator/main.py b/src/code_generator/main.py
index 495ec3f..8113d73 100644
--- a/src/code_generator/main.py
+++ b/src/code_generator/main.py
@@ -18,7 +18,12 @@ See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import annotations
+
+import json
from argparse import ArgumentParser
+import os
+
+from jinja2 import Template
from .config import get_logger
from .loader import TemplateLoader, PluginLoader
@@ -32,12 +37,33 @@ def run_server():
pass
-def render_by_config():
- file = args['file']
- templates = TemplateLoader(file).load_templates()
- plugin_file = PluginLoader(file).load_to_file()
+def _save_to_file(template_dir: str, file_name: str, content: str):
+ if not os.path.exists(template_dir):
+ os.mkdir(template_dir)
+ path = os.path.join(template_dir, file_name)
+ with open(path, 'w', encoding='utf-8') as f:
+ f.write(content)
+def _read_to_json(file: str) -> dict:
+ """read json file to json data"""
+ file_path = os.path.join(os.getcwd(), file)
+ print(file_path)
+ if not os.path.exists(file_path):
+ raise FileNotFoundError(f'file <{file}> not found')
+ with open(file_path, 'r+', encoding='utf-8') as f:
+ return json.load(f)
+
+
+def render_by_config():
+ config = _read_to_json(args['config'])
+ plugins = PluginLoader(args['plugins']).load_to_file()
+ log.info(plugins)
+ templates = TemplateLoader(args['templates']).load_templates(plugins)
+ for name, template in templates.items():
+ result = template.render(config)
+ base_name = os.path.basename(args['templates']) + '_result'
+ _save_to_file(base_name, name, result)
def main():
@@ -49,15 +75,16 @@ def main():
serve_parser.add_argument('--file', default='config.json', type=str)
serve_parser.set_defaults(func=run_server)
- config_parser = subparsers.add_parser(name='config')
- config_parser.add_argument('--file', default='config.json', type=str)
- config_parser.add_argument('--template', default='flask,vue', type=str)
+ config_parser = subparsers.add_parser(name='render')
+ config_parser.add_argument('--config', type=str, default='./config.json')
+ config_parser.add_argument('--templates', type=str, default='./templates')
+ config_parser.add_argument('--plugins', type=str, default='./plugins')
config_parser.set_defaults(func=render_by_config)
local_args = parser.parse_args()
log.info(args)
args.update(local_args.__dict__)
- local_args.func(args)
+ local_args.func()
if __name__ == '__main__':
--
GitLab