Compare commits

...

5 Commits
0.3.3 ... 0.4.0

Author SHA1 Message Date
jpk cbb8b7bbfd Version bump 0.4.0 2023-01-13 15:05:49 +01:00
jpk 36db6d8034 Added help to commands 2023-01-13 15:03:30 +01:00
jpk 85c847200c decorator to check if compose file exists 2023-01-13 15:00:31 +01:00
jpk 74e8410af6 removed unused ctx 2023-01-12 15:54:31 +01:00
jpk 4c7bd3cf17 removed dependency to xdg 2023-01-12 15:48:07 +01:00
7 changed files with 76 additions and 41 deletions

View File

@ -40,9 +40,10 @@ Options:
--help Show this message and exit. --help Show this message and exit.
Commands: Commands:
control control run docker-compose commands
edit edit edit the compose file
list list list available services
update pull the latest service images and restart
``` ```
## Examples ## Examples

View File

@ -1 +1 @@
__version__ = "0.3.3" __version__ = "0.4.0"

View File

@ -3,6 +3,7 @@ from pathlib import Path
import click import click
from rich import print from rich import print
from rich.rule import Rule
from rich.tree import Tree from rich.tree import Tree
from doxy import services from doxy import services
@ -23,9 +24,9 @@ def main(ctx):
ctx.obj["CONFIG"] = CONFIG ctx.obj["CONFIG"] = CONFIG
@click.command() @click.command(help="list available services")
@click.pass_context def list():
def list(ctx): print(Rule(f"Listing services"))
tree = Tree("[bold]Available Services") tree = Tree("[bold]Available Services")
for service in services.find_services(Path(CONFIG.root_directory)): for service in services.find_services(Path(CONFIG.root_directory)):
tree.add(service) tree.add(service)
@ -40,39 +41,64 @@ def complete_service_name(ctx, param, incomplete):
] ]
@click.command() @click.command(help="edit the compose file")
@click.argument("service", nargs=1, shell_complete=complete_service_name) @click.argument("service", nargs=1, shell_complete=complete_service_name)
@click.pass_context @click.pass_context
@services.only_if_service_exists
def edit(ctx, service): def edit(ctx, service):
try: print(Rule(f"Editing {service}"))
compose_file = services.get_compose_file( compose_file = services.get_compose_file(
Path(ctx.obj["CONFIG"].root_directory) / service Path(ctx.obj["CONFIG"].root_directory) / service
) )
click.edit(filename=Path(compose_file)) click.edit(filename=Path(compose_file))
except FileNotFoundError:
click.echo(f"Service `{service}' not found", sys.stderr)
ctx.abort()
@click.command( @click.command(
context_settings=dict( context_settings=dict(
ignore_unknown_options=True, ignore_unknown_options=True,
) ),
help="run docker-compose commands",
) )
@click.argument("service", nargs=1, shell_complete=complete_service_name) @click.argument("service", nargs=1, shell_complete=complete_service_name)
@click.argument("command", nargs=-1) @click.argument("command", nargs=-1)
@click.pass_context @click.pass_context
@services.only_if_service_exists
def control(ctx, service, command): def control(ctx, service, command):
try: print(Rule(f"Controlling {service}"))
compose_file = services.get_compose_file( compose_file = services.get_compose_file(
Path(ctx.obj["CONFIG"].root_directory) / service Path(ctx.obj["CONFIG"].root_directory) / service
) )
services.docker_compose_command(command, compose_file) services.docker_compose_command(command, compose_file)
except FileNotFoundError:
click.echo(f"Service `{service}' not found", sys.stderr)
ctx.abort() @click.command("update", help="pull the latest service images and restart")
@click.argument("service", nargs=1, shell_complete=complete_service_name)
@click.option(
"--remove", "-r", is_flag=True, default=False, help="remove unused volumes"
)
@click.pass_context
@services.only_if_service_exists
def update(ctx, service, remove):
compose_file = services.get_compose_file(
Path(ctx.obj["CONFIG"].root_directory) / service
)
print(Rule(f"Updating {service}"))
services.docker_compose_command(
[
["stop", "down"][remove],
],
compose_file,
)
services.docker_compose_command(
[
"pull",
],
compose_file,
)
services.docker_compose_command(["up", "-d"], compose_file)
main.add_command(list) main.add_command(list)
main.add_command(edit) main.add_command(edit)
main.add_command(control) main.add_command(control)
main.add_command(update)

View File

@ -1,7 +1,7 @@
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from xdg import xdg_config_home from click import get_app_dir
from yamldataclassconfig import create_file_path_field from yamldataclassconfig import create_file_path_field
from yamldataclassconfig.config import YamlDataClassConfig from yamldataclassconfig.config import YamlDataClassConfig
@ -11,6 +11,4 @@ class Config(YamlDataClassConfig):
root_directory: str = "" root_directory: str = ""
compose_executable: str = "" compose_executable: str = ""
FILE_PATH: Path = create_file_path_field( FILE_PATH: Path = create_file_path_field(Path(get_app_dir("doxy")) / "config.yml")
Path(xdg_config_home()) / "doxy/config.yml"
)

View File

@ -1,11 +1,31 @@
import glob import glob
import subprocess import subprocess
import sys
from functools import update_wrapper
from pathlib import Path from pathlib import Path
from typing import List from typing import List
import click import click
def only_if_service_exists(fn):
def wrapper(*args, **kwargs):
ctx = args[0]
service = kwargs["service"]
try:
compose_file = get_compose_file(
Path(ctx.obj["CONFIG"].root_directory) / service
)
if not compose_file.exists():
raise FileNotFoundError()
except FileNotFoundError:
click.echo(f"Service `{service}' not found", sys.stderr)
ctx.abort()
return ctx.invoke(fn, *args, **kwargs)
return update_wrapper(wrapper, fn)
def find_services(root: Path) -> List[str]: def find_services(root: Path) -> List[str]:
return [_.split("/")[0] for _ in glob.glob("*/docker-compose.y*ml", root_dir=root)] return [_.split("/")[0] for _ in glob.glob("*/docker-compose.y*ml", root_dir=root)]

11
poetry.lock generated
View File

@ -314,14 +314,6 @@ category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "xdg"
version = "5.1.1"
description = "Variables defined by the XDG Base Directory Specification"
category = "main"
optional = false
python-versions = ">=3.6,<4.0"
[[package]] [[package]]
name = "yamldataclassconfig" name = "yamldataclassconfig"
version = "1.5.0" version = "1.5.0"
@ -337,7 +329,7 @@ pyyaml = "*"
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "170eebbe419588237954ba9ca730e93d253a3c4baba92e4a26a88eff89fce121" content-hash = "6bdfca3a7a9351058dae359dae3d4333b91187a9a5535eb3fc49d04ecb771c3c"
[metadata.files] [metadata.files]
atomicwrites = [] atomicwrites = []
@ -417,5 +409,4 @@ typing-extensions = []
typing-inspect = [] typing-inspect = []
virtualenv = [] virtualenv = []
wcwidth = [] wcwidth = []
xdg = []
yamldataclassconfig = [] yamldataclassconfig = []

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "doxy" name = "doxy"
version = "0.3.3" version = "0.4.0"
description = "" description = ""
authors = ["jpk <jpk@goatpr0n.de>"] authors = ["jpk <jpk@goatpr0n.de>"]
readme = "README.md" readme = "README.md"
@ -12,7 +12,6 @@ python = "^3.10"
click = "^8.1.3" click = "^8.1.3"
rich = "^13.0.1" rich = "^13.0.1"
yamldataclassconfig = "^1.5.0" yamldataclassconfig = "^1.5.0"
xdg = "^5.1.1"
[tool.poetry.scripts] [tool.poetry.scripts]
doxy = "doxy.cli:main" doxy = "doxy.cli:main"