Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions openbot
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
# Start OpenBot using the repository's production-style launcher.
set -Eeuo pipefail

# Set OPENBOT_REPOSITORY when this launcher is installed outside the repository.
OPENBOT_REPOSITORY="${OPENBOT_REPOSITORY:-$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)}"

usage() {
cat >&2 <<'EOF'
Usage: openbot [--root DIRECTORY] [--db-root DIRECTORY]
Expand Down Expand Up @@ -72,11 +75,11 @@ if [[ ! -e "$db_root" ]]; then
fi
fi
db_root="$(canonical_directory "$db_root")"
repository_root="$(canonical_directory "$(expand_path "$OPENBOT_REPOSITORY")")"

# `make run` remains the canonical production-style startup path; these environment variables
# provide the caller-specific paths without reimplementing backend initialization here.
export WORKSPACE_ROOT="$workspace_root"
export DATABASE_URL="sqlite+aiosqlite:///$db_root/openbot.db"

script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
exec make -C "$script_dir" run
exec make -C "$repository_root" run
22 changes: 21 additions & 1 deletion scripts/test_openbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


class OpenBotLauncherTests(unittest.TestCase):
def run_launcher(self, *args, cwd=None, home=None):
def run_launcher(self, *args, cwd=None, home=None, repository=None):
with tempfile.TemporaryDirectory() as tmp:
fake_make = Path(tmp) / "make"
fake_make.write_text(
Expand All @@ -25,6 +25,8 @@ def run_launcher(self, *args, cwd=None, home=None):
env["PATH"] = f"{tmp}{os.pathsep}{env['PATH']}"
if home is not None:
env["HOME"] = str(home)
if repository is not None:
env["OPENBOT_REPOSITORY"] = str(repository)
return subprocess.run(
[str(SCRIPT), *args], cwd=cwd, env=env, text=True, capture_output=True, check=False
)
Expand Down Expand Up @@ -62,6 +64,24 @@ def test_both_overrides_are_forwarded(self):
self.assertIn(f"workspace={root.resolve()}", result.stdout)
self.assertIn(f"database=sqlite+aiosqlite:///{db.resolve() / 'openbot.db'}", result.stdout)

def test_repository_location_is_used_from_another_working_directory(self):
with tempfile.TemporaryDirectory() as tmp, tempfile.TemporaryDirectory() as home:
caller = Path(tmp) / "caller"
repository = Path(tmp) / "repository with spaces"
caller.mkdir()
repository.mkdir()
result = self.run_launcher(cwd=caller, home=home, repository=repository)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn(f"args=-C|{repository.resolve()}|run|", result.stdout)
self.assertIn(f"workspace={caller.resolve()}", result.stdout)

def test_repository_location_must_be_a_directory(self):
with tempfile.TemporaryDirectory() as tmp:
repository = Path(tmp) / "missing-repository"
result = self.run_launcher(cwd=tmp, repository=repository)
self.assertEqual(result.returncode, 2)
self.assertIn("does not exist", result.stderr)

def test_invalid_usage_is_clear(self):
result = self.run_launcher("--root")
self.assertEqual(result.returncode, 2)
Expand Down
Loading