Exemple #1
0
class CmdConfig(CmdBaseNoRepo):
    def __init__(self, args):
        from dvc.config import Config

        super().__init__(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:
            return self._list()

        if self.args.name is None:
            logger.error("name argument is required")
            return 1

        remote, section, opt = self.args.name

        if self.args.value is None and not self.args.unset:
            return self._get(remote, section, opt)

        return self._set(remote, section, opt)

    def _list(self):
        if any((self.args.name, self.args.value, self.args.unset)):
            logger.error(
                "-l/--list can't be used together with any of these "
                "options: -u/--unset, name, value"
            )
            return 1

        levels = self._get_appropriate_levels(self.args.level)

        for level in levels:
            conf = self.config.read(level)
            prefix = self._config_file_prefix(
                self.args.show_origin, self.config, level
            )
            configs = list(self._format_config(conf, prefix))
            if configs:
                ui.write("\n".join(configs))

        return 0

    def _get(self, remote, section, opt):
        from dvc.config import ConfigError

        levels = self._get_appropriate_levels(self.args.level)[::-1]

        for level in levels:
            conf = self.config.read(level)
            if remote:
                conf = conf["remote"]

            try:
                self._check(conf, remote, section, opt)
            except ConfigError:
                if self.args.level:
                    raise
            else:
                prefix = self._config_file_prefix(
                    self.args.show_origin, self.config, level
                )
                ui.write(prefix, conf[section][opt], sep="")
                break

        return 0

    def _set(self, remote, section, opt):
        with self.config.edit(self.args.level) as conf:
            if remote:
                conf = conf["remote"]
            if self.args.unset:
                self._check(conf, remote, section, opt)
                del conf[section][opt]
            else:
                self._check(conf, remote, section)
                conf[section][opt] = self.args.value

        if self.args.name == "cache.type":
            logger.warning(
                "You have changed the 'cache.type' option. This doesn't update"
                " any existing workspace file links, but it can be done with:"
                "\n             dvc checkout --relink"
            )

        return 0

    def _check(self, conf, remote, section, opt=None):
        from dvc.config import ConfigError

        name = "remote" if remote else "section"
        if section not in conf:
            raise ConfigError(f"{name} '{section}' doesn't exist")

        if opt and opt not in conf[section]:
            raise ConfigError(
                f"option '{opt}' doesn't exist in {name} '{section}'"
            )

    def _get_appropriate_levels(self, levels):
        if levels:
            self._validate_level_for_non_repo_operation(levels)
            return [levels]
        if self.config.dvc_dir is None:
            return self.config.SYSTEM_LEVELS
        return self.config.LEVELS

    def _validate_level_for_non_repo_operation(self, level):
        from dvc.config import ConfigError

        if self.config.dvc_dir is None and level in self.config.REPO_LEVELS:
            raise ConfigError("Not inside a DVC repo")

    @staticmethod
    def _format_config(config, prefix=""):
        from dvc.utils.flatten import flatten

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

    @staticmethod
    def _config_file_prefix(show_origin, config, level):
        from dvc.repo import Repo

        if not show_origin:
            return ""

        level = level or "repo"
        fname = config.files[level]

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

        return fname + "\t"
Exemple #2
0
class CmdConfig(CmdBaseNoRepo):
    def __init__(self, args):
        super().__init__(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 not self.args.level:
                logger.error(
                    "--show-origin requires one of these options: "
                    "--system, --global, --repo, --local"
                )
                return 1

        if self.args.list:
            if any((self.args.name, self.args.value, self.args.unset)):
                logger.error(
                    "-l/--list can't be used together with any of these "
                    "options: -u/--unset, name, value"
                )
                return 1

            conf = self.config.read(self.args.level)
            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:
            logger.error("name argument is required")
            return 1

        remote, section, opt = self.args.name

        if self.args.value is None and not self.args.unset:
            conf = self.config.read(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("{}{}".format(prefix, conf[section][opt]))
            return 0

        with self.config.edit(self.args.level) as conf:
            if remote:
                conf = conf["remote"]
            if self.args.unset:
                self._check(conf, remote, section, opt)
                del conf[section][opt]
            else:
                self._check(conf, remote, section)
                conf[section][opt] = self.args.value

        if self.args.name == "cache.type":
            logger.warning(
                "You have changed the 'cache.type' option. This doesn't update"
                " any existing workspace file links, but it can be done with:"
                "\n             dvc checkout --relink"
            )

        return 0

    def _check(self, conf, remote, section, opt=None):
        name = "remote" if remote else "section"
        if section not in conf:
            raise ConfigError(f"{name} '{section}' doesn't exist")

        if opt and opt not in conf[section]:
            raise ConfigError(
                f"option '{opt}' doesn't exist in {name} '{section}'"
            )

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

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

        level = level or "repo"
        fname = config.files[level]

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

        return fname + "\t"