Source code for doot.cmds._base

  1#!/usr/bin/env python3
  2"""
  3
  4"""
  5
  6# Imports:
  7from __future__ import annotations
  8
  9# ##-- stdlib imports
 10import datetime
 11import enum
 12import functools as ftz
 13import itertools as itz
 14import logging as logmod
 15import pathlib as pl
 16import re
 17import time
 18import types
 19import typing
 20import weakref
 21from uuid import UUID, uuid1
 22
 23# ##-- end stdlib imports
 24
 25# ##-- 3rd party imports
 26from jgdv import Mixin, Proto
 27from jgdv.cli import ParamSpecMaker_m
 28# ##-- end 3rd party imports
 29
 30# ##-- 1st party imports
 31import doot
 32from ._interface import Command_p
 33
 34# ##-- end 1st party imports
 35
 36# ##-- types
 37# isort: off
 38import abc
 39import collections.abc
 40from typing import TYPE_CHECKING, cast, assert_type, assert_never
 41from typing import Generic, NewType
 42# Protocols:
 43from typing import Protocol, runtime_checkable
 44# Typing Decorators:
 45from typing import no_type_check, final, override, overload
 46
 47if TYPE_CHECKING:
 48    from jgdv.cli import ParamSpec_p
 49    from jgdv import Maybe, Lambda
 50    from jgdv.structs.chainguard import ChainGuard
 51    from typing import Final
 52    from typing import ClassVar, Any, LiteralString
 53    from typing import Never, Self, Literal
 54    from typing import TypeGuard
 55    from collections.abc import Iterable, Iterator, Callable, Generator
 56    from collections.abc import Sequence, Mapping, MutableMapping, Hashable
 57
 58    from doot.errors import DootError
 59    type ListVal = Maybe[str|Lambda|tuple[str,dict]]
 60
 61# isort: on
 62# ##-- end types
 63
 64##-- logging
 65logging = logmod.getLogger(__name__)
 66##-- end logging
 67
[docs] 68@Proto(Command_p, check=False) 69@Mixin(ParamSpecMaker_m) 70class BaseCommand: 71 """ Generic implementations of command methods """ 72 build_param : Callable 73 _help : ClassVar[tuple[str, ...]] 74 75 def __init__(self, name:Maybe[str]=None): 76 self._name = name 77
[docs] 78 @property 79 def name(self) -> str: 80 """get command name as used from command line""" 81 return self._name or self.__class__.__name__.lower()
82
[docs] 83 @property 84 def help(self) -> list[str]: 85 help_lines : list[str] = [ 86 "", f"Command: {self.name}", "", 87 *list(self._help or []), 88 ] 89 90 params = self.param_specs() 91 if bool(params): 92 key_func = params[0].key_func 93 help_lines += ["", "Params:"] 94 help_lines += filter(lambda x: bool(x), (x.help_str() for x in sorted(self.param_specs(), key=key_func))) # type: ignore[arg-type] 95 96 return help_lines
97
[docs] 98 @property 99 def helpline(self) -> str: 100 """ get just the first line of the help text """ 101 match self._help: 102 case [x, *_]: 103 return f" {self.name: <10} : {x}" 104 case _: 105 return f" {self.name: <10} :"
106
[docs] 107 def param_specs(self) -> list[ParamSpec_p]: 108 """ 109 Provide parameter specs for parsing into doot.args.cmds 110 """ 111 return [ 112 self.build_param(name="--help", default=False, implicit=True), 113 self.build_param(name="--debug", default=False, implicit=True), 114 ]
115
[docs] 116 def _print_text(self, text:Iterable[ListVal]) -> None: 117 """ Utility method to print text out at the user level """ 118 match text: 119 case str(): 120 text = [text] 121 case [*_]: 122 pass 123 case x: 124 raise doot.errors.CommandError("Unknown type tried to be printed", x) 125 126 for line in text: 127 match line: 128 case str(): 129 doot.report.gen.user(line) 130 case (str() as s, dict() as d): 131 doot.report.gen.user(s, extra=d) 132 case None: 133 doot.report.gen.user("")
134 135 136
[docs] 137 def shutdown(self, tasks:ChainGuard, plugins:ChainGuard, errored:Maybe[DootError]=None) -> None: 138 pass