Skip to content
Open
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: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Cloned repositories (managed by devtools.sh)
# Cloned repositories (managed via repos.conf)
teiserver/
bar-lobby/
spads_config_bar/
Expand All @@ -8,11 +8,16 @@ BYAR-Chobby
bar-db/
bar-live-services/
RecoilEngine
lua-doc-extractor
SPADS/
SpringLobbyInterface/

# Personal config overrides
repos.local.conf
.env

# Build artifacts
bar-lua-codemod/target/

# Runtime / editor state
tasks/
Expand Down
18 changes: 18 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
set dotenv-load

mod services 'just/services.just'
mod repos 'just/repos.just'
mod engine 'just/engine.just'
mod setup 'just/setup.just'
mod link 'just/link.just'
mod lua 'just/lua.just'
mod docs 'just/docs.just'
mod bar 'just/bar.just'
mod tei 'just/tei.just'

default:
@just --list --list-submodules

reset:
just lua::reset
just docs::reset
198 changes: 149 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ Everything server-side runs in Docker. The game client runs natively.
```bash
git clone https://github.com/thvl3/BAR-Devtools.git
cd BAR-Devtools
./devtools.sh init
./devtools.sh up
just setup::init
just services::up
```

`init` walks you through installing dependencies, cloning repositories, and building Docker images. You only need to run it once.
`setup::init` walks you through installing dependencies, cloning repositories, and building Docker images. You only need to run it once.

`up` starts PostgreSQL and Teiserver. On first run it seeds the database with test data and creates default accounts (~2-3 minutes). Subsequent starts are fast.
`services::up` starts PostgreSQL and Teiserver. On first run it seeds the database with test data and creates default accounts (~2-3 minutes). Subsequent starts are fast.

Once running:

Expand All @@ -30,41 +30,113 @@ Once running:

## Requirements

- **Linux** (Arch, Debian/Ubuntu, or Fedora)
- **Linux** (Arch, Debian/Ubuntu, or Fedora) or **macOS**
- **Docker** with Compose V2
- **Git**
- **Bash 4+** (Linux ships this; macOS needs `brew install bash`)
- **[just](https://github.com/casey/just)** -- command runner

```bash
# Install just
pacman -S just # Arch
dnf install just # Fedora
apt install just # Debian/Ubuntu
brew install just # Homebrew

# macOS only: install modern bash (macOS ships bash 3.2 which is too old)
brew install bash
```

Optional:

- **Node.js** (only needed if running bar-lobby)

`./devtools.sh install-deps` will detect your distro and install what's missing.
`just setup::deps` will detect your distro and install what's missing (except `just` itself).

## Commands

### Getting Started
Run `just` with no arguments to list everything:

```
$ just
Available recipes:
...
```

### Setup

| Command | Description |
|---------|-------------|
| `init` | Full first-time setup: install deps, clone repos, build images |
| `install-deps` | Install system packages (docker, git, nodejs) |
| Recipe | Description |
|--------|-------------|
| `just setup::init` | Full first-time setup: install deps, clone repos, build images |
| `just setup::deps` | Install system packages (docker, git, nodejs) |
| `just setup::check` | Check prerequisites and build Docker images |

### Services

| Command | Description |
|---------|-------------|
| `up [lobby] [spads]` | Start services (options are additive) |
| `down` | Stop all services |
| `status` | Show running containers |
| `logs [service]` | Tail logs (postgres, teiserver, spads, or all) |
| `lobby` | Start bar-lobby dev server standalone |
| `shell [service]` | Shell into a container (default: teiserver) |
| `reset` | Destroy all data and rebuild from scratch |
| Recipe | Description |
|--------|-------------|
| `just services::up [lobby] [spads]` | Start services (options are additive) |
| `just services::down` | Stop all services |
| `just services::status` | Show running containers |
| `just services::logs [service]` | Tail logs (postgres, teiserver, spads, or all) |
| `just services::lobby` | Start bar-lobby dev server standalone |
| `just services::shell [service]` | Shell into a container (default: teiserver) |
| `just services::build` | Build Docker images |
| `just services::reset` | Destroy all data and rebuild from scratch |

### Repositories

| Command | Description |
|---------|-------------|
| `clone [group]` | Clone/update repos. Groups: `core`, `extra`, `all` |
| `repos` | Show status of all configured repositories |
| `update` | Pull latest on all cloned repos (fast-forward only) |
| Recipe | Description |
|--------|-------------|
| `just repos::clone [group]` | Clone/update repos. Groups: `core`, `extra`, `all` |
| `just repos::status` | Show status of all configured repositories |
| `just repos::update` | Pull latest on all cloned repos (fast-forward only) |

### Engine

| Recipe | Description |
|--------|-------------|
| `just engine::build <platform> [cmake-args]` | Build Recoil engine via docker-build-v2 |

### Game Directory

| Recipe | Description |
|--------|-------------|
| `just link::status` | Show symlink status |
| `just link::create <target>` | Symlink a repo into the game directory (engine, chobby, bar) |

### Lua Tooling

| Recipe | Description |
|--------|-------------|
| `just lua::build-lde` | Build lua-doc-extractor from local checkout |
| `just lua::library` | Extract Lua docs from RecoilEngine, copy into BAR submodule |
| `just lua::library-reload` | Generate library then restart LuaLS |

### Documentation

| Recipe | Description |
|--------|-------------|
| `just docs::generate` | Generate Lua API doc pages |
| `just docs::server` | Generate + start Hugo dev server |
| `just docs::server-only` | Start Hugo dev server without regenerating |

### BAR (Beyond All Reason)

| Recipe | Description |
|--------|-------------|
| `just bar::lint` | Lint BAR Lua code (luacheck via lux) |
| `just bar::fmt` | Format BAR Lua code (stylua via lux) |
| `just bar::test` | Run busted unit tests in the BAR container |
| `just bar::integrations` | Run headless integration tests (x86-64 only) |
| `just bar::all` | Run all BAR tests (units + integrations) |
| `just bar::setup-hooks` | Install git pre-commit hook in the BAR repo |

### Teiserver

| Recipe | Description |
|--------|-------------|
| `just tei::mix` | Run teiserver mix tests |

## Using Your Own Forks

Expand All @@ -84,42 +156,69 @@ bar-lobby https://github.com/yourname/bar-lobby.git your-branch core
Then clone or re-clone:

```bash
./devtools.sh clone core
just repos::clone core
```

`repos.local.conf` is gitignored so it won't affect anyone else.

### Local paths

You can also point a repo entry at a local directory instead of cloning. Add a fifth column with the path:

```
lua-doc-extractor https://github.com/rhys-vdw/lua-doc-extractor.git main extra ~/code/lua-doc-extractor
```

This creates a symlink instead of cloning.

## Repository Config Format

`repos.conf` uses a simple whitespace-delimited format:

```
# directory url branch group
# directory url branch group [local_path]
teiserver https://github.com/beyond-all-reason/teiserver.git master core
```

- **directory** -- local folder name (created by `clone`)
- **url** -- git clone URL
- **branch** -- branch to checkout
- **group** -- `core` (required for the dev stack) or `extra` (optional)
- **local_path** -- (optional) absolute or `~`-relative path to symlink instead of cloning

## Architecture

```
BAR-Devtools/
├── devtools.sh # Main CLI script
├── repos.conf # Repository sources & branches
├── docker-compose.dev.yml # Service definitions
├── Justfile # Root command runner (lists all modules)
├── just/
│ ├── services.just # Docker Compose service management
│ ├── repos.just # Git repository operations
│ ├── engine.just # RecoilEngine build
│ ├── setup.just # First-time setup & dependency install
│ ├── link.just # Game directory symlinking
│ ├── lua.just # lua-doc-extractor & Lua library generation
│ ├── docs.just # Hugo documentation server
│ └── test.just # Unit & integration tests
├── scripts/
│ ├── common.sh # Shared color/logging helpers
│ ├── repos.sh # repos.conf parsing & git operations
│ └── setup.sh # Distro detection, deps, prerequisite checks
├── repos.conf # Repository sources & branches
├── docker-compose.dev.yml # Service definitions
├── docker/
│ ├── teiserver.dev.Dockerfile # Teiserver dev image (Elixir + Phoenix)
│ ├── teiserver-entrypoint.sh # DB init, seeding, migrations
│ ├── teiserver.dockerignore # Build context optimization
│ ├── setup-spads-bot.exs # Creates SPADS bot account in Teiserver
│ ├── spads-dev-entrypoint.sh # SPADS startup + game data download
│ └── spads_dev.conf # Simplified SPADS config for dev
├── teiserver/ # ← cloned by devtools.sh (gitignored)
├── bar-lobby/ # ← cloned by devtools.sh (gitignored)
└── spads_config_bar/ # ← cloned by devtools.sh (gitignored)
│ ├── teiserver.dev.Dockerfile # Teiserver dev image (Elixir + Phoenix)
│ ├── teiserver-entrypoint.sh # DB init, seeding, migrations
│ ├── teiserver.dockerignore # Build context optimization
│ ├── bar.Dockerfile # BAR test environment (Lua 5.1 + lux)
│ ├── setup-spads-bot.exs # Creates SPADS bot account in Teiserver
│ ├── spads-dev-entrypoint.sh # SPADS startup + game data download
│ └── spads_dev.conf # Simplified SPADS config for dev
├── teiserver/ # ← cloned by just repos::clone (gitignored)
├── bar-lobby/ # ← cloned (gitignored)
├── Beyond-All-Reason/ # ← cloned (gitignored)
├── RecoilEngine/ # ← cloned (gitignored)
└── spads_config_bar/ # ← cloned (gitignored)
```

### What the Docker stack does
Expand All @@ -130,8 +229,9 @@ BAR-Devtools/
- Seeds fake data (test users, matchmaking data)
- Sets up Tachyon OAuth
- Creates a `spadsbot` account with Bot/Moderator roles
- **SPADS** (optional, `up spads`) -- Perl autohost using `badosu/spads:latest`. Downloads game data via `pr-downloader` on first run. Connects to Teiserver via Spring protocol on port 8200.
- **SPADS** (optional, `services::up spads`) -- Perl autohost using `badosu/spads:latest`. Downloads game data via `pr-downloader` on first run. Connects to Teiserver via Spring protocol on port 8200.
- **bar-lobby** -- Electron/Vue.js game client, runs natively on the host (not in Docker)
- **BAR test runner** (`test` profile) -- Ubuntu container with Lua 5.1 and [lux](https://github.com/lumen-oss/lux) for running busted unit tests against the Beyond-All-Reason codebase

### Ports

Expand All @@ -148,8 +248,8 @@ BAR-Devtools/
SPADS is optional and started separately because it requires downloading ~300MB of game data on first run. The download depends on external rapid repositories that can be unreliable.

```bash
./devtools.sh up spads # Start with SPADS
./devtools.sh logs spads # Check SPADS status
just services::up spads # Start with SPADS
just services::logs spads # Check SPADS status
```

The SPADS bot account (`spadsbot` / `password`) is created automatically during Teiserver initialization.
Expand All @@ -159,21 +259,21 @@ The SPADS bot account (`spadsbot` / `password`) is created automatically during
**Port 5432/5433 conflict with host PostgreSQL:**
Either stop your local PostgreSQL (`sudo systemctl stop postgresql`) or change the port:
```bash
BAR_POSTGRES_PORT=5434 ./devtools.sh up
BAR_POSTGRES_PORT=5434 just services::up
```

**Teiserver takes forever on first run:**
The initial database seeding includes generating fake data. Follow progress with:
```bash
./devtools.sh logs teiserver
just services::logs teiserver
```

**SPADS fails with "No Spring map/mod found":**
Game data download may have failed. Check logs and retry:
```bash
./devtools.sh logs spads
./devtools.sh down
./devtools.sh up spads
just services::logs spads
just services::down
just services::up spads
```

**Docker permission denied:**
Expand All @@ -184,6 +284,6 @@ sudo usermod -aG docker $USER

**Nuclear option -- start completely fresh:**
```bash
./devtools.sh reset
./devtools.sh up
just services::reset
just services::up
```
Loading