mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-06 07:18:28 +01:00
dvc: include cache urls in info output. (#4848)
* dvc: include cache urls in info output. Show cache urls for external and remote cache in the info output to assist in diagnosis of issues. Fixes #4574. * Remove unnecessary constant check for generator expression. * Add remotes and caches in version command for better diagnosis. * Fix flaky unit test to be runtime independent by using regex search. * Use Cache.by_scheme() for enumerating supported caches. * Add get_cloud_schemes routine for retrieval of configured remote schemes. Add tests for local remote and remote:// scheme for info. * Cleanup unused code. * info: refactor remote parsing Co-authored-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
co-authored by
Ruslan Kuprieiev
parent
251a3269c2
commit
6324bd8a69
+25
-1
@@ -8,7 +8,7 @@ from dvc.exceptions import DvcException, NotDvcRepoError
|
||||
from dvc.repo import Repo
|
||||
from dvc.scm.base import SCMError
|
||||
from dvc.system import System
|
||||
from dvc.tree import TREES
|
||||
from dvc.tree import TREES, get_tree_cls, get_tree_config
|
||||
from dvc.utils import error_link
|
||||
from dvc.utils.pkg import PKG
|
||||
from dvc.version import __version__
|
||||
@@ -50,6 +50,10 @@ def get_dvc_info():
|
||||
else:
|
||||
info.append("Cache types: " + error_link("no-dvc-cache"))
|
||||
|
||||
info.append(f"Caches: {_get_caches(repo.cache)}")
|
||||
|
||||
info.append(f"Remotes: {_get_remotes(repo.config)}")
|
||||
|
||||
except NotDvcRepoError:
|
||||
pass
|
||||
except SCMError:
|
||||
@@ -63,6 +67,26 @@ def get_dvc_info():
|
||||
return "\n".join(info)
|
||||
|
||||
|
||||
def _get_caches(cache):
|
||||
caches = (
|
||||
cache_type
|
||||
for cache_type, cache_instance in cache.by_scheme()
|
||||
if cache_instance
|
||||
)
|
||||
|
||||
# Caches will be always non-empty including the local cache
|
||||
return ", ".join(caches)
|
||||
|
||||
|
||||
def _get_remotes(config):
|
||||
schemes = (
|
||||
get_tree_cls(get_tree_config(config, name=remote)).scheme
|
||||
for remote in config["remote"]
|
||||
)
|
||||
|
||||
return ", ".join(schemes) or "None"
|
||||
|
||||
|
||||
def _get_linktype_support_info(repo):
|
||||
|
||||
links = {
|
||||
|
||||
@@ -32,23 +32,23 @@ TREES = [
|
||||
]
|
||||
|
||||
|
||||
def _get_tree(remote_conf):
|
||||
def get_tree_cls(remote_conf):
|
||||
for tree_cls in TREES:
|
||||
if tree_cls.supported(remote_conf):
|
||||
return tree_cls
|
||||
return LocalTree
|
||||
|
||||
|
||||
def _get_conf(repo, **kwargs):
|
||||
def get_tree_config(config, **kwargs):
|
||||
name = kwargs.get("name")
|
||||
if name:
|
||||
remote_conf = repo.config["remote"][name.lower()]
|
||||
remote_conf = config["remote"][name.lower()]
|
||||
else:
|
||||
remote_conf = kwargs
|
||||
return _resolve_remote_refs(repo, remote_conf)
|
||||
return _resolve_remote_refs(config, remote_conf)
|
||||
|
||||
|
||||
def _resolve_remote_refs(repo, remote_conf):
|
||||
def _resolve_remote_refs(config, remote_conf):
|
||||
# Support for cross referenced remotes.
|
||||
# This will merge the settings, shadowing base ref with remote_conf.
|
||||
# For example, having:
|
||||
@@ -74,7 +74,7 @@ def _resolve_remote_refs(repo, remote_conf):
|
||||
if parsed.scheme != "remote":
|
||||
return remote_conf
|
||||
|
||||
base = _get_conf(repo, name=parsed.netloc)
|
||||
base = get_tree_config(config, name=parsed.netloc)
|
||||
url = posixpath.join(base["url"], parsed.path.lstrip("/"))
|
||||
return {**base, **remote_conf, "url": url}
|
||||
|
||||
@@ -82,9 +82,9 @@ def _resolve_remote_refs(repo, remote_conf):
|
||||
def get_cloud_tree(repo, **kwargs):
|
||||
from dvc.config import SCHEMA, ConfigError, Invalid
|
||||
|
||||
remote_conf = _get_conf(repo, **kwargs)
|
||||
remote_conf = get_tree_config(repo.config, **kwargs)
|
||||
try:
|
||||
remote_conf = SCHEMA["remote"][str](remote_conf)
|
||||
except Invalid as exc:
|
||||
raise ConfigError(str(exc)) from None
|
||||
return _get_tree(remote_conf)(repo, remote_conf)
|
||||
return get_tree_cls(remote_conf)(repo, remote_conf)
|
||||
|
||||
@@ -11,4 +11,6 @@ def test_(tmp_dir, dvc, scm, caplog):
|
||||
assert re.search(f"Platform: {PYTHON_VERSION_REGEX} on .*", caplog.text)
|
||||
assert re.search(r"Supports: .*", caplog.text)
|
||||
assert re.search(r"Cache types: .*", caplog.text)
|
||||
assert re.search(r"Caches: local", caplog.text)
|
||||
assert re.search(r"Remotes: None", caplog.text)
|
||||
assert "Repo: dvc, git" in caplog.text
|
||||
|
||||
@@ -53,6 +53,38 @@ def test_info_in_broken_git_repo(tmp_dir, dvc, scm, caplog):
|
||||
assert "Repo: dvc, git (broken)" in dvc_info
|
||||
|
||||
|
||||
def test_caches(tmp_dir, dvc, caplog):
|
||||
tmp_dir.add_remote(
|
||||
name="sshcache", url="ssh://example.com/path", default=False
|
||||
)
|
||||
with tmp_dir.dvc.config.edit() as conf:
|
||||
conf["cache"]["ssh"] = "sshcache"
|
||||
|
||||
dvc_info = get_dvc_info()
|
||||
|
||||
# Order of cache types is runtime dependent
|
||||
assert re.search("Caches: (local, ssh|ssh, local)", dvc_info)
|
||||
|
||||
|
||||
def test_remotes_empty(tmp_dir, dvc, caplog):
|
||||
# No remotes are configured
|
||||
dvc_info = get_dvc_info()
|
||||
|
||||
assert "Remotes: None" in dvc_info
|
||||
|
||||
|
||||
def test_remotes(tmp_dir, dvc, caplog):
|
||||
tmp_dir.add_remote(name="server", url="ssh://localhost", default=False)
|
||||
tmp_dir.add_remote(
|
||||
name="r1", url="azure://example.com/path", default=False
|
||||
)
|
||||
tmp_dir.add_remote(name="r2", url="remote://server/path", default=False)
|
||||
|
||||
dvc_info = get_dvc_info()
|
||||
|
||||
assert re.search("Remotes: (ssh, azure|azure, ssh)", dvc_info)
|
||||
|
||||
|
||||
@pytest.mark.skipif(psutil is None, reason="No psutil.")
|
||||
def test_fs_info_in_repo(tmp_dir, dvc, caplog):
|
||||
os.mkdir(dvc.cache.local.cache_dir)
|
||||
|
||||
Reference in New Issue
Block a user