Пример #1
0
def test_ensure_folder(temp_folder, logged):
    assert runez.ensure_folder(None) == 0
    assert runez.ensure_folder("") == 0
    assert runez.ensure_folder(".") == 0
    assert not logged

    assert runez.ensure_folder(".", clean=True) == 0
    assert not logged

    assert runez.touch("some-file", logger=None) == 1
    with pytest.raises(Exception):
        runez.ensure_folder("some-file")
    assert "Can't create folder" in logged.pop()

    assert runez.ensure_folder("some-dir", dryrun=True) == 1
    assert "Would create some-dir" in logged.pop()
    assert runez.ensure_folder("some-dir") == 1
    assert "Created folder some-dir" in logged.pop()

    assert runez.ensure_folder("some-dir") == 0
    assert not logged

    assert runez.touch("some-dir/a/b") == 1
    assert "Created folder" not in logged
    assert "Touched some-dir/a/b" in logged.pop()
    assert runez.ensure_folder("some-dir", clean=True, dryrun=True) == 1
    assert "Would clean 1 file from some-dir" in logged.pop()

    assert runez.touch("some-dir/b", logger=False) == 1
    assert not logged

    assert runez.ensure_folder("some-dir", clean=True) == 2
    assert "Cleaned 2 files from some-dir" in logged
Пример #2
0
def auto_upgrade(force, package):
    """
    Auto-upgrade a package
    """
    package = system.PackageSpec(package)
    p = PACKAGERS.resolved(package)
    if not p.current.valid:
        sys.exit("%s is not currently installed" % package)

    ping = system.SETTINGS.meta.full_path(package.dashed, ".ping")
    if not force and runez.file.is_younger(
            ping, system.SETTINGS.version_check_seconds):
        # We checked for auto-upgrade recently, no need to check again yet
        print("Skipping auto-upgrade, checked recently")
        sys.exit(0)

    runez.touch(ping)

    try:
        p.internal_install()

    except SoftLockException:
        print(
            "Skipping auto-upgrade, %s is currently being installed by another process"
            % package)
        sys.exit(0)
Пример #3
0
def test_ensure_freeze(_, __, temp_base):
    # Test edge case for _installed_module()
    with SoftLock(temp_base) as lock:
        fake_pex = os.path.join(temp_base, "bin/pex")
        runez.touch(fake_pex)
        runez.make_executable(fake_pex)
        v = SharedVenv(lock, None)
        assert v._installed_module("pex")
Пример #4
0
def test_pathlib(temp_folder):
    subfolder = Path("subfolder")
    assert runez.to_path(subfolder) is subfolder
    assert not subfolder.is_dir()
    runez.ensure_folder(subfolder)
    assert subfolder.is_dir()

    with pytest.raises(Exception):
        runez.to_path("foo bar", no_spaces=Exception)

    with runez.CurrentFolder(subfolder, anchor=True):
        path = Path("foo")
        assert runez.short(path) == "foo"
        assert runez.short(path.absolute()) == "foo"

        assert runez.resolved_path(path)
        assert runez.parent_folder(path) == os.path.join(temp_folder, "subfolder")
        assert runez.touch(path) == 1
        assert runez.copy(path, Path("bar")) == 1
        assert runez.copy(Path("bar"), Path("baz")) == 1

        foo_json = Path("foo.json")
        runez.write(path, '{"a": "b"}')
        runez.symlink(path, foo_json)
        assert runez.read_json(foo_json) == {"a": "b"}
        assert list(runez.readlines(foo_json)) == ['{"a": "b"}']

        assert runez.basename(foo_json.absolute()) == "foo"
Пример #5
0
    def perform_delivery(self, template):
        """
        :param str template: Template describing how to name delivered files, example: {meta}/{name}-{version}
        """
        # Touch the .ping file since this is a fresh install (no need to check for upgrades right away)
        runez.touch(system.SETTINGS.meta.full_path(self.package_spec.dashed, ".ping"))

        self.executables = []
        deliverer = DELIVERERS.resolved(self.package_spec, default=self.desired.delivery)
        for name in self.entry_points:
            target = system.SETTINGS.base.full_path(name)
            if self.package_spec.dashed != system.PICKLEY and not self.current.file_exists:
                uninstall_existing(target)
            path = template.format(meta=system.SETTINGS.meta.full_path(self.package_spec.dashed), name=name, version=self.desired.version)
            deliverer.install(target, path)
            self.executables.append(target)
Пример #6
0
def test_edge_cases(temp_folder, logged):
    venv = MagicMock(bin_path=lambda x: os.path.join("some-package/bin", x))
    entry_points = {"some-source": ""}
    cfg = PickleyConfig()
    cfg.set_base(".")
    pspec = PackageSpec(cfg, "mgit", "1.0.0")
    d = DeliveryMethod()
    with pytest.raises(SystemExit):
        d.install(pspec, venv, entry_points)
    assert "Can't deliver some-source -> some-package/bin/some-source: source does not exist" in logged.pop(
    )

    runez.touch("some-package/bin/some-source")
    with pytest.raises(SystemExit):
        d.install(pspec, venv, entry_points)
    assert "Failed to deliver" in logged.pop()
Пример #7
0
def auto_upgrade(force, package):
    """Background auto-upgrade command (called by wrapper)"""
    pspec = PackageSpec(CFG, package)
    ping = pspec.ping_path
    if not force and runez.file.is_younger(
            ping, 5):  # 5 seconds cool down on version check to avoid bursts
        LOG.debug("Skipping auto-upgrade, checked recently")
        sys.exit(0)

    runez.touch(ping)
    lock_path = pspec.get_lock_path()
    if runez.file.is_younger(lock_path, CFG.install_timeout(pspec)):
        LOG.debug("Lock file present, another installation is in progress")
        sys.exit(0)

    perform_install(pspec, is_upgrade=True, force=False, quiet=True)
Пример #8
0
def test_run(temp_folder):
    assert runez.program.added_env_paths(None) is None
    ls = runez.which("ls")

    with runez.CaptureOutput(dryrun=True) as logged:
        assert "Would run: /dev/null" in runez.run("/dev/null", fatal=False)
        assert "Would run: /dev/null" in logged.pop()

        assert "Would run:" in runez.run(ls, "--invalid-flag", None, ".")
        assert "Would run: %s ." % ls in logged.pop()

    with runez.CaptureOutput() as logged:
        assert runez.run("/dev/null", fatal=False) is False
        assert "/dev/null is not installed" in logged.pop()

        assert runez.touch("sample") == 1
        assert runez.run(ls,
                         "--invalid-flag",
                         None,
                         ".",
                         path_env={"PATH": ":."}) == "sample"
        assert "Running: %s ." % ls in logged.pop()

        assert runez.run(ls, "some-file", fatal=False) is False
        assert "Running: %s some-file" % ls in logged
        assert "exited with code" in logged
        assert "No such file" in logged.pop()
Пример #9
0
    def install(self, pspec, venv, entry_points):
        """
        Args:
            pspec (pickley.PackageSpec): Package spec this installation is for
            venv (pickley.package.PythonVenv): Virtual env where executables reside (DOT_META/<package>/...)
            entry_points (dict | list): Full path of executable to deliver (<base>/<entry_point>)
        """
        if not pspec.is_clear_for_installation():
            auto_uninstall(pspec.exe_path(pspec.dashed))

        try:
            prev_manifest = pspec.get_manifest()
            for name in entry_points:
                src = venv.bin_path(name)
                dest = pspec.exe_path(name)
                if runez.DRYRUN:
                    print("Would %s %s -> %s" %
                          (self.short_name, short(dest), short(src)))
                    continue

                if not os.path.exists(src):
                    abort(
                        "Can't %s %s -> %s: source does not exist" %
                        (self.short_name, short(dest), runez.red(short(src))))

                LOG.debug("%s %s -> %s" %
                          (self.action, short(dest), short(src)))
                self._install(pspec, dest, src)

            manifest = pspec.save_manifest(entry_points)
            if not runez.DRYRUN and prev_manifest and prev_manifest.entrypoints:
                for old_ep in prev_manifest.entrypoints:
                    if old_ep and old_ep not in entry_points:
                        # Remove old entry points that are not in new manifest any more
                        runez.delete(pspec.exe_path(old_ep))

            if self.ping:
                # Touch the .ping file since this is a fresh install (no need to check for upgrades right away)
                runez.touch(pspec.ping_path)

            return manifest

        except Exception as e:
            abort("Failed to %s %s: %s" %
                  (self.short_name, short(pspec), runez.red(e)))
Пример #10
0
def test_install_pypi(cli):
    cli.expect_failure("--color install six", "it is not a CLI")
    assert not os.path.exists(dot_meta("six"))

    cli.expect_failure("install mgit+foo", "not a valid pypi package name")

    runez.touch(
        dot_meta("mgit/.foo"))  # Should stay because name starts with '.'
    runez.touch(dot_meta("mgit/mgit-foo"))  # Bogus installation
    runez.touch(dot_meta("mgit/mgit-0.0.1/foo"))  # Oldest should be deleted

    # Simulate the presence of an old entry point
    manifest_path = dot_meta("mgit/.manifest.json")
    runez.save_json(dict(entrypoints=["mgit", "old-mgit-entrypoint"]),
                    manifest_path)
    runez.touch("old-mgit-entrypoint")
    assert os.path.exists("old-mgit-entrypoint")

    time.sleep(0.01)  # Ensure 0.0.1 is older than 0.0.2
    runez.touch(
        dot_meta("mgit/mgit-0.0.2/foo"))  # Youngest should remain for an hour
    check_install_from_pypi(cli, "symlink", "mgit")
    assert not os.path.exists("old-mgit-entrypoint")
    assert os.path.islink("mgit")
    assert os.path.exists(dot_meta("mgit/.manifest.json"))
    assert os.path.exists(dot_meta("mgit/.foo"))
    assert os.path.exists(dot_meta("mgit/mgit-0.0.2"))
    assert not os.path.exists(dot_meta("mgit/mgit-foo"))
    assert not os.path.exists(dot_meta("mgit/mgit-0.0.1"))

    cfg = PickleyConfig()
    cfg.set_base(".")
    pspec = PackageSpec(cfg, "mgit")
    pspec.groom_installation(keep_for=0)
    assert not os.path.exists(dot_meta("mgit/mgit-0.0.2"))

    cli.expect_success("uninstall mgit", "Uninstalled mgit")
    assert not runez.is_executable("mgit")
    assert not os.path.exists(dot_meta("mgit"))
    assert os.path.exists(dot_meta("audit.log"))

    check_install_from_pypi(cli, "wrap", "mgit", simulate_version="0.0.0")
    check_is_wrapper("mgit", True)
Пример #11
0
def test_bogus_install(cli):
    cli.expect_failure("-b foo/bar settings",
                       "Can't use foo/bar as base: folder does not exist")

    cli.expect_failure("auto-upgrade foo", "not currently installed")
    cli.expect_failure("package foo/bar", "Folder", "does not exist")
    cli.expect_failure(["package", cli.context], "No setup.py")
    runez.touch(os.path.join(cli.context, "setup.py"))
    cli.expect_failure(["package", cli.context],
                       "Could not determine package name")

    cli.expect_success("-b{base} check",
                       "No packages installed",
                       base=cli.context)
    cli.expect_success("-b{base} list",
                       "No packages installed",
                       base=cli.context)

    cli.expect_success("settings -d", "base: %s" % short(cli.context))
Пример #12
0
def test_bogus_install(cli):
    cli.expect_success("settings -d", "base: %s" % short(cli.context))
    cli.expect_success("check", "No packages installed")
    cli.expect_success("list", "No packages installed")

    cli.expect_failure("-b foo/bar settings",
                       "Can't use foo/bar as base: folder does not exist")

    cli.expect_failure("--dryrun check -- -bogus",
                       "not a valid pypi package name")
    cli.expect_failure("--dryrun check this-package-does-not-exist",
                       "can't determine latest version")

    cli.expect_failure("--dryrun --delivery foo install tox",
                       "invalid choice: foo")

    cli.expect_failure("--dryrun uninstall --force /dev/null",
                       "is not a valid pypi package name")
    cli.expect_success(
        "--dryrun uninstall --force -- this-package-does-not-exist ",
        "Nothing to uninstall")

    runez.touch("foo")
    assert os.path.exists("foo")
    cli.expect_failure("uninstall foo", "foo was not installed with pickley")
    cli.expect_success("uninstall foo --force", "Uninstalled foo")
    assert not os.path.exists("foo")
    assert runez.ensure_folder("foo", folder=True) == 1
    cli.expect_failure("uninstall foo --force",
                       "Can't automatically uninstall")

    cli.expect_failure("auto-upgrade foo", "not currently installed")

    cli.expect_failure("package foo/bar", "Folder", "does not exist")
    cli.expect_failure(["package", cli.context], "No setup.py")
    runez.touch(os.path.join(cli.context, "setup.py"))
    cli.expect_failure(["package", cli.context],
                       "Could not determine package name")

    cli.expect_success("check", "No packages installed")
    cli.expect_success("list", "No packages installed")
    cli.expect_success("settings -d", "base: %s" % short(cli.context))
Пример #13
0
def test_debian_mode(temp_folder, logged):
    runez.write(
        "foo/setup.py",
        "import setuptools\nsetuptools.setup(name='foo', version='1.0')")
    p = dummy_finalizer("root/apps")
    assert p.dist == "root/apps/foo"
    assert p.requirements == [runez.resolved_path("foo")]
    assert "Using python:" in logged.pop()

    # Symlink not created unless source effectively exists
    p.symlink.apply("root/foo")
    assert "skipping symlink" in logged.pop()
    assert not os.path.isdir("root/usr/local/bin")

    foo = runez.resolved_path("root/foo")
    runez.touch(foo)
    logged.pop()

    # Simulate symlink
    p.symlink.apply(foo)
    assert "Symlinked root/usr/local/bin/foo -> root/foo" in logged.pop()
    assert os.path.isdir("root/usr/local/bin")
    assert os.path.islink("root/usr/local/bin/foo")

    with patch("os.path.isdir", return_value=True):  # pretend /apps exists
        p = dummy_finalizer("root/apps")
        assert "debian mode" in logged.pop()
        assert p.dist == "/apps/foo"

    with patch("runez.run",
               return_value=runez.program.RunResult("usage: ...")):
        assert p.validate_sanity_check(
            "foo", "--version") == "does not respond to --version"

    with patch("runez.run", return_value=runez.program.RunResult("failed")):
        with pytest.raises(SystemExit):
            p.validate_sanity_check("foo", "--version")

        assert "'foo' failed --version sanity check" in logged.pop()
Пример #14
0
def test_edge_cases():
    # Don't crash for no-ops
    assert runez.copy(None, None) == 0
    assert runez.move(None, None) == 0
    assert runez.symlink(None, None) == 0
    assert runez.copy("some-file", "some-file") == 0
    assert runez.move("some-file", "some-file") == 0
    assert runez.symlink("some-file", "some-file") == 0
    assert runez.delete("non-existing") == 0

    assert runez.touch(None) == 0
    assert not runez.file.is_younger("", None)
    assert not runez.file.is_younger("", 1)
    assert not runez.file.is_younger("/dev/null/not-there", 1)
Пример #15
0
def test_executable(temp_folder):
    with runez.CaptureOutput(dryrun=True) as logged:
        assert runez.make_executable("some-file") == 1
        assert "Would make some-file executable" in logged.pop()
        assert runez.make_executable("some-file", logger=False) == 1
        assert not logged

    with runez.CaptureOutput() as logged:
        assert runez.touch("some-file") == 1
        assert "Touched some-file" in logged.pop()
        assert runez.delete("some-file") == 1
        assert "Deleted some-file" in logged.pop()
        assert runez.touch("some-file", logger=logging.debug) == 1
        assert "Touched some-file" in logged.pop()
        assert runez.make_executable("some-file", logger=logging.debug) == 1
        assert "Made 'some-file' executable" in logged.pop()
        assert runez.is_executable("some-file")
        assert runez.make_executable("some-file") == 0
        assert not logged

        assert runez.touch("some-file", logger=False) == 1
        assert runez.delete("some-file", logger=False) == 1
        assert not runez.is_executable("some-file")
        assert not logged

        assert runez.make_executable("/dev/null/some-file", fatal=False) == -1
        assert "does not exist, can't make it executable" in logged.pop()

        assert runez.make_executable("/dev/null/some-file",
                                     fatal=False,
                                     logger=None) == -1  # Don't log anything
        assert not logged

        assert runez.make_executable("/dev/null/some-file",
                                     fatal=False,
                                     logger=False) == -1  # Log errors only
        assert "does not exist, can't make it executable" in logged.pop()
Пример #16
0
def test_facultative(cli):
    runez.save_json({"pinned": {
        "virtualenv": {
            "facultative": True
        }
    }}, dot_meta("config.json"))

    # Empty file -> proceed with install as if it wasn't there
    runez.touch("virtualenv")
    cli.expect_success("-n install virtualenv",
                       "Would state: Installed virtualenv")

    # Simulate pickley wrapper
    runez.write("virtualenv", "echo installed by pickley")
    runez.make_executable("virtualenv")
    cli.expect_success("-n install virtualenv",
                       "Would state: Installed virtualenv")

    # Unknown executable -> skip pickley installation (since facultative)
    runez.write("virtualenv", "echo foo")
    runez.make_executable("virtualenv")
    cli.expect_success(
        "-n install virtualenv",
        "Skipping installation of virtualenv: not installed by pickley")
    cli.expect_success("-n check virtualenv",
                       "skipped, not installed by pickley")

    # --force ignores 'facultative' setting
    cli.expect_failure("-n install --force virtualenv",
                       "Can't automatically uninstall virtualenv")

    # Simulate pickley symlink delivery
    dummy_target = dot_meta("foo")
    runez.touch(dummy_target)
    runez.symlink(dummy_target, "virtualenv")
    cli.expect_success("-n install virtualenv",
                       "Would state: Installed virtualenv")
Пример #17
0
def test_file_operations(temp_folder):
    runez.symlink("foo", "dangling-symlink", must_exist=False)
    runez.move("dangling-symlink", "dangling-symlink2")
    assert os.path.islink("dangling-symlink2")

    runez.write("README.md", "hello")
    runez.copy("README.md", "sample1/README.md")
    runez.copy("sample1", "sample2")
    runez.move("sample1/README.md", "sample1/foo")

    # overwrite=None "merges" dir contents
    runez.copy("sample1", "sample2", overwrite=None)
    assert dir_contents("sample2") == {"README.md": ["hello"], "foo": ["hello"]}

    # overwrite=True replaces dir
    runez.copy("sample1", "sample2", overwrite=True)
    assert dir_contents("sample2") == {"foo": ["hello"]}

    # overwrite=None, source is a dir, existing destination file gets replaced by source directory
    runez.copy("sample1", "sample2/foo", overwrite=None)
    assert dir_contents("sample2") == {"foo": {"foo": ["hello"]}}

    with runez.CaptureOutput(dryrun=True) as logged:
        assert runez.ensure_folder("some-folder", fatal=False) == 1
        assert "Would create" in logged.pop()

        assert runez.touch("some-file", logger=logging.debug) == 1
        assert "Would touch some-file" in logged.pop()

        assert runez.copy("some-file", "bar") == 1
        assert "Would copy some-file -> bar" in logged.pop()

        assert runez.move("some-file", "bar") == 1
        assert "Would move some-file -> bar" in logged.pop()

        assert runez.symlink("some-file", "bar") == 1
        assert "Would symlink some-file <- bar" in logged.pop()

        assert runez.delete(temp_folder) == 1
        assert "Would delete" in logged.pop()

        assert runez.copy("some-folder/bar", "some-folder", fatal=False) == -1
        assert "source contained in destination" in logged.pop()

        assert runez.move("some-folder/bar/baz", "some-folder", fatal=False) == -1
        assert "source contained in destination" in logged.pop()

        assert runez.symlink("some-folder/bar/baz", "some-folder", fatal=False) == -1
        assert "source contained in destination" in logged.pop()
Пример #18
0
def test_executable(temp_folder):
    with runez.CaptureOutput(dryrun=True) as logged:
        assert runez.make_executable("some-file") == 1
        assert "Would make some-file executable" in logged

    assert runez.touch("some-file") == 1
    assert runez.make_executable("some-file") == 1
    assert runez.is_executable("some-file")
    assert runez.make_executable("some-file") == 0

    assert runez.delete("some-file") == 1
    assert not runez.is_executable("some-file")

    with runez.CaptureOutput() as logged:
        assert runez.make_executable("/dev/null/some-file", fatal=False) == -1
        assert "does not exist, can't make it executable" in logged
Пример #19
0
def test_delivery(temp_base):
    # Test copy folder
    tox = system.PackageSpec("tox")
    deliver = DELIVERERS.get("copy")(tox)
    target = os.path.join(temp_base, "t1")
    source = os.path.join(temp_base, "t1-source")
    source_file = os.path.join(source, "foo")
    runez.touch(source_file)
    deliver.install(target, source)
    assert os.path.isdir(target)
    assert os.path.isfile(os.path.join(target, "foo"))

    # Test copy file
    deliver = DELIVERERS.get("copy")(tox)
    target = os.path.join(temp_base, "t2")
    source = os.path.join(temp_base, "t2-source")
    runez.touch(source)
    deliver.install(target, source)
    assert os.path.isfile(target)

    # Test symlink
    deliver = DELIVERERS.get("symlink")(tox)
    target = os.path.join(temp_base, "l2")
    source = os.path.join(temp_base, "l2-source")
    runez.touch(source)
    deliver.install(target, source)
    assert os.path.islink(target)

    # Test wrapper
    p = PACKAGERS.get(system.VENV_PACKAGER)(tox)
    assert p.create_symlinks(None) == 0
    assert p.create_symlinks("foo", fatal=False) == 0
    p.executables = ["foo"]
    assert p.create_symlinks("foo:bar", fatal=False) == -1
    assert str(p) == "venv tox"
    target = os.path.join(temp_base, "tox")
    source = os.path.join(temp_base, "tox-source")
    runez.touch(source)
    deliver = DELIVERERS.get("wrap")(system.PackageSpec("tox"))
    deliver.install(target, source)
    assert runez.is_executable(target)
Пример #20
0
def test_edge_cases(temp_cfg, monkeypatch, logged):
    monkeypatch.setattr(PickleyConfig, "_pickley_dev_path", None)
    pspec = PackageSpec(temp_cfg, PICKLEY)
    assert pspec._pickley_dev_mode == runez.DEV.project_folder
    assert pspec.install_path.endswith("%s-dev" % PICKLEY)

    assert pspec.find_wheel(".", fatal=False) is None
    assert "Expecting 1 wheel" in logged.pop()

    runez.touch("%s-1.0.0.whl" % PICKLEY)
    w = pspec.find_wheel(".", fatal=False)
    assert w == "./%s-1.0.0.whl" % PICKLEY

    with pytest.raises(NotImplementedError):
        Packager.package(None, None, None, None, False)

    runez.touch("share/python-wheels/some-wheel.whl")
    runez.touch("__pycache__/some_module.py")
    runez.touch("some_module.pyc")
    logged.pop()
    clean_compiled_artifacts(".")
    assert "Deleted 3 compiled artifacts" in logged.pop()
    assert not os.path.exists("share/python-wheels")
    assert os.path.isdir("share")
Пример #21
0
def test_dryrun(cli, monkeypatch):
    cli.run("-n --debug auto-upgrade mgit")
    assert cli.succeeded
    assert "Would wrap mgit" in cli.logged
    runez.touch(dot_meta("mgit.lock"))
    cli.run("-n --debug auto-upgrade mgit")
    assert cli.succeeded
    assert "Lock file present, another installation is in progress" in cli.logged

    cli.expect_success("-n check", "No packages installed")
    cli.expect_failure("-n check foo+bar",
                       "'foo+bar' is not a valid pypi package name")
    cli.expect_failure("-n check mgit pickley2-a", "is not installed",
                       "pickley2-a: does not exist")

    cli.run("-n config")
    assert cli.succeeded
    assert not cli.logged.stderr
    assert "cli:  # empty" in cli.logged.stdout
    assert "defaults:" in cli.logged.stdout

    cli.run("-n --color config")
    assert cli.succeeded

    cli.expect_failure("-n -Pfoo install bundle:bar", "No suitable python")

    # Simulate an old entry point that was now removed
    runez.write(dot_meta("mgit/.manifest.json"),
                '{"entrypoints": ["bogus-mgit"]}')
    cli.expect_failure("-n install mgit pickley2.a",
                       "Would state: Installed mgit v",
                       "'pickley2.a' is not pypi canonical")
    runez.delete(dot_meta("mgit"))

    cli.expect_success("-n -Pfoo diagnostics", "desired python : foo",
                       "foo [not available]", "sys.executable")
    with patch("runez.run", return_value=runez.program.RunResult("failed")):
        cli.run("-n install [email protected]:zsimic/mgit.git")
        assert cli.failed
        assert cli.match("No setup.py")

    with patch("pickley.git_clone", side_effect=mock_git_clone):
        cli.run("-n install [email protected]:zsimic/mgit.git")
        assert cli.succeeded
        assert " install .pickley/.cache/checkout/mgit" in cli.logged

    cli.run("-n install mgit")
    assert cli.succeeded
    assert cli.match("Would wrap mgit -> %s" % dot_meta("mgit"))
    assert cli.match("Would save %s" % dot_meta("mgit/.manifest.json"))
    assert cli.match("Would state: Installed mgit v")

    cli.expect_failure("-n -dfoo install mgit",
                       "Unknown delivery method 'foo'")

    cli.expect_success("-n list", "No packages installed")

    cli.expect_failure("-n package foo", "Folder ... does not exist")
    cli.expect_failure("-n package . -sfoo", "Invalid symlink specification")
    cli.expect_failure("-n package . -sroot:root/usr/local/bin",
                       "No setup.py in ")

    runez.touch("setup.py")
    cli.expect_failure("-n package .", "Could not determine package name")
    runez.write(
        "setup.py",
        "import sys\nfrom setuptools import setup\nif sys.argv[1]=='--version': sys.exit(1)\nsetup(name='foo')"
    )
    cli.expect_failure("-n package .", "Could not determine package version")

    cli.expect_success(["-n", "package", cli.project_folder],
                       "Would run: ...pip... install -r requirements.txt")

    cli.expect_failure("-n uninstall",
                       "Specify packages to uninstall, or --all")
    cli.expect_failure(
        "-n uninstall pickley",
        "Run 'uninstall --all' if you wish to uninstall pickley itself")
    cli.expect_failure("-n uninstall mgit",
                       "mgit was not installed with pickley")
    cli.expect_failure(
        "-n uninstall mgit --all",
        "Either specify packages to uninstall, or --all (but not both)")
    cli.expect_success("-n uninstall --all", "pickley is now uninstalled")

    cli.expect_success("-n upgrade",
                       "No packages installed, nothing to upgrade")
    cli.expect_failure("-n upgrade mgit", "'mgit' is not installed")
Пример #22
0
def test_file_inspection(temp_folder, logged):
    assert runez.touch("sample") == 1
    assert runez.delete("sample") == 1
    assert "Deleted sample" in logged.pop()

    assert runez.ensure_folder("sample") == 1
    assert runez.delete("sample") == 1
    assert "Deleted sample" in logged.pop()

    sample = runez.DEV.tests_path("sample.txt")
    assert len(list(runez.readlines(sample))) == 4
    assert len(list(runez.readlines(sample, first=1))) == 1
    assert not logged

    cc = "%s\n" % "\n".join(runez.readlines(sample))
    assert runez.write("sample", cc, fatal=False, logger=logging.debug) == 1
    cc2 = "%s\n" % "\n".join(runez.readlines("sample"))
    assert cc2 == cc
    assert "bytes to sample" in logged.pop()  # Wrote 13 bytes on linux... but 14 on windows...

    assert list(runez.readlines("sample", first=2)) == ["", "Fred"]
    assert runez.file.is_younger("sample", age=10)
    assert not runez.file.is_younger("sample", age=-1)

    # Verify that readlines() can ignore encoding errors
    with io.open("not-a-text-file", "wb") as fh:
        fh.write(b"\x89 hello\nworld")

    assert list(runez.readlines("not-a-text-file", first=1)) == [" hello"]
    assert not logged

    assert runez.copy("bar", "baz", fatal=False) == -1
    assert "does not exist" in logged.pop()
    assert runez.move("bar", "baz", fatal=False) == -1
    assert "does not exist" in logged.pop()
    assert runez.symlink("bar", "baz", fatal=False) == -1
    assert "does not exist" in logged.pop()

    # Creating dangling symlinks is possible
    assert runez.symlink("s/bar", "s/baz", fatal=False, must_exist=False) == 1
    assert "Symlink s/bar <- s/baz" in logged.pop()
    assert os.path.islink("s/baz")
    assert not os.path.exists("s/baz")
    runez.touch("s/bar")
    assert os.path.exists("s/baz")

    assert runez.copy("sample", "x/y/sample") == 1
    assert runez.symlink("sample", "x/y/sample3", fatal=False) == 1

    assert os.path.exists("sample")
    assert runez.move("sample", "x/y/sample2") == 1
    assert not os.path.exists("sample")

    assert runez.copy("x/y", "x/z1") == 1
    assert os.path.exists("x/z1/sample")
    assert os.path.exists("x/z1/sample2")
    assert os.path.exists("x/z1/sample3")
    assert os.path.islink("x/z1/sample3")

    assert runez.copy("x/y", "x/z2", ignore={"sample2"}) == 1
    assert os.path.exists("x/z2/sample")
    assert not os.path.exists("x/z2/sample2")
    assert os.path.exists("x/z2/sample3")
    assert os.path.islink("x/z2/sample3")

    def should_ignore(src, dest):
        if src == "x/y" and "sample3" in dest:
            return {"sample3"}

    assert runez.copy("x/y", "x/z3", ignore=should_ignore) == 1
    assert os.path.exists("x/z3/sample")
    assert os.path.exists("x/z3/sample2")
    assert not os.path.exists("x/z3/sample3")

    assert runez.copy("x/y", "x/z2") == 1
    assert os.path.exists("x/z2/sample2")

    # Copy a folder over an existing file
    runez.touch("x2")
    assert not os.path.exists("x2/z2/sample2")
    assert runez.copy("x", "x2") == 1
    assert os.path.exists("x2/z2/sample2")
Пример #23
0
def test_install(cli):
    cli.expect_success("--dryrun --delivery wrap install tox", "Would wrap",
                       "Would install tox")
    cli.expect_success("--dryrun --delivery symlink install tox",
                       "Would symlink", "Would install tox")
    assert not os.path.exists(".pickley/audit.log")

    cli.expect_failure("check tox", "is not installed")
    cli.expect_failure("install six", "'six' is not a CLI")

    # Install tox, but add a few files + a bogus previous entry point to test cleanup
    runez.write(".pickley/tox/.entry-points.json",
                '["tox-old1", "tox-old2"]\n')
    runez.touch("tox-old1")
    runez.touch(".pickley/tox/tox-0.1/bin")
    runez.touch(".pickley/tox/tox-0.2/bin")
    runez.touch(".pickley/tox/tox-0.3/bin")
    runez.touch(".pickley/tox/tox-old1-0.1")
    runez.touch(".pickley/tox/tox-old1-0.2")
    cli.expect_success("--delivery wrap install tox", "Installed tox")

    # Old entry point removed immediately
    assert not os.path.exists("tox-old1")

    # Only 1 cleaned up immediately (latest + 1 kept)
    assert not os.path.exists(".pickley/tox/tox-0.1")
    assert not os.path.exists(".pickley/tox/tox-0.2")
    assert os.path.exists(".pickley/tox/tox-0.3")
    assert not os.path.exists(".pickley/tox/tox-old1-0.1")
    assert os.path.exists(".pickley/tox/tox-old1-0.2")

    assert runez.is_executable("tox")
    result = run_program("tox", "--version")
    assert "tox" in result.output

    cli.expect_success("auto-upgrade tox", "Skipping auto-upgrade")
    runez.delete(system.SETTINGS.meta.full_path("tox", ".ping"))
    cli.expect_success("auto-upgrade tox", "already installed")

    cli.expect_success("copy .pickley/tox tox-copy", "Copied")
    cli.expect_success("move tox-copy tox-relocated", "Moved")
    runez.delete("tox-relocated")

    # Verify that older versions and removed entry-points do get cleaned up
    runez.save_json({"install_timeout": 0}, "custom-timeout.json")
    cli.expect_success("-ccustom-timeout.json install tox",
                       "already installed")

    # All cleaned up when enough time went by
    assert not os.path.exists(".pickley/tox/tox-0.3")
    assert not os.path.exists(".pickley/tox/tox-old1-0.2")

    cli.expect_success("check", "tox", "is installed")
    cli.expect_success(
        "check --verbose", "tox",
        "is installed (as %s wrap, channel: " % system.VENV_PACKAGER)

    # Simulate new version available
    latest = runez.read_json(".pickley/tox/.latest.json")
    latest["version"] = "10000.0"
    runez.save_json(latest, ".pickley/tox/.latest.json")
    cli.expect_failure("check", "tox", "can be upgraded to 10000.0")

    # Latest twine 2.0 requires py3
    cli.expect_success("-ppex install twine==1.14.0", "Installed twine")

    cli.expect_success("list", "tox", "twine")
    cli.expect_success("list --verbose", "tox", "twine")

    assert find_uninstaller("tox")
    assert find_uninstaller("twine")

    cli.expect_success("uninstall twine", "Uninstalled twine")

    runez.write(".pickley/tox/.current.json", "")
    cli.expect_failure("check", "tox", "Couldn't read", "is not installed")

    cli.expect_success("uninstall --all", "Uninstalled tox", "entry points")
    assert not os.path.exists("tox")
    assert not os.path.exists(".pickley")
Пример #24
0
def test_paths(temp_folder):
    assert runez.resolved_path(None) is None
    assert runez.resolved_path("some-file") == os.path.join(temp_folder, "some-file")
    assert runez.resolved_path("some-file", base="bar") == os.path.join(temp_folder, "bar", "some-file")

    assert runez.short(None) is None
    assert runez.short("") == ""
    assert runez.short(temp_folder) == temp_folder

    assert runez.short(temp_folder + "/some-file") == "some-file"
    assert runez.short(temp_folder + "/some-file") == "some-file"

    assert runez.parent_folder(None) is None
    assert runez.parent_folder(temp_folder + "/some-file") == temp_folder

    assert runez.represented_args(["ls", temp_folder + "/some-file bar", "-a"]) == 'ls "some-file bar" -a'

    # Don't crash for no-ops
    assert runez.ensure_folder(None) == 0
    assert runez.ensure_folder("") == 0
    assert runez.copy(None, None) == 0
    assert runez.move(None, None) == 0
    assert runez.symlink(None, None) == 0
    assert runez.copy("some-file", "some-file") == 0
    assert runez.move("some-file", "some-file") == 0
    assert runez.symlink("some-file", "some-file") == 0

    assert runez.ensure_folder("some-folder") == 0  # 'some-folder' would be in temp_folder, which already exists

    with runez.CaptureOutput(dryrun=True) as logged:
        assert runez.ensure_folder("some-folder", folder=True, fatal=False) == 1
        assert "Would create" in logged.pop()

        assert runez.touch("some-file", logger=logging.debug) == 1
        assert "Would touch some-file" in logged.pop()

        assert runez.copy("some-file", "bar") == 1
        assert "Would copy some-file -> bar" in logged.pop()

        assert runez.move("some-file", "bar") == 1
        assert "Would move some-file -> bar" in logged.pop()

        assert runez.symlink("some-file", "bar") == 1
        assert "Would symlink some-file <- bar" in logged.pop()

        assert runez.delete(temp_folder) == 1
        assert "Would delete" in logged.pop()

        assert runez.copy("some-folder/bar/baz", "some-folder", fatal=False) == -1
        assert "source contained in destination" in logged.pop()

        assert runez.move("some-folder/bar/baz", "some-folder", fatal=False) == -1
        assert "source contained in destination" in logged.pop()

        assert runez.symlink("some-folder/bar/baz", "some-folder", fatal=False) == -1
        assert "source contained in destination" in logged.pop()

    with runez.CaptureOutput():
        assert runez.touch("sample") == 1
        assert "Can't create folder" in runez.verify_abort(runez.ensure_folder, "sample", folder=True)
        custom = runez.verify_abort(runez.ensure_folder, "sample", folder=True, fatal=SystemExit, expected_exception=SystemExit)
        assert "Can't create folder" in custom
        with pytest.raises(AssertionError):
            assert runez.verify_abort(runez.ensure_folder, None)

        assert runez.delete("sample") == 1
        assert runez.ensure_folder("sample", folder=True) == 1
        assert os.getcwd() == temp_folder

    with runez.CurrentFolder("sample", anchor=False):
        cwd = os.getcwd()
        sample = os.path.join(temp_folder, "sample")
        assert cwd == sample
        assert runez.short(os.path.join(cwd, "some-file")) == "sample/some-file"

    with runez.CurrentFolder("sample", anchor=True):
        cwd = os.getcwd()
        sample = os.path.join(temp_folder, "sample")
        assert cwd == sample
        assert runez.short(os.path.join(cwd, "some-file")) == "some-file"

    assert os.getcwd() == temp_folder

    assert runez.delete("sample") == 1

    with runez.CaptureOutput() as logged:
        sample = os.path.join(os.path.dirname(__file__), "sample.txt")
        content = runez.get_lines(sample)

        assert runez.write("sample", "".join(content), fatal=False, logger=logging.debug) == 1
        assert runez.get_lines("sample") == content
        assert "Writing 13 bytes" in logged.pop()

        assert runez.first_line("sample") == "Fred"
        assert runez.is_younger("sample", age=10)
        assert not runez.is_younger("sample", age=-1)

        assert runez.copy("bar", "baz", fatal=False) == -1
        assert "does not exist" in logged.pop()
        assert runez.move("bar", "baz", fatal=False) == -1
        assert "does not exist" in logged.pop()
        assert runez.symlink("bar", "baz", fatal=False) == -1
        assert "does not exist" in logged.pop()

        # Creating dangling symlinks is possible
        assert runez.symlink("bar", "baz", fatal=False, must_exist=False) == 1
        assert "Symlink bar <- baz" in logged.pop()
        assert os.path.islink("baz")
        assert not os.path.exists("baz")

        assert runez.copy("sample", "x/y/sample") == 1
        assert runez.symlink("sample", "x/y/sample3", fatal=False) == 1

        assert os.path.exists("sample")
        assert runez.move("sample", "x/y/sample2") == 1
        assert not os.path.exists("sample")

        assert runez.copy("x/y", "x/z") == 1
        assert os.path.exists("x/z/sample")
        assert os.path.exists("x/z/sample2")
        assert os.path.exists("x/z/sample3")
        assert os.path.islink("x/z/sample3")

    assert runez.touch(None) == 0
    assert not runez.is_younger(None, 1)
    assert not runez.is_younger("/dev/null/not-there", 1)
    assert runez.first_line("/dev/null/not-there") is None

    assert runez.get_lines(None) is None
Пример #25
0
def test_python_installation(_, __, ___, ____, temp_base):
    system.DESIRED_PYTHON = "/dev/null/foo"
    p = system.target_python(fatal=False)
    assert not p.is_valid
    assert p.shebang() == "/dev/null/foo"

    system.DESIRED_PYTHON = None
    assert system.target_python(fatal=False).is_valid

    assert not system.PythonInstallation("").is_valid

    p = system.PythonInstallation("foo")
    assert str(p) == "python 'foo'"
    assert not p.is_valid
    assert p.problem == "No python installation 'foo' found"
    assert p.program_name == "python 'foo'"

    p = system.PythonInstallation("pythonx")
    assert not p.is_valid
    # assert p.problem == "pythonx is not installed"
    assert p.program_name == "pythonx"

    p = system.PythonInstallation("/usr/bin/python")
    assert str(p) == "/usr/bin/python [2.7]"
    assert p.is_valid
    assert p.problem is None
    assert p.program_name == "python2.7"
    assert p.short_name == "py27"
    assert p.executable == "/usr/bin/python"
    assert p.shebang(universal=True) == "/usr/bin/env python"
    assert p.shebang() == "/usr/bin/python"

    p = system.PythonInstallation("3.6")
    assert str(p) == "/test/python3.6/bin/python [3.6]"
    assert p.is_valid
    assert p.problem is None
    assert p.program_name == "python3.6"
    assert p.short_name == "py36"
    assert p.executable == "/test/python3.6/bin/python"
    assert p.shebang() == "/usr/bin/env python3.6"

    system.SETTINGS.cli.contents["python_installs"] = temp_base
    runez.touch("foo")
    runez.touch("python3.5")
    runez.touch("python3.7")

    p = system.PythonInstallation("python3")
    assert not p.is_valid
    assert p.problem == "'/test/python3' is not a valid python installation"
    assert p.program_name == "python3"

    p = system.PythonInstallation("py3.7")
    assert not p.is_valid
    assert p.problem == "python3.7 is not installed"

    runez.delete("python3.7")
    runez.touch("3.7.0/bin/python")
    runez.make_executable("3.7.0/bin/python")
    p = system.PythonInstallation("3.7")
    assert p.is_valid
    assert p.short_name == "py37"
    assert p.executable == os.path.join(temp_base, "3.7.0/bin/python")
Пример #26
0
def test_versions(_, __, temp_base):
    p = PACKAGERS.get("pex")("foo")
    p.pip_wheel = lambda *_: None

    assert p.specced_command() == "pex"
    p.implementation_version = "1.4.5"
    assert p.specced_command() == "pex==1.4.5"
    p.refresh_desired()
    assert p.desired.representation(
        verbose=True
    ) == "foo: can't determine latest version from pypi (channel: latest, source: pypi)"

    with patch("pickley.package.latest_pypi_version",
               return_value="error: test failed"):
        p.refresh_desired()
        assert p.desired.representation() == "foo: test failed"

    system.SETTINGS.cli.contents["channel"] = "stable"
    p.refresh_desired()
    assert p.desired.representation() == "foo: can't determine stable version"

    p.version = None
    assert "can't determine stable version" in verify_abort(p.install)

    # Without a build folder
    assert p.get_entry_points() is None

    # With an empty build fodler
    runez.ensure_folder(p.build_folder, folder=True)
    assert p.get_entry_points() is None

    # With a bogus wheel
    with runez.CaptureOutput() as logged:
        p.version = "0.0.0"
        whl = os.path.join(p.build_folder, "foo-0.0.0-py2.py3-none-any.whl")
        runez.touch(whl)
        assert p.get_entry_points() is None
        assert "Can't read wheel" in logged
        runez.delete(whl)

        p.refresh_desired()
        assert p.desired.channel == "adhoc"
        assert p.desired.source == "cli"
        assert p.desired.version == "0.0.0"
        assert not p.desired.problem
        p.version = None
        p.refresh_desired()
        assert p.desired.problem

    # Ambiguous package() call
    assert "Need either source_folder or version in order to package" in verify_abort(
        p.package)

    # Package bogus folder without a setup.py
    p.source_folder = temp_base
    assert "No setup.py" in verify_abort(p.package)

    # Package with a bogus setup.py
    setup_py = os.path.join(temp_base, "setup.py")
    runez.touch(setup_py)
    assert "Could not determine version" in verify_abort(p.package)

    # Provide a minimal setup.py
    runez.write(
        setup_py,
        "from setuptools import setup\nsetup(name='foo', version='0.0.0')\n")

    # Package project without entry points
    p.get_entry_points = lambda *_: None
    assert "is not a CLI" in verify_abort(p.required_entry_points)
Пример #27
0
def test_edge_cases(temp_cfg, logged):
    runez.touch("dummy.whl")
    runez.ensure_folder(".", clean=True)
    assert "Cleaned 1 file from" in logged.pop()
    assert not os.path.exists("dummy.whl")
Пример #28
0
def test_install(cli):
    tox = system.SETTINGS.base.full_path("tox")
    p = PACKAGERS.resolved("tox")
    p.refresh_desired()
    tox_version = p.desired.version
    assert not os.path.exists(tox)
    assert runez.first_line(tox) is None

    cli.expect_success("--dryrun -b{base} --delivery wrap install tox",
                       "Would wrap",
                       "Would install tox",
                       base=cli.context)
    cli.expect_success("--dryrun -b{base} --delivery symlink install tox",
                       "Would symlink",
                       "Would install tox",
                       base=cli.context)
    cli.expect_failure("--dryrun -b{base} --delivery foo install tox",
                       "invalid choice: foo",
                       base=cli.context)

    cli.expect_success("--dryrun uninstall /dev/null --force",
                       "Nothing to uninstall")

    runez.touch("foo")
    assert os.path.exists("foo")
    cli.expect_failure("uninstall foo", "foo was not installed with pickley")
    cli.expect_success("uninstall foo --force", "Uninstalled foo")

    assert not os.path.exists("foo")
    assert runez.ensure_folder("foo", folder=True) == 1
    cli.expect_failure("uninstall foo --force",
                       "Can't automatically uninstall")

    cli.expect_failure("-b{base} check tox foo/bar",
                       "is not installed",
                       "can't determine latest version",
                       base=cli.context)
    cli.expect_failure("-b{base} install six",
                       "'six' is not a CLI",
                       base=cli.context)

    # Install tox, but add a few files + a bogus previous entry point to test cleanup
    wep1 = system.SETTINGS.base.full_path("tox-old-entrypoint1")
    tep10 = system.SETTINGS.meta.full_path("tox", "tox-old-entrypoint1-1.0")
    tep11 = system.SETTINGS.meta.full_path("tox", "tox-old-entrypoint1-1.1")
    t00 = system.SETTINGS.meta.full_path("tox", "tox-0.0.0")
    tfoo = system.SETTINGS.meta.full_path("tox", "tox-foo")
    runez.touch(wep1)
    runez.touch(tep10)
    runez.touch(tep11)
    runez.touch(t00)
    runez.touch(tfoo)
    eppath = system.SETTINGS.meta.full_path("tox", ".entry-points.json")
    runez.write(eppath, '["tox-old-entrypoint1", "tox-old-entrypoint2"]\n')
    cli.expect_success("-b{base} --delivery wrap install tox",
                       "Installed tox",
                       base=cli.context)

    # Old entry point removed immediately
    assert not os.path.exists(wep1)

    # Only 1 cleaned up immediately (latest + 1 kept)
    assert not os.path.exists(tep10)
    assert os.path.exists(tep11)
    assert not os.path.exists(t00)
    assert os.path.exists(tfoo)

    assert runez.is_executable(tox)
    output = run_program(tox, "--version")
    assert "tox" in output
    assert tox_version in output

    cli.expect_success("-b{base} auto-upgrade tox",
                       "Skipping auto-upgrade",
                       base=cli.context)
    runez.delete(system.SETTINGS.meta.full_path("tox", ".ping"))
    cli.expect_success("-b{base} auto-upgrade tox",
                       "already installed",
                       base=cli.context)

    version = output.partition(" ")[0]
    cli.expect_success("copy .pickley/tox/tox-%s tox-copy" % version, "Copied")
    cli.expect_success("move tox-copy tox-relocated", "Moved")

    # Verify that older versions and removed entry-points do get cleaned up
    runez.save_json({"install_timeout": 0}, "custom-timeout.json")
    cli.expect_success("-b{base} -ccustom-timeout.json install tox",
                       "already installed",
                       base=cli.context)

    # All cleaned up when enough time went by
    assert not os.path.exists(tep10)
    assert not os.path.exists(tep11)
    assert not os.path.exists(t00)
    assert not os.path.exists(tfoo)

    cli.expect_success("-b{base} check",
                       "tox",
                       "is installed",
                       base=cli.context)
    cli.expect_success(
        "-b{base} check --verbose",
        "tox",
        "is installed (as %s wrap, channel: " % system.VENV_PACKAGER,
        base=cli.context,
    )

    p = PACKAGERS.get(system.VENV_PACKAGER)("tox")
    p.refresh_latest()
    p.latest.version = "10000.0"
    p.latest.save()
    cli.expect_failure("-b{base} check",
                       "tox",
                       "can be upgraded to 10000.0",
                       base=cli.context)

    cli.expect_success("-b{base} -ppex install twine",
                       "Installed twine",
                       base=cli.context)

    cli.expect_success("-b{base} list", "tox", "twine", base=cli.context)
    cli.expect_success("-b{base} list --verbose",
                       "tox",
                       "twine",
                       base=cli.context)

    tmp = os.path.realpath(cli.context)
    assert find_uninstaller(os.path.join(tmp, "tox"))
    assert find_uninstaller(os.path.join(tmp, "twine"))

    cli.expect_success("-b{base} uninstall twine",
                       "Uninstalled twine",
                       base=cli.context)

    runez.delete(p.current._path)
    runez.touch(p.current._path)
    cli.expect_failure("-b{base} check",
                       "tox",
                       "Couldn't read",
                       "is not installed",
                       base=cli.context)

    cli.expect_success("-b{base} uninstall tox",
                       "Uninstalled tox",
                       "entry points",
                       base=cli.context)