Files
dvc/neatlynx/data_file_obj.py
T

150 lines
4.5 KiB
Python

import os
from neatlynx.exceptions import NeatLynxException
class DataFilePathError(NeatLynxException):
def __init__(self, msg):
NeatLynxException.__init__(self, 'Data file error: {}'.format(msg))
class NotInDataDirError(NeatLynxException):
def __init__(self, file, data_dir):
NeatLynxException.__init__(self,
'Data file location error: the file "{}" has to be in the data directory "{}"'.
format(file, data_dir))
class DataFileObj(object):
STATE_FILE_SUFFIX = '.state'
CACHE_FILE_SEP = '_'
def __init__(self, data_file, git, config):
'''
nlx file name - system file name without data/cache/state prefix
'''
self._git = git
self._config = config
self._curr_dir_abs = os.path.realpath(os.curdir)
self._data_file = data_file
if not self.data_file_abs.startswith(self.data_dir_abs):
raise NotInDataDirError(self._data_file, self._config.data_dir)
pass
def create_symlink(self):
data_dir = os.path.dirname(self.data_file_relative)
cache_relative_to_data_dir = os.path.relpath(self.cache_file_relative, data_dir)
os.symlink(cache_relative_to_data_dir, self.data_file_relative)
@property
def data_dir_abs(self):
return os.path.join(self._git.git_dir_abs, self._config.data_dir)
# Data file properties
@property
def data_file_name(self):
return os.path.basename(self._data_file)
@property
def data_file_nlx(self):
return os.path.relpath(self.data_file_abs, self.data_dir_abs)
# @property
# def data_file_abs(self):
# return os.path.realpath(self.data_file_relative)
@property
def data_file_abs(self):
'''Do not fully resolve file name since it is a link'''
return os.path.abspath(self.data_file_relative)
@property
def data_file_relative(self):
return self._data_file
# Cache file properties
@property
def cache_file_name(self):
if not self._git.curr_commit:
return None
return self.data_file_name + self.CACHE_FILE_SEP + self._git.curr_commit
@property
def cache_file_nlx(self):
if not self._git.curr_commit:
return None
return self.data_file_nlx + self.CACHE_FILE_SEP + self._git.curr_commit
@property
def cache_file_aws_key(self):
return '{}/{}'.format(self._config.aws_storage_prefix, self.cache_file_nlx).strip('/')
@property
def cache_file_abs(self):
return os.path.join(self._git.git_dir_abs, self._config.cache_dir, self.cache_file_nlx)
@property
def cache_file_relative(self):
return os.path.relpath(self.cache_file_abs, self._curr_dir_abs)
# State file properties
@property
def state_file_name(self):
return self.data_file_name + self.STATE_FILE_SUFFIX
@property
def state_file_nlx(self):
return self.data_file_nlx + self.STATE_FILE_SUFFIX
@property
def state_file_abs(self):
return os.path.join(self._git.git_dir_abs, self._config.state_dir, self.state_file_nlx)
@property
def state_file_relative(self):
return os.path.relpath(self.state_file_abs, self._curr_dir_abs)
@staticmethod
def files_to_dobjs(files, git, config):
result = []
externally_created_files = []
for file in files:
try:
result.append(DataFileObj(file, git, config))
except NotInDataDirError:
externally_created_files.append(file)
return result, externally_created_files
class DataFileObjExisting(DataFileObj):
def __init__(self, data_file, git, config):
DataFileObj.__init__(self, data_file, git, config)
if not os.path.islink(data_file):
raise DataFilePathError('Data file must be a symbolic link')
pass
@property
def cache_file_name(self):
return os.path.basename(self.cache_file_abs)
@property
def cache_file_abs(self):
return os.path.realpath(self.data_file_relative)
@staticmethod
def remove_dir_if_empty(dir):
cache_file_dir = os.path.dirname(dir)
if cache_file_dir != '' and not os.listdir(cache_file_dir):
os.rmdir(cache_file_dir)
def remove_state_dir_if_empty(self):
self.remove_dir_if_empty(self.state_file_relative)
def remove_cache_dir_if_empty(self):
self.remove_dir_if_empty(self.cache_file_relative)