Files
dvc/dvc/cli.py
T
2019-11-26 20:07:20 +05:45

187 lines
4.5 KiB
Python

"""Command line interface for dvc."""
from __future__ import print_function
from __future__ import unicode_literals
import argparse
import logging
import sys
import dvc.command.add as add
import dvc.command.cache as cache
import dvc.command.checkout as checkout
import dvc.command.commit as commit
import dvc.command.config as config
import dvc.command.daemon as daemon
import dvc.command.data_sync as data_sync
import dvc.command.destroy as destroy
import dvc.command.diff as diff
import dvc.command.gc as gc
import dvc.command.get as get
import dvc.command.get_url as get_url
import dvc.command.imp as imp
import dvc.command.imp_url as imp_url
import dvc.command.init as init
import dvc.command.install as install
import dvc.command.lock as lock
import dvc.command.metrics as metrics
import dvc.command.move as move
import dvc.command.pipeline as pipeline
import dvc.command.remote as remote
import dvc.command.remove as remove
import dvc.command.repro as repro
import dvc.command.root as root
import dvc.command.run as run
import dvc.command.tag as tag
import dvc.command.unprotect as unprotect
import dvc.command.update as update
import dvc.command.version as version
from dvc.command.base import fix_subparsers
from dvc.exceptions import DvcParserError
logger = logging.getLogger(__name__)
COMMANDS = [
init,
get,
get_url,
destroy,
add,
remove,
move,
unprotect,
run,
repro,
data_sync,
gc,
imp,
imp_url,
config,
checkout,
remote,
cache,
metrics,
install,
root,
lock,
pipeline,
daemon,
commit,
tag,
diff,
version,
update,
]
class DvcParser(argparse.ArgumentParser):
"""Custom parser class for dvc CLI."""
def error(self, message):
"""Custom error method.
Args:
message (str): error message.
Raises:
dvc.exceptions.DvcParser: dvc parser exception.
"""
logger.error(message)
self.print_help()
raise DvcParserError()
class VersionAction(argparse.Action): # pragma: no cover
# pylint: disable=too-few-public-methods
"""Shows dvc version and exits."""
def __call__(self, parser, namespace, values, option_string=None):
from dvc import __version__
print(__version__)
sys.exit(0)
def get_parent_parser():
"""Create instances of a parser containing common arguments shared among
all the commands.
When overwriting `-q` or `-v`, you need to instantiate a new object
in order to prevent some weird behavior.
"""
parent_parser = argparse.ArgumentParser(add_help=False)
log_level_group = parent_parser.add_mutually_exclusive_group()
log_level_group.add_argument(
"-q", "--quiet", action="store_true", default=False, help="Be quiet."
)
log_level_group.add_argument(
"-v",
"--verbose",
action="store_true",
default=False,
help="Be verbose.",
)
return parent_parser
def parse_args(argv=None):
"""Parses CLI arguments.
Args:
argv: optional list of arguments to parse. sys.argv is used by default.
Raises:
dvc.exceptions.DvcParserError: raised for argument parsing errors.
"""
parent_parser = get_parent_parser()
# Main parser
desc = "Data Version Control"
parser = DvcParser(
prog="dvc",
description=desc,
parents=[parent_parser],
formatter_class=argparse.RawTextHelpFormatter,
add_help=False,
)
# NOTE: We are doing this to capitalize help message.
# Unfortunately, there is no easier and clearer way to do it,
# as adding this argument in get_parent_parser() either in
# log_level_group or on parent_parser itself will cause unexpected error.
parser.add_argument(
"-h",
"--help",
action="help",
default=argparse.SUPPRESS,
help="Show this help message and exit.",
)
# NOTE: On some python versions action='version' prints to stderr
# instead of stdout https://bugs.python.org/issue18920
parser.add_argument(
"-V",
"--version",
action=VersionAction,
nargs=0,
help="Show program's version.",
)
# Sub commands
subparsers = parser.add_subparsers(
title="Available Commands",
metavar="COMMAND",
dest="cmd",
help="Use dvc COMMAND --help for command-specific help.",
)
fix_subparsers(subparsers)
for cmd in COMMANDS:
cmd.add_parser(subparsers, parent_parser)
args = parser.parse_args(argv)
return args