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
55 changes: 55 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copilot instructions for `akfaiz/migris`

## Build, test, and lint commands

- Install deps: `make install`
- Install dev tools (`golangci-lint`, `gotestsum`): `make install-tools`
- Format: `make fmt`
- Lint: `make lint`
- Full test suite: `make test`
- Coverage run: `make testcov`
- CI-parity test run (race + coverage): `go test -v -cover -race ./...`

Run a single test:

- By exact test name across packages: `go test ./... -run '^TestUp$' -v`
- In one package/file area: `go test ./schema/grammars -run '^TestMysqlGrammar_CompileCreate$' -v`

## High-level architecture

Migris has two layers that work together:

1. **Migration runner layer (`migris` package root)**
`Migrate` wraps Goose provider usage (`migrate.go`, `up.go`, `down.go`, `reset.go`, `status.go`), wires the selected dialect, registry, migration dir, and dry-run behavior.
2. **Schema builder layer (`schema/`)**
DDL generation follows **Builder → Blueprint → Grammar → SQL execution**:
- `schema/builders/*`: dialect builders orchestrate schema operations
- `schema/blueprint/*`: fluent API collects column/index/command definitions
- `schema/grammars/*`: dialect-specific SQL compilation
- `schema/core/*`: execution context abstraction (`Context`) and dry-run SQL capture

Go migrations are registered in-memory through `AddMigrationContext` / `AddNamedMigrationContext` (`register.go`), then passed to Goose via `goose.WithGoMigrations(...)`.

## Key repository-specific conventions

- **Migration registration is filename-version driven.**
Version uniqueness and ordering come from numeric prefixes in migration source names (`goose.NumericComponent` in `register.go`). Keep migration filenames timestamp-prefixed and snake_case.

- **Migrations are expected to register in `init()` and be imported for side effects.**
Templates generated by `Create` and examples use this pattern; CLIs import migrations with `_ "path/to/migrations"` so registration happens before execution.

- **Schema operations should stay inside `schema.Context` (transaction-backed).**
Registered migration functions are wrapped into Goose `RunTx` handlers (`register.go`) that create `schema.NewContext(...)` with dialect/filename metadata.

- **Blueprint `Change()` preserves unspecified column attributes intentionally.**
`Blueprint.Build()` hydrates existing column metadata and carries forward nullable/default/comment when those commands are not explicitly set (`schema/blueprint/blueprint.go`).

- **When adding fluent schema features, update all dialect grammars and tests.**
New Blueprint/column modifiers must be implemented across MySQL, MariaDB, Postgres, and SQLite grammar paths, with corresponding grammar tests.

- **MySQL modifier output order is a compatibility contract.**
Keep modifier order consistent with existing SQL expectations/tests:
`Unsigned`, `Charset`, `Collate`, `VirtualAs`, `StoredAs`, `Nullable`, `Default`, `Increment`, `OnUpdate`, `Comment`, `After`, `First`.

- **Builder integration tests rely on Testcontainers.**
`schema/builders/*_test.go` spin real DB containers via `internal/testutil/db.go`; local runs need Docker available.
33 changes: 2 additions & 31 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.24'
go-version: '1.25'
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
with:
Expand All @@ -28,32 +28,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: ['1.24', '1.25']

services:
postgres:
image: postgres:16-alpine
ports:
- 5432:5432
env:
POSTGRES_USER: root
POSTGRES_PASSWORD: password
POSTGRES_DB: db_test
options: >-
--health-cmd pg_isready --health-interval 10s --health-timeout 5s
--health-retries 5
mysql:
image: mysql:8.0.36
ports:
- 3306:3306
env:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: db_test
options: >-
--health-cmd="mysqladmin ping -ppassword"
--health-interval=10s
--health-timeout=5s
--health-retries=5
go-version: ['1.25', '1.26']

steps:
- name: Checkout code
Expand All @@ -66,10 +41,6 @@ jobs:
run: |
go mod download
- name: Test
env:
DB_USER: root
DB_PASSWORD: password
DB_NAME: db_test
run: |
go test -v -cover -race ./... -coverprofile=coverage.txt
- name: Upload coverage reports to Codecov
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ go.work.sum
# Editor/IDE
.idea/
.vscode/
.serena/
.serena/
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -475,3 +475,7 @@ linters:
text: 'shadow'
linters:
- govet
- path: 'extra/(migriscli|migriscobra)/go\.mod'
text: 'local replacement are not allowed: github.com/akfaiz/migris'
linters:
- gomoddirectives
43 changes: 43 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Repository Guidelines

## Project Structure & Module Organization
Core migration APIs live at the repository root (`up.go`, `down.go`, `migrate.go`, `create.go`, `reset.go`, `status.go`).
Schema builders and SQL grammar implementations are in `schema/` (MySQL, PostgreSQL, SQLite).
Internal helper packages are in `internal/` (`config`, `dialect`, `logger`, `parser`, `util`).
Runnable examples are in `examples/` (`basic`, `migriscli`, `migriscobra`), while optional integrations are in `extra/`.
Tests are colocated with source files as `*_test.go`.

## Build, Test, and Development Commands
Use `make` targets:
- `make install`: download and tidy module dependencies.
- `make install-tools`: install `golangci-lint` and `gotestsum`.
- `make fmt`: run `go fmt ./...`.
- `make lint`: run strict lint checks (`golangci-lint run --timeout=2m --verbose`).
- `make test`: run all tests via `gotestsum`.
- `make testcov`: run tests with coverage output (`coverage.out`).

For quick checks, `go test ./...` is acceptable, but prefer `make test` in PR validation.

## Coding Style & Naming Conventions
Target Go `1.24` (see `go.mod`). Follow idiomatic Go and keep exported APIs stable.
Formatting is required before commit (`go fmt` and linter formatters like `goimports`/`golines` are enforced).
Use descriptive CamelCase for exported identifiers and short, clear lowerCamelCase for locals.
Migration filenames in examples follow timestamped snake case (for example, `20250904164848_create_users_table.go`).

## Testing Guidelines
Use Go’s `testing` package with `testify` assertions where helpful.
Name tests clearly with `TestXxx` and colocate them with implementation.
Run `make test` locally before opening a PR; use `make testcov` when changing migration logic, schema builders, or SQL grammar behavior.
Add regression tests for bug fixes.

## Commit & Pull Request Guidelines
Commit messages must follow Conventional Commits, enforced by `lefthook`:
`feat|fix|docs|style|refactor|test|chore(scope): summary`.
Examples from history include `feat: add sqlite3 support` and `fix: ...`.

Before pushing, run: `make fmt && make lint && make test`.
PRs should include:
- A concise change summary and motivation.
- Linked issue(s) when applicable.
- Notes on behavior changes and test coverage updates.
- Example CLI output or screenshots only when UX/output changed.
100 changes: 0 additions & 100 deletions CONTRIBUTING.md

This file was deleted.

48 changes: 48 additions & 0 deletions GEMINI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Migris Project Instructions

Migris is a database migration library for Go, inspired by Laravel's migrations. It combines the power of [pressly/goose](https://github.com/pressly/goose) with a fluent schema builder.

## Project Overview

- **Purpose:** Provide a fluent, Laravel-like API for defining and managing database schemas in Go.
- **Main Technologies:** Go (1.25+), [goose](https://github.com/pressly/goose), MySQL, PostgreSQL (pgx), SQLite3.
- **Architecture:**
- `schema/`: The core Schema Builder API. It uses a **Builder -> Blueprint -> Grammar -> DDL** pipeline.
- `Blueprint`: Collects column and index definitions.
- `Grammar`: Translates Blueprint definitions into dialect-specific SQL (DDL).
- `Builder`: Orchestrates the creation and modification of tables.
- `internal/`: Internal components including dialect management, logging, and configuration.
- `extra/`: Integration helpers for popular CLI frameworks like `Cobra` and `urfave/cli`.
- Root: High-level migration management (`Migrate`, `Registry`).

## Building and Running

The project uses a `Makefile` for common development tasks:

- **Install Dependencies:** `make install`
- **Format Code:** `make fmt`
- **Lint Code:** `make lint` or `make lint-fix`
- **Run Tests:** `make test` or `go test ./...`
- **Generate Coverage:** `make testcov` or `make testcov-html`

## Development Conventions

- **Code Style:** Use idiomatic Go and follow [Effective Go](https://golang.org/doc/effective_go.html). Run `go fmt` before submitting.
- **Testing:**
- ALWAYS add or update tests when making changes.
- Grammar implementations (e.g., `mysql_grammar.go`) MUST have corresponding tests (e.g., `mysql_grammar_test.go`) to verify DDL generation.
- Use `github.com/stretchr/testify` for assertions.
- **Grammar Implementation:**
- When adding new fluent modifiers to `Blueprint`, ensure they are implemented in all supported grammars (MySQL, Postgres, SQLite).
- Maintain consistent modifier order in DDL generation to match established conventions and existing tests.
- Standard MySQL modifier order: `Unsigned`, `Charset`, `Collate`, `VirtualAs`, `StoredAs`, `Nullable`, `Default`, `Increment`, `OnUpdate`, `Comment`, `After`, `First`.
- **Backward Compatibility:** Keep the public API stable. Avoid breaking changes unless absolutely necessary.
- **Transaction Safety:** Ensure all schema operations are performed within the provided `schema.Context` (which typically wraps a database transaction).

## Key Files

- `schema/blueprint.go`: The central place for defining the fluent API.
- `schema/grammar.go`: The interface for dialect-specific SQL generation.
- `schema/column_definition.go`: Defines the attributes and modifiers for table columns.
- `migrate.go`: The main entry point for running migrations.
- `internal/dialect/dialect.go`: Handles database dialect identification and mapping to Goose dialects.
Loading
Loading