summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2025-06-20 19:00:43 -0500
committerJohn Estabrook <jestabro@vyos.io>2025-06-21 08:47:49 -0500
commit3472a92cc13084db8486290e8926579e2f753cb4 (patch)
tree2480359f4dd6c0ff12e995d79c0ac2eb747181ef /python
parentecc08e77849295605700ac409b2e93bf1357969c (diff)
downloadvyos-1x-3472a92cc13084db8486290e8926579e2f753cb4.tar.gz
vyos-1x-3472a92cc13084db8486290e8926579e2f753cb4.zip
T7561: generate json if no ambiguous paths in (a subset of) XML files
Diffstat (limited to 'python')
-rwxr-xr-xpython/vyos/xml_ref/generate_op_cache.py27
-rw-r--r--python/vyos/xml_ref/op_definition.py28
2 files changed, 42 insertions, 13 deletions
diff --git a/python/vyos/xml_ref/generate_op_cache.py b/python/vyos/xml_ref/generate_op_cache.py
index 4c22672b2..117b080b4 100755
--- a/python/vyos/xml_ref/generate_op_cache.py
+++ b/python/vyos/xml_ref/generate_op_cache.py
@@ -19,6 +19,7 @@ import io
import re
import sys
import glob
+import json
import atexit
from argparse import ArgumentParser
@@ -48,6 +49,7 @@ from defaults import directories # noqa: E402
op_ref_cache = abspath(join(_here, 'op_cache.py'))
+op_ref_json = abspath(join(_here, 'op_cache.json'))
OptElement: TypeAlias = Optional[Element]
@@ -241,6 +243,11 @@ def main():
action='store_true',
help='attempt to reduce to unique paths, reporting if error',
)
+ parser.add_argument(
+ '--select',
+ type=str,
+ help='limit cache to a subset of XML files: "power_ctl | multicast-group | ..."',
+ )
args = vars(parser.parse_args())
@@ -252,15 +259,27 @@ def main():
d = {}
+ select = args['select']
+ if select:
+ select = [item.strip() for item in select.split('|')]
+
for fname in sorted(glob.glob(f'{xml_dir}/*.xml')):
- parse_file(fname, d)
+ file = os.path.basename(fname)
+ if not select or os.path.splitext(file)[0] in select:
+ parse_file(fname, d)
d = sort_op_data(d)
if args['check_path_ambiguity']:
- # when the following passes with no output, return value will be
- # the full dictionary indexed by str, not tuple
- _ = collapse(d)
+ # when the following passes without error, return value will be the
+ # full dictionary indexed by str, not tuple
+ res, out, err = collapse(d)
+ if not err:
+ with open(op_ref_json, 'w') as f:
+ json.dump(res, f, indent=2)
+ else:
+ print('Found the following duplicate paths:\n')
+ print(out)
with open(op_ref_cache, 'w') as f:
f.write('from vyos.xml_ref.op_definition import NodeData\n')
diff --git a/python/vyos/xml_ref/op_definition.py b/python/vyos/xml_ref/op_definition.py
index 71076bdb7..8e922ecb2 100644
--- a/python/vyos/xml_ref/op_definition.py
+++ b/python/vyos/xml_ref/op_definition.py
@@ -19,6 +19,7 @@ from typing import Iterator
from dataclasses import dataclass
from dataclasses import field
from dataclasses import fields
+from dataclasses import asdict
from itertools import filterfalse
@@ -134,34 +135,43 @@ def node_data_difference(a: NodeData, b: NodeData):
return out
-def collapse(d: OpData, acc: dict = None) -> dict:
+def collapse(d: OpData, acc: dict = None) -> tuple[dict, str, bool]:
+ err = False
+ inner_err = False
+ out = ''
+ inner_out = ''
if acc is None:
acc = {}
if not isinstance(d, dict):
return d
for k, v in d.items():
if isinstance(k, tuple):
- # reduce
name = key_name(k)
if name != '__node_data':
new_data = get_node_data(v)
if name in list(acc.keys()):
+ err = True
prev_data = acc[name].get('__node_data', {})
if prev_data:
- out = f'prev: {prev_data.file} {prev_data.path}\n'
+ out += f'prev: {prev_data["file"]} {prev_data["path"]}\n'
else:
- out = '\n'
- out += f'new: {new_data.file} {new_data.path}\n'
- print(out)
+ out += '\n'
+ out += f'new: {new_data.file} {new_data.path}\n\n'
else:
acc[name] = {}
- acc[name]['__node_data'] = new_data
- acc[name].update(collapse(v))
+ acc[name]['__node_data'] = asdict(new_data)
+ inner, o, e = collapse(v)
+ inner_err |= e
+ inner_out += o
+ acc[name].update(inner)
else:
name = k
acc[name] = v
- return acc
+ err |= inner_err
+ out += inner_out
+
+ return acc, out, err
class OpXml: