Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

# PYTHON
/venv
/.venv
.venv
**/*.pyc
**/*.pyo
Expand Down
35 changes: 25 additions & 10 deletions core_lib_generator/core_lib_config_generate_yaml.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from omegaconf import OmegaConf

from core_lib.helpers.shell_utils import prompt_str, prompt_yes_no
from enum import Enum
from core_lib.helpers.shell_utils import prompt_str, prompt_yes_no, prompt_enum
from core_lib.helpers.string import any_to_pascal
from core_lib_generator.config_collectors.cache import generate_cache_template
from core_lib_generator.config_collectors.data_access import generate_data_access_template
Expand All @@ -21,6 +21,12 @@ def _get_env_variables(data):
return env_variables


class ServerType(Enum):
DJANGO = 1
FLASK = 2
NOSERVER = 3


config = {}
config.setdefault('data', [])
config.setdefault('cache', [])
Expand All @@ -32,29 +38,30 @@ def _get_env_variables(data):
data_layers.setdefault('data', [])
data_layers.setdefault('data_access', [])
data_layers.setdefault('service', [])
server_type: int


def _get_data_layers_config():
want_db = prompt_yes_no('Will you be using a Database?', True)
want_db = prompt_yes_no('Will you be using a Database?', True)
if want_db:
print('Please fill out the requested Database information.')
db = generate_db_template()
env.update(_get_env_variables(db))
for db_name in db:
config['data'].append(db[db_name]['connection'])
want_entities = prompt_yes_no('\nWould you like to add entities to your database?', True)
want_entities = prompt_yes_no('\nWould you like to add entities to your database?', True)
if want_entities:
print('Please fill out the requested information for creating entities in Database.')
db_entity = generate_db_entity_template(db)
data_layers.setdefault('data', {})
data_layers['data'] = db_entity
want_data_access = prompt_yes_no('\nDo you want to create a data access for the entities?', True)
want_data_access = prompt_yes_no('\nDo you want to create a data access for the entities?', True)
if want_data_access:
print('Please fill out the requested information for creating Data Access for entities.')
data_access = generate_data_access_template(db_entity)
data_layers.setdefault('data_access', [])
data_layers['data_access'] = data_access
want_service = prompt_yes_no('\nDo you want to create services?', True)
want_service = prompt_yes_no('\nDo you want to create services?', True)
if want_service:
print('Please fill out the requested information for creating Service for Data Accesses.')
service = generate_service_template(data_access, True if len(config['cache']) > 0 else False)
Expand Down Expand Up @@ -95,6 +102,7 @@ def create_yaml_file(core_lib_name: str):
'data_accesses': data_layers['data_access'],
'services': data_layers['service'],
'setup': setup['data'],
'server_type': server_type,
}
}
)
Expand All @@ -103,20 +111,27 @@ def create_yaml_file(core_lib_name: str):
OmegaConf.save(config=conf, f=file.name)


def ask_server_type() -> int:
return prompt_enum(ServerType, '\nWhat kind of server type would you like?', default=ServerType.NOSERVER.value)


def generate_core_lib_yaml():
core_lib_name = any_to_pascal(prompt_str('Please enter the name for your Core-lib', 'MyCoreLib'))
core_lib_name = any_to_pascal(prompt_str('Please enter the name for your Core-lib', 'MyCoreLib'))

want_cache = prompt_yes_no('\nWould you like to use cache?', True)
want_cache = prompt_yes_no('\nWould you like to use cache?', True)
if want_cache:
_get_cache_config()

_get_data_layers_config()

want_job = prompt_yes_no('\nWould you like to create a Job?', False)
want_job = prompt_yes_no('\nWould you like to create a Job?', False)
if want_job:
_get_jobs_config(core_lib_name)

want_setup = prompt_yes_no('\nDo you want to add setup.py?', True)
global server_type
server_type = ask_server_type()

want_setup = prompt_yes_no('\nDo you want to add setup.py?', True)
if want_setup:
_get_setup_details()

Expand Down
7 changes: 4 additions & 3 deletions core_lib_generator/core_lib_generator_from_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def __init__(self, config: DictConfig):
self.core_lib_caches = get_dict_attr(config['core_lib'], 'caches')
self.core_lib_setup = get_dict_attr(config['core_lib'], 'setup')
self.core_lib_services = get_dict_attr(config['core_lib'], 'services')
self.core_lib_server_type = get_dict_attr(config['core_lib'], 'server_type')

def _generate_template(
self, file_path: str, yaml_data: dict, template_generator: TemplateGenerator, file_name: str = None
Expand All @@ -56,12 +57,12 @@ def _generate_template(
init_path = ''
for filename in dir_names:
init_path = os.path.join(init_path, filename)
init_file_path = f'{init_path}/__init__.py'
init_file_path = os.path.join(init_path, '__init__.py')
if not os.path.isfile(init_file_path) and filename not in excluded_init_dirs:
open(init_file_path, 'w').close()

location = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
with open(os.path.join(location, template_generator.get_template_file(yaml_data)), 'r') as template_file:
with open(os.path.normpath(os.path.join(location, template_generator.get_template_file(yaml_data))), 'r') as template_file:
new_file = template_generator.generate(template_file.read(), yaml_data, self.snake_core_lib_name, file_name)
with open(file_path, 'w') as file:
file.write(new_file)
Expand Down Expand Up @@ -209,7 +210,7 @@ def generate_tests(self):
UtilTestGenerateTemplate(),
)
self._generate_template(f'{self.snake_core_lib_name}/{self.snake_core_lib_name}_instance.py',
{},
{'server_type': self.core_lib_server_type},
CoreLibInstanceGenerate(),
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
import os
from core_lib.helpers.string import snake_to_camel
from core_lib_generator.core_lib_config_generate_yaml import ServerType
from core_lib_generator.file_generators.template_generator import TemplateGenerator



class CoreLibInstanceGenerate(TemplateGenerator):
def generate(self, template_content: str, yaml_data: dict, core_lib_name: str, file_name: str) -> str:
camel_case_class: str = snake_to_camel(core_lib_name)

server_type = yaml_data.get('server_type')
if server_type == ServerType.FLASK.value:
template_content = template_content.replace('# web_helper_template', 'WebHelpersUtils.init(WebHelpersUtils.ServerType.FLASK)')

Check failure on line 14 in core_lib_generator/file_generators/template_core_lib_instance_generator.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define a constant instead of duplicating this literal '# web_helper_template' 3 times.

See more on https://sonarcloud.io/project/issues?id=shay-te_core-lib&issues=AZ22siqXi1nXXWdfBC32&open=AZ22siqXi1nXXWdfBC32&pullRequest=150
elif server_type == ServerType.DJANGO.value:
template_content = template_content.replace('# web_helper_template', 'WebHelpersUtils.init(WebHelpersUtils.ServerType.DJANGO)')
else:
template_content = template_content.replace('# web_helper_template', '')

core_lib_import = f'from {os.path.basename(os.getcwd())}.{core_lib_name}.{core_lib_name}.{core_lib_name} import {camel_case_class}'
template_content = template_content.replace('# template_core_lib_import', core_lib_import)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class TemplateCoreLibInstance(object):
@staticmethod
def init(core_lib_cfg):
if not TemplateCoreLibInstance._app_instance:
# WebHelpersUtils.init(WebHelpersUtils.ServerType.FLASK) #TODO: initilazie the correct server type
# web_helper_template
TemplateCoreLibInstance._app_instance = TemplateCoreLibClass(core_lib_cfg)

@staticmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def load_config():
load_dotenv(dotenv_path=os.path.join(path, '.env'))

GlobalHydra.instance().clear()
hydra.initialize(config_path=os.path.join('../../../../ob-love-admin-backend', 'data', 'config'), caller_stack_depth=1)
hydra.initialize(config_path=os.path.join(f'../../../../{core_lib_name}', 'data', 'config'), caller_stack_depth=1)
TemplateInstance.config = hydra.compose('config.yaml')
return TemplateInstance.config

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# @package _global_
# @package _global_
template
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# @package _global_
# @package _global_
template
99 changes: 99 additions & 0 deletions generator_test/test_generate_yaml_prompts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import os
import tempfile
import unittest
from unittest.mock import patch

from omegaconf import OmegaConf

import core_lib_generator.core_lib_config_generate_yaml as yaml_gen_module
from core_lib_generator.core_lib_config_generate_yaml import ServerType, generate_core_lib_yaml


def _inputs(core_lib_name='', cache='no', db='no', job='no', server_type='', setup='no'):
"""Build an ordered input sequence for generate_core_lib_yaml() with all options off."""
return [
core_lib_name, # prompt_str → name ('' = accept default 'MyCoreLib')
cache, # prompt_yes_no → want_cache
db, # prompt_yes_no → want_db (inside _get_data_layers_config)
job, # prompt_yes_no → want_job
server_type, # prompt_enum → server_type ('' = accept default NOSERVER)
setup, # prompt_yes_no → want_setup
]


class TestGenerateCoreLibYamlPrompts(unittest.TestCase):
def setUp(self):
yaml_gen_module.config.clear()
yaml_gen_module.config['data'] = []
yaml_gen_module.config['cache'] = []
yaml_gen_module.config['jobs'] = []
yaml_gen_module.setup.clear()
yaml_gen_module.setup['data'] = {}
yaml_gen_module.env.clear()
yaml_gen_module.data_layers.clear()
yaml_gen_module.data_layers['data'] = []
yaml_gen_module.data_layers['data_access'] = []
yaml_gen_module.data_layers['service'] = []

def _run(self, inputs):
it = iter(inputs)
orig = os.getcwd()
with tempfile.TemporaryDirectory() as tmpdir:
try:
os.chdir(tmpdir)
with patch('builtins.input', side_effect=lambda _: next(it)):
yaml_file = generate_core_lib_yaml()
return OmegaConf.load(os.path.join(tmpdir, yaml_file))
finally:
os.chdir(orig)

# ── server type ───────────────────────────────────────────────────────────

def test_server_type_flask(self):
cfg = self._run(_inputs(server_type=str(ServerType.FLASK.value)))
self.assertEqual(cfg.core_lib.server_type, ServerType.FLASK.value)

def test_server_type_django(self):
cfg = self._run(_inputs(server_type=str(ServerType.DJANGO.value)))
self.assertEqual(cfg.core_lib.server_type, ServerType.DJANGO.value)

def test_server_type_noserver_explicit(self):
cfg = self._run(_inputs(server_type=str(ServerType.NOSERVER.value)))
self.assertEqual(cfg.core_lib.server_type, ServerType.NOSERVER.value)

def test_server_type_noserver_default(self):
# empty input → prompt_enum accepts the default (NOSERVER=3)
cfg = self._run(_inputs(server_type=''))
self.assertEqual(cfg.core_lib.server_type, ServerType.NOSERVER.value)

# ── yaml structure ────────────────────────────────────────────────────────

def test_core_lib_name_default(self):
cfg = self._run(_inputs())
self.assertEqual(cfg.core_lib.name, 'MyCoreLib')

def test_core_lib_name_custom(self):
cfg = self._run(_inputs(core_lib_name='my_cool_lib'))
self.assertEqual(cfg.core_lib.name, 'MyCoolLib')

def test_yaml_has_required_keys(self):
cfg = self._run(_inputs())
core_lib = cfg.core_lib
for key in ('name', 'server_type', 'connections', 'caches', 'jobs', 'entities', 'data_accesses', 'services'):
self.assertIn(key, core_lib)

def test_no_db_empty_connections(self):
cfg = self._run(_inputs(db='no'))
self.assertEqual(len(cfg.core_lib.connections), 0)

def test_no_cache_empty_caches(self):
cfg = self._run(_inputs(cache='no'))
self.assertEqual(len(cfg.core_lib.caches), 0)

def test_no_job_empty_jobs(self):
cfg = self._run(_inputs(job='no'))
self.assertEqual(len(cfg.core_lib.jobs), 0)


if __name__ == '__main__':
unittest.main()
14 changes: 14 additions & 0 deletions generator_test/test_generator_from_yaml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import unittest
from core_lib_generator.core_lib_generator_from_yaml import CoreLibGenerator
from omegaconf import OmegaConf


class TestGenerateFromYaml(unittest.TestCase):
def test_generating(self):
# Change to path of your generated yaml here ↓
config = OmegaConf.load('.\..\TestServerType.yaml')
core_lib_generator = CoreLibGenerator(config)
core_lib_generator.generate_tests()

if __name__ == '__main__':
unittest.main()