feat: add install script packaging
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"""Unit: `bot-bottle doctor` host prerequisite checks."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from bot_bottle.cli import doctor
|
||||
|
||||
|
||||
class TestDoctor(unittest.TestCase):
|
||||
def test_success_when_prerequisites_present(self):
|
||||
with tempfile.TemporaryDirectory() as tmp, patch.object(
|
||||
doctor.Path, "home", return_value=Path(tmp),
|
||||
), patch.object(
|
||||
doctor.shutil, "which", return_value="/usr/bin/docker",
|
||||
), patch.object(
|
||||
doctor.subprocess, "run",
|
||||
return_value=MagicMock(returncode=0),
|
||||
):
|
||||
Path(tmp, ".bot-bottle").mkdir()
|
||||
self.assertEqual(0, doctor.cmd_doctor([]))
|
||||
|
||||
def test_missing_config_fails(self):
|
||||
with tempfile.TemporaryDirectory() as tmp, patch.object(
|
||||
doctor.Path, "home", return_value=Path(tmp),
|
||||
), patch.object(
|
||||
doctor.shutil, "which", return_value="/usr/bin/docker",
|
||||
), patch.object(
|
||||
doctor.subprocess, "run",
|
||||
return_value=MagicMock(returncode=0),
|
||||
):
|
||||
self.assertEqual(1, doctor.cmd_doctor([]))
|
||||
|
||||
def test_missing_docker_fails_before_daemon_check(self):
|
||||
with tempfile.TemporaryDirectory() as tmp, patch.object(
|
||||
doctor.Path, "home", return_value=Path(tmp),
|
||||
), patch.object(
|
||||
doctor.shutil, "which", return_value=None,
|
||||
), patch.object(
|
||||
doctor.subprocess, "run",
|
||||
) as run:
|
||||
Path(tmp, ".bot-bottle").mkdir()
|
||||
self.assertEqual(1, doctor.cmd_doctor([]))
|
||||
run.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -304,6 +304,19 @@ class TestSidecarBundleShape(unittest.TestCase):
|
||||
self.assertEqual("bot-bottle-sidecars:latest", sc["image"])
|
||||
self.assertEqual("Dockerfile.sidecars", sc["build"]["dockerfile"])
|
||||
|
||||
def test_bundle_uses_packaged_dockerfile_when_root_missing(self):
|
||||
from bot_bottle.backend.docker import compose as compose_mod
|
||||
|
||||
original = compose_mod._REPO_DIR
|
||||
try:
|
||||
compose_mod._REPO_DIR = "/tmp/does-not-exist"
|
||||
self.assertEqual(
|
||||
"bot_bottle/Dockerfile.sidecars",
|
||||
compose_mod._sidecar_bundle_dockerfile(),
|
||||
)
|
||||
finally:
|
||||
compose_mod._REPO_DIR = original
|
||||
|
||||
def test_bundle_container_name_uses_sidecars_prefix(self):
|
||||
sc = self._render()["services"]["sidecars"]
|
||||
self.assertEqual(f"bot-bottle-sidecars-{SLUG}", sc["container_name"])
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
"""Unit: install.sh static contract checks."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
class TestInstallScript(unittest.TestCase):
|
||||
def test_shell_syntax(self):
|
||||
result = subprocess.run(
|
||||
["sh", "-n", str(ROOT / "install.sh")],
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertEqual("", result.stderr)
|
||||
self.assertEqual(0, result.returncode)
|
||||
|
||||
def test_contract_phrases(self):
|
||||
script = (ROOT / "install.sh").read_text(encoding="utf-8")
|
||||
self.assertIn("python3", script)
|
||||
self.assertIn("docker info", script)
|
||||
self.assertIn("pipx install --force", script)
|
||||
self.assertIn("pip install --user --upgrade", script)
|
||||
self.assertIn('"${BOT_BOTTLE_BIN}" doctor', script)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,27 @@
|
||||
"""Unit: Python package metadata for install script PRD."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import tomllib
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
class TestPyproject(unittest.TestCase):
|
||||
def test_console_script_and_no_runtime_dependencies(self):
|
||||
data = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
||||
project = data["project"]
|
||||
self.assertEqual("bot-bottle", project["name"])
|
||||
self.assertEqual(">=3.11", project["requires-python"])
|
||||
self.assertEqual([], project["dependencies"])
|
||||
self.assertEqual(
|
||||
"bot_bottle.cli:main",
|
||||
project["scripts"]["bot-bottle"],
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user