# folk-builder

Custom binary builder for Folk — generates and compiles a Folk server binary with your selected plugins.

> **Status:** in active development. See [folk-spec](https://github.com/Folk-Project/folk-spec) for the roadmap.

## Requirements

- Rust 1.85+ (with `cargo`)
- A `folk.build.toml` file

## Installation

```bash
cargo install --git https://github.com/Folk-Project/folk-builder
```

## Quick start

1. Create `folk.build.toml`:

```toml
[build]
output = "my-folk"

[[plugin]]
crate_name = "folk_plugin_http"
git = "https://github.com/Folk-Project/folk-plugin-http"
config_key = "http"

[[plugin]]
crate_name = "folk_plugin_metrics"
git = "https://github.com/Folk-Project/folk-plugin-metrics"
config_key = "metrics"

[[plugin]]
crate_name = "folk_plugin_jobs"
git = "https://github.com/Folk-Project/folk-plugin-jobs"
config_key = "jobs"
```

2. Build:

```bash
folk-builder build
```

Output:

```
INFO reading folk.build.toml
INFO generating Cargo.toml with 3 plugins
INFO generating main.rs
INFO running cargo build --release
   Compiling folk_plugin_http v0.1.0
   Compiling folk_plugin_metrics v0.1.0
   Compiling folk_plugin_jobs v0.1.0
   Compiling my-folk v0.1.0
    Finished release [optimized] target(s)
INFO copied binary to ./my-folk
```

3. Run the binary:

```bash
./my-folk serve --config folk.toml
```

## Configuration

### `folk.build.toml` format

#### `[build]`

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `output` | `String` | (required) | Name of the generated binary. |
| `rust_version` | `String` | `"1.85"` | Rust edition/version for the generated crate. |

#### `[[plugin]]` (repeatable)

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `crate_name` | `String` | (required) | Rust crate name of the plugin. |
| `version` | `String` | — | Version constraint (for crates.io). |
| `path` | `String` | — | Local filesystem path (overrides version). |
| `git` | `String` | — | Git repository URL (overrides version). |
| `config_key` | `String` | same as `crate_name` | TOML key in `folk.toml` for this plugin's config. |

### CLI

```
folk-builder build [OPTIONS]

Options:
  --config <CONFIG>        Path to build config [default: folk.build.toml]
  --output-dir <DIR>       Directory for the compiled binary [default: .]
```

## How it works

The builder generates a temporary Rust project, compiles it, and copies the resulting binary to your output directory.

**What gets compiled in:**

- `folk-core` — server core, worker pool, plugin registry
- `folk-api` — plugin contract
- `folk-runtime-pipe` — default pipe-based worker runtime
- Every plugin listed in `[[plugin]]` sections
- All transitive dependencies

**What stays external (required at runtime):**

- `folk.toml` — server configuration file
- PHP binary and worker script
- Any files your PHP application needs

### Generated code

The builder produces two files in a temp directory:

1. **`Cargo.toml`** — Lists folk-core, folk-api, the pipe runtime, and all plugin crates as dependencies.
2. **`main.rs`** — A tokio async entry point that:
   - Loads `FolkConfig` from `folk.toml`
   - Creates the worker runtime
   - Calls `folk_plugin_factory()` on each plugin crate
   - Passes each plugin its config section (looked up by `config_key`)
   - Starts the server

Each plugin must export a `folk_plugin_factory()` function — this is the single required entry point that the builder calls by name.

## License

MIT
