Files
dvc/tests/unit/test_dvcfile.py
T
b349b39d62 Decoupling dvcignore and fs (#5812)
* Decoupling dvcignore and fs

[x] remove dvcignore from fs objects
[x] attach dvcignore to repo
[x] add ignore check to functions(add, checkout, output, pipeline, etc)
[x] pass all tests
[x] final check

* Solve all of the arugments error.

* add dvcignore to dvc list

* Solve some test_ignore cases

* add dvcignore to checkout.

1. add dvcignore to 'checkout', 'add'
2. add ignore_filter to fs

* Solve two tests

* Get rid of ignore_filter

* Add ignore examine to download

* Solve a test issue

* Solve dvcignore and subrepo problems

* Solve sub repo error

* Revert some changes

* pass all tests

* Remove debug codes

* Some final exams

* dvcignore trie tree only update when needed

* reuse of the dir result in path walk.

* Some change after code review.

* Recover something from false `--force` push

* add abspath trans to dvcginore

* pass pylint

* pylint related

* Update dvc/fs/repo.py

Co-authored-by: Ruslan Kuprieiev <[email protected]>

* Changes related to reviews.

* dvcignore call api change

from dvcignore.walk_files(fs.walk(path_info)) to dvcignore.walk_files(fs, path_info)

* Get rid of PathInfo in test_ignore.py

* fs.walk follow the arguments of os.walk

* Dvcignore as parameters

* pass dvcignore as arguments to checkouts

* Decoupling state and repo

* Update dvc/dvcfile.py

Co-authored-by: Paweł Redzyński <[email protected]>

* Update dvc/objects/stage.py

Co-authored-by: Paweł Redzyński <[email protected]>

* Solve some small problems

* Add tests to verify that dependency now not ignore

fix#5256

* Update dvc/ignore.py

* Update dvc/fs/git.py

* Update dvc/repo/__init__.py

* Some small improvements

* pass black

* Refactor is_ignored

* Update dvc/output/base.py

* repofs: use dvcignore in exists/isdir/isfile

Per https://github.com/iterative/dvc/pull/5812/files#r630604524

Co-authored-by: myname <[email protected]>
Co-authored-by: Ruslan Kuprieiev <[email protected]>
Co-authored-by: Paweł Redzyński <[email protected]>
Co-authored-by: Ruslan Kuprieiev <[email protected]>
2021-05-12 05:29:04 +03:00

127 lines
3.7 KiB
Python

import pytest
from dvc.dvcfile import (
PIPELINE_FILE,
PIPELINE_LOCK,
Dvcfile,
FileIsGitIgnored,
PipelineFile,
SingleStageFile,
)
from dvc.stage import PipelineStage
from dvc.stage.exceptions import (
StageFileDoesNotExistError,
StageFileFormatError,
StageFileIsNotDvcFileError,
)
from dvc.utils.fs import remove
from dvc.utils.serialize import dump_yaml
@pytest.mark.parametrize(
"path",
[
"pipelines.yaml",
"pipelines.yml",
"custom-pipelines.yml",
"custom-pipelines.yaml",
"../models/pipelines.yml",
],
)
def test_pipelines_file(path):
file_obj = Dvcfile(object(), path)
assert isinstance(file_obj, PipelineFile)
@pytest.mark.parametrize(
"path", ["Dvcfile", "stage.dvc", "../models/stage.dvc"]
)
def test_pipelines_single_stage_file(path):
file_obj = Dvcfile(object(), path)
assert isinstance(file_obj, SingleStageFile)
@pytest.mark.parametrize("file", ["stage.dvc", "dvc.yaml"])
@pytest.mark.parametrize("is_dvcignored", [True, False])
def test_stage_load_on_not_existing_file(tmp_dir, dvc, file, is_dvcignored):
dvcfile = Dvcfile(dvc, file)
if is_dvcignored:
(tmp_dir / ".dvcignore").write_text(file)
assert not dvcfile.exists()
with pytest.raises(StageFileDoesNotExistError) as exc_info:
assert dvcfile.stages.values()
assert str(exc_info.value) == f"'{file}' does not exist"
@pytest.mark.parametrize("file", ["stage.dvc", "dvc.yaml"])
def test_stage_load_on_non_file(tmp_dir, dvc, file):
(tmp_dir / file).mkdir()
dvcfile = Dvcfile(dvc, file)
with pytest.raises(StageFileIsNotDvcFileError):
assert dvcfile.stages.values()
@pytest.mark.parametrize("file", ["stage.dvc", "dvc.yaml"])
def test_stage_load_on_invalid_data(tmp_dir, dvc, file):
data = {"is_this_a_valid_dvcfile": False}
dump_yaml(file, data)
dvcfile = Dvcfile(dvc, file)
with pytest.raises(StageFileFormatError):
assert dvcfile.stages
with pytest.raises(StageFileFormatError):
assert dvcfile.validate(data, file)
def test_dump_stage(tmp_dir, dvc):
stage = PipelineStage(
dvc, cmd="command", name="stage_name", path="dvc.yaml"
)
dvcfile = Dvcfile(dvc, "dvc.yaml")
dvcfile.dump(stage, update_lock=False, update_pipeline=False)
assert not (tmp_dir / PIPELINE_FILE).exists()
assert not (tmp_dir / PIPELINE_LOCK).exists()
dvcfile.dump(stage, update_pipeline=False)
assert not (tmp_dir / PIPELINE_FILE).exists()
assert (tmp_dir / PIPELINE_LOCK).exists()
assert dvcfile._lockfile.load()
remove(tmp_dir / PIPELINE_LOCK)
dvcfile.dump(stage)
assert (tmp_dir / PIPELINE_FILE).exists()
assert (tmp_dir / PIPELINE_LOCK).exists()
assert list(dvcfile.stages.values()) == [stage]
@pytest.mark.parametrize("file", ["stage.dvc", "dvc.yaml"])
def test_stage_load_file_exists_but_dvcignored(tmp_dir, dvc, scm, file):
(tmp_dir / file).write_text("")
(tmp_dir / ".dvcignore").write_text(file)
dvc._reset()
dvcfile = Dvcfile(dvc, file)
with pytest.raises(StageFileDoesNotExistError) as exc_info:
assert dvcfile.stages.values()
assert str(exc_info.value) == f"'{file}' is dvc-ignored"
@pytest.mark.parametrize("file", ["foo.dvc", "dvc.yaml"])
def test_try_loading_dvcfile_that_is_gitignored(tmp_dir, dvc, scm, file):
with open(tmp_dir / ".gitignore", "a+") as fd:
fd.write(file)
# create a file just to avoid other checks
(tmp_dir / file).write_text("")
scm._reset()
dvcfile = Dvcfile(dvc, file)
with pytest.raises(FileIsGitIgnored) as exc_info:
dvcfile._load()
assert str(exc_info.value) == f"bad DVC file name '{file}' is git-ignored."