Clean up color in diff cli. Fix symlink detection
This commit is contained in:
parent
a750b53a10
commit
07f6347d49
@ -8,11 +8,11 @@ import warnings
|
|||||||
|
|
||||||
|
|
||||||
def print_diff(ABdiff: fs.FSDiff, version_info='count', indent=2,
|
def print_diff(ABdiff: fs.FSDiff, version_info='count', indent=2,
|
||||||
indent_level=0, use_color=True):
|
indent_level=0, use_color=True, show_hashes=False):
|
||||||
"""Pretty print an FSDiff object"""
|
"""Pretty print an FSDiff object"""
|
||||||
if use_color:
|
if use_color:
|
||||||
try:
|
try:
|
||||||
from colorama import Fore, Back, Style
|
from colorama import init, Fore, Back, Style
|
||||||
except ImportError:
|
except ImportError:
|
||||||
warnings.warn("Could not import colorama library. Color output disabled.")
|
warnings.warn("Could not import colorama library. Color output disabled.")
|
||||||
use_color = False
|
use_color = False
|
||||||
@ -22,21 +22,52 @@ def print_diff(ABdiff: fs.FSDiff, version_info='count', indent=2,
|
|||||||
DEL=Fore.RED + 'DEL' + Style.RESET_ALL if use_color else 'DEL',
|
DEL=Fore.RED + 'DEL' + Style.RESET_ALL if use_color else 'DEL',
|
||||||
MOD=Fore.YELLOW + 'MOD' + Style.RESET_ALL if use_color else 'MOD',
|
MOD=Fore.YELLOW + 'MOD' + Style.RESET_ALL if use_color else 'MOD',
|
||||||
)
|
)
|
||||||
|
filetypecolors = dict(
|
||||||
|
DIR=Fore.BLUE if use_color else '',
|
||||||
|
REG='',
|
||||||
|
LNK=Fore.CYAN if use_color else '',
|
||||||
|
)
|
||||||
|
reset = Style.RESET_ALL if use_color else ''
|
||||||
|
hashcolor = Fore.MAGENTA if use_color else ''
|
||||||
|
|
||||||
|
def _print_row(tag, entry, level):
|
||||||
|
relpath = entry.relpath[2:]
|
||||||
|
|
||||||
|
# Format relpath using filetype-based colors
|
||||||
|
dname, fname = os.path.split(relpath)
|
||||||
|
if fname == '': # root directory leads to empty fname here
|
||||||
|
dirstr = (filetypecolors['DIR'] + '<root>' + reset)
|
||||||
|
else:
|
||||||
|
dirstr = (filetypecolors['DIR'] + dname + '/' + reset) \
|
||||||
|
if dname != '' else ''
|
||||||
|
fname = filetypecolors.get(entry.filetype, '') + fname + reset
|
||||||
|
|
||||||
|
if entry.filetype == 'LNK': # append symlink target
|
||||||
|
fname += ' -> ' + entry.symlink_target
|
||||||
|
|
||||||
|
relpath = dirstr + fname
|
||||||
|
|
||||||
|
hashchange = (hashcolor + entry.sha256.hex() + reset +
|
||||||
|
' ' + changetags[tag]) \
|
||||||
|
if show_hashes else changetags[tag]
|
||||||
|
|
||||||
|
print(
|
||||||
|
hashchange,
|
||||||
|
entry.unfrozen_perms,
|
||||||
|
relpath,
|
||||||
|
)
|
||||||
|
|
||||||
for l, d in ABdiff.flatten_tree():
|
for l, d in ABdiff.flatten_tree():
|
||||||
if d.A is None:
|
if d.A is None:
|
||||||
assert d.B is not None
|
assert d.B is not None
|
||||||
print(changetags['NEW'], d.B.unfrozen_perms,
|
_print_row('NEW', d.B, l)
|
||||||
#(indent_level + l) * indent * ' ' + d.B.filename,
|
|
||||||
d.B.relpath[2:],
|
|
||||||
)
|
|
||||||
elif d.B is None:
|
elif d.B is None:
|
||||||
print(changetags['DEL'], d.A.unfrozen_perms, (indent_level + l) * indent * ' ' + d.A.filename)
|
_print_row('DEL', d.A, l)
|
||||||
else:
|
else:
|
||||||
print(changetags['MOD'], d.B.unfrozen_perms, (indent_level + l) * indent * ' ' + d.B.filename)
|
_print_row('MOD', d.B, l)
|
||||||
|
|
||||||
|
|
||||||
def diff(store, filedir_path, version_info='count'):
|
def diff(store, filedir_path, version_info='count', show_hashes=False, use_color=True):
|
||||||
"""Unwrapped diff command that prints a diff"""
|
"""Unwrapped diff command that prints a diff"""
|
||||||
if not os.path.exists(filedir_path):
|
if not os.path.exists(filedir_path):
|
||||||
raise FileNotFoundError(f"Cannot diff non-existent file or directory {filedir_path}")
|
raise FileNotFoundError(f"Cannot diff non-existent file or directory {filedir_path}")
|
||||||
@ -44,7 +75,7 @@ def diff(store, filedir_path, version_info='count'):
|
|||||||
# get the diff object
|
# get the diff object
|
||||||
fsdiff = store.diff(filedir_path)
|
fsdiff = store.diff(filedir_path)
|
||||||
|
|
||||||
print_diff(fsdiff, version_info=version_info)
|
print_diff(fsdiff, version_info=version_info, show_hashes=show_hashes, use_color=use_color)
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@ -55,7 +86,17 @@ def diff(store, filedir_path, version_info='count'):
|
|||||||
default='count',
|
default='count',
|
||||||
help='How much info to display about file versions.',
|
help='How much info to display about file versions.',
|
||||||
)
|
)
|
||||||
def diff_cli(path, version_info):
|
@click.option(
|
||||||
|
'-H', "--show-hashes",
|
||||||
|
is_flag=True,
|
||||||
|
help='If given, prepend each line in the diff with the new file hash (SHA256).',
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--no-color",
|
||||||
|
is_flag=True,
|
||||||
|
help='If given, do not print any color output.',
|
||||||
|
)
|
||||||
|
def diff_cli(path, version_info, show_hashes, no_color):
|
||||||
"""Detect and describe changes to PATH
|
"""Detect and describe changes to PATH
|
||||||
|
|
||||||
PATH is a path to a file or directory inside an existing nancy store
|
PATH is a path to a file or directory inside an existing nancy store
|
||||||
@ -77,7 +118,7 @@ def diff_cli(path, version_info):
|
|||||||
s = store.Store(storepath)
|
s = store.Store(storepath)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
diff(store=s, filedir_path=path)
|
diff(store=s, filedir_path=path, show_hashes=show_hashes, use_color=not no_color)
|
||||||
except FileNotFoundError as e:
|
except FileNotFoundError as e:
|
||||||
print(str(e), file=sys.stderr)
|
print(str(e), file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
@ -113,7 +113,7 @@ class FSEntry:
|
|||||||
|
|
||||||
children = []
|
children = []
|
||||||
symlink_target = None
|
symlink_target = None
|
||||||
if stat.S_ISLNK(s):
|
if os.path.islink(path):
|
||||||
# Check links first, since it is not exclusive with dir or file checks
|
# Check links first, since it is not exclusive with dir or file checks
|
||||||
filetype = 'LNK'
|
filetype = 'LNK'
|
||||||
symlink_target = os.readlink(path)
|
symlink_target = os.readlink(path)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user