migrate 0.3.2

Generic file migration tool for applying ordered transformations to a project directory
Documentation
# migrate

A generic file migration tool that applies ordered transformations to a project directory. Think database migrations, but for files and project setup. Migrations can be written in any language (bash, TypeScript, Python, etc.) using shebangs.

## Install

### Option 1: Download binary (easiest)

Download the pre-built binary for your platform from [GitHub Releases](https://github.com/glideapps/migrate/releases), then move it to a directory in your PATH:

```bash
# Example for macOS (Apple Silicon)
curl -L https://github.com/glideapps/migrate/releases/latest/download/migrate-aarch64-apple-darwin -o migrate
chmod +x migrate
sudo mv migrate /usr/local/bin/
```

### Option 2: cargo-binstall (recommended if you have Rust)

If you have Rust installed, [cargo-binstall](https://github.com/cargo-bins/cargo-binstall) downloads pre-built binaries:

```bash
# Install cargo-binstall first (if you don't have it)
cargo install cargo-binstall

# Then install migrate
cargo binstall migrate
```

### Option 3: cargo install

Requires [Rust](https://rustup.rs):

```bash
cargo install migrate
```

### Option 4: Build from source

```bash
cargo install --git https://github.com/glideapps/migrate
```

## Usage

### Check migration status

```bash
migrate status
```

### Apply pending migrations

```bash
migrate up
```

### Preview changes without applying

```bash
migrate up --dry-run
```

### Create a new migration

```bash
# Create a bash migration (default)
migrate create add-prettier

# Create a TypeScript migration
migrate create add-config --template ts

# Create with description
migrate create add-prettier -d "Add Prettier configuration"

# List available templates
migrate create --list-templates
```

## Writing Migrations

Migration files use the format `XXXXX-name.{sh,ts,py,...}` where `XXXXX` is a 5-character base36 version automatically generated by `migrate create`. The version encodes the creation timestamp, ensuring migrations sort chronologically.

Migrations are executable files that receive context via environment variables:

```bash
MIGRATE_PROJECT_ROOT=/path/to/project      # Absolute path to project root
MIGRATE_MIGRATIONS_DIR=/path/to/migrations # Where migration files live
MIGRATE_ID=1fb2g-initial-setup             # Current migration ID (includes version)
MIGRATE_DRY_RUN=true|false                 # Whether this is a dry run
```

### Bash example

```bash
#!/usr/bin/env bash
set -euo pipefail
# Description: Add TypeScript configuration

cd "$MIGRATE_PROJECT_ROOT"
cat > tsconfig.json << 'EOF'
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "strict": true
  }
}
EOF
```

### TypeScript example

```typescript
#!/usr/bin/env -S npx tsx
// Description: Add configuration file

import * as fs from 'fs/promises';
import * as path from 'path';

const projectRoot = process.env.MIGRATE_PROJECT_ROOT!;

const config = {
  version: 1,
  features: ['auth', 'api']
};

await fs.writeFile(
  path.join(projectRoot, 'config.json'),
  JSON.stringify(config, null, 2)
);
```

Migrations run in order by their version prefix (e.g., `1fb2g-`) and are tracked in a `.history` file.

## CLI Reference

| Command                     | Description                         |
| --------------------------- | ----------------------------------- |
| `migrate status`            | Show applied and pending migrations |
| `migrate up`                | Apply all pending migrations        |
| `migrate create <name>`     | Create a new migration file         |

### Options

| Option                     | Description                           | Default      |
| -------------------------- | ------------------------------------- | ------------ |
| `-r, --root <path>`        | Project root directory                | `.`          |
| `-m, --migrations <path>`  | Migrations directory                  | `migrations` |
| `--dry-run`                | Preview changes (up only)             | `false`      |
| `-t, --template <name>`    | Template to use (create only)         | `bash`       |
| `-d, --description <text>` | Migration description (create only)   | -            |
| `--list-templates`         | List available templates (create only)| -            |

## Available Templates

- `bash` - Shell script (`.sh`)
- `ts` - TypeScript via tsx (`.ts`)
- `python` - Python 3 (`.py`)
- `node` - Node.js (`.js`)
- `ruby` - Ruby (`.rb`)

## Development

```bash
# Clone and setup
git clone <repo-url>
cd migrate
./scripts/setup     # Enable git hooks, fetch deps, build, test

# Common commands
cargo build         # Build debug binary
cargo nextest run   # Run tests
cargo fmt           # Format code
cargo clippy        # Lint
cargo run -- status # Run CLI locally

# Build release
cargo build --release
```