Compare commits

...

3 Commits

  1. 2
      Bucket_Game-branches/untextured_mob_body_parts_workaround-vs-211114a/mods/codercore/codersea/LICENSE
  2. 164
      pyenliven/mtpatches.py
  3. 37
      utilities/check-patches-lmk

2
Bucket_Game-branches/untextured_mob_body_parts_workaround-vs-211114a/mods/codercore/codersea/LICENSE

@ -41,7 +41,7 @@ Sushi texture:
Creative Commons Attribution Share-Alike 4.0 Creative Commons Attribution Share-Alike 4.0
https://creativecommons.org/licenses/by-sa/4.0/ https://creativecommons.org/licenses/by-sa/4.0/
by Poikilos Copyright (c) 2019 Poikilos
---------------------------------------------------------------------- ----------------------------------------------------------------------

164
pyenliven/mtpatches.py

@ -10,7 +10,9 @@ mtpatches.py [options]
Options: Options:
--skip-missing Do not list files in heads that are not in sources. --skip-missing Do not list files in heads that are not in sources.
--color Enable console colors such as <ESC character>[32m
''' '''
import json
import os import os
import platform import platform
import shlex import shlex
@ -18,6 +20,7 @@ import shutil
import sys import sys
import subprocess import subprocess
from binaryornot.check import is_binary from binaryornot.check import is_binary
from collections import OrderedDict
class Fore: class Fore:
@ -94,10 +97,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 +242,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 +256,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 +309,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 +454,8 @@ def usage():
def main(): def main():
skip_missing = False
enable_color = False
bases = ( bases = (
"/opt/minebest/assemble/bucket_game", "/opt/minebest/assemble/bucket_game",
# "/opt/minebest/mtkit/minetest/src", # "/opt/minebest/mtkit/minetest/src",
@ -462,15 +469,19 @@ def main():
for arg in sys.argv[1:]: for arg in sys.argv[1:]:
if arg == "--skip-missing": if arg == "--skip-missing":
skip_missing = True skip_missing = True
elif arg == "--color":
enable_color = True
else: else:
usage() usage()
echo0("Error: unknown argument {}".format(arg)) echo0("Error: unknown argument {}".format(arg))
return 1 return 1
return check_if_head_files_applied(bases, head_parents, return check_if_head_files_applied(bases, head_parents,
skip_missing=skip_missing) skip_missing=skip_missing,
enable_color=enable_color)
def check_if_head_files_applied(bases, head_parents, skip_missing=False): def check_if_head_files_applied(bases, head_parents, skip_missing=False,
enable_color=False):
"""Check if head files are applied. """Check if head files are applied.
Args: Args:
@ -479,21 +490,45 @@ def check_if_head_files_applied(bases, head_parents, skip_missing=False):
head_parents (list[str]): Folders containing various patches, head_parents (list[str]): Folders containing various patches,
where each sub of each parent is in the form of files to where each sub of each parent is in the form of files to
overlay onto base. overlay onto base.
enable_color (bool): Enable console colors such as
"{escape_character}[32m" for green. Defaults to False.
Returns: Returns:
int: 0 on success. int: 0 on success.
""" """
for base in bases: summary = OrderedDict(
if not os.path.isdir(base): unfinished_patch_count=0,
echo0('Warning: There is no base "{}".'.format(base)) unpatched_file_count=0,
)
reset_color = ""
color = ""
if enable_color:
reset_color = Fore.RESET
for base_root in bases:
if not os.path.isdir(base_root):
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# patches={}".format(head_parent))
for head_sub in os.listdir(head): for head_sub in os.listdir(head_parent):
echo0("## patch={}".format(head_sub))
# 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 +550,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 +563,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 +580,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 +601,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,14 +644,24 @@ 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)
if len(diffs) > 0:
summary['unfinished_patch_count'] += 1
echo0('* differs from patch "{}": {} file(s)'
''.format(head_parent, len(diffs)))
for diff in diffs: for diff in diffs:
summary['unpatched_file_count'] += 1
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:
continue continue
if enable_color:
color = Fore.GREEN color = Fore.GREEN
else: else:
if enable_color:
color = Fore.YELLOW color = Fore.YELLOW
why = "MISSING" if missing else "differs" why = "MISSING" if missing else "differs"
# echo0(" * {}: {}".format(why, diff)) # echo0(" * {}: {}".format(why, diff))
@ -626,13 +672,31 @@ 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",
os.path.join(base_sub_path, diff['rel']),
os.path.join(head_sub_path, diff['rel']),
])+"{} # {} in base (original) vs head (patch) {}".format(color, why, Fore.RESET))
# endregion check whether base has it installed
if not os.path.isfile(head_file):
raise NotImplementedError(
'every head_file should be a file,'
' but got "{}"'.format(head_file)
)
# else isdir
# echo0("head_is_binary={}".format(head_is_binary))
head_is_binary = is_binary(head_file)
difftool = "diffimage-gui" if head_is_binary else "meld"
# ^ Poikilos' diffimage from rotocanvas
# (*not* the same as nicolashahn' diffimg).
difftool = difftool
echo0(
" "+shlex.join([
difftool,
base_file,
head_file,
])
+ "{} # {} in base (original) vs head (patch) {}"
"".format(color, why, reset_color)
)
# endregion check whether base has it installed
echo0("summary={}".format(json.dumps(summary, indent=2)))
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