{"id":47965068,"url":"https://github.com/mhiro2/seedling","last_synced_at":"2026-04-04T10:29:03.650Z","repository":{"id":344912253,"uuid":"1183231101","full_name":"mhiro2/seedling","owner":"mhiro2","description":"Dependency-aware test data builder for Go that resolves foreign-key DB relationships automatically.","archived":false,"fork":false,"pushed_at":"2026-03-28T13:14:35.000Z","size":661,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-28T17:11:47.087Z","etag":null,"topics":["database","fixtures","go","gorm","pgx","sql","sqlc","testing"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mhiro2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-16T12:02:21.000Z","updated_at":"2026-03-28T14:44:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mhiro2/seedling","commit_stats":null,"previous_names":["mhiro2/seedling"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/mhiro2/seedling","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhiro2%2Fseedling","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhiro2%2Fseedling/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhiro2%2Fseedling/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhiro2%2Fseedling/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mhiro2","download_url":"https://codeload.github.com/mhiro2/seedling/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhiro2%2Fseedling/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31397051,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","fixtures","go","gorm","pgx","sql","sqlc","testing"],"created_at":"2026-04-04T10:29:02.878Z","updated_at":"2026-04-04T10:29:03.631Z","avatar_url":"https://github.com/mhiro2.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/logo.png\" width=\"256\" height=\"256\" alt=\"seedling logo\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eseedling\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eDependency-aware test data builder for Go and SQL databases.\u003c/strong\u003e\u003cbr\u003e\n  seedling lets tests create only the rows they need while automatically resolving foreign-key dependencies in the correct order. You provide the insert logic. seedling handles planning, FK assignment, and execution order.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/mhiro2/seedling\"\u003e\n    \u003cimg src=\"https://pkg.go.dev/badge/github.com/mhiro2/seedling.svg\" alt=\"Go Reference\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/mhiro2/seedling/actions/workflows/ci.yaml\"\u003e\n    \u003cimg src=\"https://github.com/mhiro2/seedling/actions/workflows/ci.yaml/badge.svg\" alt=\"CI\"\u003e\n  \u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/license-MIT-green?style=flat-square\" alt=\"MIT License\"\u003e\n\u003c/p\u003e\n\n---\n\n## ✨ Why seedling?\n\nManually wiring FK dependencies across 4 tables:\n\n```go\nfunc TestCreateTask(t *testing.T) {\n    company, err := db.InsertCompany(ctx, InsertCompanyParams{Name: \"acme\"})\n    if err != nil { t.Fatal(err) }\n\n    user, err := db.InsertUser(ctx, InsertUserParams{\n        Name: \"alice\", CompanyID: company.ID,\n    })\n    if err != nil { t.Fatal(err) }\n\n    project, err := db.InsertProject(ctx, InsertProjectParams{\n        Name: \"renewal\", CompanyID: company.ID,\n    })\n    if err != nil { t.Fatal(err) }\n\n    task, err := db.InsertTask(ctx, InsertTaskParams{\n        Title: \"design\", ProjectID: project.ID, AssigneeUserID: user.ID,\n    })\n    if err != nil { t.Fatal(err) }\n\n    _ = task\n}\n```\n\nWith seedling, the graph is resolved automatically:\n\n```go\nfunc TestCreateTask(t *testing.T) {\n    result := seedling.InsertOne[Task](t, db)\n    task := result.Root()\n    _ = task\n}\n```\n\nseedling handles FK ordering, graph expansion, and cleanup so your tests stay focused on what matters:\n\n- 🪶 Zero runtime dependencies in the core module; optional DB helpers live in companion packages\n- 🔗 Automatic FK resolution with topological insert ordering\n- 🌿 Minimal graph expansion: only required ancestors are inserted\n- 🔧 Type-safe per-test overrides with `Set`, `Use`, `Ref`, `With`, `When`, and `Only`\n- ♻️ `WithTx` and companion helpers for auto-rollback transactions -- no manual cleanup\n- 🔌 Works with sqlc, `database/sql`, pgx, GORM, or any other DB handle you own\n- 📊 Supports `HasMany`, `ManyToMany`, composite keys, cleanup, dry runs, and insert logging\n- 🎲 Includes deterministic fake data via [`seedling/faker`](https://pkg.go.dev/github.com/mhiro2/seedling/faker) with multi-locale support (en, ja, zh, ko, de, fr)\n\n## 📦 Installation\n\nAdd an import in your code, then let the toolchain record the dependency:\n\n```go\nimport \"github.com/mhiro2/seedling\"\n```\n\nUse the same pattern for companion packages when you need them, for example [`seedling/faker`](https://pkg.go.dev/github.com/mhiro2/seedling/faker) (`github.com/mhiro2/seedling/faker`) or [`seedlingpgx`](https://pkg.go.dev/github.com/mhiro2/seedling/seedlingpgx) (`github.com/mhiro2/seedling/seedlingpgx`).\n\nInstall the `seedling-gen` CLI (pick one):\n\n```bash\n# Homebrew (macOS / Linux) — [third-party tap](https://github.com/mhiro2/homebrew-tap)\nbrew install --cask mhiro2/tap/seedling-gen\n```\n\n```bash\n# Go toolchain\ngo install github.com/mhiro2/seedling/cmd/seedling-gen@latest\n```\n\n## 🚀 Quick Start\n\n1. **Generate blueprints from your schema**\n\n   ```bash\n   # From SQL DDL\n   seedling-gen sql --pkg testutil --out blueprints.go schema.sql\n\n   # Or from other sources:\n   seedling-gen sqlc --config sqlc.yaml --pkg testutil --out blueprints.go\n   seedling-gen gorm --dir ./models --import-path github.com/you/app/models --pkg testutil\n   seedling-gen ent --dir ./ent/schema --import-path github.com/you/app/ent --pkg testutil\n   seedling-gen atlas --pkg testutil schema.hcl\n   seedling-gen sql --explain schema.sql\n   ```\n\n   This generates struct types, `RegisterBlueprints()`, relations, and Insert stubs. Fill in the `// TODO` callbacks with your DB logic:\n\n   ```go\n   Insert: func(ctx context.Context, db seedling.DBTX, v Company) (Company, error) {\n       return insertCompany(ctx, db, v) // your DB call\n   },\n   ```\n\n   The snippets below assume the generated package is named `testutil`.\n   For a runnable minimal version of this flow, see [examples/quickstart](./examples/quickstart).\n\n2. **Use it in tests**\n\n   ```go\n   func TestUser(t *testing.T) {\n       seedling.ResetRegistry()\n       testutil.RegisterBlueprints()\n\n       result := seedling.InsertOne[testutil.User](t, db)\n       user := result.Root()\n\n       if user.ID == 0 {\n           t.Fatal(\"expected user ID to be set\")\n       }\n       if user.CompanyID == 0 {\n           t.Fatal(\"expected company to be inserted automatically\")\n       }\n   }\n   ```\n\n3. **Override only what the test cares about**\n\n   ```go\n   func TestNamedUser(t *testing.T) {\n       seedling.ResetRegistry()\n       testutil.RegisterBlueprints()\n\n       company := seedling.InsertOne[testutil.Company](t, db).Root()\n\n       result := seedling.InsertOne[testutil.User](t, db,\n           seedling.Set(\"Name\", \"alice\"),\n           seedling.Use(\"company\", company),\n       )\n\n       user := result.Root()\n       _ = user\n   }\n\n   func TestTaskProject(t *testing.T) {\n       seedling.ResetRegistry()\n       testutil.RegisterBlueprints()\n\n       // Only(\"project\") inserts task + project subtree only,\n       // skipping the assignee relation entirely.\n       result := seedling.InsertOne[testutil.Task](t, db,\n           seedling.Only(\"project\"),\n       )\n       _ = result\n   }\n   ```\n\n   When you want automatic rollback with `database/sql`, use `seedling.WithTx(t, db)`.\n   For a runnable transaction-focused example, see [examples/with-tx](./examples/with-tx).\n\n   For a runnable batch-oriented example, see [examples/batch-insert](./examples/batch-insert).\n\n## ⚖️ Comparison\n\n| Tool | Main model | Strong at | Not designed for |\n| --- | --- | --- | --- |\n| seedling | Dependency-aware builders with DB callbacks | Per-test graph generation, automatic FK resolution, type-safe overrides, graph inspection, codegen | Bulk loading large static fixture files |\n| [eyo-chen/gofacto](https://github.com/eyo-chen/gofacto) | Generic factory with explicit FK associations | Ergonomic zero-config field filling, `WithOne`/`WithMany` associations, multi-DB support | Automatic graph resolution, minimal graph expansion |\n| [go-testfixtures/testfixtures](https://github.com/go-testfixtures/testfixtures) | Fixture files loaded into DB | Stable predefined datasets for integration tests | Relation-aware per-test graph construction |\n| [bluele/factory-go](https://github.com/bluele/factory-go) | In-memory object factories | Flexible object construction and traits-like composition | Planning SQL insert order across FK graphs |\n| [brianvoe/gofakeit](https://github.com/brianvoe/gofakeit) | Fake data generator | Realistic random values | Database insertion orchestration or relation expansion |\n\n## 📂 Examples\n\n- [basic](./examples/basic): register blueprints and insert rows with automatic parent creation\n- [quickstart](./examples/quickstart): generated-style `RegisterBlueprints()` flow that matches the README Quick Start\n- [custom-defaults](./examples/custom-defaults): customize values with `Set`, `With`, and `Generate`\n- [reuse-parent](./examples/reuse-parent): reuse existing rows with `Use`\n- [batch-insert](./examples/batch-insert): batch inserts with shared `Ref` dependencies and per-row `SeqRef` overrides\n- [with-tx](./examples/with-tx): `database/sql` transaction helper with `seedling.WithTx`\n- [sqlc](./examples/sqlc): wire blueprints to sqlc-generated query code\n- pgx transactions: use `github.com/mhiro2/seedling/seedlingpgx` with `pgxpool.Pool` or `*pgx.Conn`\n- GORM / ent / Atlas: use `seedling-gen` with `-gorm`, `-ent`, or `-atlas` flags to generate blueprints from your existing schema definitions\n\n## 📚 Learn More\n\n- [Guide](./docs/guide.md) -- workflows, option reference, and integration patterns\n- [Architecture](./ARCHITECTURE.md) -- internal pipeline design (planner, graph, executor)\n- [Agent Skill: seedling-gen CLI](./skills/seedling-gen-cli/SKILL.md) -- instructions for AI agents that need to choose the right generator mode and scaffold blueprints\n- [Agent Skill: seedling test setup](./skills/seedling-test-setup/SKILL.md) -- instructions for AI agents that write Go tests using seedling blueprints\n- [pkg.go.dev API reference](https://pkg.go.dev/github.com/mhiro2/seedling) -- full type and function docs\n\n## 📝 License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmhiro2%2Fseedling","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmhiro2%2Fseedling","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmhiro2%2Fseedling/lists"}