{"id":16445506,"url":"https://github.com/stephenafamo/boilingseed","last_synced_at":"2025-10-08T22:13:51.423Z","repository":{"id":57529881,"uuid":"264778617","full_name":"stephenafamo/boilingseed","owner":"stephenafamo","description":"BoilingSeed is a CLI tool that helps generate database seeding helpers with sqlboiler. https://github.com/volatiletech/sqlboiler.","archived":false,"fork":false,"pushed_at":"2025-07-25T01:22:43.000Z","size":220,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-03T16:52:09.342Z","etag":null,"topics":["database","go","golang","sqlboiler"],"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/stephenafamo.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}},"created_at":"2020-05-17T23:49:53.000Z","updated_at":"2025-07-25T01:22:47.000Z","dependencies_parsed_at":"2024-06-20T01:46:28.854Z","dependency_job_id":"ef595049-5003-4b61-9abb-709d0d39fe37","html_url":"https://github.com/stephenafamo/boilingseed","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/stephenafamo/boilingseed","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenafamo%2Fboilingseed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenafamo%2Fboilingseed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenafamo%2Fboilingseed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenafamo%2Fboilingseed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stephenafamo","download_url":"https://codeload.github.com/stephenafamo/boilingseed/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenafamo%2Fboilingseed/sbom","scorecard":{"id":851438,"data":{"date":"2025-08-11","repo":{"name":"github.com/stephenafamo/boilingseed","commit":"ef9723329f065031fe25e0bad62b679f612ce48c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":6,"reason":"8 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 2/25 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 7 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T22:39:45.609Z","repository_id":57529881,"created_at":"2025-08-23T22:39:45.609Z","updated_at":"2025-08-23T22:39:45.609Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000780,"owners_count":26082851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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","go","golang","sqlboiler"],"created_at":"2024-10-11T09:44:38.414Z","updated_at":"2025-10-08T22:13:51.406Z","avatar_url":"https://github.com/stephenafamo.png","language":"Go","readme":"# BoilingSeed\n\nThis is a CLI tool that helps generate database seeding helpers with [`sqlboiler`](https://github.com/aarondl/sqlboiler).\n\nThis is a really early release, so while it works (I use it for my projects), it is not super stable YET.\n\n## Installation\n\n- Install [`sqlboiler`](https://github.com/aarondl/sqlboiler)\n- Install your database driver for [`sqlboiler`](https://github.com/aarondl/sqlboiler#supported-databases).\n- Generate your models. [Link](https://github.com/aarondl/sqlboiler#initial-generation)\n- Install boilingseed: `go get github.com/stephenafamo/boilingseed`\n\n## Usage\n\nGenerate the seeds with:\n\n```shell\nboilingseed psql\n```\n\nYou can then seed the database like this:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"database/sql\"\n\n    \"path/to/package/seed\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    db := getDB()\n    seeder := seed.Seeder\n    seeder.MinJetsToSeed = 1\n    seeder.MinLanguagesToSeed = 1\n    seeder.MinPilotsToSeed = 1\n\n    err := seeder.Run(ctx, db)\n    if err != nil {\n      panic(err)\n    }\n}\n```\n\n## Configuration\n\nBy defualt the sqlboiler configuration files are used: `sqlboiler.toml` or `json` or `yaml`.\n\nApart from the standard configuration for SQLBoiler, the only other added configuration is the package name of the generated SQLBoiler models. By default the models subdirectory of the current go module is used.\n\nThe program accepts these flags to overwrite any configuration.\n\n- `--sqlboiler-models`: The package of your generated models. Needed to import them properly in the seeder. DEFAULT: `current/go/module/models`.\n- `--config`: Configuration file path. DEFAULT: `sqlboiler.toml`\n- `--output` or `-o`: The name of the folder to output to. DEFAULT: `seeds`\n- `--pkgname` or `-p`: The name you wish to assign to your generated package. DEFAULT: `seeds`\n- `--no-context`: Were the models generated with no context?. DEFAULT `false`\n- `--wipe`: Delete the output folder (rm -rf) before generation to ensure sanity. DEFAULT `false`\n- `--version`: Print the version\n- `debug` or `d`: Debug mode prints stack traces on error. DEFAULT `false`\n\nThey can also be set in the config file, or as environment variables\n\n**NOTE:** If you have customized the output folder or pkgname in your `sqlboiler` config file and you are passing the same file to `boilingseed`, you should overwrite them using the `-o` and `p` flags respectively.\n\n## Controlling seeding\n\nMost examples will be demonstrated using the following Postgres schema, structs and variables:\n\n```sql\nCREATE TABLE pilots (\n  id integer NOT NULL,\n  name text NOT NULL\n);\n\nALTER TABLE pilots ADD CONSTRAINT pilot_pkey PRIMARY KEY (id);\n\nCREATE TABLE jets (\n  id integer NOT NULL,\n  pilot_id integer NOT NULL,\n  age integer NOT NULL,\n  name text NOT NULL,\n  color text NOT NULL\n);\n\nALTER TABLE jets ADD CONSTRAINT jet_pkey PRIMARY KEY (id);\nALTER TABLE jets ADD CONSTRAINT jet_pilots_fkey FOREIGN KEY (pilot_id) REFERENCES pilots(id);\n\nCREATE TABLE languages (\n  id integer NOT NULL,\n  language text NOT NULL\n);\n\nALTER TABLE languages ADD CONSTRAINT language_pkey PRIMARY KEY (id);\n\n-- Join table\nCREATE TABLE pilot_languages (\n  pilot_id integer NOT NULL,\n  language_id integer NOT NULL\n);\n\n-- Composite primary key\nALTER TABLE pilot_languages ADD CONSTRAINT pilot_language_pkey PRIMARY KEY (pilot_id, language_id);\nALTER TABLE pilot_languages ADD CONSTRAINT pilot_language_pilots_fkey FOREIGN KEY (pilot_id) REFERENCES pilots(id);\nALTER TABLE pilot_languages ADD CONSTRAINT pilot_language_languages_fkey FOREIGN KEY (language_id) REFERENCES languages(id);\n```\n\nThe generated package will define a Seeder struct whose fields control seeding.\nThe comments help understand what each field does.\n\n```go\ntype Seeder struct {\n\t// The minimum number of Jets to seed\n\tMinJetsToSeed int\n\t// RandomJet creates a random models.Jet\n\t// It does not need to add relationships.\n\t// If one is not set, defaultRandomJet() is used\n\tRandomJet func() (*models.Jet, error)\n\t// AfterJetsAdded runs after all Jets are added\n\tAfterJetsAdded func(ctx context.Context) error\n\t// defaultJetForeignKeySetter() is used if this is not set\n\t// setting this means that the xxxPerxxx settings cannot be guaranteed\n\tJetForeignKeySetter func(i int, o *models.Jet, allPilots models.PilotSlice) error\n\n\t// The minimum number of Languages to seed\n\tMinLanguagesToSeed int\n\t// RandomLanguage creates a random models.Language\n\t// It does not need to add relationships.\n\t// If one is not set, defaultRandomLanguage() is used\n\tRandomLanguage func() (*models.Language, error)\n\t// AfterLanguagesAdded runs after all Languages are added\n\tAfterLanguagesAdded func(ctx context.Context) error\n\n\t// The minimum number of PilotLanguages to seed\n\tMinRelsPerPilotLanguages int\n\n\t// The minimum number of Pilots to seed\n\tMinPilotsToSeed int\n\t// RandomPilot creates a random models.Pilot\n\t// It does not need to add relationships.\n\t// If one is not set, defaultRandomPilot() is used\n\tRandomPilot func() (*models.Pilot, error)\n\t// AfterPilotsAdded runs after all Pilots are added\n\tAfterPilotsAdded func(ctx context.Context) error\n\n\tJetsPerPilot int\n\n\t// Number of times to retry getting a unique relationship in many-to-many relationships\n\tRetries int\n}\n```\n\n### `MinXXXToSeed`\n\nThe `MinXXXToSeed` variables are used to control how many of each model to seed.\n\n**NOTE:** The final amount seeded could be more than this because of other variables. For example, if **MinJetsToSeed** and **MinPilotsToSeed** are set to `3`, but **JetsPerPilot** is set to `5`, then the final number of Jets seeded will be 15 because each of the 3 pilots need 5 jets.\n\n```go\nseeder.MinJetsToSeed = 5\nseeder.MinLanguagesToSeed = 4\nseeder.MinPilotsToSeed = 3\n```\n\n### `xxxPerXXX`\n\nThe `xxxPerXXX` fields are used to control how many `one-to-many` relationships are added. For example, if you seed a single pliot, it will auto-seed jets related to that pilot.\n\n```go\nseeder.JetsPerPilot = 2\n```\n\n### `MinRelsPerXXX`\n\nThe `MinRelsPerXXX` fields are control how many `many-to-many` relationships are added. In this example, it will **try** to give each Pilot _at least_ 3 Languages and each Language _at least_ 3 pilots.\n\nNaturally, if there are more pilots than languages, each language will likely have more than 3 pilots.\n\n```go\nseeder.MinRelsPerPilotLanguages = 3\n```\n\n### `RandomXXX`\n\nThe package has `defaultRandomXXX` functions that use `github.com/aarondl/randomize`. However, for better control you can set custom `RandomXXX` functions. A single function that randomly generates a model.\n\nThe `RandomXXX` functions do not need to add any relationships to the models.\n\n```go\nseeder.RandomPilot = func() (*models.Pilot, error) {\n    // Build a random pilot\n    // Do not worry about relationships those are auto generaeted by the seeder\n    // check out github.com/Pallinder/go-randomdata\n}\n\nseeder.RandomJet = func() (*models.Jet, error) {\n    // Build a random jet\n    // Do not worry about relationships those are auto generaeted by the seeder\n    // check out github.com/Pallinder/go-randomdata\n}\n\nseeder.RandomLanguage = func() (*models.Language, error) {\n    // Build a random language\n    // Do not worry about relationships those are auto generaeted by the seeder\n    // check out github.com/Pallinder/go-randomdata\n}\n```\n\n### `AfterXXXAdded`\n\nThe package has default `AfterXXXAdded` functions that do nothing.\n\nIf you'd like to perform any actions after all models of a specific table is added to the database, you can set this field.\n\n```go\nseeder.AfterPilotsAdded = func(ctx context.Context) error {\n  // Do something\n}\n\nseeder.AfterJetsAdded = func(ctx context.Context) error {\n  // Do something\n}\n\nseeder.AfterLanguagesAdded = func(ctx context.Context) error {\n  // Do something\n}\n```\n\n### `xxxForeignKeySetter`\n\nAfter a random model is generated, this function is called to set the foreign keys on the model.\n\nIn most cases, you wouldn't have to touch this, the default functions evenly distribute relationships to related models.\n\n```go\nseeder.\tJetForeignKeySetter func(i int, o *models.Jet, allPilots models.PilotSlice) error {\n    o.PilotID = 12345\n    return nil\n}\n```\n\n## Testing\n\nBoilingSeed includes comprehensive integration tests that simulate real-world usage scenarios. The integration tests validate the entire workflow from database schema creation to seeder generation and execution.\n\n### Running Integration Tests\n\nTo run the complete integration test suite:\n\n```bash\ngo test -v -run TestBoilingSeedIntegration\n```\n\n### What the Integration Tests Cover\n\nThe integration tests (`integration_test.go`) include 9 comprehensive test scenarios:\n\n1. **DatabaseSetup** - Creates a temporary SQLite database with a realistic schema (authors, books, categories, book_tags tables)\n2. **ProjectStructure** - Sets up a temporary Go project with proper module structure and SQLBoiler configuration\n3. **SQLBoilerGeneration** - Generates SQLBoiler models from the database schema\n4. **BoilingSeedGeneration** - Runs the boilingseed command to generate seeder files\n5. **GeneratedCodeCompilation** - Verifies that all generated code compiles correctly\n6. **SeederExecution** - Tests that the generated seeders actually run and create data in the database\n7. **CustomSeederFunctions** - Tests custom seeder functions and callbacks (RandomXXX, AfterXXXAdded)\n8. **ForeignKeyRelationships** - Verifies that foreign key relationships are properly handled and data integrity is maintained\n9. **ConfigurationOptions** - Tests various configuration options (custom output directory, package names, wipe option)\n\n### Test Database Schema\n\nThe integration tests use a realistic book store schema with:\n\n```sql\n-- Authors table\nCREATE TABLE authors (\n    id INTEGER PRIMARY KEY AUTOINCREMENT,\n    name TEXT NOT NULL,\n    email TEXT UNIQUE NOT NULL,\n    bio TEXT,\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- Categories table\nCREATE TABLE categories (\n    id INTEGER PRIMARY KEY AUTOINCREMENT,\n    name TEXT NOT NULL UNIQUE,\n    description TEXT,\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- Books table with foreign keys\nCREATE TABLE books (\n    id INTEGER PRIMARY KEY AUTOINCREMENT,\n    title TEXT NOT NULL,\n    isbn TEXT UNIQUE NOT NULL,\n    author_id INTEGER NOT NULL,\n    category_id INTEGER NOT NULL,\n    published_date DATE,\n    pages INTEGER,\n    price DECIMAL(10,2),\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    FOREIGN KEY (author_id) REFERENCES authors(id),\n    FOREIGN KEY (category_id) REFERENCES categories(id)\n);\n\n-- Many-to-many relationship table\nCREATE TABLE book_tags (\n    book_id INTEGER NOT NULL,\n    tag_name TEXT NOT NULL,\n    PRIMARY KEY (book_id, tag_name),\n    FOREIGN KEY (book_id) REFERENCES books(id)\n);\n```\n\n### Prerequisites for Running Tests\n\nThe integration tests require:\n\n1. **SQLBoiler** - Must be installed and available in your PATH\n\n   ```bash\n   go install github.com/aarondl/sqlboiler/v4@latest\n   go install github.com/aarondl/sqlboiler/v4/drivers/sqlboiler-sqlite3@latest\n   ```\n\n2. **Go environment** - The tests create temporary Go modules and build executables\n\n3. **SQLite** - The tests use SQLite as the database backend\n\n### Test Output\n\nThe integration tests provide detailed output showing:\n\n- Database setup and schema creation\n- SQLBoiler model generation\n- BoilingSeed seeder generation\n- Code compilation results\n- Seeder execution with data counts\n- Foreign key relationship validation\n\nExample successful test output:\n\n```\n=== RUN   TestBoilingSeedIntegration\n=== RUN   TestBoilingSeedIntegration/DatabaseSetup\n=== RUN   TestBoilingSeedIntegration/ProjectStructure\n=== RUN   TestBoilingSeedIntegration/SQLBoilerGeneration\n=== RUN   TestBoilingSeedIntegration/BoilingSeedGeneration\n=== RUN   TestBoilingSeedIntegration/GeneratedCodeCompilation\n=== RUN   TestBoilingSeedIntegration/SeederExecution\n=== RUN   TestBoilingSeedIntegration/CustomSeederFunctions\n=== RUN   TestBoilingSeedIntegration/ForeignKeyRelationships\n=== RUN   TestBoilingSeedIntegration/ConfigurationOptions\n--- PASS: TestBoilingSeedIntegration (9.25s)\n```\n\n## Contributing\n\nThis still needs some polishing, looking forward to pull requests!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstephenafamo%2Fboilingseed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstephenafamo%2Fboilingseed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstephenafamo%2Fboilingseed/lists"}