mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
dvc: add basic 'dvc status'
(dvc) ➜ myrepo git:(master) ✗ dvc status
foo.dvc
outs
changed: foo
foo2.dvc
outs
changed: foo2
deps
changed: foo1
foo1.dvc
outs
changed: foo1
deps
changed: foo
(dvc) ➜ myrepo git:(master) ✗ dvc status --cloud
new: c1/57a79031e1c40f85931829bc5fc552
Signed-off-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
+6
-1
@@ -163,7 +163,12 @@ def parse_args(argv=None):
|
||||
status_parser = subparsers.add_parser(
|
||||
'status',
|
||||
parents=[parent_cache_parser],
|
||||
help='Show mismatches between local cache and cloud cache')
|
||||
help='Show the project status')
|
||||
status_parser.add_argument('-c',
|
||||
'--cloud',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Show status of a local cache compared to a cloud')
|
||||
status_parser.set_defaults(func=CmdDataStatus)
|
||||
|
||||
# Repro
|
||||
|
||||
+18
-15
@@ -6,27 +6,30 @@ from dvc.command.data_sync import CmdDataBase
|
||||
|
||||
|
||||
class CmdDataStatus(CmdDataBase):
|
||||
def _show(self, status):
|
||||
for s in status:
|
||||
target, ret = s
|
||||
STATUS_LEN = 10
|
||||
STATUS_INDENT = '\t'
|
||||
|
||||
if ret == cloud.STATUS_UNKNOWN or ret == cloud.STATUS_OK:
|
||||
continue
|
||||
def _normalize(self, s):
|
||||
s+=':'
|
||||
if len(s) >= self.STATUS_LEN:
|
||||
return s
|
||||
return s + (self.STATUS_LEN - len(s))*' '
|
||||
|
||||
prefix_map = {
|
||||
cloud.STATUS_DELETED : 'deleted: ',
|
||||
cloud.STATUS_MODIFIED : 'modified:',
|
||||
cloud.STATUS_NEW : 'new file:',
|
||||
}
|
||||
def _show(self, status, indent=0):
|
||||
ind = indent * self.STATUS_INDENT
|
||||
|
||||
path = os.path.relpath(target, self.project.cache.cache_dir)
|
||||
|
||||
self.project.logger.info('\t{}\t{}'.format(prefix_map[ret], path))
|
||||
for key, value in status.items():
|
||||
if isinstance(value, dict):
|
||||
self.project.logger.info('{}{}'.format(ind, key))
|
||||
self._show(value, indent+1)
|
||||
else:
|
||||
self.project.logger.info('{}{}{}'.format(ind, self._normalize(value), key))
|
||||
|
||||
def do_run(self, target=None):
|
||||
indent = 1 if self.args.cloud else 0
|
||||
try:
|
||||
status = self.project.status(target=target, jobs=self.args.jobs)
|
||||
self._show(status)
|
||||
status = self.project.status(target=target, jobs=self.args.jobs, cloud=self.args.cloud)
|
||||
self._show(status, indent)
|
||||
except Exception as exc:
|
||||
self.project.logger.error('Failed to obtain data status', exc)
|
||||
return 1
|
||||
|
||||
@@ -75,6 +75,12 @@ class Dependency(object):
|
||||
def changed(self):
|
||||
return self._changed_md5()
|
||||
|
||||
def status(self):
|
||||
if self.changed():
|
||||
#FIXME better msgs
|
||||
return {self.rel_path: 'changed'}
|
||||
return {}
|
||||
|
||||
@staticmethod
|
||||
def is_dir_cache(cache):
|
||||
return cache.endswith(Output.MD5_DIR_SUFFIX)
|
||||
|
||||
+37
-2
@@ -2,6 +2,8 @@ import os
|
||||
import stat
|
||||
import networkx as nx
|
||||
|
||||
import dvc.cloud.base as cloud
|
||||
|
||||
from dvc.logger import Logger
|
||||
from dvc.exceptions import DvcException
|
||||
from dvc.stage import Stage, Output
|
||||
@@ -209,8 +211,41 @@ class Project(object):
|
||||
self.checkout()
|
||||
return ret
|
||||
|
||||
def status(self, target=None, jobs=1):
|
||||
return self.cloud.status(self._used_cache(target), jobs)
|
||||
def _local_status(self, target=None):
|
||||
status = {}
|
||||
|
||||
if target:
|
||||
stages = [Stage.load(self, target)]
|
||||
else:
|
||||
stages = self.stages()
|
||||
|
||||
for stage in self.stages():
|
||||
status.update(stage.status())
|
||||
|
||||
return status
|
||||
|
||||
def _cloud_status(self, target=None, jobs=1):
|
||||
status = {}
|
||||
for target, ret in self.cloud.status(self._used_cache(target), jobs):
|
||||
if ret == cloud.STATUS_UNKNOWN or ret == cloud.STATUS_OK:
|
||||
continue
|
||||
|
||||
prefix_map = {
|
||||
cloud.STATUS_DELETED: 'deleted',
|
||||
cloud.STATUS_MODIFIED: 'modified',
|
||||
cloud.STATUS_NEW: 'new',
|
||||
}
|
||||
|
||||
path = os.path.relpath(target, self.cache.cache_dir)
|
||||
|
||||
status[path] = prefix_map[ret]
|
||||
|
||||
return status
|
||||
|
||||
def status(self, target=None, jobs=1, cloud=False):
|
||||
if cloud:
|
||||
return self._cloud_status(target, jobs)
|
||||
return self._local_status(target)
|
||||
|
||||
def graph(self):
|
||||
G = nx.DiGraph()
|
||||
|
||||
@@ -183,3 +183,24 @@ class Stage(object):
|
||||
def checkout(self):
|
||||
for out in self.outs:
|
||||
out.checkout()
|
||||
|
||||
def _status(self, entries, name):
|
||||
ret = {}
|
||||
|
||||
for entry in entries:
|
||||
ret.update(entry.status())
|
||||
|
||||
if ret:
|
||||
return {name: ret}
|
||||
|
||||
return {}
|
||||
|
||||
def status(self):
|
||||
ret = {}
|
||||
ret.update(self._status(self.deps, 'deps'))
|
||||
ret.update(self._status(self.outs, 'outs'))
|
||||
|
||||
if ret:
|
||||
return {self.relpath: ret}
|
||||
|
||||
return {}
|
||||
|
||||
Reference in New Issue
Block a user