예제 #1
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
예제 #2
0
def check_install_from_pypi(cli, delivery, package, simulate_version=None):
    cli.run("--debug", "-d%s" % delivery, "install", package)
    assert cli.succeeded
    assert cli.match("Installed %s" % package)
    assert runez.is_executable(package)
    m = TrackedManifest.from_file(dot_meta("%s/.manifest.json" % package))
    assert str(m)
    assert m.entrypoints[package]
    assert m.install_info.args == runez.quoted(cli.args)
    assert m.install_info.timestamp
    assert m.install_info.vpickley == __version__
    assert m.settings.delivery == delivery
    assert m.settings.python
    assert m.version

    r = runez.run(package, "--version")
    assert r.succeeded

    cli.expect_success("--debug auto-upgrade %s" % package,
                       "Skipping auto-upgrade, checked recently")
    cli.expect_success("install %s" % package, "is already installed")
    cli.expect_success("check", "is installed")
    cli.expect_success("list", package)
    cli.expect_success("upgrade", "is already up-to-date")

    if simulate_version:
        m.version = simulate_version
        runez.save_json(m.to_dict(), dot_meta("%s/.manifest.json" % package))
        cli.expect_success(
            "check", "v%s installed, can be upgraded to" % simulate_version)
예제 #3
0
def get_program_path(path=None):
    if path is None:
        path = runez.resolved_path(sys.argv[0])

    if path.endswith(".py") or path.endswith(".pyc"):
        packaged = runez.SYS_INFO.venv_bin_path(PICKLEY)
        if runez.is_executable(packaged):
            path = packaged  # Convenience when running from debugger

    return path
예제 #4
0
 def _set_executable(self, path):
     path = runez.resolved_path(path)
     if runez.is_executable(path):
         self.executable = path
         if not self.major or not self.minor:
             result = runez.run(self.executable, "--version", dryrun=False, fatal=False)
             if result.succeeded:
                 m = RE_PYTHON_LOOSE.match(result.full_output)
                 if m:
                     self.major = m.group(3)
                     self.minor = m.group(4)
예제 #5
0
def test_package_venv(cli):
    # Verify that "debian mode" works as expected, with -droot/tmp <-> /tmp
    runez.delete("/tmp/pickley")
    cli.run("package", cli.project_folder, "-droot/tmp", "--no-compile",
            "--sanity-check=--version", "-sroot:root/usr/local/bin")
    assert cli.succeeded
    assert "--version" in cli.logged
    assert runez.is_executable("/tmp/pickley/bin/pickley")
    r = runez.run("/tmp/pickley/bin/pickley", "--version")
    assert r.succeeded
    runez.delete("/tmp/pickley")
예제 #6
0
    def is_venv_exe(self, path):
        """
        Args:
            path (str): Path to file to examine

        Returns:
            (bool): True if 'path' points to a python executable part of this venv
        """
        if runez.is_executable(path):
            for line in runez.readlines(path, first=1):
                if line.startswith("#!"):
                    if path.startswith(self.folder):
                        return True
예제 #7
0
def test_package(cli):
    pickley = system.SETTINGS.base.full_path("dist", "pickley", "bin",
                                             "pickley")
    expected_version = system.run_python(os.path.join(PROJECT, "setup.py"),
                                         "--version")

    # Package pickley as venv
    cli.expect_success(["package", "-d", "dist", PROJECT],
                       "Packaged %s successfully" % short(PROJECT))

    # Verify that it packaged OK, and is relocatable
    assert runez.is_executable(pickley)
    assert run_program(pickley, "--version") == expected_version
    assert runez.first_line(pickley).startswith("#!/usr/bin/env python")
예제 #8
0
def test_package(cli):
    result = system.run_python(os.path.join(PROJECT, "setup.py"), "--version")
    assert result.succeeded and result.output
    expected_version = result.output

    # Package pickley as venv
    cli.expect_success(["package", "-d", "dist", PROJECT],
                       "Packaged %s successfully" % short(PROJECT))

    # Verify that it packaged OK, and is relocatable
    pickley = os.path.abspath("dist/pickley/bin/pickley")
    assert runez.is_executable(pickley)
    assert run_program(pickley, "--version") == runez.program.RunResult(
        expected_version, "", 0)
예제 #9
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()
예제 #10
0
 def _set_executable(self, path):
     path = runez.resolved_path(path)
     if runez.is_executable(path):
         self.executable = path
         if not self.major or not self.minor:
             output = runez.run(self.executable,
                                "--version",
                                dryrun=False,
                                fatal=None,
                                include_error=True,
                                logger=None)
             if output:
                 m = RE_PYTHON_LOOSE.match(output)
                 if m:
                     self.major = m.group(3)
                     self.minor = m.group(4)
예제 #11
0
 def _installed_module(self, package_name, version=None):
     """
     :param str package_name: Pypi module to install in venv, if not already installed
     :param str|None version: Version (default: latest)
     """
     program = os.path.join(self.bin, package_name)
     current = self.frozen.get(package_name)
     if not current and runez.is_executable(program):
         # Edge case for older versions that weren't based on freeze
         self._refresh_frozen()
         current = self.frozen.get(package_name)
     if not current or (version and current != version):
         spec = package_name if not version else "%s==%s" % (package_name,
                                                             version)
         self._run_pip("install", "-i", system.SETTINGS.index, spec)
         self._refresh_frozen()
     return program
예제 #12
0
파일: lock.py 프로젝트: reallistic/pickley
 def _installed_module(self, command_spec):
     """
     :param system.PackageSpec command_spec: Associated package spec
     """
     program = os.path.join(self.bin, command_spec.dashed)
     current = self.frozen.get(command_spec.dashed)
     if not current and runez.is_executable(program):
         # Edge case for older versions that weren't based on freeze
         self._refresh_frozen()
         current = self.frozen.get(command_spec.dashed)
     if not current or (command_spec.version
                        and current != command_spec.version):
         self._run_builtin_module("pip", "install", "-i",
                                  system.SETTINGS.index,
                                  command_spec.specced)
         self._refresh_frozen()
     return program
예제 #13
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)
예제 #14
0
def find_brew_name(target):
    """
    :param str target: Path to executable file
    :return str, str: Name of brew formula, if target was installed with brew
    """
    if not os.path.islink(target):
        return None, None

    path = os.path.realpath(target)
    folder = runez.parent_folder(target)
    cellar = os.path.join(runez.parent_folder(folder), "Cellar")
    if not path.startswith(cellar):
        return None, None

    brew = os.path.join(folder, "brew")
    if not runez.is_executable(brew):
        return None, None

    name, _, _ = path[len(cellar) + 1:].partition("/")
    return brew, name
예제 #15
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)
예제 #16
0
def find_venvs(folder, _seen=None):
    """
    :param str folder: Folder to scan for venvs
    :param set|None _seen: Allows to not get stuck on circular symlinks
    """
    if folder and os.path.isdir(folder):
        if _seen is None:
            folder = os.path.realpath(folder)
            _seen = set()
        if folder not in _seen:
            _seen.add(folder)
            files = os.listdir(folder)
            if "bin" in files:
                bin_folder = os.path.join(folder, "bin")
                if runez.is_executable(os.path.join(bin_folder, "python")):
                    yield bin_folder
                    return
            for name in files:
                fname = os.path.join(folder, name)
                for path in find_venvs(fname, _seen=_seen):
                    yield path
예제 #17
0
    def is_clear_for_installation(self):
        """
        Returns:
            (bool): True if we can proceed with installation without needing to uninstall anything
        """
        if self.is_already_installed_by_pickley:
            return True

        target = self.exe_path(self.dashed)
        if not target or not os.path.exists(target):
            return True

        path = os.path.realpath(target)
        if path.startswith(self.cfg.meta.path):
            return True  # Pickley symlink

        if os.path.isfile(target):
            if os.path.getsize(target) == 0 or not runez.is_executable(target):
                return True  # Empty file or not executable

        for line in runez.readlines(target, first=5):
            if PICKLEY in line:
                return True  # Pickley wrapper
예제 #18
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")
예제 #19
0
 def _first_executable(self, *paths):
     for path in paths:
         if runez.is_executable(path):
             return path
     return None
예제 #20
0
def parent_python():
    prefix = getattr(sys, "real_prefix", None)
    if prefix:
        path = os.path.join(prefix, "bin", "python")
        if runez.is_executable(path):
            return path
예제 #21
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)