コード例 #1
0
    def test_remove_raises_oserror(self, tmp_path, monkeypatch, capsys):
        def mock_remove(p):
            raise OSError("MOCK_REMOVE: %s" % p)

        setup_workdir(tmp_path, [
            "foo/one.xxx",
            "more/two.xxx",
        ])
        problematic_file1 = tmp_path / "foo/one.xxx"
        problematic_file1 = problematic_file1.relative_to(tmp_path)
        problematic_file2 = tmp_path / "more/two.xxx"
        problematic_file2 = problematic_file2.relative_to(tmp_path)

        with cd(str(tmp_path)):
            monkeypatch.setattr("path.Path.remove_p", mock_remove)
            cleanup_files(["**/*.xxx"])

            captured = capsys.readouterr()
            print(captured.out)
            expected1 = "REMOVE: %s" % problematic_file1
            expected2 = "OSError: MOCK_REMOVE: %s" % problematic_file1
            assert expected1 in captured.out
            assert expected2 in captured.out
            expected2 = "OSError: MOCK_REMOVE: %s" % problematic_file2
            assert expected2 in captured.out
コード例 #2
0
    def test_within_readonly_dir__is_not_removed(self, tmp_path, capsys):
        # -- SETUP:
        readonly_mode = 0o555  # dr-xr-xr-x (disabled: write-mode)
        setup_workdir(tmp_path,
                      ["one.xxx/.ignored", "readonly.dir/two.xxx/.ignored"])
        my_dir1 = tmp_path / "one.xxx/"
        readonly_dir = tmp_path / "readonly.dir/"
        my_dir2 = readonly_dir / "two.xxx/"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        readonly_dir_initial_mode = stat.S_IMODE(readonly_dir.stat().st_mode)
        readonly_dir.chmod(readonly_mode)
        readonly_dir_mode = stat.S_IMODE(readonly_dir.stat().st_mode)
        print("DIAG: readonly_dir.mode= 0o%o" % readonly_dir_mode)
        assert path_is_readonly(readonly_dir)

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_dirs(["**/*.xxx"], cwd)
        captured = capsys.readouterr()
        assert not my_dir1.exists(), "OOPS: my_dir1 was NOT_REMOVED"
        assert my_dir2.exists(), "OOPS: my_dir2 was REMOVED"
        expected = "RMTREE: {0}".format(my_dir2)
        assert expected in captured.out

        # -- CLEANUP:
        readonly_dir.chmod(readonly_dir_initial_mode)
コード例 #3
0
    def test_cleanup_dirs_without_configfile(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            ".venv_DEFAULT/.dir",
            "downloads/.dir",
        ])
        my_dir1 = tmp_path / ".venv_DEFAULT"
        my_dir2 = tmp_path / "downloads"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        tasks_dir = tmp_path / "tasks.py"
        tasks_dir.write_text(TASKS_FILE_TEXT_USING_CLEANUP_MODULE_ONLY)
        config_dir = tmp_path / "invoke.yaml"
        assert not config_dir.exists()

        # -- EXECUTE AND VERIFY:
        with use_subprocess_coverage(tmp_path):
            with cd(str(tmp_path)):
                output = ensure_text(run_with_output("invoke cleanup.all"))

        assert not my_dir1.exists()
        assert not my_dir2.exists()
        expected1 = "RMTREE: .venv_DEFAULT"
        expected2 = "RMTREE: downloads"
        assert expected1 in output
        assert expected2 in output
コード例 #4
0
    def test_with_configfile_and_cleanup_files_overrides_default(
            self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx",
            "more/two.zzz",
        ])
        my_file1 = tmp_path / "one.xxx"
        my_file2 = tmp_path / "more/two.zzz"
        assert my_file1.exists() and my_file1.is_file()
        assert my_file2.exists() and my_file2.is_file()

        tasks_file = tmp_path / "tasks.py"
        tasks_file.write_text(TASKS_FILE_TEXT_USING_CLEANUP_MODULE_ONLY)
        config_file = tmp_path / "invoke.yaml"
        config_file.write_text(u"""
cleanup_all:
    files:
      - "**/*.xxx"
      - "**/*.zzz"
""")

        # -- EXECUTE AND VERIFY:
        with use_subprocess_coverage(tmp_path):
            with cd(str(tmp_path)):
                output = ensure_text(run_with_output("invoke cleanup.all"))

        assert not my_file1.exists()
        assert not my_file2.exists()
        expected1 = "REMOVE: one.xxx"
        expected2 = "REMOVE: more/two.zzz"
        assert expected1 in output
        assert expected2 in output
コード例 #5
0
    def test_with_configfile_and_cleanup_extra_directories_extends_default(
            self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx/.dir",
            "more/two.zzz/.dir",
        ])
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "more/two.zzz"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        tasks_dir = tmp_path / "tasks.py"
        tasks_dir.write_text(TASKS_FILE_TEXT_USING_CLEANUP_MODULE_ONLY)
        config_dir = tmp_path / "invoke.yaml"
        config_dir.write_text(u"""
cleanup:
    extra_directories:
      - "**/*.xxx"
      - "**/*.zzz"
""")

        # -- EXECUTE AND VERIFY:
        output = run_with_output_in_directory(tmp_path)

        assert not my_dir1.exists()
        assert not my_dir2.exists()
        expected1 = "RMTREE: one.xxx"
        expected2 = "RMTREE: more/two.zzz"
        assert expected1 in output
        assert expected2 in output
コード例 #6
0
    def test_cleanup_files_without_configfile(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "DEFAULT_FILE.bak",
            "more/DEFAULT_FILE.log",
        ])
        my_file1 = tmp_path / "DEFAULT_FILE.bak"
        my_file2 = tmp_path / "more/DEFAULT_FILE.log"
        assert my_file1.exists() and my_file1.is_file()
        assert my_file2.exists() and my_file2.is_file()

        tasks_file = tmp_path / "tasks.py"
        tasks_file.write_text(TASKS_FILE_TEXT_USING_CLEANUP_MODULE_ONLY)
        config_file = tmp_path / "invoke.yaml"
        assert not config_file.exists()

        # -- EXECUTE AND VERIFY:
        output = run_with_output_in_directory(tmp_path)

        assert not my_file1.exists()
        assert not my_file2.exists()
        expected1 = "REMOVE: DEFAULT_FILE.bak"
        expected2 = "REMOVE: more/DEFAULT_FILE.log"
        assert expected1 in output
        assert expected2 in output
コード例 #7
0
    def test_within_no_permissions_dir__is_not_removed(self, tmp_path, capsys):
        # -- SETUP:
        no_permission_mode = 0o000  # d---.---.--- (NO_PERMISSIONS)
        setup_workdir(tmp_path,
                      ["one.xxx/.ignored", "no_permission/two.xxx/.ignored"])
        my_dir1 = tmp_path / "one.xxx/"
        no_permission_dir = tmp_path / "no_permission/"
        my_dir2 = no_permission_dir / "two.xxx/"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        no_permission_initial_mode = stat.S_IMODE(
            no_permission_dir.stat().st_mode)
        no_permission_dir.chmod(no_permission_mode)
        no_permission_mode = stat.S_IMODE(no_permission_dir.stat().st_mode)
        print("DIAG: no_permission_dir.mode= 0o%o" % no_permission_mode)
        assert not path_is_readable(no_permission_dir)
        assert not path_is_writable(no_permission_dir)
        assert not path_is_executable(no_permission_dir)

        # -- EXECUTE AND CLEANUP:
        cwd = tmp_path
        cleanup_dirs(["**/*.xxx"], cwd)
        captured = capsys.readouterr()
        no_permission_dir.chmod(no_permission_initial_mode)

        # -- VERIFY:
        assert not my_dir1.exists(), "OOPS: my_dir1 was NOT_REMOVED"
        assert my_dir2.exists(), "OOPS: my_dir2 was REMOVED"
        expected = "RMTREE: {0}".format(my_dir2)
        assert expected not in captured.out, "OOPS: Traversal into NO_PERMISSION.dir"
コード例 #8
0
    def test_with_file_in_readonly_dir_is_not_removed(self, tmp_path, capsys):
        # -- SETUP:
        readonly_mode = 0o555   # dr-xr-xr-x (disabled: write-mode)
        setup_workdir(tmp_path, [
            "readonly.dir/one.xxx",
        ])
        my_dir = tmp_path/"readonly.dir"
        my_file1 = my_dir/"one.xxx"
        my_dir.chmod(readonly_mode)
        assert my_file1.exists() and my_file1.is_file()
        my_dir_mode = stat.S_IMODE(my_file1.stat().st_mode)
        print("DIAG: my_dir.mode= 0o%o" % my_dir_mode)
        assert path_is_readable(my_dir)
        assert not path_is_writable(my_dir)

        # -- EXECUTE AND VERIFY: Best-effort, ignore read-only file(s)
        # with pytest.raises(OSError, match="Permission denied"):
        cwd = tmp_path
        cleanup_files(["**/*.xxx"], cwd)
        captured = capsys.readouterr()
        assert my_file1.exists(), "OOPS: my_file1 was removed."
        if python_version < python35:
            # -- REASON: OSError is not raised for newer py3 versions.
            assert "OSError" in captured.out
            assert "Permission denied:" in captured.out
            assert str(my_file1) in captured.out
コード例 #9
0
    def test_invoke_removes_other_cleanup_dirs(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx/.dir",
            "more/two.xxx/.dir",
        ])
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "more/two.xxx"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        tasks_file = tmp_path / "tasks.py"
        tasks_file.write_text(u"""
from __future__ import absolute_import, print_function
from invoke import task, Collection
import invoke_cleanup as cleanup

namespace = Collection()
namespace.add_collection(Collection.from_module(cleanup), name="cleanup")
namespace.configure(cleanup.namespace.configuration())

from invoke_cleanup import config_add_cleanup_dirs
config_add_cleanup_dirs(["**/*.xxx", "one.xxx"])
""")

        # -- EXECUTE AND VERIFY:
        output = run_with_output_in_directory(tmp_path)

        assert not my_dir1.exists()
        assert not my_dir2.exists()
        expected1 = "RMTREE: one.xxx"
        expected2 = "RMTREE: more/two.xxx"
        assert expected1 in output
        assert expected2 in output
コード例 #10
0
    def test_with_two_patterns(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, ["one.xxx/.ignored", "more/two.zzz/.ignored"])
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "more/two.zzz"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_dirs(["**/*.xxx/", "**/*.zzz/"], cwd)
        assert not my_dir1.exists(), "OOPS: my_dir1 was NOT_REMOVED"
        assert not my_dir2.exists(), "OOPS: my_dir2 was NOT_REMOVED"
コード例 #11
0
    def test_with_one_pattern_in_other_workdir_subtree(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, ["one.xxx/.ignored", "other/two.xxx/.ignored"])
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "other/two.xxx"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_dirs(["**/*.xxx"], workdir=cwd / "other")
        assert my_dir1.exists(), "OOPS: my_dir1 was REMOVED"
        assert not my_dir2.exists(), "OOPS: my_dir2 was NOT_REMOVED"
コード例 #12
0
    def test_with_exact_name(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, ["one.xxx/.ignored", "more/two.xxx/.ignored"])
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "more/two.xxx"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_dirs(["more/two.xxx"], cwd)
        assert my_dir1.exists(), "OOPS: my_dir1 was REMOVED"
        assert not my_dir2.exists(), "OOPS: my_dir2 was NOT REMOVED"
コード例 #13
0
    def test_without_any_matching_dirs(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, ["one.xxx/.ignored", "more/two.xxx/.ignored"])
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "more/two.xxx"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_dirs(["**/*.OTHER"], cwd)
        assert my_dir1.exists(), "OOPS: my_dir1 was REMOVED"
        assert my_dir2.exists(), "OOPS: my_dir2 was REMOVED"
コード例 #14
0
    def test_dry_run__should_removes_no_dirs(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, ["one.xxx/.ignored", "more/two.xxx/.ignored"])
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "more/two.xxx"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_dirs(["**/*.xxx"], cwd, dry_run=True)
        assert my_dir1.exists(), "OOPS: my_dir1 was REMOVED"
        assert my_dir2.exists(), "OOPS: my_dir2 was REMOVED"
コード例 #15
0
    def test_with_one_pattern_in_other_workdir_subtree(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx",
            "other/more/two.xxx"
        ])
        my_file1 = tmp_path/"one.xxx"
        my_file2 = tmp_path/"other/more/two.xxx"
        assert my_file1.exists() and my_file1.is_file()
        assert my_file2.exists() and my_file2.is_file()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_files(["**/*.xxx"], cwd/"other")
        assert my_file1.exists()
        assert not my_file2.exists()
コード例 #16
0
    def test_with_two_patterns(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx",
            "more/two.zzz"
        ])
        my_file1 = tmp_path/"one.xxx"
        my_file2 = tmp_path/"more/two.zzz"
        assert my_file1.exists() and my_file1.is_file()
        assert my_file2.exists() and my_file2.is_file()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_files(["**/*.xxx", "**/*.zzz"], cwd)
        assert not my_file1.exists(), "OOPS: my_file1 was NOT_REMOVED"
        assert not my_file2.exists(), "OOPS: my_file2 was NOT_REMOVED"
コード例 #17
0
    def test_removes_uncommitted_files(self, mode, tmp_path, capsys,
                                       monkeypatch):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx",
            "two.xxx",
        ])
        my_file1 = tmp_path / "one.xxx"
        my_file2 = tmp_path / "two.xxx"
        assert my_file1.exists() and my_file1.is_file()
        assert my_file2.exists() and my_file2.is_file()

        # -- EXECUTE AND VERIFY:
        Path = tmp_path.__class__
        git_clean_dry_run = (mode == "dry_run")
        curdir = Path(".").resolve()
        with cd(str(tmp_path)):
            work_dir = Path(".").resolve()
            not_in_curdir = not tmp_path.samefile(curdir)
            print("WORK_DIR: %s (work_dir is not CURDIR: %s)" %
                  (work_dir, not_in_curdir))
            assert not_in_curdir, "DANGER_ZONE.SANITY_CHECK_BARRIER.saved_you"

            # with capsys.disabled():
            run("git init")
            git_dir = tmp_path / ".git/"
            assert git_dir.is_dir()
            run('git add one.xxx')
            run('git commit -m"INITIAL" one.xxx')
            run("git status")

            config = Config(DEFAULT_CONFIG)
            ctx = Context(config=config)
            ctx.config.run.dry = False
            ctx.config.git_clean.interactive = False
            monkeypatch.setattr("_pytest.capture.DontReadFromInput.read",
                                mock_read_from_stdin)
            git_clean(ctx, force=True, dry_run=git_clean_dry_run)

        assert my_file1.exists(), "OOPS: my_file1 was REMOVED"
        if git_clean_dry_run:
            # -- DRY-RUN MODE:
            captured = capsys.readouterr()
            assert "Would remove two.xxx" in captured.out
            assert my_file2.exists(), "OOPS: my_file2 was REMOVED"
        else:
            assert not my_file2.exists(), "OOPS: my_file2 was NOT_REMOVED"
コード例 #18
0
    def test_without_any_matching_files(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx",
            "more/two.xxx"
        ])
        my_file1 = tmp_path/"one.xxx"
        my_file2 = tmp_path/"more/two.xxx"
        assert my_file1.exists() and my_file1.is_file()
        assert my_file2.exists() and my_file2.is_file()

        # -- EXECUTE AND VERIFY: Best-effort, ignore read-only file(s)
        # with pytest.raises(OSError, match="Permission denied"):
        cwd = tmp_path
        cleanup_files(["**/*.zzz"], cwd)
        assert my_file1.exists(), "OOPS: my_file1 was REMOVED"
        assert my_file2.exists(), "OOPS: my_file2 was REMOVED"
コード例 #19
0
    def test_with_one_pattern_in_current_workdir(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx/.ignored", "two.xxx/.ignored", "more/ignored.xxx/.ignored"
        ])
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "two.xxx"
        my_dir3 = tmp_path / "more/ignored.xxx"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()
        assert my_dir3.exists() and my_dir3.is_dir()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_dirs(["*.xxx"], cwd)
        assert not my_dir1.exists(), "OOPS: my_dir1 was NOT_REMOVED"
        assert not my_dir2.exists(), "OOPS: my_dir2 was NOT_REMOVED"
        assert my_dir3.exists(), "OOPS: my_dir3 was REMOVED"
コード例 #20
0
    def test_with_exact_name(self, tmp_path):
        remove_pattern = "more/two.xxx"

        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx",
            "more/two.xxx"
        ])
        my_file1 = tmp_path/"one.xxx"
        my_file2 = tmp_path/"more/two.xxx"
        assert my_file1.exists() and my_file1.is_file()
        assert my_file2.exists() and my_file2.is_file()

        # -- EXECUTE AND VERIFY: Best-effort, ignore read-only file(s)
        # with pytest.raises(OSError, match="Permission denied"):
        cwd = tmp_path
        cleanup_files([remove_pattern], cwd)
        assert my_file1.exists(), "OOPS: my_file1 was REMOVED"
        assert not my_file2.exists(), "OOPS: my_file2 was NOT_REMOVED"
コード例 #21
0
    def test_without_workdir_param_uses_current_directory(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx/.ignored", "two.xxx/.ignored", "more/ignored.xxx/.ignored"
        ])
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "two.xxx"
        my_dir3 = tmp_path / "more/ignored.xxx"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()
        assert my_dir3.exists() and my_dir3.is_dir()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        with cd(str(cwd)):  # -- STRING-CONVERSION (needed for: python2.7)
            cleanup_dirs(["*.xxx"])
        assert not my_dir1.exists(), "OOPS: my_dir1 was NOT_REMOVED"
        assert not my_dir2.exists(), "OOPS: my_dir2 was NOT_REMOVED"
        assert my_dir3.exists(), "OOPS: my_dir3 was REMOVED"
コード例 #22
0
    def test_with_matching_file__should_skip_remove_and_showit_in_verbose_mode(
            self, tmp_path, capsys):
        # -- SETUP:
        setup_workdir(tmp_path, ["one.xxx/.ignored", "more/two.xxx"])
        my_dir1 = tmp_path / "one.xxx"
        my_file2 = tmp_path / "more/two.xxx"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_file2.exists() and my_file2.is_file()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_dirs(["**/*.xxx"], cwd, verbose=True)
        captured = capsys.readouterr()
        assert not my_dir1.exists(), "OOPS: my_dir1 was NOT_REMOVED"
        assert my_file2.exists(), "OOPS: my_file2 was REMOVED"

        # -- ONLY IN VERBOSE MODE:
        expected = "RMTREE: {0} (SKIPPED: Not a directory)".format(my_file2)
        assert expected in captured.out
コード例 #23
0
    def test_invoke_calls_other_task_that_uses_cleanup_dirs(self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx/.dir",
            "more/two.xxx/.dir",
        ])
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "more/two.xxx"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        tasks_file = tmp_path / "tasks.py"
        tasks_file.write_text(u"""
from __future__ import absolute_import, print_function
from invoke import task, Collection
import invoke_cleanup as cleanup
from invoke_cleanup import cleanup_dirs

@task
def foo_clean(ctx):
    print("CALLED: foo_clean")
    cleanup_dirs(["**/*.xxx"])

namespace = Collection(foo_clean)
namespace.add_collection(Collection.from_module(cleanup), name="cleanup")
namespace.configure(cleanup.namespace.configuration())

from invoke_cleanup import cleanup_all_tasks
cleanup_all_tasks.add_task(foo_clean, name="foo_clean")
cleanup_all_tasks.configure(namespace.configuration())
""")

        # -- EXECUTE AND VERIFY:
        with cd(str(tmp_path)):
            output = ensure_text(run_with_output("invoke cleanup.all"))

        assert not my_dir1.exists()
        assert not my_dir2.exists()
        expected1 = "RMTREE: one.xxx"
        expected2 = "RMTREE: more/two.xxx"
        assert expected1 in output
        assert expected2 in output
コード例 #24
0
    def test_with_matching_file__should_skip_remove(self, tmp_path, capsys):
        # -- SETUP:
        setup_workdir(tmp_path, ["one.xxx/.ignored", "more/two.xxx"])
        my_dir1 = tmp_path / "one.xxx"
        my_file2 = tmp_path / "more/two.xxx"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_file2.exists() and my_file2.is_file()

        # -- EXECUTE AND VERIFY:
        cwd = tmp_path
        cleanup_dirs(["**/*.xxx"], cwd)
        captured = capsys.readouterr()
        assert not my_dir1.exists(), "OOPS: my_dir1 was NOT_REMOVED"
        assert my_file2.exists(), "OOPS: my_file2 was REMOVED"

        # -- ONLY IN NON-VERBOSE MODE:
        expected1 = "RMTREE: {0}".format(my_file2)
        expected2 = "REMOVE: {0}".format(my_file2)
        assert expected1 not in captured.out
        assert expected2 not in captured.out
コード例 #25
0
    def test_skips_rmtree_below_sys_executable_basedir(self, tmp_path,
                                                       monkeypatch, capsys):
        """SKIP-SUICIDE in context of cleanup_dirs in virtual environment."""
        setup_workdir(tmp_path, [
            "opt/python_x.y/bin/python", "opt/python_x.y/lib/foo/one.xxx/.dir"
        ])
        python_basedir = tmp_path / "opt/python_x.y"
        mock_sys_executable = python_basedir / "bin/python"
        mock_sys_executable = str(mock_sys_executable.absolute())
        problematic_dir = python_basedir / "lib/foo/one.xxx"
        problematic_dir = problematic_dir.relative_to(tmp_path)

        with cd(str(tmp_path)):
            monkeypatch.setattr("sys.executable", mock_sys_executable)
            cleanup_dirs(["**/*.xxx"], dry_run=True)

            captured = capsys.readouterr()
            print(captured.out)
            expected = "SKIP-SUICIDE: 'opt/python_x.y/lib/foo/one.xxx'"
            assert expected in captured.out
コード例 #26
0
    def test_with_configfile_and_cleanup_directories_overrides_default(
            self, tmp_path):
        # -- SETUP:
        setup_workdir(
            tmp_path,
            [
                # -- HINT: DEFAULT cleanup.directories = [] EMPTY-LIST
                ".venv_DEFAULT/.dir",
                "one.xxx/.dir",
                "more/two.zzz/.dir",
            ])
        my_dir0 = tmp_path / ".venv_DEFAULT"
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "more/two.zzz"
        assert my_dir0.exists() and my_dir0.is_dir()
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        tasks_dir = tmp_path / "tasks.py"
        tasks_dir.write_text(TASKS_FILE_TEXT_USING_CLEANUP_MODULE_ONLY)
        config_dir = tmp_path / "invoke.yaml"
        config_dir.write_text(u"""
cleanup_all:
    directories:
      - "**/*.xxx"
      - "**/*.zzz"
""")

        # -- EXECUTE AND VERIFY:
        with use_subprocess_coverage(tmp_path):
            with cd(str(tmp_path)):
                output = ensure_text(run_with_output("invoke cleanup.all"))

        assert my_dir0.exists(
        ), "OOPS: DEFAULT cleanup_all.directories was NOT_OVERWRITTEN"
        assert not my_dir1.exists()
        assert not my_dir2.exists()
        expected1 = "RMTREE: one.xxx"
        expected2 = "RMTREE: more/two.zzz"
        assert expected1 in output
        assert expected2 in output
コード例 #27
0
    def test_with_configfile_and_cleanup_extra_directories_extends_default(
            self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            ".venv_CONFIG/.dir",
            "one.xxx/.dir",
            "more/two.zzz/.dir",
        ])
        my_dir0 = tmp_path / ".venv_CONFIG"
        my_dir1 = tmp_path / "one.xxx"
        my_dir2 = tmp_path / "more/two.zzz"
        assert my_dir1.exists() and my_dir1.is_dir()
        assert my_dir2.exists() and my_dir2.is_dir()

        tasks_dir = tmp_path / "tasks.py"
        tasks_dir.write_text(TASKS_FILE_TEXT_USING_CLEANUP_MODULE_ONLY)
        config_dir = tmp_path / "invoke.yaml"
        config_dir.write_text(u"""
cleanup:
    directories:
      - ".venv*"
    extra_directories:
      - "**/*.xxx"
      - "**/*.zzz"
""")

        # -- EXECUTE AND VERIFY:
        with use_subprocess_coverage(tmp_path):
            with cd(str(tmp_path)):
                output = ensure_text(run_with_output("invoke cleanup.all"))

        assert not my_dir0.exists()
        assert not my_dir1.exists()
        assert not my_dir2.exists()
        expected0 = "RMTREE: .venv_CONFIG"
        expected1 = "RMTREE: one.xxx"
        expected2 = "RMTREE: more/two.zzz"
        assert expected0 in output
        assert expected1 in output
        assert expected2 in output
コード例 #28
0
    def test_with_matching_directory__should_skip_remove_and_showit_in_verbose_mode(self, tmp_path, capsys):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "one.xxx",
            "more/two.xxx/.dir"
        ])
        my_file1 = tmp_path/"one.xxx"
        my_dir2 = tmp_path/"more/two.xxx"
        assert my_file1.exists() and my_file1.is_file()
        assert my_dir2.exists() and my_dir2.is_dir()

        # -- EXECUTE AND VERIFY: Best-effort, ignore read-only file(s)
        # with pytest.raises(OSError, match="Permission denied"):
        cwd = tmp_path
        cleanup_files(["**/*.xxx"], cwd, verbose=True)
        captured = capsys.readouterr()
        assert not my_file1.exists(), "OOPS: my_file1 was NOT_REMOVED"
        assert my_dir2.exists(), "OOPS: my_dir2 was REMOVED"

        # -- ONLY IN VERBOSE MODE:
        expected = "REMOVE: {0} (SKIPPED: Not a file)".format(my_dir2)
        assert expected in captured.out
コード例 #29
0
    def test_with_configfile_and_cleanup_extra_files_extends_default(
            self, tmp_path):
        # -- SETUP:
        setup_workdir(tmp_path, [
            "DEFAULT_FILE.bak",
            "one.xxx",
            "more/two.zzz",
        ])
        my_file0 = tmp_path / "DEFAULT_FILE.bak"
        my_file1 = tmp_path / "one.xxx"
        my_file2 = tmp_path / "more/two.zzz"
        assert my_file0.exists() and my_file0.is_file()
        assert my_file1.exists() and my_file1.is_file()
        assert my_file2.exists() and my_file2.is_file()

        tasks_file = tmp_path / "tasks.py"
        tasks_file.write_text(TASKS_FILE_TEXT_USING_CLEANUP_MODULE_ONLY)
        config_file = tmp_path / "invoke.yaml"
        config_file.write_text(u"""
cleanup:
    extra_files:
      - "**/*.xxx"
      - "**/*.zzz"
""")

        # -- EXECUTE AND VERIFY:
        output = run_with_output_in_directory(tmp_path)

        assert not my_file0.exists(
        ), "OOPS: DEFAULT:cleanup.files was NOT_REMOVED"
        assert not my_file1.exists()
        assert not my_file2.exists()
        expected0 = "REMOVE: DEFAULT_FILE.bak"
        expected1 = "REMOVE: one.xxx"
        expected2 = "REMOVE: more/two.zzz"
        assert expected0 in output
        assert expected1 in output
        assert expected2 in output
コード例 #30
0
    def test_skips_rmtree_that_contains_sys_executable(self, tmp_path,
                                                       monkeypatch, capsys):
        """SKIP-SUICIDE in context of cleanup_dirs in virtual environment."""
        setup_workdir(tmp_path, [
            "foo/one.xxx/python_x.y/bin/python",
        ])
        python_basedir = tmp_path / "foo/one.xxx/python_x.y"
        mock_sys_executable = python_basedir / "bin/python"
        mock_sys_executable = str(mock_sys_executable.absolute())
        problematic_dir = "foo/one.xxx"

        with cd(str(tmp_path)):
            monkeypatch.setattr("sys.executable", mock_sys_executable)
            cleanup_dirs(["**/*.xxx"], dry_run=True)

        # pylint: disable=line-too-long
        captured = capsys.readouterr()
        print(captured.out)
        # expected = "SKIP-SUICIDE: 'foo/one.xxx' contains current python executable"
        expected1 = "SKIP-SUICIDE: '%s'" % problematic_dir
        expected2 = "SKIP-SUICIDE: '%s' contains current python executable" % problematic_dir
        assert expected1 in captured.out
        assert expected2 in captured.out