kkpy-cli 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kkpy/__init__.py +0 -0
- kkpy/__version__.py +1 -0
- kkpy/poetry/install-poetry.py +831 -0
- kkpy/poetry/install.sh +22 -0
- kkpy/template.py +227 -0
- kkpy/templates/.editorconfig +23 -0
- kkpy/templates/.gitignore +54 -0
- kkpy/templates/.requirements-template.txt +4 -0
- kkpy/templates/.requirements-test.txt +3 -0
- kkpy/templates/Jenkinsfile +0 -0
- kkpy/templates/README.md +0 -0
- kkpy/templates/bin/start.py +33 -0
- kkpy/templates/bin/start.sh +9 -0
- kkpy/templates/src/__init__.py +11 -0
- kkpy/templates/src/configs/app.ini +9 -0
- kkpy/templates/src/configs/db.ini +5 -0
- kkpy/templates/src/configs/logging_config.ini +27 -0
- kkpy/templates/src/main.py +27 -0
- kkpy/templates/src/requirements.txt +0 -0
- kkpy/templates/src/utils/__init__.py +0 -0
- kkpy/templates/src/utils/utils.py +63 -0
- kkpy/templates/tests/__init__.py +0 -0
- kkpy/templates/tests/conftest.py +9 -0
- kkpy/templates/tests/test_sample.py +4 -0
- kkpy/templates/tox.ini +27 -0
- kkpy_cli/__init__.py +0 -0
- kkpy_cli/cli.py +197 -0
- kkpy_cli/commands/__init__.py +0 -0
- kkpy_cli/commands/build.py +34 -0
- kkpy_cli/commands/clean.py +19 -0
- kkpy_cli/commands/init.py +34 -0
- kkpy_cli/commands/install.py +22 -0
- kkpy_cli/commands/run.py +23 -0
- kkpy_cli/commands/test.py +15 -0
- kkpy_cli/utils/__init__.py +1 -0
- kkpy_cli/utils/cli_args.py +21 -0
- kkpy_cli/utils/exception.py +12 -0
- kkpy_cli-0.1.1.dist-info/METADATA +26 -0
- kkpy_cli-0.1.1.dist-info/RECORD +42 -0
- kkpy_cli-0.1.1.dist-info/WHEEL +5 -0
- kkpy_cli-0.1.1.dist-info/entry_points.txt +2 -0
- kkpy_cli-0.1.1.dist-info/top_level.txt +2 -0
kkpy/poetry/install.sh
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# !/bin/bash
|
|
2
|
+
export HRER="$(cd "`dirname "$0"`"; pwd)"
|
|
3
|
+
|
|
4
|
+
echo "========================= [Install Poetry] ========================="
|
|
5
|
+
INPUT_POETRY_VERSION=$1
|
|
6
|
+
INPUT_POETRY_HOME=$2
|
|
7
|
+
|
|
8
|
+
echo "> Install poetry(v${INPUT_POETRY_VERSION})."
|
|
9
|
+
echo "> Located at: ${INPUT_POETRY_HOME}"
|
|
10
|
+
export POETRY_HOME=${INPUT_POETRY_HOME}
|
|
11
|
+
|
|
12
|
+
python3 ${HRER}/install-poetry.py --version ${INPUT_POETRY_VERSION}
|
|
13
|
+
|
|
14
|
+
# check execution result
|
|
15
|
+
if [ $? -eq 0 ] ;then
|
|
16
|
+
echo "> Successfully."
|
|
17
|
+
else
|
|
18
|
+
echo "> Failed."
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
echo "===================================================================="
|
kkpy/template.py
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import distutils
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
import platform
|
|
5
|
+
import subprocess
|
|
6
|
+
import uuid
|
|
7
|
+
from distutils import dir_util
|
|
8
|
+
|
|
9
|
+
here = os.path.abspath(os.path.dirname(__file__))
|
|
10
|
+
|
|
11
|
+
TEMPLATE_VENV_NAME = '.venv'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Template:
|
|
15
|
+
|
|
16
|
+
LOG_DIR = 'logs'
|
|
17
|
+
|
|
18
|
+
def __init__(self, template_home):
|
|
19
|
+
self.template_home = template_home
|
|
20
|
+
self._init_basic_folder()
|
|
21
|
+
|
|
22
|
+
def _init_basic_folder(self):
|
|
23
|
+
# log directory
|
|
24
|
+
log_dir = os.path.join(self.template_home, self.LOG_DIR)
|
|
25
|
+
if not os.path.exists(log_dir):
|
|
26
|
+
logging.info(f"make new directory: {log_dir}")
|
|
27
|
+
os.makedirs(log_dir, exist_ok=True)
|
|
28
|
+
|
|
29
|
+
def generate(self):
|
|
30
|
+
logging.info(f"start to copy template files from template to {self.template_home}")
|
|
31
|
+
distutils.dir_util.copy_tree(f'{here}/templates', f"{self.template_home}")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TemplateEnv:
|
|
35
|
+
|
|
36
|
+
TEMPLATE_ENV_NAME = '.env'
|
|
37
|
+
|
|
38
|
+
def __init__(self, template_home):
|
|
39
|
+
self.template_home = template_home
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def project_home(self):
|
|
43
|
+
return self.template_home
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def project_name(self):
|
|
47
|
+
return os.path.basename(self.project_home)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def env_path(self):
|
|
51
|
+
return os.path.join(self.template_home, self.TEMPLATE_ENV_NAME)
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def venv_conf_path(self):
|
|
55
|
+
return os.path.join(self.template_home, TEMPLATE_VENV_NAME)
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def env(self):
|
|
59
|
+
return self._env
|
|
60
|
+
|
|
61
|
+
@env.setter
|
|
62
|
+
def env(self, value):
|
|
63
|
+
self._env = value
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def py_ver(self):
|
|
67
|
+
return self._py_ver
|
|
68
|
+
|
|
69
|
+
@py_ver.setter
|
|
70
|
+
def py_ver(self, value):
|
|
71
|
+
self._py_ver = value
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def venv_path(self):
|
|
75
|
+
return self._venv_path
|
|
76
|
+
|
|
77
|
+
@venv_path.setter
|
|
78
|
+
def venv_path(self, value):
|
|
79
|
+
self._venv_path = value
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def check_is_exist(env_directory):
|
|
83
|
+
if os.path.isfile(os.path.join(env_directory, TemplateEnv.TEMPLATE_ENV_NAME)):
|
|
84
|
+
return True
|
|
85
|
+
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
def create(self):
|
|
89
|
+
with open(self.env_path, 'w') as text_file:
|
|
90
|
+
text_file.write('# It is automatically generated at init time, please do not edit it. \n')
|
|
91
|
+
|
|
92
|
+
logging.info(f'write args in {self.env_path}')
|
|
93
|
+
|
|
94
|
+
logging.info(f'write {self.project_home} to arg: KKPY_PROJECT_HOME.')
|
|
95
|
+
text_file.write(f'KKPY_PROJECT_HOME=\"{self.project_home}\"\n')
|
|
96
|
+
|
|
97
|
+
logging.info(f'write {self.project_name} to arg: KKPY_PROJECT_NAME.')
|
|
98
|
+
text_file.write(f'KKPY_PROJECT_NAME=\"{self.project_name}\"\n')
|
|
99
|
+
|
|
100
|
+
logging.info(f'write {self.env_path} to arg: KKPY_ENV_PATH.')
|
|
101
|
+
text_file.write(f'KKPY_ENV_PATH=\"{self.env_path}\"\n')
|
|
102
|
+
|
|
103
|
+
logging.info(f'write {self.env} to arg: KKPY_ENV.')
|
|
104
|
+
text_file.write(f'KKPY_ENV=\"{self.env}\"\n')
|
|
105
|
+
|
|
106
|
+
logging.info(f'write {self.py_ver} to arg: KKPY_PYTHON_VERSION.')
|
|
107
|
+
text_file.write(f'KKPY_PYTHON_VERSION=\"{self.py_ver}\"\n')
|
|
108
|
+
|
|
109
|
+
logging.info(f'write {self.venv_conf_path} to arg: KKPY_VIRTUALENV_CONF_PATH.')
|
|
110
|
+
text_file.write(f'KKPY_VIRTUALENV_CONF_PATH=\"{self.venv_conf_path}\"\n')
|
|
111
|
+
|
|
112
|
+
logging.info(f'write {self.venv_path} to arg: KKPY_VIRTUALENV_PATH.')
|
|
113
|
+
text_file.write(f'KKPY_VIRTUALENV_PATH=\"{self.venv_path}\"\n')
|
|
114
|
+
|
|
115
|
+
def load_to_env_vars(self):
|
|
116
|
+
import dotenv
|
|
117
|
+
dotenv.load_dotenv(self.env_path)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class TemplateVirtualEnv:
|
|
121
|
+
|
|
122
|
+
# template requirement
|
|
123
|
+
TEMPLATE_REQUIREMENTS = '.requirements-template.txt'
|
|
124
|
+
TEMPLATE_VENV_REQUIREMENTS = 'requirements.txt'
|
|
125
|
+
# pyenv
|
|
126
|
+
PYENV_CONF_NAME = '.python-version'
|
|
127
|
+
BUILD_PYENV_CONF_NAME = 'build-python-version'
|
|
128
|
+
# poetry
|
|
129
|
+
POETRY_COMMAND = '$HOME/.poetry/bin/poetry'
|
|
130
|
+
|
|
131
|
+
def __init__(self, template_home, python_version=None):
|
|
132
|
+
self.template_home = template_home
|
|
133
|
+
self.py_ver = python_version
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def path(self):
|
|
137
|
+
return subprocess.getoutput(f'cd {os.path.join(self.template_home, TEMPLATE_VENV_NAME)}; {self.POETRY_COMMAND} env info -p')
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def py_ver(self):
|
|
141
|
+
return self._py_ver
|
|
142
|
+
|
|
143
|
+
@py_ver.setter
|
|
144
|
+
def py_ver(self, value):
|
|
145
|
+
if value:
|
|
146
|
+
self._py_ver = value
|
|
147
|
+
else:
|
|
148
|
+
# check build-python-version
|
|
149
|
+
python_version_path = os.path.join(self.template_home, self.BUILD_PYENV_CONF_NAME)
|
|
150
|
+
if os.path.isfile(python_version_path):
|
|
151
|
+
# use existing build-python-version setting
|
|
152
|
+
with open(python_version_path, 'r') as f:
|
|
153
|
+
self._py_ver = f.read().replace('\n', '')
|
|
154
|
+
else:
|
|
155
|
+
# default: system python version
|
|
156
|
+
self._py_ver = platform.python_version()
|
|
157
|
+
|
|
158
|
+
self._install_python_in_pyenv()
|
|
159
|
+
|
|
160
|
+
# write python version for pyenv
|
|
161
|
+
if not os.path.isdir(os.path.join(self.template_home, TEMPLATE_VENV_NAME)):
|
|
162
|
+
os.mkdir(os.path.join(self.template_home, TEMPLATE_VENV_NAME))
|
|
163
|
+
|
|
164
|
+
with open(os.path.join(self.template_home, TEMPLATE_VENV_NAME, self.PYENV_CONF_NAME), 'w') as text_file:
|
|
165
|
+
text_file.write(f'{self._py_ver}')
|
|
166
|
+
|
|
167
|
+
with open(os.path.join(self.template_home, self.BUILD_PYENV_CONF_NAME), 'w') as text_file:
|
|
168
|
+
text_file.write(f'{self._py_ver}')
|
|
169
|
+
|
|
170
|
+
def _install_python_in_pyenv(self):
|
|
171
|
+
logging.info(f'installing python {self.py_ver} via pyenv, please wait...')
|
|
172
|
+
|
|
173
|
+
command = f'pyenv install -s {self.py_ver}'
|
|
174
|
+
try:
|
|
175
|
+
logging.info(f'exec command: {command}')
|
|
176
|
+
subprocess.run([command], shell=True, check=True)
|
|
177
|
+
except Exception as e:
|
|
178
|
+
logging.error(e)
|
|
179
|
+
exit(-1)
|
|
180
|
+
|
|
181
|
+
def build(self):
|
|
182
|
+
base_build_command = f'cd {os.path.join(self.template_home, TEMPLATE_VENV_NAME)};'
|
|
183
|
+
|
|
184
|
+
# poetry init
|
|
185
|
+
init_command = f'{base_build_command} {self.POETRY_COMMAND} init --python {self._py_ver} -n'
|
|
186
|
+
logging.info(f'exec command: {init_command}')
|
|
187
|
+
os.system(init_command)
|
|
188
|
+
|
|
189
|
+
# set virtualenvs.in-project=true by project
|
|
190
|
+
set_command = f'{base_build_command} {self.POETRY_COMMAND} config virtualenvs.in-project true --local'
|
|
191
|
+
logging.info(f'exec command: {set_command}')
|
|
192
|
+
os.system(set_command)
|
|
193
|
+
|
|
194
|
+
# create virtualenv via specific python version (from .python-version)
|
|
195
|
+
venv_command = f'{base_build_command} {self.POETRY_COMMAND} env use $(pyenv which python)'
|
|
196
|
+
logging.info(f'exec command: {venv_command}')
|
|
197
|
+
os.system(venv_command)
|
|
198
|
+
|
|
199
|
+
# poetry install
|
|
200
|
+
install_command = f'{base_build_command} {self.POETRY_COMMAND} install'
|
|
201
|
+
logging.info(f'exec command: {install_command}')
|
|
202
|
+
os.system(install_command)
|
|
203
|
+
|
|
204
|
+
# poetry add
|
|
205
|
+
full_template_requirement_path = os.path.join(self.template_home, self.TEMPLATE_REQUIREMENTS)
|
|
206
|
+
add_command = f'{base_build_command} if [ -s {full_template_requirement_path} ] ; then cat {full_template_requirement_path} | xargs {self.POETRY_COMMAND} add ; fi'
|
|
207
|
+
logging.info(f'exec command: {add_command}')
|
|
208
|
+
os.system(add_command)
|
|
209
|
+
|
|
210
|
+
logging.info(f'create python ({self.py_ver}) venv at: {self.path}')
|
|
211
|
+
|
|
212
|
+
def install(self):
|
|
213
|
+
logging.info(f"install python packages ({self.TEMPLATE_VENV_REQUIREMENTS}) in virtualenv")
|
|
214
|
+
|
|
215
|
+
if self.path:
|
|
216
|
+
# poetry add
|
|
217
|
+
full_template_venv_requirement_path = os.path.join(self.template_home, 'src', self.TEMPLATE_VENV_REQUIREMENTS)
|
|
218
|
+
add_command = f'cd {os.path.join(self.template_home, TEMPLATE_VENV_NAME)}; if [ -s {full_template_venv_requirement_path} ] ; then cat {full_template_venv_requirement_path} | xargs {self.POETRY_COMMAND} add ; fi'
|
|
219
|
+
logging.info(f'exec command: {add_command}')
|
|
220
|
+
os.system(add_command)
|
|
221
|
+
else:
|
|
222
|
+
# pip install
|
|
223
|
+
install_command = f'pip install -r {self.template_home}/{self.TEMPLATE_VENV_REQUIREMENTS}'
|
|
224
|
+
logging.info(f'exec command: {install_command}')
|
|
225
|
+
os.system(install_command)
|
|
226
|
+
|
|
227
|
+
logging.info('install finished.')
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
indent_style = space
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
charset = utf-8
|
|
7
|
+
trim_trailing_whitespace = true
|
|
8
|
+
insert_final_newline = true
|
|
9
|
+
indent_size = 2
|
|
10
|
+
|
|
11
|
+
[*.py]
|
|
12
|
+
indent_size = 4
|
|
13
|
+
|
|
14
|
+
[*.sh]
|
|
15
|
+
indent_size = 4
|
|
16
|
+
|
|
17
|
+
[*.md]
|
|
18
|
+
trim_trailing_whitespace = false
|
|
19
|
+
|
|
20
|
+
[*.rst]
|
|
21
|
+
indent_size = 3
|
|
22
|
+
|
|
23
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Compiled source #
|
|
2
|
+
###################
|
|
3
|
+
*.pyc
|
|
4
|
+
|
|
5
|
+
# Logs and databases #
|
|
6
|
+
######################
|
|
7
|
+
*.log
|
|
8
|
+
*.log.*
|
|
9
|
+
*/logs
|
|
10
|
+
|
|
11
|
+
# OS generated files #
|
|
12
|
+
######################
|
|
13
|
+
.DS_Store*
|
|
14
|
+
|
|
15
|
+
# Editor Files #
|
|
16
|
+
################
|
|
17
|
+
*~
|
|
18
|
+
*.swp
|
|
19
|
+
|
|
20
|
+
# Build output directies #
|
|
21
|
+
##########################
|
|
22
|
+
build
|
|
23
|
+
.eggs
|
|
24
|
+
*.egg-info
|
|
25
|
+
dist
|
|
26
|
+
|
|
27
|
+
# virtual env #
|
|
28
|
+
###############
|
|
29
|
+
.venv
|
|
30
|
+
.tox
|
|
31
|
+
|
|
32
|
+
# IDE Files #
|
|
33
|
+
#############
|
|
34
|
+
.vscode/
|
|
35
|
+
|
|
36
|
+
# Cache #
|
|
37
|
+
#########
|
|
38
|
+
__pycache__
|
|
39
|
+
.pytest_cache
|
|
40
|
+
.cache
|
|
41
|
+
|
|
42
|
+
# coverage output #
|
|
43
|
+
###################
|
|
44
|
+
.coverage
|
|
45
|
+
htmlcov
|
|
46
|
+
|
|
47
|
+
# Temp #
|
|
48
|
+
########
|
|
49
|
+
tmp
|
|
50
|
+
temp
|
|
51
|
+
|
|
52
|
+
# Template #
|
|
53
|
+
.env
|
|
54
|
+
src/configs/vars
|
|
File without changes
|
kkpy/templates/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import logging
|
|
3
|
+
import time
|
|
4
|
+
import traceback
|
|
5
|
+
|
|
6
|
+
from src.main import Main
|
|
7
|
+
from utils.utils import get_configs_path, get_config_by_env
|
|
8
|
+
|
|
9
|
+
@click.command()
|
|
10
|
+
def receive(**kwargs):
|
|
11
|
+
try:
|
|
12
|
+
logging.info('======== Receive running request ========')
|
|
13
|
+
start = time.time()
|
|
14
|
+
|
|
15
|
+
# load configs
|
|
16
|
+
configs_path = get_configs_path()
|
|
17
|
+
configs = get_config_by_env(configs_path)
|
|
18
|
+
|
|
19
|
+
# trigger main task
|
|
20
|
+
main = Main(config=configs, input_args=kwargs)
|
|
21
|
+
main.run()
|
|
22
|
+
|
|
23
|
+
end = time.time()
|
|
24
|
+
execution_time = end - start
|
|
25
|
+
|
|
26
|
+
logging.info(f'======== Successfully! Execution time: {execution_time} sec ========')
|
|
27
|
+
except Exception:
|
|
28
|
+
error_msg = traceback.format_exc()
|
|
29
|
+
logging.exception(error_msg)
|
|
30
|
+
exit(-1)
|
|
31
|
+
|
|
32
|
+
if __name__ == '__main__':
|
|
33
|
+
receive()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import logging
|
|
4
|
+
from logging import config
|
|
5
|
+
|
|
6
|
+
if hasattr(sys, '_called_from_test'):
|
|
7
|
+
# called from within a test run
|
|
8
|
+
pass
|
|
9
|
+
else:
|
|
10
|
+
logging.logfilename = os.environ.get('KKPY_PROJECT_NAME', 'app')
|
|
11
|
+
config.fileConfig('src/configs/logging_config.ini')
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[loggers]
|
|
2
|
+
keys=root
|
|
3
|
+
|
|
4
|
+
[handlers]
|
|
5
|
+
keys=stdout,filelog
|
|
6
|
+
|
|
7
|
+
[formatters]
|
|
8
|
+
keys=default
|
|
9
|
+
|
|
10
|
+
[logger_root]
|
|
11
|
+
level=INFO
|
|
12
|
+
handlers=filelog,stdout
|
|
13
|
+
|
|
14
|
+
[handler_stdout]
|
|
15
|
+
class=StreamHandler
|
|
16
|
+
level=DEBUG
|
|
17
|
+
formatter=default
|
|
18
|
+
args=(sys.stdout,)
|
|
19
|
+
|
|
20
|
+
[handler_filelog]
|
|
21
|
+
class=handlers.RotatingFileHandler
|
|
22
|
+
level=DEBUG
|
|
23
|
+
args=('logs/'+logfilename+'.log', 'a', 10000000, 10)
|
|
24
|
+
formatter=default
|
|
25
|
+
|
|
26
|
+
[formatter_default]
|
|
27
|
+
format=%(asctime)s-[%(threadName)s][%(thread)x]-%(filename)-8s-%(name)-8s-%(funcName)-10s-%(levelname)-5s-%(lineno)d: %(message)s
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Main(object):
|
|
9
|
+
|
|
10
|
+
def __init__(self, config, **kwargs):
|
|
11
|
+
self.config = config
|
|
12
|
+
self.args = kwargs.get('input_args')
|
|
13
|
+
|
|
14
|
+
def run(self):
|
|
15
|
+
try:
|
|
16
|
+
logger.info('>>> run')
|
|
17
|
+
logger.info(f'config(app): {self.config["app"]}')
|
|
18
|
+
logger.info(f'input args: {self.args}')
|
|
19
|
+
|
|
20
|
+
# TODO Let's start coding for the project !
|
|
21
|
+
|
|
22
|
+
except Exception:
|
|
23
|
+
raise
|
|
24
|
+
|
|
25
|
+
# ===== Just for testing test feature =====
|
|
26
|
+
def just_test_fun():
|
|
27
|
+
return True
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from configparser import ConfigParser
|
|
4
|
+
|
|
5
|
+
from jinja2 import Environment, FileSystemLoader
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
CONF_BASE_PATH = 'src/configs'
|
|
10
|
+
EXTRA_VAR_FILE_NAME = 'vars'
|
|
11
|
+
|
|
12
|
+
jinja_env = Environment(loader=FileSystemLoader('.'))
|
|
13
|
+
|
|
14
|
+
def get_configs_path():
|
|
15
|
+
exclude_list = ['logging_config.ini']
|
|
16
|
+
return [f'{CONF_BASE_PATH}/{f}'
|
|
17
|
+
for f in os.listdir(CONF_BASE_PATH) if f.endswith('.ini') and f not in exclude_list]
|
|
18
|
+
|
|
19
|
+
def _load_vars_from_file():
|
|
20
|
+
extra_var_file_path = os.path.join(CONF_BASE_PATH, EXTRA_VAR_FILE_NAME)
|
|
21
|
+
|
|
22
|
+
udf_vars = {}
|
|
23
|
+
if os.path.exists(extra_var_file_path):
|
|
24
|
+
with open(extra_var_file_path, 'r') as f:
|
|
25
|
+
for line in f:
|
|
26
|
+
line = line.rstrip('\n')
|
|
27
|
+
if line != '':
|
|
28
|
+
k, v = line.split('=', 1)
|
|
29
|
+
udf_vars[k.strip()] = v.strip()
|
|
30
|
+
|
|
31
|
+
return udf_vars
|
|
32
|
+
|
|
33
|
+
def get_config_by_env(configs_path):
|
|
34
|
+
try:
|
|
35
|
+
current_env = os.environ.get('KKPY_ENV', 'dev')
|
|
36
|
+
|
|
37
|
+
# load vars from vars file
|
|
38
|
+
udf_vars = _load_vars_from_file()
|
|
39
|
+
|
|
40
|
+
configs_by_file_name = {}
|
|
41
|
+
for path in configs_path:
|
|
42
|
+
|
|
43
|
+
file_name = os.path.basename(path).rstrip('.ini')
|
|
44
|
+
|
|
45
|
+
# load .ini as a template
|
|
46
|
+
conf_template = jinja_env.get_template(f'{CONF_BASE_PATH}/{file_name}.ini')
|
|
47
|
+
|
|
48
|
+
parser = ConfigParser()
|
|
49
|
+
parser.read_string(conf_template.render(**udf_vars)) # render vars to config template(.ini)
|
|
50
|
+
|
|
51
|
+
options = {}
|
|
52
|
+
if file_name == 'app' \
|
|
53
|
+
and parser.has_section(current_env): # load runtime env section (dev|sit|stage|prod) in app.ini
|
|
54
|
+
options = dict(parser.items(current_env))
|
|
55
|
+
else: # load all sections in other .ini files
|
|
56
|
+
for section_key in parser.sections():
|
|
57
|
+
options[section_key] = dict(parser.items(section_key))
|
|
58
|
+
|
|
59
|
+
configs_by_file_name[file_name] = options
|
|
60
|
+
except Exception:
|
|
61
|
+
raise
|
|
62
|
+
else:
|
|
63
|
+
return configs_by_file_name
|
|
File without changes
|
kkpy/templates/tox.ini
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[tox]
|
|
2
|
+
skipsdist = True
|
|
3
|
+
|
|
4
|
+
[testenv]
|
|
5
|
+
setenv =
|
|
6
|
+
PYTHONPATH = {toxinidir}/src
|
|
7
|
+
PYTHONDONTWRITEBYTECODE = 1
|
|
8
|
+
|
|
9
|
+
deps =
|
|
10
|
+
-r{toxinidir}/src/requirements.txt
|
|
11
|
+
-r{toxinidir}/.requirements-test.txt
|
|
12
|
+
-r{toxinidir}/.requirements-template.txt
|
|
13
|
+
|
|
14
|
+
commands =
|
|
15
|
+
- pytest \
|
|
16
|
+
--cov-config {toxinidir}/tox.ini \
|
|
17
|
+
--color yes \
|
|
18
|
+
--cov {toxinidir}/src \
|
|
19
|
+
-vvv
|
|
20
|
+
|
|
21
|
+
[coverage:run]
|
|
22
|
+
omit =
|
|
23
|
+
*/__init__.py
|
|
24
|
+
|
|
25
|
+
[pytest]
|
|
26
|
+
filterwarnings =
|
|
27
|
+
ignore:: DeprecationWarning
|
kkpy_cli/__init__.py
ADDED
|
File without changes
|