1from __future__ import unicode_literals
2
3import os
4import argparse
5
6import dvc.logger as logger
7from dvc.command.base import CmdBase
8from dvc.config import Config
9from dvc.exceptions import DvcException
10
11
12class CmdConfig(CmdBase):
13    def __init__(self, args):
14        from dvc.repo import Repo, NotDvcRepoError
15
16        self.args = args
17
18        try:
19            dvc_dir = os.path.join(Repo.find_root(), Repo.DVC_DIR)
20            saved_exc = None
21        except NotDvcRepoError as exc:
22            dvc_dir = None
23            saved_exc = exc
24
25        self.config = Config(dvc_dir, validate=False)
26        if self.args.system:
27            self.configobj = self.config._system_config
28        elif self.args.glob:
29            self.configobj = self.config._global_config
30        elif self.args.local:
31            if dvc_dir is None:
32                raise saved_exc
33            self.configobj = self.config._local_config
34        else:
35            if dvc_dir is None:
36                raise saved_exc
37            self.configobj = self.config._repo_config
38
39    def run_cmd(self):
40        return self.run()
41
42    def _unset(self, section, opt=None, configobj=None):
43        if configobj is None:
44            configobj = self.configobj
45
46        try:
47            self.config.unset(configobj, section, opt)
48            self.config.save(configobj)
49        except DvcException:
50            logger.error("failed to unset '{}'".format(self.args.name))
51            return 1
52        return 0
53
54    def _show(self, section, opt):
55        try:
56            self.config.show(self.configobj, section, opt)
57        except DvcException:
58            logger.error("failed to show '{}'".format(self.args.name))
59            return 1
60        return 0
61
62    def _set(self, section, opt, value):
63        try:
64            self.config.set(self.configobj, section, opt, value)
65            self.config.save(self.configobj)
66        except DvcException:
67            logger.error(
68                "failed to set '{}.{}' to '{}'".format(section, opt, value)
69            )
70            return 1
71        return 0
72
73    def run(self):
74        section, opt = self.args.name.lower().strip().split(".", 1)
75
76        if self.args.unset:
77            return self._unset(section, opt)
78        elif self.args.value is None:
79            return self._show(section, opt)
80        else:
81            return self._set(section, opt, self.args.value)
82
83
84parent_config_parser = argparse.ArgumentParser(add_help=False)
85parent_config_parser.add_argument(
86    "--global",
87    dest="glob",
88    action="store_true",
89    default=False,
90    help="Use global config.",
91)
92parent_config_parser.add_argument(
93    "--system", action="store_true", default=False, help="Use system config."
94)
95parent_config_parser.add_argument(
96    "--local", action="store_true", default=False, help="Use local config."
97)
98
99
100def add_parser(subparsers, parent_parser):
101    CONFIG_HELP = "Get or set config options."
102    config_parser = subparsers.add_parser(
103        "config",
104        parents=[parent_config_parser, parent_parser],
105        description=CONFIG_HELP,
106        help=CONFIG_HELP,
107    )
108    config_parser.add_argument(
109        "-u",
110        "--unset",
111        default=False,
112        action="store_true",
113        help="Unset option.",
114    )
115    config_parser.add_argument("name", help="Option name.")
116    config_parser.add_argument(
117        "value", nargs="?", default=None, help="Option value."
118    )
119    config_parser.set_defaults(func=CmdConfig)
120