add template generation functionality, version mapping
This commit is contained in:
parent
b565d99882
commit
433af79028
0
example/README.md
Normal file
0
example/README.md
Normal file
@ -8,5 +8,9 @@ from symconf import config
|
|||||||
from symconf import matching
|
from symconf import matching
|
||||||
from symconf import reader
|
from symconf import reader
|
||||||
from symconf import template
|
from symconf import template
|
||||||
from symconf import theme
|
|
||||||
from symconf import util
|
from symconf import util
|
||||||
|
|
||||||
|
from importlib.metadata import version
|
||||||
|
|
||||||
|
|
||||||
|
__version__ = version('symconf')
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
from importlib.metadata import version
|
||||||
|
|
||||||
from symconf import util
|
from symconf import util, __version__
|
||||||
from symconf.config import ConfigManager
|
from symconf.config import ConfigManager
|
||||||
|
|
||||||
|
|
||||||
@ -85,6 +86,34 @@ def add_config_subparser(subparsers):
|
|||||||
)
|
)
|
||||||
parser.set_defaults(func=configure_apps)
|
parser.set_defaults(func=configure_apps)
|
||||||
|
|
||||||
|
def add_generate_subparser(subparsers):
|
||||||
|
def generate_apps(args):
|
||||||
|
cm = ConfigManager(args.config_dir)
|
||||||
|
cm.generate_app_templates(
|
||||||
|
gen_dir=args.gen_dir,
|
||||||
|
apps=args.apps,
|
||||||
|
)
|
||||||
|
|
||||||
|
parser = subparsers.add_parser(
|
||||||
|
'generate',
|
||||||
|
description='Generate all template config files for specified apps'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-g', '--gen-dir',
|
||||||
|
required = True,
|
||||||
|
type = util.absolute_path,
|
||||||
|
help = 'Path to write generated template files'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-a', '--apps',
|
||||||
|
required = False,
|
||||||
|
default = "*",
|
||||||
|
type = lambda s: s.split(',') if s != '*' else s,
|
||||||
|
help = 'Application target for theme. App must be present in the registry. ' \
|
||||||
|
+ 'Use "*" to apply to all registered apps'
|
||||||
|
)
|
||||||
|
parser.set_defaults(func=generate_apps)
|
||||||
|
|
||||||
|
|
||||||
# central argparse entry point
|
# central argparse entry point
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
@ -97,12 +126,19 @@ parser.add_argument(
|
|||||||
type = util.absolute_path,
|
type = util.absolute_path,
|
||||||
help = 'Path to config directory'
|
help = 'Path to config directory'
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-v', '--version',
|
||||||
|
action='version',
|
||||||
|
version=__version__,
|
||||||
|
help = 'Print symconf version'
|
||||||
|
)
|
||||||
|
|
||||||
# add subparsers
|
# add subparsers
|
||||||
subparsers = parser.add_subparsers(title='subcommand actions')
|
subparsers = parser.add_subparsers(title='subcommand actions')
|
||||||
|
add_config_subparser(subparsers)
|
||||||
|
add_generate_subparser(subparsers)
|
||||||
add_install_subparser(subparsers)
|
add_install_subparser(subparsers)
|
||||||
add_update_subparser(subparsers)
|
add_update_subparser(subparsers)
|
||||||
add_config_subparser(subparsers)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -346,6 +346,45 @@ class ConfigManager:
|
|||||||
|
|
||||||
return template_dict, relaxed_theme_matches
|
return template_dict, relaxed_theme_matches
|
||||||
|
|
||||||
|
def _prepare_all_templates(self) -> dict[str, dict]:
|
||||||
|
palette_map = {}
|
||||||
|
palette_group_dir = Path(self.group_dir, 'palette')
|
||||||
|
if palette_group_dir.exists():
|
||||||
|
for palette_path in palette_group_dir.iterdir():
|
||||||
|
palette_map[palette_path.stem] = palette_path
|
||||||
|
|
||||||
|
palette_base = []
|
||||||
|
if 'none' in palette_map:
|
||||||
|
palette_base.append(palette_map['none'])
|
||||||
|
|
||||||
|
# then palette-scheme groups (require 2-combo logic)
|
||||||
|
theme_map = {}
|
||||||
|
theme_group_dir = Path(self.group_dir, 'theme')
|
||||||
|
if theme_group_dir.exists():
|
||||||
|
for theme_toml in theme_group_dir.iterdir():
|
||||||
|
fp = FilePart(theme_toml)
|
||||||
|
|
||||||
|
theme_matches = self.matcher.match_paths(
|
||||||
|
theme_group_dir.iterdir(), # match files in groups/theme/
|
||||||
|
self.matcher.prefix_order(fp.scheme, fp.style) # reg non-template order
|
||||||
|
)
|
||||||
|
relaxed_theme_matches = self.matcher.relaxed_match(theme_matches)
|
||||||
|
|
||||||
|
palette = fp.style.split('-')[-1]
|
||||||
|
palette_paths = [*palette_base]
|
||||||
|
if palette in palette_map:
|
||||||
|
palette_paths.append(palette_map[palette])
|
||||||
|
|
||||||
|
theme_dict = {}
|
||||||
|
palette_dict = TOMLTemplate.stack_toml(palette_paths)
|
||||||
|
for file_part in relaxed_theme_matches:
|
||||||
|
toml_dict = TOMLTemplate(file_part.path).fill(palette_dict)
|
||||||
|
theme_dict = util.deep_update(theme_dict, toml_dict)
|
||||||
|
|
||||||
|
theme_map[fp.path.stem] = {'theme': theme_dict}
|
||||||
|
|
||||||
|
return theme_map
|
||||||
|
|
||||||
def get_matching_configs(
|
def get_matching_configs(
|
||||||
self,
|
self,
|
||||||
app_name,
|
app_name,
|
||||||
@ -764,3 +803,55 @@ class ConfigManager:
|
|||||||
apps: str | list[str] = '*',
|
apps: str | list[str] = '*',
|
||||||
):
|
):
|
||||||
self._app_action('update.sh', apps)
|
self._app_action('update.sh', apps)
|
||||||
|
|
||||||
|
def generate_app_templates(
|
||||||
|
self,
|
||||||
|
gen_dir : str | Path,
|
||||||
|
apps : str | list[str] = '*',
|
||||||
|
):
|
||||||
|
if apps == '*':
|
||||||
|
app_list = list(self.app_registry.keys())
|
||||||
|
else:
|
||||||
|
app_list = [a for a in apps if a in self.app_registry]
|
||||||
|
|
||||||
|
if not app_list:
|
||||||
|
print(f'None of the apps "{apps}" are registered, exiting')
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f'> symconf parameters: ')
|
||||||
|
print(f' > registered apps :: {color_text(app_list, Fore.YELLOW)}')
|
||||||
|
print(f'> Writing templates...')
|
||||||
|
|
||||||
|
gen_dir = util.absolute_path(gen_dir)
|
||||||
|
theme_map = self._prepare_all_templates()
|
||||||
|
|
||||||
|
for app_name in app_list:
|
||||||
|
app_template_dir = Path(self.apps_dir, app_name, 'templates')
|
||||||
|
if not app_template_dir.exists():
|
||||||
|
continue
|
||||||
|
|
||||||
|
app_template_files = list(app_template_dir.iterdir())
|
||||||
|
|
||||||
|
print(
|
||||||
|
color_text("├─", Fore.BLUE),
|
||||||
|
f'{app_name} :: generating ({len(app_template_files)}) template files'
|
||||||
|
)
|
||||||
|
|
||||||
|
for template_file in app_template_files:
|
||||||
|
app_template = FileTemplate(template_file)
|
||||||
|
|
||||||
|
for theme_stem, theme_dict in theme_map.items():
|
||||||
|
tgt_template_dir = Path(gen_dir, app_name)
|
||||||
|
tgt_template_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
tgt_template_path = Path(
|
||||||
|
tgt_template_dir,
|
||||||
|
f'{theme_stem}.{template_file.name}'
|
||||||
|
)
|
||||||
|
filled_template = app_template.fill(theme_dict)
|
||||||
|
tgt_template_path.write_text(filled_template)
|
||||||
|
|
||||||
|
print(
|
||||||
|
color_text("│", Fore.BLUE),
|
||||||
|
f'> generating "{tgt_template_path.name}"'
|
||||||
|
)
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
import argparse
|
|
||||||
import inspect
|
|
||||||
import json
|
|
||||||
import tomllib as toml
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
|
|
||||||
# separation sequences to use base on app
|
|
||||||
app_sep_map = {
|
|
||||||
'kitty': ' ',
|
|
||||||
}
|
|
||||||
|
|
||||||
def generate_theme_files():
|
|
||||||
basepath = get_running_path()
|
|
||||||
|
|
||||||
# set arg conditional variables
|
|
||||||
palette_path = Path(basepath, 'themes', args.palette)
|
|
||||||
colors_path = Path(palette_path, 'colors.json')
|
|
||||||
theme_app = args.app
|
|
||||||
|
|
||||||
template_path = None
|
|
||||||
output_path = None
|
|
||||||
|
|
||||||
if args.template is None:
|
|
||||||
template_path = Path(palette_path, 'apps', theme_app, 'templates')
|
|
||||||
else:
|
|
||||||
template_path = Path(args.template).resolve()
|
|
||||||
|
|
||||||
if args.output is None:
|
|
||||||
output_path = Path(palette_path, 'apps', theme_app, 'generated')
|
|
||||||
else:
|
|
||||||
output_path = Path(args.output).resolve()
|
|
||||||
|
|
||||||
# check paths
|
|
||||||
if not colors_path.exists():
|
|
||||||
print(f'Resolved colors path [{colors_path}] doesn\'t exist, exiting')
|
|
||||||
return
|
|
||||||
|
|
||||||
if not template_path.exists():
|
|
||||||
print(f'Template path [{template_path}] doesn\'t exist, exiting')
|
|
||||||
return
|
|
||||||
|
|
||||||
if not output_path.exists() or not output_path.is_dir():
|
|
||||||
print(f'Output path [{output_path}] doesn\'t exist or not a directory, exiting')
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f'Using palette colors [{colors_path}]')
|
|
||||||
print(f'-> with templates in [{template_path}]')
|
|
||||||
print(f'-> to output path [{output_path}]\n')
|
|
||||||
|
|
||||||
# load external files (JSON, TOML)
|
|
||||||
colors_json = json.load(colors_path.open())
|
|
||||||
|
|
||||||
# get all matching TOML files
|
|
||||||
template_list = [template_path]
|
|
||||||
if template_path.is_dir():
|
|
||||||
template_list = template_path.rglob('*.toml')
|
|
||||||
|
|
||||||
for template_path in template_list:
|
|
||||||
template_toml = toml.load(template_path.open('rb'))
|
|
||||||
|
|
||||||
# lookup app-specific config separator
|
|
||||||
config_sep = app_sep_map.get(theme_app, ' ')
|
|
||||||
output_lines = []
|
|
||||||
for config_key, color_key in template_toml.items():
|
|
||||||
color_value = colors_json
|
|
||||||
for _key in color_key.split('.'):
|
|
||||||
color_value = color_value.get(_key, {})
|
|
||||||
output_lines.append(f'{config_key}{config_sep}{color_value}')
|
|
||||||
|
|
||||||
output_file = Path(output_path, template_path.stem).with_suffix('.conf')
|
|
||||||
output_file.write_text('\n'.join(output_lines))
|
|
||||||
print(f'[{len(output_lines)}] lines written to [{output_file}] for app [{theme_app}]')
|
|
||||||
|
|
@ -7,5 +7,4 @@ def test_imports():
|
|||||||
|
|
||||||
from symconf import config
|
from symconf import config
|
||||||
from symconf import reader
|
from symconf import reader
|
||||||
from symconf import theme
|
|
||||||
from symconf import util
|
from symconf import util
|
||||||
|
Loading…
Reference in New Issue
Block a user