Add show command
This commit is contained in:
parent
3a2c15aaf4
commit
a51ff2a877
@ -5,6 +5,7 @@ from ..version import __version__
|
|||||||
|
|
||||||
from . import diff
|
from . import diff
|
||||||
from . import record
|
from . import record
|
||||||
|
from . import show
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
@ -51,4 +52,5 @@ def main(log_level: str) -> None:
|
|||||||
|
|
||||||
main.add_command(diff.status, name="status")
|
main.add_command(diff.status, name="status")
|
||||||
main.add_command(record.record_cli, name="record")
|
main.add_command(record.record_cli, name="record")
|
||||||
|
main.add_command(show.show_cli, name="show")
|
||||||
main.add_command(version)
|
main.add_command(version)
|
||||||
|
|||||||
135
src/nancy/cli/show.py
Normal file
135
src/nancy/cli/show.py
Normal 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,
|
||||||
|
)
|
||||||
Loading…
x
Reference in New Issue
Block a user