Continuing bug fixes
This commit is contained in:
parent
cbfe6d9e38
commit
982f977429
4 changed files with 84 additions and 26 deletions
|
|
@ -45,7 +45,7 @@
|
||||||
current node instead of failing.
|
current node instead of failing.
|
||||||
- Better error handling of in-node syntax errors.
|
- Better error handling of in-node syntax errors.
|
||||||
- Improve dedent of default text/helptext formatter. Right-strip whitespace.
|
- Improve dedent of default text/helptext formatter. Right-strip whitespace.
|
||||||
- Add `debug` option when creating menu - this turns of persistence and makes the `menudebug`
|
- Add `debug` option when creating menu - this turns off persistence and makes the `menudebug`
|
||||||
command available for examining the current menu state.
|
command available for examining the current menu state.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1944,21 +1944,26 @@ def _apply_diff(caller, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def _keep_diff(caller, **kwargs):
|
def _keep_diff(caller, **kwargs):
|
||||||
|
"""Change to KEEP setting for a given section of a diff"""
|
||||||
|
# from evennia import set_trace;set_trace(term_size=(182, 50))
|
||||||
path = kwargs['path']
|
path = kwargs['path']
|
||||||
diff = kwargs['diff']
|
diff = kwargs['diff']
|
||||||
tmp = diff
|
tmp = diff
|
||||||
for key in path[:-1]:
|
for key in path[:-1]:
|
||||||
tmp = diff[key]
|
tmp = tmp[key]
|
||||||
tmp[path[-1]] = "KEEP"
|
tmp[path[-1]] = tuple(list(tmp[path[-1]][:-1]) + ["KEEP"])
|
||||||
|
|
||||||
|
|
||||||
def _format_diff_text_and_options(diff):
|
def _format_diff_text_and_options(diff, **kwargs):
|
||||||
"""
|
"""
|
||||||
Reformat the diff in a way suitable for the olc menu.
|
Reformat the diff in a way suitable for the olc menu.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
diff (dict): A diff as produced by `prototype_diff`.
|
diff (dict): A diff as produced by `prototype_diff`.
|
||||||
|
|
||||||
|
Kwargs:
|
||||||
|
any (any): Forwarded into the generated options as arguments to the callable.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
options (list): List of options dict.
|
options (list): List of options dict.
|
||||||
|
|
||||||
|
|
@ -1968,49 +1973,60 @@ def _format_diff_text_and_options(diff):
|
||||||
def _visualize(obj, rootname, get_name=False):
|
def _visualize(obj, rootname, get_name=False):
|
||||||
if utils.is_iter(obj):
|
if utils.is_iter(obj):
|
||||||
if get_name:
|
if get_name:
|
||||||
return obj[0]
|
return obj[0] if obj[0] else "<unset>"
|
||||||
if rootname == "attrs":
|
if rootname == "attrs":
|
||||||
return "{} |W=|n {} |W(category:|n {}|W, locks:|n {}|W)|n".format(*obj)
|
return "{} |W=|n {} |W(category:|n {}|W, locks:|n {}|W)|n".format(*obj)
|
||||||
elif rootname == "tags":
|
elif rootname == "tags":
|
||||||
return "{} |W(category:|n {}|W)|n".format(obj[0], obj[1])
|
return "{} |W(category:|n {}|W)|n".format(obj[0], obj[1])
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def _parse_diffpart(diffpart, optnum, indent, *args):
|
def _parse_diffpart(diffpart, optnum, *args):
|
||||||
typ = type(diffpart)
|
typ = type(diffpart)
|
||||||
texts = []
|
texts = []
|
||||||
options = []
|
options = []
|
||||||
if typ == tuple and len(diffpart) == 3 and diffpart[2] in valid_instructions:
|
if typ == tuple and len(diffpart) == 3 and diffpart[2] in valid_instructions:
|
||||||
|
rootname = args[0]
|
||||||
old, new, instruction = diffpart
|
old, new, instruction = diffpart
|
||||||
if instruction == 'KEEP':
|
if instruction == 'KEEP':
|
||||||
texts.append("{old} |gKEEP|n".format(old=old))
|
texts.append(" |gKEEP|W:|n {old}".format(old=old))
|
||||||
else:
|
else:
|
||||||
texts.append("{indent}|c({num}) {inst}|W:|n {old} |W->|n {new}".format(
|
vold = _visualize(old, rootname)
|
||||||
indent=" " * indent,
|
vnew = _visualize(new, rootname)
|
||||||
inst="|rREMOVE|n" if instruction == 'REMOVE' else "|y{}|n".format(instruction),
|
vsep = "" if len(vold) < 78 else "\n"
|
||||||
num=optnum,
|
vinst = "|rREMOVE|n" if instruction == 'REMOVE' else "|y{}|n".format(instruction)
|
||||||
old=_visualize(old, args[-1]),
|
texts.append(" |c[{num}] {inst}|W:|n {old} |W->|n{sep} {new}".format(
|
||||||
new=_visualize(new, args[-1])))
|
inst=vinst, num=optnum, old=vold, sep=vsep, new=vnew))
|
||||||
options.append({"key": str(optnum),
|
options.append({"key": str(optnum),
|
||||||
"desc": "|gKEEP|n {}".format(
|
"desc": "|gKEEP|n ({}) {}".format(
|
||||||
_visualize(old, args[-1], get_name=True)),
|
rootname, _visualize(old, args[-1], get_name=True)),
|
||||||
"goto": (_keep_diff, {"path": args, "diff": diff})})
|
"goto": (_keep_diff, dict((("path", args),
|
||||||
|
("diff", diff)), **kwargs))})
|
||||||
optnum += 1
|
optnum += 1
|
||||||
else:
|
else:
|
||||||
for key, subdiffpart in diffpart.items():
|
for key, subdiffpart in diffpart.items():
|
||||||
text, option, optnum = _parse_diffpart(
|
text, option, optnum = _parse_diffpart(
|
||||||
subdiffpart, optnum, indent + 1, *(args + (key, )))
|
subdiffpart, optnum, *(args + (key, )))
|
||||||
texts.extend(text)
|
texts.extend(text)
|
||||||
options.extend(option)
|
options.extend(option)
|
||||||
return text, options, optnum
|
return texts, options, optnum
|
||||||
|
|
||||||
texts = []
|
texts = []
|
||||||
options = []
|
options = []
|
||||||
# we use this to allow for skipping full KEEP instructions
|
# we use this to allow for skipping full KEEP instructions
|
||||||
flattened_diff = spawner.flatten_diff(diff)
|
|
||||||
optnum = 1
|
optnum = 1
|
||||||
|
|
||||||
for root_key, diffpart in flattened_diff.items():
|
for root_key in sorted(diff):
|
||||||
text, option, optnum = _parse_diffpart(diffpart, optnum, 1, root_key)
|
diffpart = diff[root_key]
|
||||||
|
text, option, optnum = _parse_diffpart(diffpart, optnum, root_key)
|
||||||
|
|
||||||
|
heading = "- |w{}:|n ".format(root_key)
|
||||||
|
if root_key in ("attrs", "tags", "permissions"):
|
||||||
|
texts.append(heading)
|
||||||
|
elif text:
|
||||||
|
text = [heading + text[0]] + text[1:]
|
||||||
|
else:
|
||||||
|
text = [heading]
|
||||||
|
|
||||||
texts.extend(text)
|
texts.extend(text)
|
||||||
options.extend(option)
|
options.extend(option)
|
||||||
|
|
||||||
|
|
@ -2047,7 +2063,6 @@ def node_apply_diff(caller, **kwargs):
|
||||||
# use one random object as a reference to calculate a diff
|
# use one random object as a reference to calculate a diff
|
||||||
base_obj = choice(update_objects)
|
base_obj = choice(update_objects)
|
||||||
|
|
||||||
# from evennia import set_trace
|
|
||||||
diff, obj_prototype = spawner.prototype_diff_from_object(prototype, base_obj)
|
diff, obj_prototype = spawner.prototype_diff_from_object(prototype, base_obj)
|
||||||
|
|
||||||
helptext = """
|
helptext = """
|
||||||
|
|
@ -2068,7 +2083,7 @@ def node_apply_diff(caller, **kwargs):
|
||||||
if not custom_location:
|
if not custom_location:
|
||||||
diff.pop("location", None)
|
diff.pop("location", None)
|
||||||
|
|
||||||
txt, options = _format_diff_text_and_options(diff)
|
txt, options = _format_diff_text_and_options(diff, objects=update_objects, base_obj=base_obj)
|
||||||
|
|
||||||
if options:
|
if options:
|
||||||
text = ["Suggested changes to {} objects. ".format(len(update_objects)),
|
text = ["Suggested changes to {} objects. ".format(len(update_objects)),
|
||||||
|
|
|
||||||
|
|
@ -299,19 +299,31 @@ def prototype_diff(prototype1, prototype2, maxdepth=2):
|
||||||
|
|
||||||
if old_type != new_type:
|
if old_type != new_type:
|
||||||
if old and not new:
|
if old and not new:
|
||||||
|
if depth < maxdepth and old_type == dict:
|
||||||
|
return {key: (part, None, "REMOVE") for key, part in old.items()}
|
||||||
|
elif depth < maxdepth and is_iter(old):
|
||||||
|
return {part[0] if is_iter(part) else part:
|
||||||
|
(part, None, "REMOVE") for part in old}
|
||||||
return (old, new, "REMOVE")
|
return (old, new, "REMOVE")
|
||||||
elif not old and new:
|
elif not old and new:
|
||||||
|
if depth < maxdepth and new_type == dict:
|
||||||
|
return {key: (None, part, "ADD") for key, part in new.items()}
|
||||||
|
elif depth < maxdepth and is_iter(new):
|
||||||
|
return {part[0] if is_iter(part) else part: (None, part, "ADD") for part in new}
|
||||||
return (old, new, "ADD")
|
return (old, new, "ADD")
|
||||||
else:
|
else:
|
||||||
|
# this condition should not occur in a standard diff
|
||||||
return (old, new, "UPDATE")
|
return (old, new, "UPDATE")
|
||||||
elif depth < maxdepth and new_type == dict:
|
elif depth < maxdepth and new_type == dict:
|
||||||
all_keys = set(old.keys() + new.keys())
|
all_keys = set(old.keys() + new.keys())
|
||||||
return {key: _recursive_diff(old.get(key), new.get(key), depth=depth + 1) for key in all_keys}
|
return {key: _recursive_diff(old.get(key), new.get(key), depth=depth + 1)
|
||||||
|
for key in all_keys}
|
||||||
elif depth < maxdepth and is_iter(new):
|
elif depth < maxdepth and is_iter(new):
|
||||||
old_map = {part[0] if is_iter(part) else part: part for part in old}
|
old_map = {part[0] if is_iter(part) else part: part for part in old}
|
||||||
new_map = {part[0] if is_iter(part) else part: part for part in new}
|
new_map = {part[0] if is_iter(part) else part: part for part in new}
|
||||||
all_keys = set(old_map.keys() + new_map.keys())
|
all_keys = set(old_map.keys() + new_map.keys())
|
||||||
return {key: _recursive_diff(old_map.get(key), new_map.get(key), depth=depth + 1) for key in all_keys}
|
return {key: _recursive_diff(old_map.get(key), new_map.get(key), depth=depth + 1)
|
||||||
|
for key in all_keys}
|
||||||
elif old != new:
|
elif old != new:
|
||||||
return (old, new, "UPDATE")
|
return (old, new, "UPDATE")
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -569,6 +569,37 @@ class TestMenuModule(EvenniaTest):
|
||||||
self.assertEqual(olc_menus._prototype_load_select(caller, self.test_prot['prototype_key']),
|
self.assertEqual(olc_menus._prototype_load_select(caller, self.test_prot['prototype_key']),
|
||||||
('node_examine_entity', {'text': '|gLoaded prototype test_prot.|n', 'back': 'index'}) )
|
('node_examine_entity', {'text': '|gLoaded prototype test_prot.|n', 'back': 'index'}) )
|
||||||
|
|
||||||
|
# diff helpers
|
||||||
|
obj_diff = {
|
||||||
|
'attrs': {
|
||||||
|
u'desc': ((u'desc', u'This is User #1.', None, ''),
|
||||||
|
(u'desc', u'This is User #1.', None, ''),
|
||||||
|
'KEEP'),
|
||||||
|
u'foo': (None,
|
||||||
|
(u'foo', u'bar', None, ''),
|
||||||
|
'ADD'),
|
||||||
|
u'prelogout_location': ((u'prelogout_location', "#2", None, ''),
|
||||||
|
(u'prelogout_location', "#2", None, ''),
|
||||||
|
'KEEP')},
|
||||||
|
'home': ('#2', '#2', 'KEEP'),
|
||||||
|
'key': (u'TestChar', u'TestChar', 'KEEP'),
|
||||||
|
'locks': ('boot:false();call:false();control:perm(Developer);delete:false();'
|
||||||
|
'edit:false();examine:perm(Developer);get:false();msg:all();'
|
||||||
|
'puppet:false();tell:perm(Admin);view:all()',
|
||||||
|
'boot:false();call:false();control:perm(Developer);delete:false();'
|
||||||
|
'edit:false();examine:perm(Developer);get:false();msg:all();'
|
||||||
|
'puppet:false();tell:perm(Admin);view:all()',
|
||||||
|
'KEEP'),
|
||||||
|
'permissions': {'developer': ('developer', 'developer', 'KEEP')},
|
||||||
|
'prototype_desc': ('Testobject build', None, 'REMOVE'),
|
||||||
|
'prototype_key': ('TestDiffKey', 'TestDiffKey', 'KEEP'),
|
||||||
|
'prototype_locks': ('spawn:all();edit:all()', 'spawn:all();edit:all()', 'KEEP'),
|
||||||
|
'prototype_tags': {},
|
||||||
|
'tags': {'foo': (None, ('foo', None, ''), 'ADD')},
|
||||||
|
'typeclass': (u'typeclasses.characters.Character',
|
||||||
|
u'typeclasses.characters.Character', 'KEEP')}
|
||||||
|
self.assertEqual(olc_menus._format_diff_text_and_options(obj_diff), "")
|
||||||
|
|
||||||
|
|
||||||
@mock.patch("evennia.prototypes.menus.protlib.search_prototype", new=mock.MagicMock(
|
@mock.patch("evennia.prototypes.menus.protlib.search_prototype", new=mock.MagicMock(
|
||||||
return_value=[{"prototype_key": "TestPrototype",
|
return_value=[{"prototype_key": "TestPrototype",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue