Fix record command funky timekeeping

This commit is contained in:
Jacob Hinkle 2022-10-11 13:43:43 -04:00
parent e76489b1c0
commit c3dd418c8c
5 changed files with 75 additions and 46 deletions

View File

@ -6,6 +6,7 @@ from .. import store
from .common import confirm
from .diff import print_diff
from datetime import datetime
import os
import sys
from typing import Any, Optional, Union
@ -21,6 +22,7 @@ def record(
skip_confirm: bool = False,
) -> None:
"""Unwrapped record command"""
start_time = datetime.now()
if store_path is None:
curdir = os.path.realpath(os.getcwd())
@ -36,6 +38,12 @@ def record(
else: # this is an existing store
s = store.Store(store_path)
with s.new_program("RECORD", message) as p:
p.start_time = start_time # reset start to actual start of command
with s.committing() as cur: # entire record operation should be one transaction
# create a task for this operation
task = p.new_task(name="Store._record_recursive", cur=cur)
fsdiff = s.diff()
if show_diff:
@ -43,14 +51,21 @@ def record(
logger.info("Recording with message: {}", message)
if skip_confirm or confirm("Record the values above into the database?"):
s.record(fsdiff, message=message)
if skip_confirm or confirm(f"Record to {s.db_path}?"):
# descend the diff, tracking parent filedir IDs, creating them and
# recording new versions of each, when necessary
fsdiff.persist(cur=cur, source_task=task)
else:
logger.info("Cancelled!")
sys.exit(1)
@click.command()
@click.option(
"--no-show",
is_flag=True,
help="Do not show what is about to be recorded.",
)
@click.option(
"-H",
"--show-hashes",
@ -62,6 +77,12 @@ def record(
is_flag=True,
help="If given, do not print any color output.",
)
@click.option(
"-y",
"--yes",
is_flag=True,
help="Do not ask for confirmation.",
)
@click.option(
"-m",
"--message",
@ -78,7 +99,14 @@ def record(
"of given paths. If given the path to a non-store directory, a new "
"store is initialized there.",
)
def record_cli(show_hashes: bool, no_color: bool, message: str, store: str) -> None:
def record_cli(
no_show: bool,
show_hashes: bool,
yes: bool,
no_color: bool,
message: str,
store: str,
) -> None:
"""
Initialize tracking or record changes to a tracked directory.
"""
@ -87,4 +115,6 @@ def record_cli(show_hashes: bool, no_color: bool, message: str, store: str) -> N
show_hashes=show_hashes,
use_color=not no_color,
store_path=store,
skip_confirm=yes,
show_diff=not no_show,
)

View File

@ -154,7 +154,7 @@ class FSEntry:
cls: Type[_FSEntryT],
store: Optional["Store"] = None,
relpath: Optional[str] = None,
exclude: List[str] = ["nancy.db"],
exclude_prefixes: List[str] = ["nancy.db", "."],
parent: Optional[_FSEntryT] = None,
direntry: Optional["os.DirEntry[str]"] = None,
) -> _FSEntryT:
@ -206,15 +206,23 @@ class FSEntry:
for e in direntries
)
children = [
children = []
for rp, e in zip(childrenrelpaths, direntries):
skip = False
for p in exclude_prefixes:
if os.path.basename(rp).startswith(p):
skip = True
break
if skip:
continue
children.append(
cls.from_path(
store=store,
relpath=rp,
direntry=e,
)
for rp, e in zip(childrenrelpaths, direntries)
if rp not in exclude
]
)
for c in children: # now hash concatenated sorted hashes
# hash on perms+sha256 to enable recursively detecting perm
# changes without modifying the hashes of individual files,

View File

@ -129,7 +129,7 @@ class Program:
name: str
message: str
start_time: Optional[datetime.datetime] = None
start_time: datetime.datetime = datetime.datetime.fromtimestamp(0)
evaluated: bool = False
uuid: str = ""
@ -195,7 +195,7 @@ class Program:
WHERE
uuid = ?
""",
(self.start_time, end_time, self.uuid),
(self.start_time.timestamp(), end_time.timestamp(), self.uuid),
)
self.evaluated = True # prevent re-running
assert self.start_time is not None

View File

@ -78,7 +78,6 @@ class Store:
@classmethod
def init(cls: Type[_StoreT], message: str, directory: fs.PathStr) -> _StoreT:
start_time = datetime.datetime.now()
if not os.path.isdir(directory):
raise FileNotFoundError(
f"Directory {directory} must exist before initializing a store there.",
@ -107,10 +106,6 @@ class Store:
(new_store.uuid,),
)
with new_store.new_program("INIT", message) as p:
# set the timing to the actual times it took to initialize the db
p.start_time = start_time
return new_store
def filedir_root_key(self, cur: Optional[sqlite3.Cursor] = None) -> Optional[str]:
@ -188,26 +183,6 @@ class Store:
return fs.FSDiff.compute(recorded, current)
def record(
self,
diff: fs.FSDiff,
message: str,
parent_id: Optional[str] = None,
cur: Optional[sqlite3.Cursor] = None,
) -> None:
if cur is None:
assert self.conn is not None
cur = self.conn.cursor()
with self.new_program("RECORD", message) as p:
with self.committing() as cur: # entire record operation is one transaction
# create a task for this operation
task = p.new_task(name="Store._record_recursive", cur=cur)
# descend the diff, tracking parent filedir IDs, creating them and
# recording new versions of each, when necessary
diff.persist(cur=cur, source_task=task)
def find_store(path: Union[str, "os.PathLike[str]"]) -> Optional[str]:
"""

View File

@ -22,6 +22,22 @@ def junk_dir() -> Iterator[Path]:
def test_record(junk_dir: Path) -> None:
runner = CliRunner()
result = runner.invoke(
main,
[
"record",
"-s",
str(junk_dir),
"-m",
"This is just a test recording",
"--yes", # don't ask for confirmation
],
)
print(result.output)
assert result.exit_code == 0
assert "ERROR" not in result.output
# test again with confirmation
result = runner.invoke(
main,
[