rfc: Prompt as functions instead of a class

This commit is contained in:
Mr. Outis
2018-12-14 10:47:18 -06:00
parent df044c60ac
commit 948021f5b0
10 changed files with 39 additions and 48 deletions
+2 -2
View File
@@ -1,3 +1,4 @@
import dvc.prompt as prompt
from dvc.command.base import CmdBase
from dvc.exceptions import DvcException
@@ -9,8 +10,7 @@ class CmdDestroy(CmdBase):
u'all data files, as well as cache in .dvc/cache.\n' \
u'Are you sure you want to continue?'
if not self.args.force \
and not self.project.prompt.prompt(msg, False):
if not self.args.force and not prompt.confirm(msg):
msg = u'Cannot destroy without a confirmation from the ' \
u'user. Use \'-f\' to force.'
raise DvcException(msg)
+2 -1
View File
@@ -1,4 +1,5 @@
import os
import dvc.prompt as prompt
from dvc.command.base import CmdBase
@@ -26,7 +27,7 @@ class CmdGC(CmdBase):
self.project.logger.warn(msg)
msg = 'Are you sure you want to proceed?'
if not self.args.force and not self.project.prompt.prompt(msg):
if not self.args.force and not prompt.confirm(msg):
return 1
self.project.gc(all_branches=self.args.all_branches,
+2 -3
View File
@@ -1,3 +1,4 @@
import dvc.prompt as prompt
from dvc.exceptions import DvcException
from dvc.command.base import CmdBase
from dvc.logger import logger
@@ -16,9 +17,7 @@ class CmdRemove(CmdBase):
.format(target)
)
confirmed = self.project.prompt.prompt(msg)
if confirmed:
if prompt.confirm(msg):
return False
raise DvcException(
+2 -3
View File
@@ -1,5 +1,6 @@
import collections
import os
import dvc.prompt as prompt
from dvc.exceptions import DvcException, MoveNotDataSourceError
from dvc.exceptions import NotDvcProjectError
@@ -29,7 +30,6 @@ class Project(object):
from dvc.cache import Cache
from dvc.data_cloud import DataCloud
from dvc.updater import Updater
from dvc.prompt import Prompt
root_dir = self._find_root(root_dir)
@@ -51,7 +51,6 @@ class Project(object):
self.cache = Cache(self)
self.cloud = DataCloud(self, config=self.config._config)
self.updater = Updater(self.dvc_dir)
self.prompt = Prompt()
self._files_to_git_add = []
@@ -619,7 +618,7 @@ class Project(object):
msg = "Missing cache for directory '{}'. " \
"Cache for files inside will be lost. " \
"Would you like to continue? Use '-f' to force. "
if not (force or self.prompt.prompt(msg, False)):
if not force and not prompt.confirm(msg):
raise DvcException("Unable to fully collect "
"used cache without cache "
"for directory '{}'".format(out))
+19 -23
View File
@@ -1,6 +1,5 @@
import sys
from dvc.progress import progress
from getpass import getpass
try:
# NOTE: in Python3 raw_input() was renamed to input()
@@ -9,32 +8,29 @@ except NameError:
pass
class Prompt(object):
def __init__(self):
self.default = None
def ask(prompt, limited_to=None):
if not sys.stdout.isatty():
return
def prompt(self, msg, default=False): # pragma: no cover
if self.default is not None:
return self.default
while True:
answer = input(prompt + ' ').lower()
if not sys.stdout.isatty():
return default
if not limited_to:
return answer
answer = input(msg + u' (y/n)\n').lower()
while answer not in ['yes', 'no', 'y', 'n']:
answer = input('Enter \'yes\' or \'no\'.\n').lower()
if answer in limited_to:
return answer
return answer[0] == "y"
print("Your response must be one of: {options}. Please try again."
.format(options=limited_to))
def prompt_password(self, msg): # pragma: no cover
import getpass
if not sys.stdout.isatty():
return None
def confirm(statement):
prompt = '{statement} [y/n]'.format(statement=statement)
answer = ask(prompt, limited_to=['yes', 'no', 'y', 'n'])
return answer and answer.startswith('y')
msg = '{}:\n'.format(msg)
if not progress.is_finished:
msg = u'\n' + msg
return getpass.getpass(msg)
def password(statement):
prompt = '{statement}: '.format(statement=statement)
return getpass(prompt)
+2 -3
View File
@@ -7,6 +7,7 @@ import shutil
import posixpath
from operator import itemgetter
import dvc.prompt as prompt
from dvc.system import System
from dvc.remote.base import RemoteBase, STATUS_MAP
from dvc.logger import logger
@@ -372,9 +373,7 @@ class RemoteLOCAL(RemoteBase):
.format(file)
)
confirmed = self.project.prompt.prompt(msg, False)
if not confirmed:
if not prompt.confirm(msg):
raise DvcException('Unable to remove {} without a confirmation'
" from the user. Use '-f' to force."
.format(file))
+2 -1
View File
@@ -7,6 +7,7 @@ try:
except ImportError:
paramiko = None
import dvc.prompt as prompt
from dvc.logger import logger
from dvc.progress import progress
from dvc.remote.base import RemoteBase, RemoteBaseCmdError
@@ -93,7 +94,7 @@ class RemoteSSH(RemoteBase):
if self.ask_password and self.password is None:
msg = ("Enter a private key passphrase or a password for "
"host '{}' port '{}' user '{}'").format(host, port, user)
self.password = self.project.prompt.prompt_password(msg)
self.password = prompt.password(msg)
ssh.connect(host,
username=user,
+5 -3
View File
@@ -4,6 +4,7 @@ import posixpath
import subprocess
from schema import Schema, SchemaError, Optional, Or, And
import dvc.prompt as prompt
import dvc.dependency as dependency
import dvc.output as output
from dvc.exceptions import DvcException
@@ -251,8 +252,8 @@ class Stage(object):
msg = "Going to reproduce '{}'. Are you sure you want to continue?"
msg = msg.format(self.relpath)
if interactive \
and not self.project.prompt.prompt(msg):
if interactive and not prompt.confirm(msg):
raise DvcException('Reproduction aborted by the user')
self.project.logger.info(u'Reproducing \'{}\''.format(self.relpath))
@@ -412,7 +413,8 @@ class Stage(object):
msg = "'{}' already exists. Do you wish to run the command and " \
"overwrite it?".format(stage.relpath)
if not overwrite and not project.prompt.prompt(msg, False):
if not overwrite and not prompt.confirm(msg):
raise StageFileAlreadyExistsError(stage.relpath)
return stage
+2 -6
View File
@@ -163,12 +163,10 @@ class TestRemoveFilesWhenCheckout(CheckoutBase):
class TestCheckoutCleanWorkingDir(CheckoutBase):
@patch('dvc.prompt.Prompt.prompt')
@patch('dvc.prompt.confirm', return_value=True)
def test(self, mock_prompt):
from tests.test_data_cloud import sleep
mock_prompt.return_value = True
stages = self.dvc.add(self.DATA_DIR)
stage = stages[0]
@@ -184,12 +182,10 @@ class TestCheckoutCleanWorkingDir(CheckoutBase):
self.assertEqual(ret, 0)
self.assertFalse(os.path.exists(working_dir_change))
@patch('dvc.prompt.Prompt.prompt')
@patch('dvc.prompt.confirm', return_value=False)
def test_force(self, mock_prompt):
from tests.test_data_cloud import sleep
mock_prompt.return_value = False
stages = self.dvc.add(self.DATA_DIR)
self.assertEqual(len(stages), 1)
stage = stages[0]
+1 -3
View File
@@ -69,10 +69,8 @@ class TestRemovePurge(TestDvc):
self.assertFalse(os.path.exists(self.FOO))
self.assertFalse(os.path.exists(dvcfile))
@patch('dvc.prompt.Prompt.prompt')
@patch('dvc.prompt.confirm', return_value=False)
def test_force(self, mock_prompt):
mock_prompt.return_value = False
dvcfile = self.dvc.add(self.FOO)[0].path
ret = main(['remove', '--purge', dvcfile])