mirror of
ssh://git.janware.com/srv/git/janware/proj/jw-python
synced 2026-01-15 09:53:32 +01:00
Cmd / Cmds: Add config file support
An application based on Cmds will now try to read StringTree formatted config data from a file $HOME/.<name>rc, and make the data available via the newly added conf_value() method. Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
b7de950750
commit
a4fb791649
2 changed files with 31 additions and 0 deletions
|
|
@ -22,6 +22,7 @@ class Cmd(abc.ABC): # export
|
||||||
self.parent = None
|
self.parent = None
|
||||||
self.children: List[Cmd] = []
|
self.children: List[Cmd] = []
|
||||||
self.child_classes: List[Type[Cmd]] = []
|
self.child_classes: List[Type[Cmd]] = []
|
||||||
|
self.app: Optional[Cmds] = None
|
||||||
|
|
||||||
async def _run(self, args):
|
async def _run(self, args):
|
||||||
pass
|
pass
|
||||||
|
|
@ -52,3 +53,9 @@ class Cmd(abc.ABC): # export
|
||||||
# Will be called from App base class constructor and set up the parser hierarchy
|
# Will be called from App base class constructor and set up the parser hierarchy
|
||||||
def add_arguments(self, parser: ArgumentParser) -> None:
|
def add_arguments(self, parser: ArgumentParser) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def conf_value(self, path, default=None):
|
||||||
|
ret = None if self.app is None else self.app.conf_value(path, default)
|
||||||
|
if ret is None and default is not None:
|
||||||
|
return default
|
||||||
|
return ret
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,11 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
import os, sys, argcomplete, argparse, importlib, inspect, re, pickle, asyncio, cProfile
|
import os, sys, argcomplete, argparse, importlib, inspect, re, pickle, asyncio, cProfile
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
from pathlib import Path, PurePath
|
||||||
|
|
||||||
import jwutils
|
import jwutils
|
||||||
from jwutils.log import *
|
from jwutils.log import *
|
||||||
|
from jwutils.stree import serdes
|
||||||
|
|
||||||
class Cmds: # export
|
class Cmds: # export
|
||||||
|
|
||||||
|
|
@ -30,10 +32,19 @@ class Cmds: # export
|
||||||
for sub_cmd in cmd.children:
|
for sub_cmd in cmd.children:
|
||||||
self.__add_cmd_to_parser(sub_cmd, subparsers)
|
self.__add_cmd_to_parser(sub_cmd, subparsers)
|
||||||
|
|
||||||
|
def __parse_config(self):
|
||||||
|
exe_stem = str(PurePath(sys.argv[0]).stem)
|
||||||
|
path = str(Path.home()) + '/.' + exe_stem + 'rc'
|
||||||
|
if not os.path.exists(path):
|
||||||
|
return None, []
|
||||||
|
slog(DEBUG, 'Reading configuration "{}"'.format(path))
|
||||||
|
return serdes.read(path, ''), [path]
|
||||||
|
|
||||||
def __init__(self, description: str = '', filter: str = '^Cmd.*', modules: None=None, eloop: None=None) -> None:
|
def __init__(self, description: str = '', filter: str = '^Cmd.*', modules: None=None, eloop: None=None) -> None:
|
||||||
self.__description = description
|
self.__description = description
|
||||||
self.__filter = filter
|
self.__filter = filter
|
||||||
self.__modules = modules
|
self.__modules = modules
|
||||||
|
self.__conf, self.__conf_paths = self.__parse_config()
|
||||||
self.__cmds = []
|
self.__cmds = []
|
||||||
self.eloop = eloop
|
self.eloop = eloop
|
||||||
self.__own_eloop = False
|
self.__own_eloop = False
|
||||||
|
|
@ -43,6 +54,7 @@ class Cmds: # export
|
||||||
|
|
||||||
log_level = "notice"
|
log_level = "notice"
|
||||||
log_flags = 'stderr,position,prio,color'
|
log_flags = 'stderr,position,prio,color'
|
||||||
|
log_file = None
|
||||||
# poor man's parsing in the absence of a complete command-line definition
|
# poor man's parsing in the absence of a complete command-line definition
|
||||||
for i in range(1, len(sys.argv)):
|
for i in range(1, len(sys.argv)):
|
||||||
if i >= len(sys.argv) - 1:
|
if i >= len(sys.argv) - 1:
|
||||||
|
|
@ -64,6 +76,7 @@ class Cmds: # export
|
||||||
self.__parser.add_argument('--log-level', help='Log level', default=log_level)
|
self.__parser.add_argument('--log-level', help='Log level', default=log_level)
|
||||||
self.__parser.add_argument('--backtrace', help='Show exception backtraces', action='store_true', default=False)
|
self.__parser.add_argument('--backtrace', help='Show exception backtraces', action='store_true', default=False)
|
||||||
self.__parser.add_argument('--write-profile', help='Profile code and store output to file', default=None)
|
self.__parser.add_argument('--write-profile', help='Profile code and store output to file', default=None)
|
||||||
|
self.__parser.add_argument('--log-file', help='Log file', default=log_file)
|
||||||
if self.__modules == None:
|
if self.__modules == None:
|
||||||
self.__modules = [ '__main__' ]
|
self.__modules = [ '__main__' ]
|
||||||
subcmds = set()
|
subcmds = set()
|
||||||
|
|
@ -118,6 +131,11 @@ class Cmds: # export
|
||||||
if pr is not None:
|
if pr is not None:
|
||||||
pr.enable()
|
pr.enable()
|
||||||
|
|
||||||
|
if self.__conf:
|
||||||
|
self.__conf.dump(DEBUG, "Configuration")
|
||||||
|
if self.args.log_file is not None:
|
||||||
|
add_log_file(self.args.log_file)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ret = await self._run(self.args)
|
ret = await self._run(self.args)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -144,6 +162,12 @@ class Cmds: # export
|
||||||
self.eloop = None
|
self.eloop = None
|
||||||
self.__own_eloop = False
|
self.__own_eloop = False
|
||||||
|
|
||||||
|
def conf_value(self, path, default=None):
|
||||||
|
ret = None if self.__conf is None else self.__conf.value(path)
|
||||||
|
if ret is None and default is not None:
|
||||||
|
return default
|
||||||
|
return ret
|
||||||
|
|
||||||
def parser(self) -> ArgumentParser:
|
def parser(self) -> ArgumentParser:
|
||||||
return self.__parser
|
return self.__parser
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue