Only create userdir when explicitly requested

This commit is contained in:
Matthias 2019-07-31 19:39:54 +02:00
parent 8cef567abc
commit 2a141af42e
5 changed files with 32 additions and 7 deletions

View File

@ -104,6 +104,7 @@ user_data/
You can add the entry "user_data_dir" setting to your configuration, to always point your bot to this directory. You can add the entry "user_data_dir" setting to your configuration, to always point your bot to this directory.
Alternatively, pass in `--userdir` to every command. Alternatively, pass in `--userdir` to every command.
The bot will fail to start if the directory does not exist, but will create necessary subdirectories.
This directory should contain your custom strategies, custom hyperopts and hyperopt loss functions, backtesting historical data (downloaded using either backtesting command or the download script) and plot outputs. This directory should contain your custom strategies, custom hyperopts and hyperopt loss functions, backtesting historical data (downloaded using either backtesting command or the download script) and plot outputs.

View File

@ -178,7 +178,7 @@ class Configuration(object):
config.update({'user_data_dir': str(Path.cwd() / "user_data")}) config.update({'user_data_dir': str(Path.cwd() / "user_data")})
# reset to user_data_dir so this contains the absolute path. # reset to user_data_dir so this contains the absolute path.
config['user_data_dir'] = create_userdata_dir(config['user_data_dir']) config['user_data_dir'] = create_userdata_dir(config['user_data_dir'], create_dir=False)
logger.info('Using user-data directory: %s ...', config['user_data_dir']) logger.info('Using user-data directory: %s ...', config['user_data_dir'])
if 'datadir' in self.args and self.args.datadir: if 'datadir' in self.args and self.args.datadir:

View File

@ -2,6 +2,7 @@ import logging
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from pathlib import Path from pathlib import Path
from freqtrade import OperationalException
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -20,12 +21,26 @@ def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> str
return str(folder) return str(folder)
def create_userdata_dir(directory: str) -> Path: def create_userdata_dir(directory: str, create_dir=False) -> Path:
"""
Create userdata directory structure.
if create_dir is True, then the parent-directory will be created if it does not exist.
Sub-directories will always be created if the parent directory exists.
Raises OperationalException if given a non-existing directory.
:param directory: Directory to check
:param create_dir: Create directory if it does not exist.
:return: Path object containing the directory
"""
sub_dirs = ["backtest_results", "data", "hyperopts", "hyperopt_results", "plot", "strategies", ] sub_dirs = ["backtest_results", "data", "hyperopts", "hyperopt_results", "plot", "strategies", ]
folder = Path(directory) folder = Path(directory)
if not folder.is_dir(): if not folder.is_dir():
if create_dir:
folder.mkdir(parents=True) folder.mkdir(parents=True)
logger.info(f'Created user-data directory: {folder}') logger.info(f'Created user-data directory: {folder}')
else:
raise OperationalException(
f"Directory `{folder}` does not exist. "
"Please use `freqtrade create-userdir` to create a user directory")
# Create required subdirectories # Create required subdirectories
for f in sub_dirs: for f in sub_dirs:

View File

@ -335,7 +335,7 @@ def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> Non
) )
mocker.patch( mocker.patch(
'freqtrade.configuration.configuration.create_userdata_dir', 'freqtrade.configuration.configuration.create_userdata_dir',
lambda x: Path(x) lambda x, *args, **kwargs: Path(x)
) )
arglist = [ arglist = [
'--config', 'config.json', '--config', 'config.json',
@ -625,7 +625,7 @@ def test_create_userdata_dir(mocker, default_conf, caplog) -> None:
mocker.patch.object(Path, "is_dir", MagicMock(return_value=False)) mocker.patch.object(Path, "is_dir", MagicMock(return_value=False))
md = mocker.patch.object(Path, 'mkdir', MagicMock()) md = mocker.patch.object(Path, 'mkdir', MagicMock())
x = create_userdata_dir('/tmp/bar') x = create_userdata_dir('/tmp/bar', create_dir=True)
assert md.call_count == 7 assert md.call_count == 7
assert md.call_args[1]['parents'] is False assert md.call_args[1]['parents'] is False
assert log_has('Created user-data directory: /tmp/bar', caplog.record_tuples) assert log_has('Created user-data directory: /tmp/bar', caplog.record_tuples)
@ -641,6 +641,15 @@ def test_create_userdata_dir_exists(mocker, default_conf, caplog) -> None:
assert md.call_count == 0 assert md.call_count == 0
def test_create_userdata_dir_exists_exception(mocker, default_conf, caplog) -> None:
mocker.patch.object(Path, "is_dir", MagicMock(return_value=False))
md = mocker.patch.object(Path, 'mkdir', MagicMock())
with pytest.raises(OperationalException, match=r'Directory `/tmp/bar` does not exist.*'):
create_userdata_dir('/tmp/bar', create_dir=False)
assert md.call_count == 0
def test_validate_tsl(default_conf): def test_validate_tsl(default_conf):
default_conf['trailing_stop'] = True default_conf['trailing_stop'] = True
default_conf['trailing_stop_positive'] = 0 default_conf['trailing_stop_positive'] = 0

View File

@ -49,7 +49,7 @@ def start_create_userdir(args: Namespace) -> None:
:return: None :return: None
""" """
if "user_data_dir" in args and args.user_data_dir: if "user_data_dir" in args and args.user_data_dir:
create_userdata_dir(args.user_data_dir) create_userdata_dir(args.user_data_dir, create_dir=True)
else: else:
logger.warning("`create-userdir` requires --userdir to be set.") logger.warning("`create-userdir` requires --userdir to be set.")
sys.exit(1) sys.exit(1)