Przeglądaj źródła

Update boilerplate

Arkadiusz Ryś 1 rok temu
rodzic
commit
bf24329ddf
6 zmienionych plików z 148 dodań i 95 usunięć
  1. 18 4
      .gitlab-ci.yml
  2. 0 48
      docs/templates/pyproject.toml
  3. 2 22
      mocka/__main__.py
  4. 60 0
      mocka/cli.py
  5. 0 15
      mocka/main.py
  6. 68 6
      tasks.py

+ 18 - 4
.gitlab-ci.yml

@@ -22,9 +22,23 @@ before_script:
   - docker info
   - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
 
+pytest:
+  image: python:3.11
+  stage: test
+  before_script:
+    - python -V
+  script:
+    - pip install -r requirements.txt
+    - pytest
+  rules:
+    - if: $CI_COMMIT_TAG
+    - if: $CI_PIPELINE_SOURCE == "push" || $CI_COMMIT_BRANCH == "dev"
+      when: manual
+      allow_failure: true
+
 build-upload:
   image: python:3.11
-  stage: build
+  stage: release
   before_script:
     - python -V
     - echo "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi"
@@ -40,7 +54,7 @@ build-upload:
 
 .build-upload-pypi:
   image: python:3.11
-  stage: build
+  stage: release
   before_script:
     - python -V
     - echo "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi"
@@ -55,7 +69,7 @@ build-upload:
       allow_failure: true
 
 build-docker:
-  stage: build
+  stage: release
   script:
     - docker pull $DOCKER_BRANCH || true
     - docker build --cache-from $DOCKER_BRANCH -f ./Dockerfile --tag $DOCKER_BRANCH .
@@ -67,7 +81,7 @@ build-docker:
       allow_failure: true
 
 build-tagged-docker:
-  stage: build
+  stage: release
   script:
     - docker pull $DOCKER_BRANCH || true
     - docker tag $DOCKER_BRANCH $DOCKER_LATEST

+ 0 - 48
docs/templates/pyproject.toml

@@ -1,48 +0,0 @@
-[build-system]
-requires = ["flit_core >=3.2,<4"]
-build-backend = "flit_core.buildapi"
-
-[project]
-name = "mocka"
-authors = [
-    {name = "Arkadiusz Michał Ryś", email = "Arkadiusz.Michal.Rys@gmail.com"},
-    {name = "Lucas Albertins de Lima", email = "lucas.albertinsdelima@uantwerpen.be"},
-    {name = "Rakshit Mittal", email = "rakshit.mittal@uantwerpen.be"},
-]
-readme = "README.md"
-requires-python = ">=3.9"
-classifiers = [
-    "License :: OSI Approved :: MIT License",
-    "Programming Language :: Python :: 3",
-    "Development Status :: 2 - Pre-Alpha",
-    "Intended Audience :: Developers",
-    "Natural Language :: English",
-]
-dynamic = ["version", "description"]
-license = {file = "LICENSE"}
-keywords = ["mocka"]
-dependencies = [
-{%- for dependency in requirements.mocka %}
-    "{{ dependency }}",
-{%- endfor %}
-]
-
-[project.optional-dependencies]
-test = [
-{%- for dependency in requirements.test %}
-    "{{ dependency }}",
-{%- endfor %}
-]
-doc = [
-{%- for dependency in requirements.doc %}
-    "{{ dependency }}",
-{%- endfor %}
-]
-dev = [
-{%- for dependency in requirements.dev %}
-    "{{ dependency }}",
-{%- endfor %}
-]
-
-[project.urls]
-source = "https://git.rys.one/dtdesign/mocka"

+ 2 - 22
mocka/__main__.py

@@ -1,23 +1,3 @@
-import logging
-import sys
-from pathlib import Path
+from mocka.cli import entry_point
 
-import arklog
-import dacite
-import toml
-import uvicorn
-
-from mocka.configuration import Configuration
-from mocka.main import get_application
-
-arklog.set_config_logging()
-
-data_dir = Path(__file__).resolve().parent.parent / Path("data")
-logging.debug(f"Looking for configuration in '{data_dir}'.")
-try:
-    configuration = toml.loads((data_dir / Path("configuration.toml")).read_text(encoding="utf-8"))
-    configuration = dacite.from_dict(data_class=Configuration, data=configuration, )
-except FileNotFoundError as e:
-    logging.error(f"Configuration 'configuration.toml' not found. {e}")
-    sys.exit(8)
-uvicorn.run(get_application(configuration), host=configuration.server.host, port=configuration.server.port)
+entry_point()

+ 60 - 0
mocka/cli.py

@@ -0,0 +1,60 @@
+"""
+Handles parsing arguments and passing them to the correct places when launching the application.
+"""
+import click
+import logging
+import sys
+import arklog
+import dacite
+import toml
+import uvicorn
+
+from mocka import __version__
+from pathlib import Path
+from signal import SIGINT, SIGTERM, signal
+from mocka.endpoint import MockActivityEndpoint
+from mocka.configuration import Configuration
+
+
+def handler(signal_code, _) -> None:
+    """Signal handler."""
+    logger = logging.getLogger(__name__)
+    logger.debug(f"Shutting down because signal {signal_code} was received.")
+    sys.exit(1)
+
+
+@click.option("--host", "-h", default="0.0.0.0", type=str, help="Address on which to listen")
+@click.option("--port", "-p", default=7999, type=int, help="Port on which to listen")
+def launch(host: str, port: int) -> int:
+    """"""
+    data_dir = Path(__file__).resolve().parent.parent / Path("data")
+    logging.debug(f"Looking for configuration in '{data_dir}'.")
+    try:
+        configuration = toml.loads((data_dir / Path("configuration.toml")).read_text(encoding="utf-8"))
+        configuration = dacite.from_dict(data_class=Configuration, data=configuration, )
+    except FileNotFoundError as e:
+        logging.error(f"Configuration 'configuration.toml' not found. {e}")
+        sys.exit(8)
+    host = configuration.server.host if configuration.server.host else host
+    port = configuration.server.port if configuration.server.port else port
+    app = MockActivityEndpoint(
+        version = __version__,
+        title = "Mock Activity Endpoint",
+        description = "Mock Activity Endpoint",
+        configuration=configuration
+    )
+    uvicorn.run(app, host=host, port=port)
+    return 0
+
+
+def entry_point():
+    """"""
+    signal(SIGINT, handler)
+    signal(SIGTERM, handler)
+    arklog.set_config_logging()
+    logging.info(f"Mocka {__version__}.")
+    sys.exit(launch("0.0.0.0", 7999))
+
+
+if __name__ == "__main__":
+    entry_point()

+ 0 - 15
mocka/main.py

@@ -1,15 +0,0 @@
-import arklog
-
-from mocka.configuration import Configuration
-from mocka.endpoint import MockActivityEndpoint
-from mocka import __version__
-
-def get_application(configuration: Configuration):
-    arklog.set_config_logging()
-    app = MockActivityEndpoint(
-        version = __version__,
-        title = "Mock Activity Endpoint",
-        description = "Mock Activity Endpoint",
-        configuration=configuration
-    )
-    return app

+ 68 - 6
tasks.py

@@ -3,9 +3,63 @@ from pathlib import Path
 from invoke import task
 from jinja2 import Template
 
-system = "mocka"  # Directory name of the project
-main_branch = "main" # The release branch on origin
-dev_branch = "dev" # The main development branch on origin
+system = "mocka"      # Directory name of the project
+main_branch = "main"  # The release branch on origin
+dev_branch = "dev"    # The main development branch on origin
+
+project_template = """
+[build-system]
+requires = ["flit_core >=3.9,<4"]
+build-backend = "flit_core.buildapi"
+
+[project]
+name = "{{ system }}"
+authors = [
+    {name = "Arkadiusz Michał Ryś", email = "Arkadiusz.Michal.Rys@gmail.com"},
+    {name = "Lucas Albertins de Lima", email = "lucas.albertinsdelima@uantwerpen.be"},
+    {name = "Rakshit Mittal", email = "rakshit.mittal@uantwerpen.be"},
+]
+readme = "README.md"
+requires-python = ">={{ minimum_version }}"
+classifiers = [
+    "License :: OSI Approved :: MIT License",
+    "Programming Language :: Python :: 3",
+    "Development Status :: 2 - Pre-Alpha",
+    "Intended Audience :: Developers",
+    "Natural Language :: English",
+]
+dynamic = ["version", "description"]
+license = {file = "LICENSE"}
+keywords = ["mocka"]
+dependencies = [
+{%- for dependency in requirements.mocka %}
+    "{{ dependency }}",
+{%- endfor %}
+]
+
+[project.optional-dependencies]
+test = [
+{%- for dependency in requirements.test %}
+    "{{ dependency }}",
+{%- endfor %}
+]
+doc = [
+{%- for dependency in requirements.doc %}
+    "{{ dependency }}",
+{%- endfor %}
+]
+dev = [
+{%- for dependency in requirements.dev %}
+    "{{ dependency }}",
+{%- endfor %}
+]
+
+[project.urls]
+source = "https://git.rys.one/dtdesign/mocka"
+
+[project.scripts]
+mocka = "mocka.cli:entry_point"
+"""
 
 
 @task
@@ -41,7 +95,7 @@ def clean(c):
 @task
 def test(c):
     """Run all tests under the tests directory."""
-    c.run("python3 -m unittest discover tests 'test_*' -v")
+    c.run("python3 -m pytest")
 
 
 @task
@@ -74,8 +128,14 @@ def migrate_requirements(c):
         if line.strip() == "" or ("=" in line and "#" in line):
             continue
         requirements[current].append("".join(line.split()))
-    template = Template(Path("docs/templates/pyproject.toml").read_text())
-    Path("pyproject.toml").write_text(template.render(requirements=requirements))
+    import vermin
+    config = vermin.Config()
+    source_file_paths = list(set(vermin.detect_paths([system, "tests", "docs"], config=config)))
+    minimums, *_ = vermin.Processor().process(source_file_paths, config, config.processes())
+    minimum_version = vermin.version_strings(list(filter(lambda ver: ver, minimums)))
+    Path("pyproject.toml").write_text(
+        Template(project_template[1:]).render(requirements=requirements, system=system, minimum_version=minimum_version)
+    )
 
 
 @task
@@ -85,6 +145,8 @@ def release(c, version):
         print("Version can be either major, minor or patch.")
         return
 
+    migrate_requirements(c)
+
     import importlib
     current_module = importlib.import_module(system)
     __version_info__ = current_module.__version_info__