diff --git a/dvc/cli.py b/dvc/cli.py index 0ea61e3a5..075aff008 100644 --- a/dvc/cli.py +++ b/dvc/cli.py @@ -16,7 +16,7 @@ from dvc.command.gc import CmdGC from dvc.command.add import CmdAdd from dvc.command.config import CmdConfig from dvc.command.checkout import CmdCheckout -from dvc.command.remote import CmdRemoteAdd, CmdRemoteRemove, CmdRemoteModify +from dvc.command.remote import CmdRemoteAdd, CmdRemoteRemove, CmdRemoteModify, CmdRemoteList from dvc.command.metrics import CmdMetrics from dvc.command.install import CmdInstall from dvc.stage import Stage @@ -327,6 +327,18 @@ def parse_args(argv=None): help='Use local config') remote_modify_parser.set_defaults(func=CmdRemoteModify) + + remote_list_parser = remote_subparsers.add_parser( + 'list', + parents=[parent_parser], + help='List remotes') + remote_list_parser.add_argument( + '--local', + action='store_true', + default=False, + help='Use local config') + remote_list_parser.set_defaults(func=CmdRemoteList) + # Metrics metrics_parser = subparsers.add_parser( 'metrics', diff --git a/dvc/command/config.py b/dvc/command/config.py index dc669c657..7e33b1f99 100644 --- a/dvc/command/config.py +++ b/dvc/command/config.py @@ -42,16 +42,15 @@ class CmdConfig(CmdBase): return 1 return 0 - def unset(self, section, opt): + def unset(self, section, opt=None): if section not in self.configobj.keys(): Logger.error("Section '{}' doesn't exist".format(section)) return 1 - if opt not in self.configobj[section].keys(): - return 0 + if opt in self.configobj[section].keys(): + del self.configobj[section][opt] - del self.configobj[section][opt] - if len(self.configobj[section]) == 0: + if len(self.configobj[section]) == 0 or opt == None: del self.configobj[section] return self.save() diff --git a/dvc/command/remote.py b/dvc/command/remote.py index 48c0dd853..d0335d830 100644 --- a/dvc/command/remote.py +++ b/dvc/command/remote.py @@ -1,6 +1,8 @@ -from dvc.command.common.base import CmdBase +import re + from dvc.config import Config from dvc.command.config import CmdConfig +from dvc.logger import Logger class CmdRemoteAdd(CmdConfig): @@ -20,3 +22,14 @@ class CmdRemoteModify(CmdConfig): section = Config.SECTION_REMOTE_FMT.format(self.args.name) self.args.name = '{}.{}'.format(section, self.args.option) return super(CmdRemoteModify, self).run() + + +class CmdRemoteList(CmdConfig): + def run(self): + for section in self.configobj.keys(): + r = re.match(Config.SECTION_REMOTE_REGEX, section) + if r: + name = r.group('name') + url = self.configobj[section].get(Config.SECTION_REMOTE_URL, '') + Logger.info('{}\t{}'.format(name, url)) + return 0 diff --git a/dvc/config.py b/dvc/config.py index a98454d9a..110a46d38 100644 --- a/dvc/config.py +++ b/dvc/config.py @@ -82,7 +82,7 @@ class Config(object): } - SECTION_REMOTE_REGEX = r'^\s*remote\s*"(.*)"\s*$' + SECTION_REMOTE_REGEX = r'^\s*remote\s*"(?P.*)"\s*$' SECTION_REMOTE_FMT = 'remote "{}"' SECTION_REMOTE_URL = 'url' SECTION_REMOTE_SCHEMA = { diff --git a/dvc/main.py b/dvc/main.py index b62ce0801..1f708d00f 100644 --- a/dvc/main.py +++ b/dvc/main.py @@ -1,11 +1,17 @@ from dvc.logger import Logger from dvc.cli import parse_args +from dvc.command.common.base import CmdBase + def main(argv=None): Logger.init() args = parse_args(argv) + # Init loglevel early in case we'll run + # into errors before setting it properly + CmdBase._set_loglevel(args) + try: cmd = args.func(args) except Exception as ex: diff --git a/tests/test_remote.py b/tests/test_remote.py new file mode 100644 index 000000000..8ad6b35b6 --- /dev/null +++ b/tests/test_remote.py @@ -0,0 +1,21 @@ +from dvc.main import main + +from tests.basic_env import TestDvc + + +class TestRemote(TestDvc): + def test(self): + remotes = ['a', 'b', 'c'] + + self.assertEqual(main(['remote', 'list']), 0) + self.assertNotEqual(main(['remote', 'remove', remotes[0]]), 0) + + for r in remotes: + self.assertEqual(main(['remote', 'add', r, 's3://bucket/name']), 0) + + self.assertEqual(main(['remote', 'list']), 0) + + self.assertEqual(main(['remote', 'remove', remotes[0]]), 0) + self.assertEqual(main(['remote', 'modify', remotes[0], 'option', 'value']), 0) + + self.assertEqual(main(['remote', 'list']), 0)