Browse Source

Fix: Check if file is binary and use appropriate diff option(s). Fix: Add "B" (ignore changes where all lines are blank) in mtpatches.

master
poikilos 10 months ago
parent
commit
64a4f82724
  1. 123
      pyenliven/mtpatches.py
  2. 3
      pyproject.toml

123
pyenliven/mtpatches.py

@ -17,6 +17,7 @@ import shlex
import shutil
import sys
import subprocess
from binaryornot.check import is_binary
class Fore:
@ -106,6 +107,65 @@ def diff_only_head(base, head, more_1char_args=None, log_level=0):
)
def validate_diff_args(more_1char_args):
"""Check the given arguments format for diff or fc
and convert to a list if has spaces.
Args:
more_1char_args (Union[str,list[str],tuple[str]]): Arguments for
the diff tool.
Raises:
TypeError: Not list, tuple, nor str.
ValueError: is blank str
ValueError: is just a '-' or '/'
ValueError: starts with '/' when using diff, or '-' when not
Returns:
list(str): Arguments (usually only one, such as "-wbB" for diff,
or for FC, "/B" for binary and "/W" to ignore whitespace).
In other words, return the original more_1char_args or
split it into a list.
"""
diff_bin_name = DIFF_CMD_PARTS[0].lower()
opener_for_1char = "-" if (diff_bin_name == "fc") else "/"
# ^ even on Windows, diff would take "-" (fc takes "/" before options)
if not isinstance(more_1char_args, (list, tuple)):
if not isinstance(more_1char_args, str):
raise TypeError("more_1char_args must be list, tuple, or str")
more_1char_args = more_1char_args.strip()
if len(more_1char_args) == 0:
raise ValueError("more_1char_args for \"{}\" was empty str"
" but should be None or an args string"
" starting with '{}'"
"".format(diff_bin_name, opener_for_1char))
elif len(more_1char_args) == 1:
if more_1char_args in ("-", "/"):
raise ValueError("more_1char_args was only '{}' with no args"
"".format(more_1char_args))
# Allow string too (split if has space, otherwise convert
# to 1-long list still)
# Split into tuple and recurse:
return validate_diff_args(more_1char_args.strip().split())
for arg in more_1char_args:
if not arg.startswith(opener_for_1char):
bin_msg = "diff"
if diff_bin_name != "diff":
bin_msg = (
"diff wasn't in your PATH so {} is being used, but it"
"".format(diff_bin_name)
)
raise ValueError(
"{} only accepts options"
" starting with '{}'"
" (got \"{}\")".format(bin_msg, opener_for_1char,
arg)
)
return more_1char_args # It is a list now.
def _diff_only_head(base, head, rel=None, more_1char_args=None, depth=0,
log_level=0):
"""Compare two directories or files.
@ -127,39 +187,6 @@ def _diff_only_head(base, head, rel=None, more_1char_args=None, depth=0,
raise FileNotFoundError("There is no {} in your PATH."
"".format(ok_commands))
args_1char = None
is_binary = False
if more_1char_args is None:
if platform.system() == "Windows":
if not is_binary:
args_1char = ["/W"] # ignore whitespace
else:
args_1char = ["/B"] # binary comparison
else:
if not is_binary:
args_1char = ["-wb"]
# -b: ignore changes in the amount of whitespace
# -w: ignore all white space (better for code since
# "a=1" is same as "a == 1", otherwise tokenizing
# the specific language would be necessary)
# -a: --text treat all files as text and
# --strip-trailing-cr strip trailing carriage
# return
# -E, --ignore-tab-expansion
else:
if more_1char_args.startswith("-"):
if DIFF_CMD_PARTS[0].lower() == "fc":
raise ValueError(
"diff wasn't in your PATH so fc is being used,"
" but it only accepts options"
" starting with '/'"
" (got \"{}\")".format(more_1char_args)
)
if isinstance(more_1char_args, (list, tuple)):
args_1char = more_1char_args
else:
# allow string too (split if has space, otherwise convert
# to 1-long list still)
args_1char = more_1char_args.strip().split()
whats = [None, None]
if rel:
@ -169,6 +196,7 @@ def _diff_only_head(base, head, rel=None, more_1char_args=None, depth=0,
base_path = base
head_path = head
paths = (base_path, head_path)
names = ("base", "head")
for i, path in enumerate(paths):
if not os.path.exists(path):
@ -223,6 +251,35 @@ def _diff_only_head(base, head, rel=None, more_1char_args=None, depth=0,
'rel': rel,
'new': True,
}]
head_is_binary = is_binary(head_path)
if more_1char_args is None:
if platform.system() == "Windows":
if not head_is_binary:
args_1char = ["/W"] # ignore whitespace
else:
args_1char = ["/B"] # binary comparison
else:
if not head_is_binary:
args_1char = ["-wbB"]
# -b: ignore changes in the amount of whitespace
# -w: ignore all white space (better for code since
# "a=1" is same as "a == 1", otherwise tokenizing
# the specific language would be necessary)
# -a: --text treat all files as text and
# --strip-trailing-cr strip trailing carriage
# return
# [doesn't do enough if has extra blank line,
# still says different, so use -B instead]
# -B, ignore changes where all lines are blank
# -E, --ignore-tab-expansion
# else None (just use diff without any options)
else:
args_1char = validate_diff_args(more_1char_args)
del more_1char_args
# echo0("^ in base")
cmd_parts = DIFF_CMD_PARTS.copy()
# echo0("args_1char={}".format(args_1char))

3
pyproject.toml

@ -8,6 +8,9 @@ version = "0.2.0"
authors = [
{ name="Jake Gustafson", email="7557867+poikilos@users.noreply.github.com" },
]
dependencies = [
"binaryornot", # only for mtpatches
]
# requires-python = ">=3.3"
# TODO: (shutil.which requires 3.3 but) may need newer version,
# & other code may run on older version

Loading…
Cancel
Save