mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
118 lines
4.0 KiB
Python
118 lines
4.0 KiB
Python
import os
|
|
from boto.s3.connection import S3Connection
|
|
import fasteners
|
|
|
|
from neatlynx.cmd_base import CmdBase
|
|
from neatlynx.logger import Logger
|
|
from neatlynx.exceptions import NeatLynxException
|
|
from neatlynx.data_file_obj import DataFileObjExisting
|
|
|
|
|
|
class DataRemoveError(NeatLynxException):
|
|
def __init__(self, msg):
|
|
NeatLynxException.__init__(self, 'Data remove error: {}'.format(msg))
|
|
|
|
|
|
class CmdDataRemove(CmdBase):
|
|
def __init__(self):
|
|
CmdBase.__init__(self)
|
|
pass
|
|
|
|
def define_args(self, parser):
|
|
self.set_skip_git_actions(parser)
|
|
|
|
parser.add_argument('target', metavar='', help='Target to remove - file or directory', nargs='*')
|
|
parser.add_argument('-r', '--recursive', action='store_true', help='Remove directory recursively')
|
|
parser.add_argument('-c', '--remove-from-cloud', action='store_true', help='Keep file in cloud')
|
|
pass
|
|
|
|
def run(self):
|
|
lock = fasteners.InterProcessLock(self.git.lock_file)
|
|
gotten = lock.acquire(timeout=5)
|
|
if not gotten:
|
|
Logger.printing('Cannot perform the command since NLX is busy and locked. Please retry the command later.')
|
|
return 1
|
|
|
|
try:
|
|
if not self.skip_git_actions and not self.git.is_ready_to_go():
|
|
return 1
|
|
|
|
for target in self.args.target:
|
|
self.remove_target(target)
|
|
|
|
if self.skip_git_actions:
|
|
self.not_committed_changes_warning()
|
|
return 0
|
|
|
|
message = 'NLX data remove: {}'.format(' '.join(self.args.target))
|
|
self.git.commit_all_changes_and_log_status(message)
|
|
finally:
|
|
lock.release()
|
|
|
|
def remove_target(self, target):
|
|
if os.path.isdir(target):
|
|
if not self.args.recursive:
|
|
raise DataRemoveError('Directory cannot be removed. Use --recurcive flag.')
|
|
|
|
if os.path.realpath(target) == \
|
|
os.path.realpath(os.path.join(self.git.git_dir_abs, self.config.data_dir)):
|
|
raise DataRemoveError('data directory cannot be removed')
|
|
|
|
return self.remove_dir(target)
|
|
dobj = DataFileObjExisting(target, self.git, self.config)
|
|
if os.path.islink(dobj.data_file_relative):
|
|
return self.remove_symlink(dobj.data_file_relative)
|
|
|
|
raise DataRemoveError('Cannot remove a regular file "{}"'.format(target))
|
|
|
|
def remove_symlink(self, file):
|
|
dobj = DataFileObjExisting(file, self.git, self.config)
|
|
|
|
if os.path.isfile(dobj.cache_file_relative):
|
|
os.remove(dobj.cache_file_relative)
|
|
dobj.remove_cache_dir_if_empty()
|
|
|
|
if os.path.isfile(dobj.state_file_relative):
|
|
os.remove(dobj.state_file_relative)
|
|
dobj.remove_state_dir_if_empty()
|
|
|
|
if self.args.remove_from_cloud:
|
|
self.remove_from_cloud(dobj.cache_file_aws_key)
|
|
|
|
os.remove(file)
|
|
pass
|
|
|
|
def remove_from_cloud(self, aws_file_name):
|
|
conn = S3Connection(self.config.aws_access_key_id, self.config.aws_secret_access_key)
|
|
bucket_name = self.config.aws_storage_bucket
|
|
bucket = conn.lookup(bucket_name)
|
|
if bucket:
|
|
key = bucket.get_key(aws_file_name)
|
|
if not key:
|
|
Logger.warn('S3 remove warning: file "{}" does not exist in S3'.format(aws_file_name))
|
|
else:
|
|
key.delete()
|
|
Logger.printing('File "{}" was removed from S3'.format(aws_file_name))
|
|
|
|
def remove_dir(self, data_dir):
|
|
for f in os.listdir(data_dir):
|
|
fname = os.path.join(data_dir, f)
|
|
if os.path.isdir(fname):
|
|
self.remove_dir(fname)
|
|
elif os.path.islink(fname):
|
|
self.remove_symlink(fname)
|
|
else:
|
|
raise DataRemoveError('Unsupported file type "{}"'.format(fname))
|
|
|
|
os.rmdir(data_dir)
|
|
pass
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import sys
|
|
try:
|
|
sys.exit(CmdDataRemove().run())
|
|
except NeatLynxException as e:
|
|
Logger.error(e)
|
|
sys.exit(1)
|