feat: add docker preset
This commit is contained in:
@@ -23,8 +23,8 @@ pm <task> [-v] [-vv]
|
|||||||
## Presets locations
|
## Presets locations
|
||||||
|
|
||||||
- default presets `$PROJECT_MANAGER/project_manager/preset/default/*.toml`
|
- default presets `$PROJECT_MANAGER/project_manager/preset/default/*.toml`
|
||||||
- user preset `$HOME/.preset.toml`
|
- user preset `$HOME/.pm.toml`
|
||||||
- project preset `./.preset.toml`
|
- project preset `./.pm.toml`
|
||||||
|
|
||||||
|
|
||||||
## Preset format
|
## Preset format
|
||||||
|
|||||||
Generated
+30
-1
@@ -119,6 +119,20 @@ files = [
|
|||||||
graph = ["objgraph (>=1.7.2)"]
|
graph = ["objgraph (>=1.7.2)"]
|
||||||
profile = ["gprof2dot (>=2022.7.29)"]
|
profile = ["gprof2dot (>=2022.7.29)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dotenv"
|
||||||
|
version = "0.9.9"
|
||||||
|
description = "Deprecated package"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
groups = ["main"]
|
||||||
|
files = [
|
||||||
|
{file = "dotenv-0.9.9-py2.py3-none-any.whl", hash = "sha256:29cf74a087b31dafdb5a446b6d7e11cbce8ed2741540e2339c69fbef92c94ce9"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
python-dotenv = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iniconfig"
|
name = "iniconfig"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
@@ -448,6 +462,21 @@ pygments = ">=2.7.2"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"]
|
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-dotenv"
|
||||||
|
version = "1.2.2"
|
||||||
|
description = "Read key-value pairs from a .env file and set them as environment variables"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.10"
|
||||||
|
groups = ["main"]
|
||||||
|
files = [
|
||||||
|
{file = "python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a"},
|
||||||
|
{file = "python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
cli = ["click (>=5.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytokens"
|
name = "pytokens"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@@ -617,4 +646,4 @@ typing-extensions = ">=4.12.0"
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.1"
|
lock-version = "2.1"
|
||||||
python-versions = ">=3.14,<4.0"
|
python-versions = ">=3.14,<4.0"
|
||||||
content-hash = "4d19fc54b607d98b8ae277fa031223daac3cdda07545cb03ed5875688018936e"
|
content-hash = "df515ec4294fec745964e448a08d5fd797ae3a096208330ae9ccb1d2ea82276a"
|
||||||
|
|||||||
+1
-1
@@ -59,7 +59,7 @@ def addLoggingLevel(levelName, levelNum, methodName=None):
|
|||||||
addLoggingLevel("TRACE", logging.DEBUG - 5)
|
addLoggingLevel("TRACE", logging.DEBUG - 5)
|
||||||
|
|
||||||
|
|
||||||
class CustomFormatter(logging.Formatter):
|
class ColoredFormatter(logging.Formatter):
|
||||||
def __init__(self, fmt):
|
def __init__(self, fmt):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.fmt = fmt
|
self.fmt = fmt
|
||||||
@@ -2,7 +2,7 @@ import logging
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
from .command import CommandExecutor
|
from .common.command import CommandExecutor
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"EntryTaskNotImplementedError",
|
"EntryTaskNotImplementedError",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from collections import Counter
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
from .command import CommandError
|
from .common.command import CommandError
|
||||||
from .entry import Entry, EntryResolver, EntryTaskNotImplementedError
|
from .entry import Entry, EntryResolver, EntryTaskNotImplementedError
|
||||||
from .preset.entry import PresetEntryDetector
|
from .preset.entry import PresetEntryDetector
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from ...util import reflect
|
import dotenv
|
||||||
|
import tomli
|
||||||
|
|
||||||
from ..core import Pipe
|
from ..core import Pipe
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@@ -11,31 +14,24 @@ __all__ = (
|
|||||||
|
|
||||||
|
|
||||||
class FileData:
|
class FileData:
|
||||||
_LOADERS = {
|
|
||||||
".toml": "tomli:load",
|
|
||||||
".json": "json:load",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, filepath: Path, loader: str | None = None):
|
def __init__(self, filepath: Path, loader: str | None = None):
|
||||||
self._filepath = filepath
|
self._filepath = filepath
|
||||||
self._loader = loader
|
self._loader = loader
|
||||||
self._data = None
|
self._data = None
|
||||||
|
|
||||||
def _resolve_loader(self, filepath: Path):
|
|
||||||
loader = self._loader or self._LOADERS.get(filepath.suffix)
|
|
||||||
return reflect(loader) if loader else None
|
|
||||||
|
|
||||||
def _load_data(self):
|
def _load_data(self):
|
||||||
loader = self._resolve_loader(self._filepath)
|
if self._filepath.suffix == ".toml":
|
||||||
with open(self._filepath, "rb") as fd:
|
return tomli.loads(self._filepath.read_text())
|
||||||
if loader:
|
elif self._filepath.suffix == ".json":
|
||||||
self._data = loader(fd)
|
return json.loads(self._filepath.read_text())
|
||||||
else:
|
elif self._filepath.suffix == ".env" or self._filepath.name == ".env":
|
||||||
self._data = fd.read()
|
return dotenv.dotenv_values(self._filepath)
|
||||||
|
return self._filepath.read_text()
|
||||||
|
|
||||||
def get(self, key: str):
|
def get(self, key: str):
|
||||||
if self._data is None and self._filepath.exists():
|
if self._data is None and self._filepath.exists():
|
||||||
self._load_data()
|
self._data = self._load_data()
|
||||||
if self._data:
|
if self._data:
|
||||||
return self._data.get(key)
|
return self._data.get(key)
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[presets.docker]
|
||||||
|
conditions = ["file(Dockerfile)"]
|
||||||
|
|
||||||
|
# build
|
||||||
|
[presets.docker.tasks.build.default]
|
||||||
|
variables.docker_target = "file(.env) | get(DOCKER_PROJECTS)"
|
||||||
|
variables.docker_name = "file(pyproject.toml) | get(project.name)"
|
||||||
|
variables.docker_group = "file(.env) | get(DOCKER_GROUP)"
|
||||||
|
commands = [
|
||||||
|
# "docker build --target {docker_target} -t {docker_group}/{docker_name} . -f Dockerfile",
|
||||||
|
"docker build -t {docker_group}/{docker_name} . -f Dockerfile",
|
||||||
|
]
|
||||||
|
|
||||||
|
# publish
|
||||||
|
[presets.docker.tasks.publish.default]
|
||||||
|
commands = ["docker publish"]
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
[presets.python]
|
[presets.python]
|
||||||
conditions = ["file(pyproject.toml)"]
|
conditions = ["file(pyproject.toml)"]
|
||||||
|
|
||||||
|
# setup
|
||||||
[presets.python.tasks.setup.poetry]
|
[presets.python.tasks.setup.poetry]
|
||||||
conditions = [
|
conditions = [
|
||||||
"file(pyproject.toml) | get(build-system.build-backend) | equal(poetry.core.masonry.api)",
|
"file(pyproject.toml) | get(build-system.build-backend) | equal(poetry.core.masonry.api)",
|
||||||
@@ -11,12 +12,14 @@ commands = [
|
|||||||
"poetry install",
|
"poetry install",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# build
|
||||||
[presets.python.tasks.build.poetry]
|
[presets.python.tasks.build.poetry]
|
||||||
conditions = [
|
conditions = [
|
||||||
"file(pyproject.toml) | get(build-system.build-backend) | equal(poetry.core.masonry.api)",
|
"file(pyproject.toml) | get(build-system.build-backend) | equal(poetry.core.masonry.api)",
|
||||||
]
|
]
|
||||||
commands = ["poetry build"]
|
commands = ["poetry build"]
|
||||||
|
|
||||||
|
# publish
|
||||||
[presets.python.tasks.publish.poetry]
|
[presets.python.tasks.publish.poetry]
|
||||||
conditions = [
|
conditions = [
|
||||||
"file(pyproject.toml) | get(build-system.build-backend) | equal(poetry.core.masonry.api)",
|
"file(pyproject.toml) | get(build-system.build-backend) | equal(poetry.core.masonry.api)",
|
||||||
@@ -25,10 +28,12 @@ conditions = [
|
|||||||
variables.python_repository = "file(poetry.toml) | get(repositories) | key(0)"
|
variables.python_repository = "file(poetry.toml) | get(repositories) | key(0)"
|
||||||
commands = ["poetry publish -r {python_repository}"]
|
commands = ["poetry publish -r {python_repository}"]
|
||||||
|
|
||||||
|
# test
|
||||||
[presets.python.tasks.test.pytest]
|
[presets.python.tasks.test.pytest]
|
||||||
conditions = ["file(.venv/bin/pytest)"]
|
conditions = ["file(.venv/bin/pytest)"]
|
||||||
commands = [".venv/bin/python -m pytest"]
|
commands = [".venv/bin/python -m pytest"]
|
||||||
|
|
||||||
|
# lint
|
||||||
[presets.python.tasks.lint.pylint]
|
[presets.python.tasks.lint.pylint]
|
||||||
conditions = ["file(.venv/bin/pylint)"]
|
conditions = ["file(.venv/bin/pylint)"]
|
||||||
commands = [".venv/bin/pylint ./"]
|
commands = [".venv/bin/pylint ./"]
|
||||||
@@ -37,18 +42,20 @@ commands = [".venv/bin/pylint ./"]
|
|||||||
conditions = ["file(.venv/bin/isort)"]
|
conditions = ["file(.venv/bin/isort)"]
|
||||||
commands = [".venv/bin/isort --profile black --check-only ./"]
|
commands = [".venv/bin/isort --profile black --check-only ./"]
|
||||||
|
|
||||||
[presets.python.tasks.format.isort]
|
|
||||||
conditions = ["file(.venv/bin/isort)"]
|
|
||||||
commands = [".venv/bin/isort --profile black ./"]
|
|
||||||
|
|
||||||
[presets.python.tasks.lint.black]
|
[presets.python.tasks.lint.black]
|
||||||
conditions = ["file(.venv/bin/black)"]
|
conditions = ["file(.venv/bin/black)"]
|
||||||
commands = [".venv/bin/black --check --diff ./"]
|
commands = [".venv/bin/black --check --diff ./"]
|
||||||
|
|
||||||
|
# format
|
||||||
|
[presets.python.tasks.format.isort]
|
||||||
|
conditions = ["file(.venv/bin/isort)"]
|
||||||
|
commands = [".venv/bin/isort --profile black ./"]
|
||||||
|
|
||||||
[presets.python.tasks.format.black]
|
[presets.python.tasks.format.black]
|
||||||
conditions = ["file(.venv/bin/black)"]
|
conditions = ["file(.venv/bin/black)"]
|
||||||
commands = [".venv/bin/black ./"]
|
commands = [".venv/bin/black ./"]
|
||||||
|
|
||||||
|
# clean
|
||||||
[presets.python.tasks.clean.venv]
|
[presets.python.tasks.clean.venv]
|
||||||
conditions = ["file(.venv)"]
|
conditions = ["file(.venv)"]
|
||||||
commands = ["rm -rf .venv"]
|
commands = ["rm -rf .venv"]
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ class PresetResolver:
|
|||||||
if self._config.default:
|
if self._config.default:
|
||||||
yield from (Path(__file__).parent / "default").iterdir()
|
yield from (Path(__file__).parent / "default").iterdir()
|
||||||
if self._config.user:
|
if self._config.user:
|
||||||
user_preset = Path.home() / ".preset.toml"
|
user_preset = Path.home() / ".pm.toml"
|
||||||
if user_preset.exists():
|
if user_preset.exists():
|
||||||
yield user_preset
|
yield user_preset
|
||||||
if self._config.project:
|
if self._config.project:
|
||||||
projectpath = self._basepath
|
projectpath = self._basepath
|
||||||
while projectpath.exists():
|
while projectpath.exists():
|
||||||
project_preset = projectpath / ".preset.toml"
|
project_preset = projectpath / ".pm.toml"
|
||||||
if project_preset.exists():
|
if project_preset.exists():
|
||||||
yield project_preset
|
yield project_preset
|
||||||
if projectpath.parent == projectpath:
|
if projectpath.parent == projectpath:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from argparse import ArgumentParser
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Self
|
from typing import Self
|
||||||
|
|
||||||
from .common.logging_custom import CustomFormatter
|
from .common.logging_colored import ColoredFormatter
|
||||||
from .manager import ProjectManager
|
from .manager import ProjectManager
|
||||||
|
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ class ProjectManagerRunner:
|
|||||||
logging_level = logging.CRITICAL
|
logging_level = logging.CRITICAL
|
||||||
|
|
||||||
stdout_handler = logging.StreamHandler()
|
stdout_handler = logging.StreamHandler()
|
||||||
stdout_handler.setFormatter(CustomFormatter("%(message)s"))
|
stdout_handler.setFormatter(ColoredFormatter("%(message)s"))
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level=logging_level,
|
level=logging_level,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ dependencies = [
|
|||||||
"termcolor (>=3.3.0,<4.0.0)",
|
"termcolor (>=3.3.0,<4.0.0)",
|
||||||
"pydantic (>=2.13.4,<3.0.0)",
|
"pydantic (>=2.13.4,<3.0.0)",
|
||||||
"tomli (>=2.4.1,<3.0.0)",
|
"tomli (>=2.4.1,<3.0.0)",
|
||||||
|
"dotenv (>=0.9.9,<0.10.0)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
import project_manager.common.logging_custom
|
import project_manager.common.logging_colored
|
||||||
|
|||||||
Reference in New Issue
Block a user