Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion dvc/repo/add.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
import os
import logging
import colorama

from dvc.repo.scm_context import scm_context
from dvc.stage import Stage
from dvc.utils import walk_files
from dvc.utils import walk_files, LARGE_DIR_SIZE
from dvc.exceptions import RecursiveAddingWhileUsingFilename


logger = logging.getLogger(__name__)


@scm_context
def add(repo, target, recursive=False, no_commit=False, fname=None):
if recursive and fname:
raise RecursiveAddingWhileUsingFilename()

targets = _find_all_targets(repo, target, recursive)

if os.path.isdir(target) and len(targets) > LARGE_DIR_SIZE:
logger.warning(
"You are adding a large directory '{target}' recursively,"
" consider tracking it as a whole instead.\n"
"{purple}HINT:{nc} Remove the generated stage files and then"
" run {cyan}dvc add {target}{nc}".format(
purple=colorama.Fore.MAGENTA,
cyan=colorama.Fore.CYAN,
nc=colorama.Style.RESET_ALL,
target=target,
)
)

stages = _create_stages(repo, targets, fname, no_commit)

repo.check_dag(repo.stages() + stages)
Expand Down
2 changes: 2 additions & 0 deletions dvc/utils/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ def _makedirs(name, mode=0o777, exist_ok=False):
input = raw_input # noqa: F821
cast_bytes_py2 = cast_bytes
makedirs = _makedirs
range = xrange # noqa: F821

import StringIO
import io
Expand Down Expand Up @@ -148,3 +149,4 @@ def __exit__(self, *args):
input = input # noqa: F821
open = open # noqa: F821
cast_bytes_py2 = no_code
range = range # noqa: F821
29 changes: 28 additions & 1 deletion tests/func/test_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
import shutil
import filecmp
import posixpath
import logging
import colorama

from dvc.system import System
from mock import patch

from dvc.main import main
from dvc.utils import file_md5
from dvc.utils import file_md5, LARGE_DIR_SIZE
from dvc.utils.stage import load_stage_file
from dvc.utils.compat import range
from dvc.stage import Stage
from dvc.exceptions import DvcException, RecursiveAddingWhileUsingFilename
from dvc.output.base import OutputAlreadyTrackedError
Expand Down Expand Up @@ -87,6 +90,30 @@ def test(self):
ret = main(["add", "--recursive", self.DATA_DIR])
self.assertEqual(ret, 0)

def test_warn_about_large_directories(self):
warning = (
"You are adding a large directory 'large-dir' recursively,"
" consider tracking it as a whole instead.\n"
"{purple}HINT:{nc} Remove the generated stage files and then"
" run {cyan}dvc add large-dir{nc}".format(
purple=colorama.Fore.MAGENTA,
cyan=colorama.Fore.CYAN,
nc=colorama.Style.RESET_ALL,
)
)

os.mkdir("large-dir")

# Create a lot of files
for iteration in range(LARGE_DIR_SIZE + 1):
path = os.path.join("large-dir", str(iteration))
with open(path, "w") as fobj:
fobj.write(path)

with self._caplog.at_level(logging.WARNING, logger="dvc"):
assert main(["add", "--recursive", "large-dir"]) == 0
assert warning in self._caplog.text


class TestAddDirectoryWithForwardSlash(TestDvc):
def test(self):
Expand Down