AGENTS.md
Wallaby is a family of Rails engine gems that autocomplete resourceful controllers and views for an ORM (ActiveRecord) to build admin interfaces.
Repository layout
Monorepo of five gems plus the documentation site. Dependency direction (low → high):
| Gem | Path | Role |
|---|---|---|
wallaby-view | wallaby-view/ | Plain view/rendering helpers, no Rails app |
wallaby-core | wallaby-core/ | Core: decorators, servicers, paginators, providers |
wallaby-active_record | wallaby-active_record/ | ActiveRecord adaptor for wallaby-core |
wallaby | wallaby/ | Rails engine (app/), assets, generators, JS |
wallaby-cop | wallaby-cop/ | Shared RuboCop config, standalone |
Supporting structure at the repository root:
| Area | Path | Role |
|---|---|---|
| Documentation site | docs/, index.md, _config.yml | just-the-docs (Jekyll) site covering the whole project; home page is index.md, pages under docs/ |
| Docs deployment | .github/workflows/pages.yml | Builds the Jekyll site and deploys to GitHub Pages on pushes to main (also workflow_dispatch) |
| CI (lint) | .github/workflows/pr-build.yml | RuboCop only, on changed files (does not run specs) |
| Test harness | spec/ | Host dummy app at spec/dummy; spec/support/ holds helpers/shared examples |
| Version matrix | .gemfiles/ | Gemfile.rails-8.0 / Gemfile.rails-8.1 for the CI matrix; do not pin Ruby |
| Agent files | .opencode/ | Skills for running specs and releasing gems (see Skills) |
wallaby-coreis the bulk of the logic underlib/wallaby/; thewallabygem is mostly the mountable engine inapp/pluslib/wallaby/generators/.- Gem versions are independent.
wallaby’s gemspec comment (This will determine wallaby-core's version) means the dependency constraints in the gemspecs must stay in sync when releasing. - The docs site is built by GitHub Pages with the
github-pagesgem, which only bundles its own themes — so_config.ymlmust keep usingremote_theme: just-the-docs/just-the-docs(fetched at build time), nottheme: just-the-docs. Jekyll build artifacts (.jekyll-cache/,_site/) are gitignored.
Toolchain
- Ruby: root
Gemfilepinsruby '4.0.7'; gems require>= 3.3.0. The.gemfiles/*matrix gemfiles do not pin a Ruby version. - Rails:
~> 8.1.0in the root Gemfile; CI matrix is Rails8.0/8.1. Gemfile.lockis gitignored. Never commit it.
Commands
Run from the repository root.
bundle install # root Gemfile (requires Ruby 4.0.7)
bundle exec rspec # full suite
bundle exec rspec path/to_spec.rb:42 # single example
bundle exec rake # default task == spec
bundle exec rubocop # lint
bundle exec rubocop path/to/file.rb
bundle exec yard # API docs (.yardopts)
Rails/Ruby version matrix (used by CI and for compatibility checks):
BUNDLE_GEMFILE=.gemfiles/Gemfile.rails-8.0 bundle install
BUNDLE_GEMFILE=.gemfiles/Gemfile.rails-8.0 bundle exec rspec
# same with .gemfiles/Gemfile.rails-8.1
Docker
Dockerfile, docker-compose.yml and docker/entrypoint.sh provide a self-contained dev environment (Ruby 4.0.7, Node/Yarn, Postgres 18, MySQL 9) so the suite and the dummy app can run without a local toolchain. SQLite is file-based and needs no service.
docker compose build # build the app image
docker compose up -d # app + Postgres + MySQL
docker compose exec app bin/rails db:schema:load # load the test schemas
docker compose exec app bundle exec rspec # full suite
docker compose exec app bundle exec rspec spec/foo_spec.rb:42
- Gems are installed into the
bundlenamed volume; the entrypoint runsbundle installon first boot and whenever the Gemfile changes. The
appservice defaults toRAILS_ENV=test, like CI. To boot the dummy app (the service publishes${APP_PORT:-3000}), override the environment:docker compose exec -e RAILS_ENV=development app bin/rails db:schema:load docker compose exec -e RAILS_ENV=development app bin/rails server -b 0.0.0.0- Database ports are intentionally not published, so the stack does not clash with a local Postgres/MySQL. Publish them per service if a host client needs access.
postgres:18mounts its data at/var/lib/postgresql(not.../data). Node 20 / Yarn 1 are in the image for the
wallabygem’s asset build, kept in thenode_modulesvolume:docker compose exec app bash -lc 'cd wallaby && yarn install' docker compose exec app bash -lc 'cd wallaby && yarn build:js && yarn build:scss'db:seedpopulates demo data for the dummy app (products, categories, orders, blogs with Active Storage images). It downloads placeholder images frompicsum.photos, so it needs network access.ostructandpumawere added as development dependencies so the dummy app boots on Ruby 4.0 (massarequiresostruct, which is no longer a default gem) and sobin/rails serverhas a server gem. The specs need neither.
Testing
- Specs boot the host dummy app at
spec/dummy, not the gems in isolation.spec/rails_helper.rbrequiresdummy/config/environment. DBselects the adapter the specs run against (defaultpostgresql):DB=postgresql POSTGRES_USER=postgres POSTGRES_PASSWORD=password bundle exec rspec DB=mysql MYSQL_ROOT_PASSWORD=password bundle exec rspec DB=sqlite bundle exec rspecSchemas live in
spec/dummy/db/{sqlite,postgresql,mysql}_schema.rband all three carry the shared tables.AllPostgresTypeis pinned to thepostgresqlconnection (likeAllMysqlType/AllSqliteType), so its PostgreSQL-only columns work regardless of which adapterDBselects.- All three databases must be running, regardless of
DB. The dummy app overridesdb:test:load_schemaanddb:test:purgeinspec/dummy/lib/tasks/database.raketo loop overpostgresql,mysqlandsqlite; the purge task also touches every configured connection.DB=sqlitetherefore does not avoid needing Postgres and MySQL. CI supplies Postgres and MySQL services for this reason. - Coverage:
simplecovenforcesSimpleCov.minimum_coverage 100inspec/rails_helper.rb. Adding untested code fails the suite. SetDEEP=1to switch todeep-coverinstead. - CI (
.github/workflows/pr-build.yml) runs RuboCop only, and only on changed files. It does not run the test suite. A green CI does not mean the specs pass — run them yourself.
Conventions
- Every Ruby file starts with
# frozen_string_literal: true. - RuboCop config is inherited from the local
wallaby-copgem (gitlab-styles+rubocop-rails+rubocop-rspec,Layout/LineLengthmax 120). Spec files are excluded from several cops — see.rubocop.yml. - Follow Keep a Changelog + SemVer. Each gem has its own
CHANGELOG.mdwith an## [Unreleased]section; add entries there. - Test support lives in
spec/support/(helpers, metadata, shared examples, custom spec types), auto-required byrails_helper.rb.
Gotchas
- Docs live in this repo. The documentation site (just-the-docs/Jekyll) is built from the root
_config.ymland the markdown underdocs/. Thedocs/*.mdlinks inwallaby/README.mdpoint at these local files. When adding or updating documentation, edit the markdown indocs/and add Jekyll build artifacts (.jekyll-cache/,_site/) to.gitignore, not the repo. wallaby-cop’s version constant is inlib/wallaby-cop.rb(Wallaby::Cop::VERSION), not aversion.rb.wallabyhas a separate JS/asset build (package.json,yarn.lock);node_modules/is gitignored.- RuboCop command in CI uses
--force-exclusionagainstgit diffoutput. csvmust stay declared. It is not a default gem since Ruby 3.4, butwallaby-coreandwallabyrequire 'csv'at runtime, so each gemspec declares it. Do not remove those dependencies.- Building Ruby 4.0.7 locally on macOS needs
MACOSX_DEPLOYMENT_TARGETset to the Homebrew libraries’ target (e.g.26.0); the default in some shell setups is lower, andldwarnings then make Ruby’s configure probes report false negatives.
Skills
.opencode/skills/run-wallaby-specs— running/debugging the suite..opencode/skills/release-wallaby-gems— version bumps and releases.