Ejemplo n.º 1
0
    def resolved_name_version(self):
        if not self.folder:
            if self.version:
                return self.original, self.version

            return despecced(self.original)

        setup_py = os.path.join(self.folder, "setup.py")
        if not os.path.exists(setup_py):
            abort("No setup.py in %s" % self.folder)

        with runez.CurrentFolder(self.folder):
            # Some setup.py's assume current folder is the one with their setup.py
            r = runez.run(sys.executable,
                          "setup.py",
                          "--name",
                          dryrun=False,
                          fatal=False,
                          logger=False)
            package_name = r.output
            if r.failed or not package_name:
                abort("Could not determine package name from %s" % setup_py)

            validate_pypi_name(package_name)
            r = runez.run(sys.executable,
                          "setup.py",
                          "--version",
                          dryrun=False,
                          fatal=False,
                          logger=False)
            package_version = r.output
            if r.failed or not package_version:
                abort("Could not determine package version from setup.py")

        return package_name, package_version
Ejemplo n.º 2
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"
Ejemplo n.º 3
0
Archivo: srv.py Proyecto: zsimic/gdot
    def upgrade(self):
        self.stop()
        with runez.CurrentFolder(self.target):
            runez.run("docker-compose", "pull")
            runez.run("docker-compose", "prune", "-f")

        self.sync()
        self.start()
Ejemplo n.º 4
0
def package(build, dist, symlink, relocatable, sanity_check, folder):
    """
    Package a project from source checkout
    """
    build = runez.resolved_path(build)

    root = None
    target_dist = dist
    if target_dist.startswith("root/"):
        # Special case: we're targeting 'root/...' probably for a debian, use target in that case to avoid venv relocation issues
        target = target_dist[4:]
        if os.path.isdir(target):
            root = target_dist[:4]
            target_dist = target
            LOG.debug("debian mode: %s -> %s", dist, target)

    folder = runez.resolved_path(folder)

    if not os.path.isdir(folder):
        sys.exit("Folder %s does not exist" % short(folder))

    system.SETTINGS.set_base(build)

    setup_py = os.path.join(folder, "setup.py")
    if not os.path.exists(setup_py):
        sys.exit("No setup.py in %s" % short(folder))

    with runez.CurrentFolder(folder):
        # Some setup.py's assume their working folder is the folder where they're in
        result = system.run_python(setup_py,
                                   "--name",
                                   fatal=False,
                                   dryrun=False)
        name = result.output
        if result.failed or not name:
            sys.exit("Could not determine package name from %s" %
                     short(setup_py))

    package_spec = system.PackageSpec(name)
    runez.Anchored.add(folder)
    p = PACKAGERS.resolved(package_spec)
    p.build_folder = build
    p.dist_folder = runez.resolved_path(target_dist)
    p.relocatable = relocatable
    p.source_folder = folder
    p.package()

    p.create_symlinks(symlink, root=root)
    p.sanity_check(sanity_check)

    if p.executables:
        overview = "produced: %s" % runez.quoted(p.executables)

    else:
        overview = "package has no entry-points"

    print("Packaged %s successfully, %s" % (short(folder), overview))
    runez.Anchored.pop(folder)
Ejemplo n.º 5
0
def test_current_folder(temp_folder):
    sample = os.path.join(temp_folder, "sample")
    assert os.getcwd() == temp_folder
    assert runez.ensure_folder("sample") == 1

    with runez.CurrentFolder("sample", anchor=False):
        cwd = os.getcwd()
        assert cwd == sample
        assert runez.short(os.path.join(cwd, "some-file")) == os.path.join(
            "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
Ejemplo n.º 6
0
def test_background_run(logged):
    with runez.CurrentFolder(os.path.dirname(CHATTER)):
        r = runez.run(CHATTER,
                      "hello",
                      background=True,
                      dryrun=True,
                      logger=True)
        assert r.succeeded
        assert "chatter hello &" in logged.pop()

        r = runez.run(CHATTER, "hello", background=True, dryrun=False)
        assert r.succeeded
        assert r.pid
        assert r.output is None
        assert r.error is None
        assert "chatter hello &" in logged.pop()
Ejemplo n.º 7
0
def test_status(cli):
    # Note: using explicit lists below, to support case where used directory path may have a space in it
    # [wouldn't work if args passed as string, due to naive split in run()]
    # Status on a non-existing folder should fail
    cli.expect_failure("foo", "No folder 'foo'")

    # Status on this test folder should succeed and report no git folders found
    cli.expect_success(cli.tests_folder, "no git folders")

    # Status on project folder should succeed (we're not calling fetch)
    project = runez.DEV.project_folder
    cli.expect_success(project, "mgit")
    with runez.CurrentFolder(project):
        cli.run()
        assert cli.succeeded
        assert "%s:" % os.path.basename(project) in cli.logged.stdout

        cli.expect_success("-cs")
Ejemplo n.º 8
0
def package(build, dist, symlink, relocatable, sanity_check, folder):
    """
    Package a project from source checkout
    """
    build = runez.resolved_path(build)
    dist = runez.resolved_path(dist)
    folder = runez.resolved_path(folder)

    system.SETTINGS.meta = meta_folder(build)

    if not os.path.isdir(folder):
        sys.exit("Folder %s does not exist" % short(folder))

    setup_py = os.path.join(folder, "setup.py")
    if not os.path.exists(setup_py):
        sys.exit("No setup.py in %s" % short(folder))

    with runez.CurrentFolder(folder):
        # Some setup.py's assume their working folder is the folder where they're in
        name = system.run_python(setup_py, "--name", fatal=False, dryrun=False)
        if not name:
            sys.exit("Could not determine package name from %s" %
                     short(setup_py))

    runez.Anchored.add(folder)
    p = PACKAGERS.resolved(name)
    p.build_folder = build
    p.dist_folder = dist
    p.relocatable = relocatable
    p.source_folder = folder
    p.package()
    p.create_symlinks(symlink)
    p.sanity_check(sanity_check)
    print("Packaged %s successfully, produced: %s" %
          (short(folder), runez.represented_args(p.executables)))
    runez.Anchored.pop(folder)
Ejemplo n.º 9
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
Ejemplo n.º 10
0
def test_capture(monkeypatch):
    with runez.CurrentFolder(os.path.dirname(CHATTER)):
        # Check which finds programs in current folder
        assert runez.which("chatter") == CHATTER
        assert runez.shell("chatter hello") == "hello"

    with runez.CaptureOutput(dryrun=True) as logged:
        # Dryrun mode doesn't fail (since it doesn't actually run the program)
        r = runez.run(CHATTER, "silent-fail", fatal=True)
        assert r.succeeded
        assert "[dryrun] " in r.output
        assert r.error == ""
        assert "Would run:" in logged.pop()

        r = runez.run(CHATTER,
                      "silent-fail",
                      stdout=None,
                      stderr=None,
                      fatal=True)
        assert r.succeeded
        assert r.output is None
        assert r.error is None
        assert "Would run:" in logged.pop()

    with runez.CaptureOutput(seed_logging=True) as logged:
        # Test success
        assert runez.run(CHATTER, "hello",
                         fatal=False) == RunResult("hello", "", 0)
        assert runez.run(CHATTER, "hello",
                         fatal=True) == RunResult("hello", "", 0)
        assert "chatter hello" in logged.pop()
        assert runez.run(CHATTER, stdout=None) == RunResult(None, "", 0)
        assert "Running:" in logged.pop()
        crasher = CrashingWrite()
        assert runez.run(CHATTER, "hello", fatal=True,
                         passthrough=crasher) == RunResult("hello", "", 0)
        assert crasher.crash_counter
        assert "hello" in logged.pop()

        # Test no-wait
        r = runez.run(CHATTER, "hello", fatal=None, stdout=None, stderr=None)
        assert r.exit_code is None  # We don't know exit code because we didn't wait
        assert r.pid

        r = runez.run(CHATTER, stdout=None, stderr=None)
        assert r
        assert str(r) == "RunResult(exit_code=0)"
        assert r.succeeded
        assert r.output is None
        assert r.error is None
        assert r.full_output is None

        r = runez.run(CHATTER,
                      "hello",
                      path_env={
                          "PATH": ":.",
                          "CPPFLAGS": " -I/usr/local/opt/openssl/include"
                      })
        assert str(r) == "RunResult(exit_code=0)"
        assert r.succeeded
        assert r.output == "hello"
        assert r.error == ""
        assert r.full_output == "hello"

        # Test stderr
        r = runez.run(CHATTER, "complain")
        assert r.succeeded
        assert r.output == ""
        assert r.error == "complaining"
        assert r.full_output == "complaining"
        logged.pop()

        # Test failure
        with pytest.raises(Exception):
            runez.run(CHATTER, "fail")
        assert "Run failed:" in logged.pop()

        r = runez.run(CHATTER, "silent-fail", fatal=False)
        assert str(r) == "RunResult(exit_code=1)"
        assert r.failed
        assert r.error == ""
        assert r.output == ""
        assert r.full_output == r.error

        if hasattr(subprocess.Popen, "__enter__"):
            # Simulate an EIO
            with patch("runez.program._read_data",
                       side_effect=simulate_os_error(errno.EIO)):
                r = runez.run(CHATTER, "fail", fatal=False, passthrough=True)
                assert r.failed
                assert r.exc_info is None
                assert r.output == ""
                assert r.error == ""

            # Simulate an OSError
            with patch("runez.program._read_data",
                       side_effect=simulate_os_error(errno.EINTR)):
                r = runez.run(CHATTER, "fail", fatal=False, passthrough=True)
                assert r.failed
                assert r.output is None
                assert "failed: OSError(" in r.error

        # Verify no extra "exited with code ..." message is added when pass-through had some output
        logged.clear()
        with pytest.raises(SystemExit):
            runez.run(CHATTER, "fail", fatal=SystemExit, passthrough=True)
        assert "exited with code" not in logged.pop()

        with pytest.raises(runez.system.AbortException):
            runez.run(CHATTER, "fail", fatal=True, passthrough=True)
        assert "exited with code" not in logged.pop()

        # Verify that silent pass-through gets at least mention of exit code
        with pytest.raises(SystemExit):
            runez.run(CHATTER,
                      "silent-fail",
                      fatal=SystemExit,
                      passthrough=True)
        assert "exited with code" in logged.pop()

        with pytest.raises(runez.system.AbortException):
            runez.run(CHATTER, "silent-fail", fatal=True, passthrough=True)
        assert "exited with code" in logged.pop()

        r = runez.run(CHATTER, "fail", fatal=False, passthrough=True)
        assert r.failed
        assert r.error == "failed"
        assert r.output == "hello there"
        assert r.full_output == "failed\nhello there"

        r = runez.run("foo/bar", fatal=False)
        assert r.exit_code == 1
        assert "foo/bar is not an executable" in r.error

        r = runez.run("foo-bar-no-such-program", fatal=False)
        assert r.exit_code == 1
        assert "is not installed (PATH=" in r.error

        with monkeypatch.context() as m:
            m.setattr(subprocess, "Popen",
                      exception_raiser(OSError("testing")))
            r = runez.run("python", "--version", fatal=False)
            assert not r
            assert r.failed
            assert "python failed: OSError(" in r.error
            assert r.output is None

            with pytest.raises(OSError):
                runez.run("python", "--version")

        # Test convenience arg None filtering
        logged.clear()
        assert runez.run(CHATTER, "hello", "-a", 0, "-b", None, 1, 2, None,
                         "foo bar") == RunResult("hello -a 0 1 2 foo bar", "",
                                                 0)
        assert 'chatter hello -a 0 1 2 "foo bar"' in logged.pop()
Ejemplo n.º 11
0
Archivo: srv.py Proyecto: zsimic/gdot
 def stop(self):
     self.validate()
     with runez.CurrentFolder(self.target):
         runez.run("docker-compose", "stop")
Ejemplo n.º 12
0
Archivo: srv.py Proyecto: zsimic/gdot
 def start(self):
     self.validate()
     with runez.CurrentFolder(self.target):
         runez.run("docker-compose", "up", "-d")
Ejemplo n.º 13
0
def test_depot(temp_folder, monkeypatch, logged):
    # Create some pyenv-style python installation mocks (using version 8 so it sorts above any real version...)
    mk_python("8.6.1")
    mk_python("8.7.2")
    runez.symlink("8.6.1",
                  ".pyenv/versions/8.6",
                  must_exist=False,
                  logger=None)

    # Verify that if invoker is one of the pyenv-installations, it is properly detected
    depot = mocked_invoker(pyenv=".pyenv",
                           base_prefix=".pyenv/versions/8.6.1",
                           version_info=(8, 6, 1))
    p8 = depot.find_python("8")
    p86 = depot.find_python("8.6")
    assert str(
        p8
    ) == ".pyenv/versions/8.7.2 [cpython:8.7.2]"  # Latest version 8 (invoker doesn't take precedence)
    assert p8.folder == runez.to_path(".pyenv/versions/8.7.2/bin").absolute()
    assert p86 is depot.invoker
    assert str(depot) == "2 scanned"
    assert depot.scanned == [p8, p86]
    assert depot.from_path == []
    assert not logged

    mk_python("8.8.3", executable=False)
    mk_python("8.9.0")
    mk_python("miniconda3-4.7.12")

    # Create some PATH-style python installation mocks (using version 9 so it sorts higher than pyenv ones)
    mk_python("python", folder="path1", version="9.5.1")
    mk_python("python3", folder="path1", content=[
        "foo"
    ])  # Invalid: mocked _pv.py does not return the right number of lines
    mk_python("python", folder="path2",
              content=["foo; bar"])  # --version fails
    mk_python("some-other-python-exe-name", folder="path3", version="8.5.0")
    mk_python("python3", folder="path3")  # Invalid version
    with runez.CurrentFolder("path3/bin"):
        runez.symlink("some-other-python-exe-name", "python", logger=None)

    monkeypatch.setenv("PATH", "bar:path1/bin:path2/bin:path3/bin")
    scanner = PythonInstallationScanner(".pyenv")
    assert str(scanner) == "portable python [.pyenv]"
    depot = PythonDepot(scanner=scanner, use_path=True)
    assert str(depot) == "4 scanned, 2 from PATH"
    r = depot.representation()
    assert "Installed portable python:" in r
    assert "Available pythons from PATH:" in r

    depot.find_preferred_python("8.7.2,8.9.0", "8.7", "8.10")
    assert depot.preferred_python.version == "8.7.2"

    depot.find_preferred_python("8.7.2,8.9.0", "8.7", "8.8")
    assert depot.preferred_python.version == "8.9.0"
    assert depot.find_python(None) is depot.preferred_python
    assert depot.find_python("8") is depot.preferred_python

    depot.find_preferred_python("8.7.2,8.9.0", "10.7", "10.8")
    assert depot.preferred_python is None

    depot.find_preferred_python("")
    assert depot.preferred_python is None

    assert len(depot.from_path) == 2
    assert len(depot.scanned) == 4
    assert depot.scan_path_env_var(
    ) is None  # Already scanned to try and find invoker
    p95 = depot.find_python("9.5.1")
    assert str(p95) == "path1/bin/python [cpython:9.5.1]"

    check_find_python(depot, "9", "path1/bin/python [cpython:9.5.1]")
    check_find_python(depot, "42.4", "42.4 [not available]")
    check_find_python(depot, "foo", "foo [not available]")
    check_find_python(depot, "python:43.0.0", "python:43.0.0 [not available]")

    with pytest.raises(runez.system.AbortException):
        depot.find_python("/bar", fatal=True)

    pbar = depot.find_python("/bar")
    assert str(pbar) == "/bar [not an executable]"
    assert pbar.problem
    assert not pbar.satisfies(depot.spec_from_text("python"))

    p8 = depot.find_python("8")
    p8a = depot.find_python(PythonSpec("8"))
    assert p8a is p8
    p86 = depot.find_python("8.6")
    p87 = depot.find_python("8.7")
    p88 = depot.find_python("8.8")
    p89 = depot.find_python("8.9")
    c = depot.find_python("conda")
    c47 = depot.find_python("conda:4.7")
    assert c47 is c
    assert depot.find_python(PythonSpec("conda47")) is c47
    assert depot.scanned == [p89, p87, p86, c47]

    assert p8.major == 8
    assert p88.major == 8
    assert str(p8) == ".pyenv/versions/8.9.0 [cpython:8.9.0]"
    assert str(p88) == "8.8 [not available]"
    assert str(c47) == ".pyenv/versions/miniconda3-4.7.12 [conda:4.7.12]"
    assert p8 is p89
    assert p8 == p89
    assert p8 != p88
    assert p8 != pbar
    assert p8.satisfies(PythonSpec("python"))
    assert p8.satisfies(PythonSpec("python8"))
    assert p8.satisfies(PythonSpec("py8.9.0"))
    assert not p8.satisfies(PythonSpec("py8.9.1"))
    assert c47.satisfies(PythonSpec("conda47"))
    assert len({p8, p89}) == 1
    assert len({p8, p89, p88}) == 2