Add show command

This commit is contained in:
Jacob Hinkle 2022-10-12 10:21:20 -04:00
parent 3a2c15aaf4
commit a51ff2a877
2 changed files with 137 additions and 0 deletions

View File

@ -5,6 +5,7 @@ from ..version import __version__
from . import diff
from . import record
from . import show
from typing import Optional
@ -51,4 +52,5 @@ def main(log_level: str) -> None:
main.add_command(diff.status, name="status")
main.add_command(record.record_cli, name="record")
main.add_command(show.show_cli, name="show")
main.add_command(version)

135
src/nancy/cli/show.py Normal file
View File

@ -0,0 +1,135 @@
import click
from loguru import logger
from .. import fs, store
from datetime import datetime
import os
import sys
from typing import Any, Optional, Union
import warnings
def print_recorded(
root: fs.FSEntry,
indent: int = 2,
indent_level: int = 0,
use_color: bool = True,
show_hashes: bool = False,
) -> None:
"""Pretty print an FSEntry object"""
if use_color:
try:
from colorama import init, Fore, Back, Style # NOQA
except ImportError:
warnings.warn("Could not import colorama library. Color output disabled.")
use_color = False
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(entry: fs.FSEntry, level: int) -> None:
if len(entry.versions) == 0:
print(Fore.RED + "NOVERSIONS" + Style.RESET_ALL + entry.sha256)
else:
ver = entry.versions[-1]
relpath = entry.relpath
# 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 ""
)
assert ver.filetype is not None
fname = filetypecolors.get(str(ver.filetype), "") + fname + reset
if ver.filetype == fs.FileType.LNK: # append symlink target
assert ver.symlink_target is not None
fname += " -> " + ver.symlink_target
relpath = dirstr + fname
print(
(hashcolor + ver.sha256.hex() + reset) if show_hashes else "",
ver.perms,
relpath,
)
for lev, d in root.flatten_tree():
_print_row(d, lev)
@logger.catch
def show(
store_path: Optional[Union[str, "os.PathLike[Any]"]] = None,
show_hashes: bool = False,
use_color: bool = True,
) -> None:
"""Unwrapped show command"""
start_time = datetime.now()
if store_path is None:
curdir = os.path.realpath(os.getcwd())
logger.info("Looking for store in {}", curdir)
store_path = store.find_store(curdir)
if store_path is None: # If no store found, assume we're creating here
logger.error(
"Could not find nancy.db in any directory containing {}", curdir
)
sys.exit(1)
logger.info("Found store at {}", store_path)
s = store.Store(store_path)
# then find a listing covering all the expected paths
recorded = s.fs_entries(shallow=True)
if recorded is None:
logger.warning(
f"No recorded entries in {store_path}. Have you run `nancy record` yet?"
)
else:
print_recorded(recorded, show_hashes=show_hashes, use_color=use_color)
@click.command()
@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.",
)
@click.option(
"-s",
"--store",
type=str,
default=None,
help="Top-level of store. If omitted, use closest common parent directory "
"of given paths. If given the path to a non-store directory, a new "
"store is initialized there.",
)
def show_cli(
show_hashes: bool,
no_color: bool,
store: str,
) -> None:
"""
Show what's currently recorded in a store.
"""
show(
show_hashes=show_hashes,
use_color=not no_color,
store_path=store,
)