Browse Source

Fix: Correctly detect is_binary on file not dir (and rename related variables for clarity).

master
poikilos 8 months ago
parent
commit
0ac4f13bec
  1. 129
      pyenliven/mtpatches.py
  2. 37
      utilities/check-patches-lmk

129
pyenliven/mtpatches.py

@ -94,10 +94,12 @@ def diff_only_head(base, head, more_1char_args=None, log_level=0):
Returns: Returns:
list(dict): A list of differing files as info dicts, each with: list(dict): A list of differing files as info dicts, each with:
- 'rel': The path relative to head. - 'rel' (str): The path relative to head.
- 'new': True if not in base, otherwise False or not present. - 'new' (bool): True if not in base, otherwise False or not present.
- 'code': Return code (1 if file in head&base differ) - 'code' (int): Return code (1 if file in head&base differ)
- 'head_is_binary' (bool): If detected binary (implies binary
comparison was used, unless 'new' is True then not actually
compared but still detected head_is_binary).
""" """
return _diff_only_head( return _diff_only_head(
base, base,
@ -237,6 +239,7 @@ def _diff_only_head(base, head, rel=None, more_1char_args=None, depth=0,
log_level=log_level, log_level=log_level,
) )
else: else:
head_is_binary = is_binary(head_path)
# echo0('base={}:"{}"'.format(whats[0], paths[0])) # echo0('base={}:"{}"'.format(whats[0], paths[0]))
# echo0('head={}:"{}"'.format(whats[1], paths[1])) # echo0('head={}:"{}"'.format(whats[1], paths[1]))
# file, so actually compare # file, so actually compare
@ -250,11 +253,9 @@ def _diff_only_head(base, head, rel=None, more_1char_args=None, depth=0,
'code': 1, 'code': 1,
'rel': rel, 'rel': rel,
'new': True, 'new': True,
'head_is_binary': head_is_binary,
}] }]
head_is_binary = is_binary(head_path)
if more_1char_args is None: if more_1char_args is None:
if platform.system() == "Windows": if platform.system() == "Windows":
if not head_is_binary: if not head_is_binary:
@ -305,6 +306,7 @@ def _diff_only_head(base, head, rel=None, more_1char_args=None, depth=0,
return [{ return [{
'code': rc, 'code': rc,
'rel': rel, 'rel': rel,
'head_is_binary': head_is_binary,
}] }]
return diffs # folder, so return every sub's diff(s) ([] if None) return diffs # folder, so return every sub's diff(s) ([] if None)
@ -449,6 +451,7 @@ def usage():
def main(): def main():
skip_missing = False
bases = ( bases = (
"/opt/minebest/assemble/bucket_game", "/opt/minebest/assemble/bucket_game",
# "/opt/minebest/mtkit/minetest/src", # "/opt/minebest/mtkit/minetest/src",
@ -483,17 +486,29 @@ def check_if_head_files_applied(bases, head_parents, skip_missing=False):
Returns: Returns:
int: 0 on success. int: 0 on success.
""" """
for base in bases: for base_root in bases:
if not os.path.isdir(base): if not os.path.isdir(base_root):
echo0('Warning: There is no base "{}".'.format(base)) echo0('Warning: There is no base_root "{}".'.format(base_root))
continue continue
for head in head_parents: for head_parent in head_parents:
echo0("\n# {}".format(head)) echo0("\n# {}".format(head_parent))
for head_sub in os.listdir(head): for head_sub in os.listdir(head_parent):
# Identify each head folder as an overlay to "patch" a base. # Identify each head folder as an overlay to "patch" a base.
head_sub_path = os.path.join(head, head_sub)
# *Ignore files* in each head parent!
# Files there may be diff and zip files etc.!
# Each sub *folder* is a overlay for base.
# - This method is *not* recursive, but:
# diff_only_head (recursive) is called below on each dir.
# - This method does *display* each file, for diffs
# returned by recursive diff_only_head.
head_fuzzy_root = os.path.join(head_parent, head_sub)
# ^ head_fuzzy_root is not yet known in terms of depth
# which will be detected later if possible as patch_root
# (if contains "mods" folder, head_parent is patch_root)
# region skip non-patch subs # region skip non-patch subs
if os.path.isfile(head_sub_path): if os.path.isfile(head_fuzzy_root):
# echo0('Warning: Only folders, skipped "{}"' # echo0('Warning: Only folders, skipped "{}"'
# ''.format(head_sub)) # ''.format(head_sub))
continue continue
@ -515,12 +530,12 @@ def check_if_head_files_applied(bases, head_parents, skip_missing=False):
# region identify patch structure # region identify patch structure
mod_rel = get_shallowest_files_sub( mod_rel = get_shallowest_files_sub(
head_sub_path, head_fuzzy_root,
mask=["init.lua", "mod.conf", "depends.txt", mask=["init.lua", "mod.conf", "depends.txt",
"description.txt"], "description.txt"],
) )
modpack_rel = get_shallowest_files_sub( modpack_rel = get_shallowest_files_sub(
head_sub_path, head_fuzzy_root,
mask=["modpack.txt", "modpack.conf"], mask=["modpack.txt", "modpack.conf"],
) )
game_patch_root = None game_patch_root = None
@ -528,14 +543,13 @@ def check_if_head_files_applied(bases, head_parents, skip_missing=False):
modpack_patch_root = None modpack_patch_root = None
if head_sub.endswith("_game"): if head_sub.endswith("_game"):
game_patch_root = head_sub_path game_patch_root = head_fuzzy_root
elif os.path.isdir(os.path.join(head_sub_path, "mods")): elif os.path.isdir(os.path.join(head_fuzzy_root, "mods")):
game_patch_root = head_sub_path game_patch_root = head_fuzzy_root
echo0('game_patch_root="{}"'.format(head_sub))
elif (mod_rel is not None) and (modpack_rel is None): elif (mod_rel is not None) and (modpack_rel is None):
mod_parent = os.path.dirname(os.path.join(head_sub_path, mod_parent = os.path.dirname(os.path.join(head_fuzzy_root,
mod_rel)) mod_rel))
mod_parent_rel = mod_parent[len(head_sub_path)+1:] mod_parent_rel = mod_parent[len(head_fuzzy_root)+1:]
# ^ +1 no os.path.sep # ^ +1 no os.path.sep
_, mod_parent_name = os.path.split(mod_parent) _, mod_parent_name = os.path.split(mod_parent)
if mod_parent_rel and (mod_parent_name not in ["mods"]): if mod_parent_rel and (mod_parent_name not in ["mods"]):
@ -546,17 +560,19 @@ def check_if_head_files_applied(bases, head_parents, skip_missing=False):
if game_patch_root: if game_patch_root:
pass # Already set above. pass # Already set above.
echo0('set game_patch_root="{}"'.format(head_sub))
elif modpack_patch_root: elif modpack_patch_root:
pass # Already set above. pass # Already set above.
echo0('set modpack_patch_root="{}"'.format(head_sub))
elif mod_rel is not None: elif mod_rel is not None:
if mod_rel: if mod_rel:
mod_patch_root = os.path.join(head_sub_path, mod_rel) mod_patch_root = os.path.join(head_fuzzy_root, mod_rel)
else: else:
# Must be "", so don't do join or will add os.path.sep # Must be "", so don't do join or will add os.path.sep
mod_patch_root = head_sub_path mod_patch_root = head_fuzzy_root
_, got_mod_name = os.path.split(mod_patch_root) _, got_mod_name = os.path.split(mod_patch_root)
echo0('mod_patch="{}" root="{}"' echo0('set mod_patch="{}"'.format(got_mod_name))
''.format(got_mod_name, mod_patch_root)) echo0('set mod_patch_root="{}"'.format(mod_patch_root))
else: else:
pass pass
# echo0('Warning: mod not identified in "{}"' # echo0('Warning: mod not identified in "{}"'
@ -565,42 +581,42 @@ def check_if_head_files_applied(bases, head_parents, skip_missing=False):
# endregion identify patch structure # endregion identify patch structure
# region check whether base has it installed # region check whether base has it installed
patch_root = None parallel_head = None # detected depth matches parallel_base
if game_patch_root is not None: if game_patch_root is not None:
patch_root = game_patch_root parallel_head = game_patch_root
_, game_name = os.path.split(base) _, game_name = os.path.split(base_root)
base_sub_path = base parallel_base = base_root
echo0("* Checking whether {} was applied to {} game" echo0("* Checking whether {} was applied to {} game"
"".format(head_sub, game_name)) "".format(head_sub, game_name))
elif modpack_patch_root is not None: elif modpack_patch_root is not None:
patch_root = modpack_patch_root parallel_head = modpack_patch_root
_, modpack_name = os.path.split(modpack_patch_root) _, modpack_name = os.path.split(modpack_patch_root)
modpack_rel = find_modpack(base, modpack_name) modpack_rel = find_modpack(base_root, modpack_name)
if modpack_rel is None: if modpack_rel is None:
echo0("Error: {} was not found in {}" echo0("Error: {} was not found in {}"
"".format(modpack_name, base)) "".format(modpack_name, base_root))
continue continue
if modpack_rel: if modpack_rel:
base_sub_path = os.path.join(base, modpack_rel) parallel_base = os.path.join(base_root, modpack_rel)
else: else:
# Must be "", so avoid join to avoid adding os.path.sep # Must be "", so avoid join to avoid adding os.path.sep
base_sub_path = base parallel_base = base_root
echo0("* Checking whether {} was applied to" echo0("* Checking whether {} was applied to"
" {} modpack in {} game" " {} modpack in {} game"
"".format(head_sub, modpack_name, game_name)) "".format(head_sub, modpack_name, game_name))
elif mod_patch_root is not None: elif mod_patch_root is not None:
patch_root = mod_patch_root parallel_head = mod_patch_root
_, mod_name = os.path.split(mod_patch_root) _, mod_name = os.path.split(mod_patch_root)
mod_rel = find_mod(base, mod_name) mod_rel = find_mod(base_root, mod_name)
if mod_rel is None: if mod_rel is None:
echo0("Error: {} was not found in {}" echo0("Error: {} was not found in {}"
"".format(mod_name, base)) "".format(mod_name, base_root))
continue continue
if modpack_rel: if modpack_rel:
base_sub_path = os.path.join(base, modpack_rel) parallel_base = os.path.join(base_root, modpack_rel)
else: else:
# Must be "", so avoid join to avoid adding os.path.sep # Must be "", so avoid join to avoid adding os.path.sep
base_sub_path = base parallel_base = base_root
echo0("* Checking whether {} was applied to" echo0("* Checking whether {} was applied to"
" {} mod in {} game" " {} mod in {} game"
"".format(head_sub, mod_name, game_name)) "".format(head_sub, mod_name, game_name))
@ -608,8 +624,11 @@ def check_if_head_files_applied(bases, head_parents, skip_missing=False):
echo0('Warning: Skipping unknown patch structure: "{}"' echo0('Warning: Skipping unknown patch structure: "{}"'
''.format(head_sub)) ''.format(head_sub))
diffs = diff_only_head(base_sub_path, patch_root, log_level=-1) diffs = diff_only_head(parallel_base, parallel_head,
log_level=-1)
for diff in diffs: for diff in diffs:
base_file = os.path.join(parallel_base, diff['rel'])
head_file = os.path.join(parallel_head, diff['rel'])
missing = bool(diff.get("new")) missing = bool(diff.get("new"))
if missing: if missing:
if skip_missing: if skip_missing:
@ -626,11 +645,27 @@ def check_if_head_files_applied(bases, head_parents, skip_missing=False):
" or it will override base or head." " or it will override base or head."
"".format(os.path.sep) "".format(os.path.sep)
) )
echo0(" "+shlex.join([
"meld", if not os.path.isfile(head_file):
os.path.join(base_sub_path, diff['rel']), raise NotImplementedError(
os.path.join(head_sub_path, diff['rel']), 'every head_file should be a file,'
])+"{} # {} in base (original) vs head (patch) {}".format(color, why, Fore.RESET)) ' but got "{}"'.format(head_file)
)
# else isdir
# echo0("head_is_binary={}".format(head_is_binary))
head_is_binary = is_binary(head_file)
difftool = "diffimg-gui" if head_is_binary else "meld"
difftool = difftool
echo0(
" "+shlex.join([
difftool,
base_file,
head_file,
])
+ "{} # {} in base (original) vs head (patch) {}"
"".format(color, why, Fore.RESET)
)
# endregion check whether base has it installed # endregion check whether base has it installed
return 0 return 0

37
utilities/check-patches-lmk

@ -0,0 +1,37 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# #!/usr/bin/python3
# based on EnlivenMinetest/utilities/install-lmk
#
# The copy in hierosoft is relicensed by Poikilos (original author)
# under license of hierosoft
'''
install-lmk
-----------
Use any "minetest" folder under the current working directory
to install or upgrade.
Developers: If /opt/minebest/mtkit is present, that will be used.
See hierosoft.hminetestsrc documentation for more info.
'''
import re
import sys
import os
SCRIPTS_DIR = os.path.dirname(os.path.realpath(__file__))
REPO_DIR = os.path.dirname(SCRIPTS_DIR)
if __name__ == "__main__":
sys.path.insert(0, REPO_DIR)
# if os.path.isfile(os.path.join(repos_dir, "hierosoft", "init.py")):
# sys.path.insert(repos_dir)
# ^ implies both are installed (and that repos_dir is actually modules_dir),
# so leave path alone.
from pyenliven.mtpatches import main # noqa E402
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
Loading…
Cancel
Save