aboutsummaryrefslogtreecommitdiff
path: root/src_doit
diff options
context:
space:
mode:
Diffstat (limited to 'src_doit')
-rw-r--r--src_doit/__init__.py56
-rw-r--r--src_doit/common.py19
-rw-r--r--src_doit/js.py117
-rw-r--r--src_doit/py.py99
4 files changed, 291 insertions, 0 deletions
diff --git a/src_doit/__init__.py b/src_doit/__init__.py
new file mode 100644
index 0000000..e2999f2
--- /dev/null
+++ b/src_doit/__init__.py
@@ -0,0 +1,56 @@
+from pathlib import Path
+import subprocess
+import sys
+
+from . import common
+
+from .js import * # NOQA
+from .py import * # NOQA
+from . import js
+from . import py
+
+
+__all__ = ['task_clean_all',
+ 'task_build',
+ 'task_test',
+ *js.__all__,
+ *py.__all__]
+
+
+build_dir = Path('build')
+pytest_dir = Path('test_pytest')
+
+
+def task_clean_all():
+ """Clean all"""
+ return {'actions': [(common.rm_rf, [build_dir,
+ js.dst_dir,
+ py.json_schema_repo_path])]}
+
+
+def task_build():
+ """Build"""
+
+ def build():
+ subprocess.run([sys.executable, 'setup.py', '-q', 'bdist_wheel'],
+ cwd=str(build_dir),
+ check=True)
+
+ return {'actions': [build],
+ 'task_dep': ['py_build']}
+
+
+def task_test():
+ """Test"""
+
+ def run(args):
+ js.dst_dir.mkdir(parents=True, exist_ok=True)
+ subprocess.run([sys.executable, '-m', 'pytest',
+ '-s', '-p', 'no:cacheprovider',
+ *(args or [])],
+ cwd=str(pytest_dir),
+ check=True)
+
+ return {'actions': [run],
+ 'pos_arg': 'args',
+ 'task_dep': ['py_json_schema_repo']}
diff --git a/src_doit/common.py b/src_doit/common.py
new file mode 100644
index 0000000..6697b6e
--- /dev/null
+++ b/src_doit/common.py
@@ -0,0 +1,19 @@
+from pathlib import Path
+import shutil
+
+
+def rm_rf(*paths: Path):
+ for path in paths:
+ if not path.exists():
+ continue
+ if path.is_dir():
+ shutil.rmtree(str(path), ignore_errors=True)
+ else:
+ path.unlink()
+
+
+def cp_r(src: Path, dest: Path):
+ if src.is_dir():
+ shutil.copytree(str(src), str(dest), dirs_exist_ok=True)
+ else:
+ shutil.copy2(str(src), str(dest))
diff --git a/src_doit/js.py b/src_doit/js.py
new file mode 100644
index 0000000..dea8d04
--- /dev/null
+++ b/src_doit/js.py
@@ -0,0 +1,117 @@
+from pathlib import Path
+import subprocess
+import tempfile
+
+from . import common
+
+
+__all__ = ['task_js_build',
+ 'task_js_deps',
+ 'task_js_deps_clean']
+
+
+src_py_dir = Path('src_py')
+src_js_dir = Path('src_js')
+src_scss_dir = Path('src_scss')
+node_modules_dir = Path('node_modules')
+openapi_dir = Path('schemas_openapi')
+
+dst_dir = src_py_dir / 'restlog/ui'
+
+
+def task_js_build():
+ """JavaScript - build"""
+
+ def build(args):
+ args = args or []
+ entry = src_js_dir / 'main.js'
+ conf = _webpack_conf.format(
+ entry=entry.resolve(),
+ dst_dir=dst_dir.resolve(),
+ src_js_dir=src_js_dir.resolve(),
+ src_scss_dir=src_scss_dir.resolve(),
+ node_modules_dir=node_modules_dir.resolve())
+
+ common.rm_rf(dst_dir)
+ dst_dir.mkdir(parents=True, exist_ok=True)
+
+ common.cp_r(openapi_dir / 'main.yaml', dst_dir / 'openapi.yaml')
+ (dst_dir / 'index.html').write_text(_index_html)
+
+ with tempfile.TemporaryDirectory() as tmpdir:
+ tmpdir = Path(tmpdir)
+ config_path = tmpdir / 'webpack.config.js'
+ config_path.write_text(conf)
+ subprocess.run([str(node_modules_dir / '.bin/webpack'),
+ '--config', str(config_path),
+ *args],
+ check=True)
+
+ return {'actions': [(common.rm_rf, [dst_dir]),
+ build],
+ 'pos_arg': 'args',
+ 'task_dep': ['js_deps']}
+
+
+def task_js_deps():
+ """JavaScript - install dependencies"""
+ return {'actions': ['yarn install --silent']}
+
+
+def task_js_deps_clean():
+ """JavaScript - remove dependencies"""
+ return {'actions': [(common.rm_rf, [node_modules_dir,
+ Path('yarn.lock')])]}
+
+
+_index_html = r"""<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>restlog</title>
+ <script src="index.js"></script>
+</head>
+<body>
+</body>
+</html>
+"""
+
+
+_webpack_conf = r"""
+module.exports = {{
+ mode: 'none',
+ entry: '{entry}',
+ output: {{
+ filename: 'index.js',
+ path: '{dst_dir}'
+ }},
+ module: {{
+ rules: [
+ {{
+ test: /\.scss$/,
+ use: [
+ "style-loader",
+ "css-loader",
+ "resolve-url-loader",
+ {{
+ loader: "sass-loader",
+ options: {{ sourceMap: true }}
+ }}
+ ]
+ }}
+ ]
+ }},
+ resolve: {{
+ modules: [
+ '{src_js_dir}',
+ '{src_scss_dir}',
+ '{node_modules_dir}'
+ ]
+ }},
+ watchOptions: {{
+ ignored: /node_modules/
+ }},
+ devtool: 'source-map',
+ stats: 'errors-only'
+}};
+"""
diff --git a/src_doit/py.py b/src_doit/py.py
new file mode 100644
index 0000000..f2876ae
--- /dev/null
+++ b/src_doit/py.py
@@ -0,0 +1,99 @@
+from pathlib import Path
+
+import packaging.requirements
+
+from hat import json
+
+from . import common
+
+
+__all__ = ['task_py_build',
+ 'task_py_json_schema_repo']
+
+
+build_dir = Path('build')
+src_py_dir = Path('src_py')
+schemas_json_dir = Path('schemas_json')
+requirements_path = Path('requirements.pip.runtime.txt')
+
+json_schema_repo_path = src_py_dir / 'restlog/json_schema_repo.json'
+
+
+def task_py_build():
+ """Python - build"""
+
+ def build():
+ common.rm_rf(build_dir)
+ build_dir.mkdir(parents=True, exist_ok=True)
+
+ common.cp_r(src_py_dir, build_dir)
+ common.rm_rf(*build_dir.rglob('__pycache__'))
+
+ manifest_path = build_dir / 'MANIFEST.in'
+ paths = [path for path in build_dir.rglob('*') if not path.is_dir()]
+ with open(manifest_path, 'w', encoding='utf-8') as f:
+ for path in paths:
+ f.write(f"include {path.relative_to(manifest_path.parent)}\n")
+
+ readme = Path('README.rst').read_text()
+ requirements = list(_get_requirements(requirements_path))
+ setup_py = _setup_py.format(readme=repr(readme),
+ requirements=repr(requirements))
+ (build_dir / 'setup.py').write_text(setup_py)
+
+ return {'actions': [build],
+ 'task_dep': ['py_json_schema_repo',
+ 'js_build']}
+
+
+def task_py_json_schema_repo():
+ """Python - JSON schema repo"""
+ src_paths = list(schemas_json_dir.rglob('*.yaml'))
+
+ def generate():
+ repo = json.SchemaRepository(*src_paths)
+ data = repo.to_json()
+ json.encode_file(data, json_schema_repo_path, indent=None)
+
+ return {'actions': [generate],
+ 'file_dep': src_paths,
+ 'targets': [json_schema_repo_path]}
+
+
+def _get_requirements(path):
+ # TODO: implement full format
+ # https://pip.pypa.io/en/stable/cli/pip_install/
+ for i in path.read_text().split('\n'):
+ i = i.strip()
+ if not i or i.startswith('#'):
+ continue
+ requirement = packaging.requirements.Requirement(i)
+ yield str(requirement)
+
+
+_setup_py = r"""
+from setuptools import setup
+
+readme = {readme}
+requirements = {requirements}
+
+setup(
+ name='restlog',
+ version='0.0.1',
+ description='JSON log-structured data storage with REST API',
+ long_description=readme,
+ long_description_content_type='text/x-rst',
+ url='https://github.com/bnozokopic/restlog',
+ license='GPLv3',
+ classifiers=[
+ 'Programming Language :: Python :: 3',
+ 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)'],
+ packages=['restlog'],
+ include_package_data=True,
+ install_requires=requirements,
+ python_requires='>=3.8',
+ zip_safe=False,
+ entry_points={{
+ 'console_scripts': ['restlog = restlog.main:main']
+ }})
+""" # NOQA