Start work on config infrastructure for ssh kitten

This commit is contained in:
Kovid Goyal
2022-02-25 15:14:10 +05:30
parent 5c8651c7cd
commit 846021296f
10 changed files with 211 additions and 3 deletions

View File

View File

@@ -0,0 +1,29 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
# After editing this file run ./gen-config.py to apply the changes
from kitty.conf.types import Definition
definition = Definition(
'kittens.ssh',
)
agr = definition.add_group
egr = definition.end_group
opt = definition.add_option
agr('global', 'Global') # {{{
opt('hostname', '*', option_type='hostname',
long_text='''
The hostname the following options apply to. A glob pattern to match multiple
hosts can be used. When not specified options apply to all hosts, until the
first hostname specification is found. Note that the hostname this matches
against is the hostname used by the remote computer, not the name you pass
to SSH to connect to it.
'''
)
egr() # }}}

View File

@@ -0,0 +1,42 @@
# generated by gen-config.py DO NOT edit
import typing
from kittens.ssh.options.utils import hostname
from kitty.conf.utils import merge_dicts
class Parser:
def hostname(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
hostname(val, ans)
def create_result_dict() -> typing.Dict[str, typing.Any]:
return {
}
actions: typing.FrozenSet[str] = frozenset(())
def merge_result_dicts(defaults: typing.Dict[str, typing.Any], vals: typing.Dict[str, typing.Any]) -> typing.Dict[str, typing.Any]:
ans = {}
for k, v in defaults.items():
if isinstance(v, dict):
ans[k] = merge_dicts(v, vals.get(k, {}))
elif k in actions:
ans[k] = v + vals.get(k, [])
else:
ans[k] = vals.get(k, v)
return ans
parser = Parser()
def parse_conf_item(key: str, val: str, ans: typing.Dict[str, typing.Any]) -> bool:
func = getattr(parser, key, None)
if func is not None:
func(val, ans)
return True
return False

View File

@@ -0,0 +1,61 @@
# generated by gen-config.py DO NOT edit
import typing
option_names = ( # {{{
'hostname',) # }}}
class Options:
hostname: str = '*'
config_paths: typing.Tuple[str, ...] = ()
config_overrides: typing.Tuple[str, ...] = ()
def __init__(self, options_dict: typing.Optional[typing.Dict[str, typing.Any]] = None) -> None:
if options_dict is not None:
null = object()
for key in option_names:
val = options_dict.get(key, null)
if val is not null:
setattr(self, key, val)
@property
def _fields(self) -> typing.Tuple[str, ...]:
return option_names
def __iter__(self) -> typing.Iterator[str]:
return iter(self._fields)
def __len__(self) -> int:
return len(self._fields)
def _copy_of_val(self, name: str) -> typing.Any:
ans = getattr(self, name)
if isinstance(ans, dict):
ans = ans.copy()
elif isinstance(ans, list):
ans = ans[:]
return ans
def _asdict(self) -> typing.Dict[str, typing.Any]:
return {k: self._copy_of_val(k) for k in self}
def _replace(self, **kw: typing.Any) -> "Options":
ans = Options()
for name in self:
setattr(ans, name, self._copy_of_val(name))
for name, val in kw.items():
setattr(ans, name, val)
return ans
def __getitem__(self, key: typing.Union[int, str]) -> typing.Any:
k = option_names[key] if isinstance(key, int) else key
try:
return getattr(self, k)
except AttributeError:
pass
raise KeyError(f"No option named: {k}")
defaults = Options()

View File

@@ -0,0 +1,30 @@
#!/usr/bin/env python
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
from typing import Any, Dict, Optional
def init_results_dict(ans: Dict[str, Any]) -> Dict[str, Any]:
ans['current_hostname'] = '*'
ans['current_host_dict'] = chd = {'hostname': '*'}
ans['per_host_dicts'] = {'*': chd}
return ans
ignored_dict_keys = tuple(init_results_dict({}))
def hostname(val: str, dict_with_parse_results: Optional[Dict[str, Any]] = None) -> str:
if dict_with_parse_results is not None:
ch = dict_with_parse_results['current_hostname']
if val != ch:
hd = dict_with_parse_results.copy()
for k in ignored_dict_keys:
del hd[k]
phd = dict_with_parse_results['per_host_dicts']
phd[ch] = hd
dict_with_parse_results.clear()
dict_with_parse_results['per_host_dicts'] = phd
dict_with_parse_results['current_hostname'] = val
dict_with_parse_results['current_host_dict'] = phd.setdefault(val, {'hostname': val})
return val