mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-10 23:10:42 +01:00
Intermediate PR in removing path_info from our code base. It is completely removed from the main codebase and is still being used in tests, which will be migrated in the followups. For fs-specific simple path manipulation, we've introduced `fs.path` helper (similar to `os.path`). Fixes #6774
74 lines
2.4 KiB
Python
74 lines
2.4 KiB
Python
from dataclasses import dataclass, field
|
|
from typing import TYPE_CHECKING, List
|
|
|
|
from dvc.output import Output
|
|
|
|
if TYPE_CHECKING:
|
|
from dvc.repo import Repo
|
|
|
|
|
|
@dataclass
|
|
class Metadata:
|
|
"""
|
|
Container for storing metadata for a given path, similar in spirit to
|
|
`os.stat_result`.
|
|
"""
|
|
|
|
# required field
|
|
fs_path: str
|
|
repo: "Repo"
|
|
|
|
# computed fields
|
|
is_output: bool = field(init=False, default=False) # is it an output?
|
|
# is the path part of an output?
|
|
part_of_output: bool = field(init=False, default=False)
|
|
# does the path contain outputs?
|
|
contains_outputs: bool = field(init=False, default=False)
|
|
# is the path tracked by dvc? equivalent to (is_output or part_of_output)
|
|
is_dvc: bool = field(init=False, default=False)
|
|
# does dvc has any output in that path or inside it? equiv. to bool(outs)
|
|
output_exists: bool = field(init=False)
|
|
|
|
# optional fields
|
|
isdir: bool = False # is it a directory?
|
|
is_exec: bool = False # is it an executable?
|
|
outs: List[Output] = field(default_factory=list) # list of outputs
|
|
|
|
def __post_init__(self):
|
|
self.output_exists = bool(self.outs)
|
|
|
|
if not self.output_exists:
|
|
return
|
|
|
|
# it can contain multiple outputs
|
|
if len(self.outs) > 1:
|
|
self.contains_outputs = True
|
|
else:
|
|
out = self.outs[0]
|
|
# or, the path itself could be an output
|
|
self.is_output = self.fs_path == out.fs_path
|
|
|
|
# or, a directory must have an output somewhere deep inside it
|
|
if not self.is_output:
|
|
self.contains_outputs = self.repo.fs.path.isin(
|
|
out.fs_path, self.fs_path
|
|
)
|
|
|
|
# or, the path could be a part of an output, i.e. inside of an output
|
|
self.part_of_output = not self.is_output and not self.contains_outputs
|
|
|
|
self.is_dvc = self.is_output or self.part_of_output
|
|
# if it contains outputs, it must be a dir
|
|
self.isdir = self.contains_outputs
|
|
|
|
@property
|
|
def isfile(self):
|
|
# self.isdir might require additional computation, especially if it's
|
|
# a dir that's inside a dvc-tracked dir
|
|
# since, `Metadata()` does not support being used as null (i.e. when
|
|
# path does not exist), `isfile` becomes `isdir`'s complement.
|
|
return not self.isdir
|
|
|
|
def __str__(self):
|
|
return f"Metadata: {self.fs_path}"
|