def test_custom_settings(temp_base): system.SETTINGS.set_base(sample_path("custom")) stgs = system.SETTINGS assert isinstance(stgs, Settings) system.SETTINGS.load_config() check_specs("bundle:dev", ["tox", "twine"]) check_specs("bundle:dev2", ["tox", "twine", "pipenv"]) check_specs("bundle:dev bundle:dev2", ["tox", "twine", "pipenv"]) check_specs("pipenv bundle:dev bundle:dev2", ["pipenv", "tox", "twine"]) assert str(stgs) == "[4] base: %s" % short(stgs.base.path) assert str(stgs.defaults) == "defaults" assert str(stgs.base) == "base: %s" % short(stgs.base.path) assert stgs.get_definition("") is None assert stgs.resolved_definition("") is None assert stgs.resolved_value("foo") is None p = stgs.base.full_path("foo/bar") assert stgs.base.relative_path(p) == "foo/bar" d = stgs.resolved_definition( "delivery", package_spec=system.PackageSpec("dict_sample")) assert str(d) == ".pickley/config.json:delivery.copy" assert stgs.resolved_value( "delivery", package_spec=system.PackageSpec("tox")) == "venv" assert stgs.resolved_value( "delivery", package_spec=system.PackageSpec("virtualenv")) == "wrap" assert stgs.resolved_value( "packager", package_spec=system.PackageSpec("tox")) == system.VENV_PACKAGER assert stgs.resolved_value( "packager", package_spec=system.PackageSpec("virtualenv")) == "pex" with runez.Anchored(system.SETTINGS.meta.path): old_width = pickley.settings.REPRESENTATION_WIDTH pickley.settings.REPRESENTATION_WIDTH = 40 actual = stgs.represented(include_defaults=False).replace( short(stgs.base.path), "{base}") assert actual == EXPECTED_REPRESENTATION.strip() pickley.settings.REPRESENTATION_WIDTH = old_width stgs.cli.contents["packager"] = "copy" d = stgs.resolved_definition("packager") assert d.value == "copy" assert d.source is stgs.cli d = stgs.get_definition("packager") assert d.value == "copy" assert d.source is stgs.cli assert stgs.install_timeout == 2 assert stgs.version_check_seconds == 60
def test_settings_base(): old_program = system.PICKLEY_PROGRAM_PATH # Verify that .pickley/... part of base gets ignored base = sample_path("foo") system.PICKLEY_PROGRAM_PATH = os.path.join(base, pickley.settings.DOT_PICKLEY, "pickley-1.0.0", "bin", "pickley") s = pickley.settings.Settings() assert s.base.path == base # Convenience dev case base = sample_path(".venv", "bin", "pickley") system.PICKLEY_PROGRAM_PATH = base with patch("pickley.settings.get_user_index", return_value="https://example.net/pypi"): s = pickley.settings.Settings() assert s.base.path == sample_path(".venv", "root") assert s.index == "https://example.net/pypi" system.PICKLEY_PROGRAM_PATH = old_program with pytest.raises(Exception): system.PackageSpec("some.bogus name")
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)
def test_version_meta(): assert find_prefix({}, "") is None foo = system.PackageSpec("foo") v = VersionMeta(foo) v2 = VersionMeta(foo) assert v.equivalent(v2) v2.packager = "bar" assert not v.equivalent(v2) v2 = VersionMeta(foo) assert v.equivalent(v2) v2.delivery = "bar" assert not v.equivalent(v2) assert not v.equivalent(None) assert str(v) == "foo: no version" assert v.representation(verbose=True) == "foo: no version" v.invalidate("some problem") assert str(v) == "foo: some problem" assert v.problem == "some problem" v3 = VersionMeta(foo) v3.version = "1.0" v3.timestamp = time.time() assert v3.still_valid v3.timestamp = "foo" assert not v3.still_valid
def test_missing_implementation(): m = ImplementationMap("custom") m.register(ImplementationMap) foo = system.PackageSpec("foo") assert len(m.names()) == 1 assert "No custom type configured" in verify_abort(m.resolved, foo) system.SETTINGS.cli.contents["custom"] = "bar" assert "Unknown custom type" in verify_abort(m.resolved, foo)
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)
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) if runez.PY2: v = SharedVenv(lock, None) assert v._installed_module(system.PackageSpec("pex"))
def test_channel(*_): p = PACKAGERS.get(system.VENV_PACKAGER)(system.PackageSpec("foo")) p.refresh_desired() assert p.desired.representation( verbose=True ) == "foo 1.0 (as venv wrap, channel: stable, source: test:channel.stable.foo)" with runez.CaptureOutput(dryrun=True) as logged: p.executables = ["foo/bar"] assert p.create_symlinks("foo:baz", fatal=False) == 1 assert "Would symlink /bar <- baz/bar" in logged.pop()
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)
def _run_from_venv(self, command, *args, **kwargs): """ Should be called while holding the soft file lock in context only :param str command: Command to run from that package (optionally specced with version) :param args: Args to invoke program with :param kwargs: Additional args """ cmd = system.PackageSpec(command) if cmd.dashed in ("pip", "venv"): return self._run_builtin_module(cmd.dashed, *args, **kwargs) args = runez.flattened(args, shellify=True) full_path = self._installed_module(cmd) return runez.run(full_path, *args, **kwargs)
def test_wrapper(temp_base): repeater = os.path.join(temp_base, "repeat.sh") target = os.path.join(temp_base, system.PICKLEY) runez.write(repeater, "#!/bin/bash\n\necho :: $*\n") runez.make_executable(repeater) # Actual wrapper d = DeliveryMethodWrap(system.PackageSpec(system.PICKLEY)) d.install(target, repeater) assert runez.run(target, "auto-upgrade", "foo") == RunResult(":: auto-upgrade foo", "", 0) assert runez.run(target, "--debug", "auto-upgrade", "foo") == RunResult(":: --debug auto-upgrade foo", "", 0) assert runez.run(target, "settings", "-d") == RunResult(":: settings -d", "", 0) # Verify that we're triggering background auto-upgrade as expected d.hook = "echo " d.bg = "" d.install(target, repeater) result = runez.run(target, "settings", "-d") assert "nohup" in result.output assert "repeat.sh settings -d" in result.output result = runez.run(target, "auto-upgrade", "foo") assert "nohup" not in result.output assert "repeat.sh auto-upgrade foo" in result.output result = runez.run(target, "--debug", "auto-upgrade", "foo") assert "nohup" not in result.output assert "repeat.sh --debug auto-upgrade foo" in result.output runez.delete(repeater) result = runez.run(target, "foo", fatal=False) assert result.failed assert "Please reinstall with" in result.full_output assert os.path.exists(target) assert uninstall_existing(target, fatal=False) == 1 assert not os.path.exists(target)
def test_sorting(): some_list = sorted( [system.PackageSpec("tox"), system.PackageSpec("awscli")]) assert [str(s) for s in some_list] == ["awscli", "tox"]
def test_pypi(*_): pyyaml = system.PackageSpec("PyYAML.Yandex==1.0") assert pyyaml.dashed == "pyyaml-yandex" assert pyyaml.specced == "pyyaml-yandex==1.0" assert pyyaml.pythonified == "PyYAML_Yandex" assert pyyaml.original == "PyYAML.Yandex" assert pyyaml.version_part( "PyYAML.Yandex-3.11.1.tar.gz") == "3.11.1.tar.gz" assert pyyaml.version_part("PyYAML_Yandex-1.2.whl") == "1.2.whl" assert pyyaml.version_part("pyyaml_Yandex-1.2.whl") == "1.2.whl" assert pyyaml.version_part( "PyYAML.Yandex-3.11nikicat.tar.gz") == "3.11nikicat.tar.gz" assert pyyaml.version_part("PyYAML.Yandex-3") == "3" assert pyyaml.version_part("pyyaml-yandex-3") == "3" assert pyyaml.version_part("PyYAML.Yandex-") is None assert pyyaml.version_part("PyYAML.Yandex-foo-3.11") is None tox = system.PackageSpec("tox") foo = system.PackageSpec("foo") black = system.PackageSpec("black") twine = system.PackageSpec("twine") shell_functools = system.PackageSpec("shell-functools") assert latest_pypi_version(None, tox) with patch("pickley.pypi.request_get", return_value="{foo"): # 404 assert latest_pypi_version(None, foo).startswith("error: ") with patch("pickley.pypi.request_get", return_value='{"info": {"version": "1.0"}}'): assert latest_pypi_version(None, foo) == "1.0" with patch("pickley.pypi.request_get", return_value=None): assert latest_pypi_version(None, twine).startswith("error: ") with patch("pickley.pypi.request_get", return_value="foo"): assert latest_pypi_version(None, twine).startswith("error: ") with patch("pickley.pypi.request_get", return_value=LEGACY_SAMPLE): assert latest_pypi_version("https://pypi-mirror.mycompany.net/pypi", shell_functools) == "1.9.1" assert latest_pypi_version( "https://pypi-mirror.mycompany.net/pypi/{name}", shell_functools) == "1.9.1" with patch("pickley.pypi.request_get", return_value=PRERELEASE_SAMPLE): assert latest_pypi_version("https://pypi-mirror.mycompany.net/pypi", black).startswith("error: ") with patch("pickley.pypi.request_get", return_value=UNKNOWN_VERSIONING_SAMPLE): # Unknown version: someproj-1.3.0_custom assert latest_pypi_version("https://pypi-mirror.mycompany.net/pypi", black).startswith("error: ") with patch("pickley.pypi.urlopen", side_effect=Exception): # GET fails, and fallback curl also fails assert request_get("") is None with patch("runez.run", return_value=runez.program.RunResult("foo", "", 0)): # GET fails, but curl succeeds assert request_get("") == "foo" e = Exception() e.code = 404 with patch("pickley.pypi.urlopen", side_effect=e): # With explicit 404 we don't fallback to curl assert request_get("") is None
def test_versions(_, __, temp_base): p = PACKAGERS.get("pex")(system.PackageSpec("foo")) assert not p.package_spec.version 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 "can't determine latest version" in p.desired.representation( verbose=True) 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" 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 not p.get_entry_points() # With a bogus wheel with runez.CaptureOutput() as logged: p.package_spec.version = "0.0.0" whl = os.path.join(p.build_folder, "foo-0.0.0-py2.py3-none-any.whl") runez.touch(whl) assert not p.get_entry_points() 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.package_spec.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")
def test_bogus_delivery(): deliver = DELIVERERS.get(system.DEFAULT_DELIVERY)( system.PackageSpec("foo")) assert "does not exist" in verify_abort(deliver.install, None, INEXISTING_FILE) assert "Failed symlink" in verify_abort(deliver.install, None, __file__)