diff --git a/komodo/cli.py b/komodo/cli.py index fea04c0b..f47f249b 100755 --- a/komodo/cli.py +++ b/komodo/cli.py @@ -20,8 +20,8 @@ from komodo.yaml_file_types import ReleaseFile, RepositoryFile # If this package is included in a build, it will always -# be installed as the last pip package -LAST_PIP_PACKAGE_TO_INSTALL = "komodo-shims" +# be installed as the last package, and directly from downloaded source code +LAST_PACKAGE_TO_INSTALL = "komodo-shims" class KomodoNamespace(argparse.Namespace): @@ -266,6 +266,29 @@ def apply_fallback_tmpdir_for_pip_if_set(tmp_dir: Optional[str] = None): os.environ["TMPDIR"] = tmp_dir +@profile_time("pip install komodo-shims") +def install_komodo_shims( + komodo_shims_name: str, + komodo_shims_version: str, + downloads_directory: str, + pip_executable: str, + release_root: Path, +) -> None: + cmd = [ + pip_executable, + ( + f"install {downloads_directory}/{komodo_shims_name}-" + f"{strip_version(komodo_shims_version)}" + ), + "--prefix", + str(release_root), + "--no-deps", + "--ignore-installed", + "--no-compile", + ] + print(shell(cmd)) + + @profile_time("pip install to final destination") def install_previously_downloaded_pip_packages( release_file_content: Mapping[str, str], @@ -292,11 +315,9 @@ def pip_shell_command( makeopts, ] - komodo_shims: Optional[Tuple[str, str]] = None for pkg, ver in release_file_content.items(): - if pkg == LAST_PIP_PACKAGE_TO_INSTALL: + if pkg == LAST_PACKAGE_TO_INSTALL: # This is a magic package name that will always be installed after all other pip packages if found. - komodo_shims = (pkg, ver) continue pkg_data = repository_file_content[pkg][ver] if pkg_data["make"] != "pip": @@ -307,9 +328,6 @@ def pip_shell_command( ) print(shell(shell_input)) - if komodo_shims is not None: - print(shell(pip_shell_command(komodo_shims[0], komodo_shims[1], None))) - def run_post_installation_scripts_if_set( postinst: Optional[str], release_path: Path @@ -406,6 +424,25 @@ def _main(args: KomodoNamespace) -> None: pip_executable=args.pip, release_root=release_root, ) + + komodo_shims_version = args.pkgs.content.get(LAST_PACKAGE_TO_INSTALL) + if komodo_shims_version: + assert ( + args.repo.content[LAST_PACKAGE_TO_INSTALL][komodo_shims_version]["fetch"] + == "git" + ), "komodo-shims install is only supported with git as fetch method" + assert ( + args.repo.content[LAST_PACKAGE_TO_INSTALL][komodo_shims_version]["make"] + == "sh" + ), "komodo-shims install is only supported with sh as make method" + install_komodo_shims( + LAST_PACKAGE_TO_INSTALL, + komodo_shims_version, + downloads_directory=args.downloads, + pip_executable=args.pip, + release_root=release_root, + ) + fixup_python_shebangs(args.prefix, args.release) komodo.switch.create_activator_switch(data, args.prefix, args.release) diff --git a/tests/test_cli.py b/tests/test_cli.py index b0ed9e01..6edc6ab3 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -7,7 +7,7 @@ import pytest import yaml -from komodo import cli +from komodo import build, cli from komodo.cli import cli_main from tests import _get_test_root @@ -259,10 +259,21 @@ def test_komodo_shims_is_installed_at_the_end(tmpdir): } }, "komodo-shims": { - "1.0.0": {"source": "pypi", "make": "pip", "maintainer": "com"} + "1.0.0": { + "source": "https://mykey@githøbb.com", + "fetch": "git", + "make": "sh", + "maintainer": "com", + "makefile": "setup-py.sh", + } }, } (Path(tmpdir) / "repository.yml").write_text(yaml.dump(repo), encoding="utf-8") + + # Since we are mocking the shell command to a no-op, we need to mkdir here: + (Path(tmpdir) / "downloads" / "komodo-shims-1.0.0").mkdir(parents=True) + (Path(tmpdir) / "a_komodo_release_with_shims").mkdir() + sys.argv = [ "kmd", "--workspace", @@ -271,15 +282,16 @@ def test_komodo_shims_is_installed_at_the_end(tmpdir): str(tmpdir / "repository.yml"), "--release", "a_komodo_release_with_shims", + "--overwrite", # Since we have mkdir()'ed "--prefix", str(tmpdir), ] mocked_shell = Mock(return_value=b"") - mocked_fetch = Mock(return_value={}) + mocked_fetch = Mock(return_value={"komodo-shims": "main"}) with patch.object(cli, "shell", mocked_shell), patch.object( cli, "fetch", mocked_fetch - ): + ), patch.object(build, "shell", mocked_shell): cli_main() pip_install_calls = [ shell_call