Skip to content

Commit

Permalink
Now --sync option supports nanoseconds timestamp without precision loss
Browse files Browse the repository at this point in the history
  • Loading branch information
xymy committed Nov 20, 2023
1 parent a38d9ae commit 37ddd26
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 9 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Now `--sync` option supports nanoseconds timestamp without precision loss.

### Documentation

- Added `--no-clean` and `--no-dist` options to `docs/release.py` script.
Expand Down
17 changes: 8 additions & 9 deletions src/gethash/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,17 @@ class AggOutput(Output):
def __init__(self, filepath: str | Path, *, sync: bool = False) -> None:
self.hash_file = HashFileWriter(filepath)
self.sync = sync
self.maxmtime = 0.0
self.maxt = 0

def close(self) -> None:
self.hash_file.close()
if self.sync:
os.utime(self.hash_file.name, (self.maxmtime, self.maxmtime))
os.utime(self.hash_file.name, ns=(self.maxt, self.maxt))

def dump(self, hash_line: str, hash_path: str, path: str) -> None:
self.hash_file.write_hash_line(hash_line)
if self.sync:
mtime = os.path.getmtime(path)
self.maxmtime = max(self.maxmtime, mtime)
self.maxt = max(os.stat(path).st_mtime_ns, self.maxt)


class SepOutput(Output):
Expand All @@ -74,8 +73,8 @@ def dump(self, hash_line: str, hash_path: str, path: str) -> None:
with HashFileWriter(hash_path) as hash_file:
hash_file.write_hash_line(hash_line)
if self.sync:
mtime = os.path.getmtime(path)
os.utime(hash_path, (mtime, mtime))
t = os.stat(path).st_mtime_ns
os.utime(hash_path, ns=(t, t))


class NullOutput(Output):
Expand Down Expand Up @@ -198,20 +197,20 @@ def check_hash(self, patterns: Iterable[str]) -> None:
self.echo_exception(hash_path, e)

def _check_hash(self, hash_path: str) -> None:
maxmtime = 0.0
maxt = 0
for i, hash_line in enumerate(HashFileReader(hash_path)):
try:
root = self.check_root(hash_path)
path = check_hash_line(hash_line, self.hash_function, root=root)
maxmtime = max(maxmtime, os.path.getmtime(path))
maxt = max(os.stat(path).st_mtime_ns, maxt)
except ParseHashLineError as e:
raise ParseHashFileError(e.hash_line, i) from None
except CheckHashLineError as e:
self.echo(f"[FAILURE] {e.path}", fg="red")
else:
self.echo(f"[SUCCESS] {path}", fg="green")
if self.sync:
os.utime(hash_path, (maxmtime, maxmtime))
os.utime(hash_path, ns=(maxt, maxt))

def check_root(self, path: str) -> str | None:
if self.inplace:
Expand Down

0 comments on commit 37ddd26

Please sign in to comment.