mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-09 07:18:27 +01:00
* objects: make HashInfo & HashFile hashable * stage/output: collect objects (HashFiles) instead of NamedCache * remote/data_cloud: use objs instead of NamedCache * repo: use objects instead of NamedCache * rerun black after rebase * remove NamedCache usage from run-cache * drop NamedCache * update HashInfo.__hash__ * update unit tests * revert remote_name change * start cleaning up test failures * fix tree obj expansion * update missing cache logging * fix external dict handling * update naive odb.gc * update state save behavior for pull * update test_data_cloud * update test_remote * fix gc with multiple repos * objects.tree: support filtering w/preserved hash_info * fix stage cache restore * drop fs.path_info from HashFile.__hash__ * objects: add optional name attribute * revert missing cache logging name/suffix changes * revert name changes in remote tests * review fixes * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update dvc/remote/base.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: Ruslan Kuprieiev <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
87 lines
2.1 KiB
Python
87 lines
2.1 KiB
Python
import errno
|
|
import logging
|
|
import os
|
|
from typing import TYPE_CHECKING, Optional
|
|
|
|
from .errors import ObjectFormatError
|
|
|
|
if TYPE_CHECKING:
|
|
from dvc.fs.base import BaseFileSystem
|
|
from dvc.hash_info import HashInfo
|
|
from dvc.types import DvcPath
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class HashFile:
|
|
def __init__(
|
|
self,
|
|
path_info: Optional["DvcPath"],
|
|
fs: Optional["BaseFileSystem"],
|
|
hash_info: "HashInfo",
|
|
name: Optional[str] = None,
|
|
):
|
|
self.path_info = path_info
|
|
self.fs = fs
|
|
self.hash_info = hash_info
|
|
self.name = name
|
|
|
|
@property
|
|
def size(self):
|
|
if not (self.path_info and self.fs):
|
|
return None
|
|
return self.fs.getsize(self.path_info)
|
|
|
|
def __len__(self):
|
|
return 1
|
|
|
|
def __str__(self):
|
|
return f"object {self.hash_info}"
|
|
|
|
def __bool__(self):
|
|
return bool(self.hash_info)
|
|
|
|
def __eq__(self, other):
|
|
if not isinstance(other, HashFile):
|
|
return False
|
|
return (
|
|
self.path_info == other.path_info
|
|
and self.fs == other.fs
|
|
and self.hash_info == other.hash_info
|
|
)
|
|
|
|
def __hash__(self):
|
|
return hash(
|
|
(
|
|
self.hash_info,
|
|
self.path_info,
|
|
self.fs.scheme if self.fs else None,
|
|
)
|
|
)
|
|
|
|
def check(self, odb, check_hash=True):
|
|
from .stage import get_file_hash
|
|
|
|
if not check_hash:
|
|
if not self.fs.exists(self.path_info):
|
|
raise FileNotFoundError(
|
|
errno.ENOENT, os.strerror(errno.ENOENT), self.path_info
|
|
)
|
|
else:
|
|
return None
|
|
|
|
actual = get_file_hash(
|
|
self.path_info, self.fs, self.hash_info.name, odb.state
|
|
)
|
|
|
|
logger.trace(
|
|
"cache '%s' expected '%s' actual '%s'",
|
|
self.path_info,
|
|
self.hash_info,
|
|
actual,
|
|
)
|
|
|
|
assert actual.name == self.hash_info.name
|
|
if actual.value.split(".")[0] != self.hash_info.value.split(".")[0]:
|
|
raise ObjectFormatError(f"{self} is corrupted")
|