feat: add docker preset

This commit is contained in:
2026-08-01 21:06:30 +03:00
parent 9a9338cfdc
commit 48f8b2d5a9
13 changed files with 80 additions and 31 deletions
+2 -2
View File
@@ -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
View File
@@ -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"
@@ -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
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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
+12 -16
View File
@@ -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"]
+11 -4
View File
@@ -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"]
+2 -2
View File
@@ -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:
+2 -2
View File
@@ -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,
+1
View File
@@ -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
View File
@@ -1 +1 @@
import project_manager.common.logging_custom import project_manager.common.logging_colored