Improve Python config file template substitution #8
1 changed files with 42 additions and 37 deletions
cmds.projects.CmdCreateFile: Add more options
- Add an additional, more generic value that --format understands: "tmpl". If chosen, the template selected by the new option --template-name is rendered by replacing --field key=value pairs.- This commit also adds the option --quote, which makes the renderer enclose the rendered variable values in double quotes.Signed-off-by: Jan Lindemann <jan@janware.com>
commit
da877c624f
|
|
@ -1,11 +1,10 @@
|
||||||
from argparse import ArgumentParser, ArgumentTypeError, Namespace
|
from argparse import ArgumentParser, ArgumentTypeError, Namespace
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from typing import Iterable, TypeAlias
|
|
||||||
|
|
||||||
from ...lib.log import WARNING, log
|
from ...lib.log import WARNING, log
|
||||||
from .Cmd import Cmd, Parent
|
from .Cmd import Cmd, Parent
|
||||||
from .lib.pkg_relations import VersionSyntax, pkg_relations
|
from .lib.pkg_relations import VersionSyntax, pkg_relations
|
||||||
from .lib.templates import RenderValues, tmpl_render
|
from .lib.templates import ListDict, RenderValues, tmpl_render
|
||||||
|
|
||||||
def key_value(s):
|
def key_value(s):
|
||||||
try:
|
try:
|
||||||
|
|
@ -18,24 +17,26 @@ def key_value(s):
|
||||||
class Fmt(Enum):
|
class Fmt(Enum):
|
||||||
Pyright = auto()
|
Pyright = auto()
|
||||||
|
|
||||||
TupleList: TypeAlias = Iterable[tuple[str, str]]
|
|
||||||
ListDict: TypeAlias = dict[str, list[str]]
|
|
||||||
|
|
||||||
class CmdCreateFile(Cmd): # export
|
class CmdCreateFile(Cmd): # export
|
||||||
|
|
||||||
def __tuple_list_to_dict(self, src: TupleList) -> ListDict:
|
def __jw_required(self, module: str | None = None) -> list[str]:
|
||||||
ret: ListDict = {}
|
if module is None:
|
||||||
for key, val in src:
|
module = self.app.args.module
|
||||||
entry = ret.setdefault(key, [])
|
if module is None:
|
||||||
entry.append(val)
|
raise Exception('Can\'t get required packages without module name')
|
||||||
return ret
|
return pkg_relations(
|
||||||
|
self.app,
|
||||||
def __update_dict(self, dst: ListDict, src: TupleList) -> ListDict:
|
rel_type = 'requires',
|
||||||
ret = dst
|
flavours = ['run'],
|
||||||
for key, val in src:
|
subsections = ['jw'],
|
||||||
entry = ret.setdefault(key, [])
|
seed_pkgs = [module],
|
||||||
entry.append(val)
|
syntax = VersionSyntax.names_only,
|
||||||
return ret
|
no_subpackages = True,
|
||||||
|
recursive = True,
|
||||||
|
quote = False,
|
||||||
|
hide_self = False,
|
||||||
|
hide_jw_pkg = False,
|
||||||
|
)
|
||||||
|
|
||||||
def __render(
|
def __render(
|
||||||
self,
|
self,
|
||||||
|
|
@ -52,23 +53,19 @@ class CmdCreateFile(Cmd): # export
|
||||||
search_path = self.app.args.search_path.split(':'),
|
search_path = self.app.args.search_path.split(':'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def render_pyright(self, module: str, extra_fields: TupleList) -> str:
|
def render_tmpl(self, module: str, extra_fields: RenderValues) -> str:
|
||||||
prereq = pkg_relations(
|
template_name = self.app.args.template_name
|
||||||
self.app,
|
if template_name is None:
|
||||||
rel_type = 'requires',
|
raise Exception('Can\'t render template without name')
|
||||||
flavours = ['run'],
|
return self.__render(
|
||||||
subsections = ['jw'],
|
template_name, [extra_fields],
|
||||||
seed_pkgs = [module],
|
li_quote = self.app.args.quote,
|
||||||
syntax = VersionSyntax.names_only,
|
li_delimiter = ',\n'
|
||||||
no_subpackages = True,
|
|
||||||
recursive = True,
|
|
||||||
quote = False,
|
|
||||||
hide_self = False,
|
|
||||||
hide_jw_pkg = False,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def render_pyright(self, module: str, extra_fields: RenderValues) -> str:
|
||||||
extra_paths = []
|
extra_paths = []
|
||||||
for m in prereq:
|
for m in self.__jw_required():
|
||||||
path = self.app.find_dir(m, search_subdirs = ['src/python', 'tools/python'])
|
path = self.app.find_dir(m, search_subdirs = ['src/python', 'tools/python'])
|
||||||
if path is None:
|
if path is None:
|
||||||
log(WARNING, f'No project directory for module "{m}"')
|
log(WARNING, f'No project directory for module "{m}"')
|
||||||
|
|
@ -77,10 +74,10 @@ class CmdCreateFile(Cmd): # export
|
||||||
values: ListDict = {
|
values: ListDict = {
|
||||||
'extra_paths': extra_paths,
|
'extra_paths': extra_paths,
|
||||||
}
|
}
|
||||||
self.__update_dict(values, extra_fields)
|
|
||||||
|
|
||||||
return self.__render(
|
return self.__render(
|
||||||
'pyrightconfig.json', [values], li_quote = True, li_delimiter = ',\n'
|
'pyrightconfig.json', [values, extra_fields],
|
||||||
|
li_quote = True,
|
||||||
|
li_delimiter = ',\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, parent: Parent) -> None:
|
def __init__(self, parent: Parent) -> None:
|
||||||
|
|
@ -92,14 +89,22 @@ class CmdCreateFile(Cmd): # export
|
||||||
super().add_arguments(parser)
|
super().add_arguments(parser)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--format',
|
'--format',
|
||||||
choices = [fmt.name.lower() for fmt in Fmt],
|
help = (
|
||||||
help = 'Output format'
|
'Output format, for example: '
|
||||||
|
', '.join([fmt.name.lower() for fmt in Fmt])
|
||||||
|
)
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--search-path',
|
'--search-path',
|
||||||
default = '/etc/opt/jw-pkg/templates',
|
default = '/etc/opt/jw-pkg/templates',
|
||||||
help = 'Template search path, colon separated',
|
help = 'Template search path, colon separated',
|
||||||
)
|
)
|
||||||
|
parser.add_argument('--template-name', help = 'Template file name')
|
||||||
|
parser.add_argument(
|
||||||
|
'--quote',
|
||||||
|
action = 'store_true',
|
||||||
|
help = 'Enclose variable values in double quotes before substituting'
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-f',
|
'-f',
|
||||||
'--field',
|
'--field',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue