mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-11 23:10:10 +01:00
91 lines
3.3 KiB
Python
91 lines
3.3 KiB
Python
import re
|
|
import sys
|
|
from collections import defaultdict
|
|
|
|
from dvc.logger import Logger
|
|
from dvc.command.common.base import CmdBase
|
|
from dvc.graph.workflow import Workflow
|
|
from dvc.graph.commit import Commit
|
|
from dvc.executor import Executor, ExecutorError
|
|
from dvc.utils import parse_target_metric_file
|
|
|
|
|
|
class CmdShowWorkflow(CmdBase):
|
|
COMMIT_LEN = 7
|
|
LOG_SEPARATOR = '|'
|
|
LOG_FORMAT = ['%h', '%p', '%an', '%ai', '%s']
|
|
|
|
def get_all_commits(self, target):
|
|
# git log --all --abbrev=7 --pretty=format:"%h|%p|%an|%ai|%s"
|
|
try:
|
|
merges_map = self.get_merges_map()
|
|
|
|
format_str = self.LOG_SEPARATOR.join(self.LOG_FORMAT)
|
|
git_cmd = ['git', 'log', '--all', '--abbrev={}'.format(self.COMMIT_LEN),
|
|
'--pretty=format:{}'.format(format_str)]
|
|
lines = Executor.exec_cmd_only_success(git_cmd).split('\n')
|
|
|
|
branches_multimap = self.branches_multimap()
|
|
|
|
wf = Workflow(target, merges_map, branches_multimap)
|
|
for line in lines:
|
|
items = line.split(self.LOG_SEPARATOR, len(self.LOG_FORMAT))
|
|
assert len(items) == 5, 'Git wrapper: git log format has {} items, 5 expected'.format(len(items))
|
|
hash, parent_hash, name, date, comment = items
|
|
|
|
commit = Commit(hash, parent_hash, name, date, comment,
|
|
*self.was_target_changed(hash, target),
|
|
branch_tips=branches_multimap.get(hash))
|
|
wf.add_commit(commit)
|
|
|
|
return wf
|
|
except ExecutorError:
|
|
raise
|
|
|
|
def was_target_changed(self, hash, target):
|
|
git_cmd = ['git', 'show', '--pretty=', '--name-only', hash]
|
|
changed_files = set(Executor.exec_cmd_only_success(git_cmd).split('\n'))
|
|
|
|
if target not in changed_files:
|
|
return False, None
|
|
|
|
metric = parse_target_metric_file(target)
|
|
if metric is None:
|
|
return False, None
|
|
|
|
return True, metric
|
|
|
|
def get_merges_map(self):
|
|
# git log --merges --all --abbrev=7
|
|
# {'a4b56f1': back_to_600_est}
|
|
git_cmd = ['git', 'log', '--all', '--merges',
|
|
'--abbrev={}'.format(self.COMMIT_LEN)]
|
|
# lines = map(str.strip, Executor.exec_cmd_only_success(git_cmd).split('\n'))
|
|
# lines.map
|
|
return {}
|
|
|
|
def branches_multimap(self):
|
|
git_cmd = ['git', 'show-ref', '--abbrev={}'.format(self.COMMIT_LEN)]
|
|
lines = Executor.exec_cmd_only_success(git_cmd).split('\n')
|
|
func = unicode.split if sys.version_info[0] < 3 else str.split
|
|
items_full = map(func, lines)
|
|
items = map(lambda it: (it[0], re.sub(r'^refs/heads/', '', it[1])), items_full)
|
|
|
|
result = defaultdict(list)
|
|
for (hash, branch) in items:
|
|
result[hash].append(branch)
|
|
return result
|
|
|
|
def run(self):
|
|
target = self.args.target
|
|
if not target:
|
|
target = self.project.config._config['Global'].get('Target', '')
|
|
self.project.logger.debug(u'Set show workflow target as {}'.format(target))
|
|
|
|
wf = self.get_all_commits(target)
|
|
wf.build_graph(self.args.dvc_commits,
|
|
self.args.all_commits,
|
|
self.args.max_commits)
|
|
return 0
|
|
|