Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions dvc/command/config.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import argparse
import logging
import os

from dvc.command.base import CmdBaseNoRepo, append_doc_link
from dvc.config import Config, ConfigError
from dvc.repo import Repo
from dvc.utils.flatten import flatten

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -34,6 +36,14 @@ def __init__(self, args):
self.config = Config(validate=False)

def run(self):
if self.args.show_origin:
if any((self.args.value, self.args.unset)):
logger.error(
"--show-origin can't be used together with any of these "
"options: -u/--unset, value"
)
return 1

if self.args.list:
if any((self.args.name, self.args.value, self.args.unset)):
logger.error(
Expand All @@ -43,7 +53,11 @@ def run(self):
return 1

conf = self.config.load_one(self.args.level)
logger.info("\n".join(self._format_config(conf)))
prefix = self._config_file_prefix(
self.args.show_origin, self.config, self.args.level
)

logger.info("\n".join(self._format_config(conf, prefix)))
return 0

if self.args.name is None:
Expand All @@ -54,10 +68,14 @@ def run(self):

if self.args.value is None and not self.args.unset:
conf = self.config.load_one(self.args.level)
prefix = self._config_file_prefix(
self.args.show_origin, self.config, self.args.level
)

if remote:
conf = conf["remote"]
self._check(conf, remote, section, opt)
logger.info(conf[section][opt])
logger.info("{}{}".format(prefix, conf[section][opt]))
Comment thread
mrstegeman marked this conversation as resolved.
return 0

with self.config.edit(self.args.level) as conf:
Expand Down Expand Up @@ -90,9 +108,21 @@ def _check(self, conf, remote, section, opt=None):
)

@staticmethod
def _format_config(config):
def _format_config(config, prefix=""):
for key, value in flatten(config).items():
yield f"{key}={value}"
yield f"{prefix}{key}={value}"

@staticmethod
def _config_file_prefix(show_origin, config, level):
if not show_origin:
return ""

fname = config.files[level]

if level in ["local", "repo"]:
fname = os.path.relpath(fname, start=Repo.find_root())

return fname + "\t"


parent_config_parser = argparse.ArgumentParser(add_help=False)
Expand Down Expand Up @@ -152,4 +182,10 @@ def add_parser(subparsers, parent_parser):
action="store_true",
help="List all defined config values.",
)
config_parser.add_argument(
"--show-origin",
default=False,
action="store_true",
help="Show the source file containing each config value.",
)
config_parser.set_defaults(func=CmdConfig)
37 changes: 37 additions & 0 deletions tests/func/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,15 @@ def _do_test(self, local=False):
self.assertEqual(ret, 0)
self.assertTrue(self._contains(section, field, value, local))

ret = main(base + [section_field, value, "--show-origin"])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we parametrize these tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests are being reworked in #5179.

self.assertEqual(ret, 1)

ret = main(base + [section_field])
self.assertEqual(ret, 0)

ret = main(base + ["--show-origin", section_field])
self.assertEqual(ret, 0)

ret = main(base + [section_field, newvalue])
self.assertEqual(ret, 0)
self.assertTrue(self._contains(section, field, newvalue, local))
Expand All @@ -60,9 +66,15 @@ def _do_test(self, local=False):
self.assertEqual(ret, 0)
self.assertFalse(self._contains(section, field, value, local))

ret = main(base + [section_field, "--unset", "--show-origin"])
self.assertEqual(ret, 1)

ret = main(base + ["--list"])
self.assertEqual(ret, 0)

ret = main(base + ["--list", "--show-origin"])
self.assertEqual(ret, 0)

def test(self):
self._do_test(False)

Expand Down Expand Up @@ -174,3 +186,28 @@ def test_config_remote(tmp_dir, dvc, caplog):
caplog.clear()
assert main(["config", "remote.myremote.region"]) == 0
assert "myregion" in caplog.text


def test_config_show_origin(tmp_dir, dvc, caplog):
(tmp_dir / ".dvc" / "config").write_text(
"['remote \"myremote\"']\n"
" url = s3://bucket/path\n"
" region = myregion\n"
)

caplog.clear()
assert main(["config", "--show-origin", "remote.myremote.url"]) == 0
assert (
"{}\t{}\n".format(os.path.join(".dvc", "config"), "s3://bucket/path")
in caplog.text
)

caplog.clear()
assert main(["config", "--list", "--show-origin"]) == 0
assert (
"{}\t{}\n".format(
os.path.join(".dvc", "config"),
"remote.myremote.url=s3://bucket/path",
)
in caplog.text
)