Files
core/CONTRIBUTE.md
T

4.6 KiB

Contributing to boboko-core

This is a Composer library, not a runnable app — you can't php artisan serve it directly. To develop and verify changes, you need a consumer app wired to a local checkout via a Composer path repository, plus a real database, since a large part of this package (Lunar models, migrations, Filament panel resources) can only be meaningfully verified against a live Lunar install.

Local dev setup

This works against any consumer app that follows the same convention — boboko-test, boboko-starter, boboko-3dealer, etc. — checked out next to this repo:

RadicalElements/
├── boboko-core/    (this repo)
└── boboko-test/    (or boboko-starter, boboko-3dealer, ... — consumer app, Docker-based)

Each of these consumer apps ships a bin/dc-core.sh helper that wraps the Docker Compose overlay needed to bind-mount a local boboko-core checkout into the app container:

./bin/dc-core.sh exec app <command>

This is shorthand for docker compose -f docker-compose.dev.yml -f docker-compose.core-dev.yml exec app <command>. Use ./bin/dc-core.sh for everything below instead of typing the full compose invocation.

  1. Path repository. In the consumer app's composer.json, the repositories array needs a path entry pointing at ../boboko-core. If it only exists in a disabled block (e.g. _repositories), move it into the live array.

  2. Relaxed version constraint. The consumer app's composer.json should require "boboko/core": "0.*" (not a tight ^0.0.1 caret) — otherwise Composer rejects newer 0.0.x versions resolved from the path repo.

  3. Bind mount. The consumer app's docker-compose.core-dev.yml overlays ../boboko-core into the container at /var/www/boboko-core, matching where the path repo resolves it relative to /var/www/html.

  4. Re-resolve after every change. Composer's path repo does not hot-reload — after editing anything in boboko-core (including adding new files, which need autoload discovery), the container needs to re-run composer update boboko/core. In boboko-test, the entrypoint does this automatically on every dev boot (see docker/entrypoint.sh), so ./bin/dc-core.sh up alone picks up local core changes. If a consumer app's entrypoint doesn't do this yet, run it manually:

    ./bin/dc-core.sh exec app composer update boboko/core --with-all-dependencies
    

    Skipping this step is the most common cause of "my change isn't showing up."

Verifying changes against a real database

There is no automated test suite for this package — too much of Lunar's behavior (table prefixing, nested sets, translatable attributes, Filament panel filters) only breaks in combination, against real Postgres, in a way that's impractical to fake in isolation. Instead, verify changes directly against a consumer app's live database. The practical workflow used throughout this package's MigrateImport feature:

One-off checks, via php artisan tinker --execute="..." in the consumer app's container:

./bin/dc-core.sh exec app php artisan tinker --execute="
use Modules\Core\MigrateImport\Shopify\Resolvers\ProductTypeResolver;
\$type = (new ProductTypeResolver())->resolve('Test Type');
echo \$type->name . PHP_EOL;
"

Multi-step scripts (creating related records, checking round-trips), via a raw PHP script bootstrapped like an Artisan command — this avoids tinker's persistent-session quirks and more closely matches how code actually runs in a queued job:

./bin/dc-core.sh exec app php -r "
require 'vendor/autoload.php';
\$app = require 'bootstrap/app.php';
\$kernel = \$app->make(Illuminate\Contracts\Console\Kernel::class);
\$kernel->bootstrap();

// ... your verification code ...
"

Always clean up fixtures created this way — either via DB::statement('DELETE FROM ...') in the same script (respecting foreign key order — Lunar has cascading relations like lunar_customer_group_product that block naive deletes), or leave them if they're harmless and the DB is a disposable dev/test instance.

Non-obvious Lunar bugs/traps hit while building against it are documented in docs/lunar.md, not here — check there before debugging something that looks like a Lunar quirk.

Code organization

Feature work lives under src/<Feature>/, with models in a Models/ subdirectory (see src/Auth/Models, src/Customer/Models, src/MigrateImport/Models). Source-specific importer logic is grouped by source name (e.g. src/MigrateImport/Shopify/), with resolver classes (one responsibility each — resolve-or-create a single Lunar entity) grouped further under Resolvers/.