CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
WikidataAdaptor is a Ruby gem that wraps the Wikibase REST API. It extends ApiAdaptor::Base and uses a modular mixin pattern — each API resource (Items, Labels, Statements, etc.) is a separate module included into WikidataAdaptor::RestApi. Corresponding test helper modules in lib/wikidata_adaptor/test_helpers/ provide WebMock stubs for consumers of the gem.
Commands
# Run all checks (specs + rubocop)
bundle exec rake
# Unit tests only (integration tests excluded by default)
bundle exec rspec
# Single test file
bundle exec rspec spec/wikidata_adaptor/rest_api/items_spec.rb
# Single test by line
bundle exec rspec spec/wikidata_adaptor/rest_api/items_spec.rb:42
# Lint
bundle exec rubocop
# Integration tests (requires running Wikibase instance)
./script/integration-up # start Docker Compose stack
./script/integration-test # run integration specs
./script/integration-down # tear down
Architecture
lib/wikidata_adaptor/rest_api.rb— Main client class, inheritsApiAdaptor::Base, includes all resource moduleslib/wikidata_adaptor/rest_api/— One module per API resource (items, labels, descriptions, aliases, statements, sitelinks, properties, search_item, search_property, property_data_types, open_api_document)lib/wikidata_adaptor/test_helpers/— Mirrorsrest_api/structure, providingstub_*methods for WebMock-based testingspec/wikidata_adaptor/rest_api/— Unit tests using WebMock stubsspec/integration/— Integration tests against a real Wikibase instance via Docker Compose
Testing Conventions
- Unit tests use
include WikidataAdaptor::TestHelpers::RestApifor stubbing - Integration tests use
include WikidataAdaptor::Integration::Helpersand are tagged:integration - Integration tests use
before(:context)with instance variables (notlet) to seed data once per group - Integration tests are excluded by default; enabled with
INTEGRATION=1
Environment Variables
WIKIBASE_REST_ENDPOINT— API base URL (default:https://www.wikidata.org/w/rest.php/wikibase)WIKIBASE_BEARER_TOKEN— Optional OAuth token for write operationsINTEGRATION— Set to1to include integration tests
Git Standards
Never commit to main branch, Always create a new branch with a sensible descriptive name and expect a Pull Request process.
You'll need to provide a good PR description that sums up any collected change.
Commit Standards
Follows GDS Git conventions, informed by chris.beams.io/posts/git-commit, thoughtbot, mislav.net, and Joel Chippindale's "Telling Stories Through Your Commits".
Formatting
- Conventional Commits — subject line format:
<type>[optional scope]: <description> - Types:
feat,fix,docs,style,refactor,perf,test,build,ci,chore - Scope — optional parenthetical context, e.g.
feat(labels):orfix(integration): - Breaking changes — indicated with
!before the colon, e.g.feat!:, or aBREAKING CHANGE:footer - Subject line — max 50 characters, no trailing period, imperative mood ("Add feature" not "Added feature")
- Body — separated from subject by a blank line, wrapped at 72 characters
- Links supplement, not replace — issue/PR links may go stale, so the message must stand on its own
Content
- Answer three questions: Why is this change necessary? How does it address the issue? What side effects does it have?
- Explain the "why" — the code shows how; the commit message must capture why. Rationale and context are hard to reconstruct later
- Note alternatives considered — if you chose approach A over B, say so and why
Structure
- Atomic commits — each commit is a self-contained, logical unit of work; avoid needing "and" in your subject line
- Tell a story — commits should be logically ordered so the history reads as a coherent narrative, not a jumbled log
- Clean up before sharing — revise commit history on feature branches before opening a PR
Development Workflow (TDD)
When adding new API endpoints, follow this test-driven approach. You are expected to pause and commit between each step, once we are ready for PR you may soft reset and re-commit if the audit history does not properly represent the above rules.
A good flow might look like:
- Write unit tests (red) — Add
describeblocks to the relevant spec file callingstub_*and API methods that don't exist yet. Verifybundle exec rubocoppasses andbundle exec rspecfails. Then commit and push. - Add test helpers + implementation (green) — Add
stub_*helpers and implement the API methods. Verifybundle exec rakepasses (rspec + rubocop). Then commit and push. - Add integration tests — Add tests to
spec/integration/that exercise the real API. Then commit and push. - Update TODO — Move endpoints from "Uncovered" to "Covered" in
TODO.mdand update counts. Then commit and push.
Style
- Double quotes for strings
- Ruby >= 3.2
Release Process
WikidataAdaptor uses automated publishing to RubyGems via GitHub Actions with OIDC trusted publishing.
Prerequisites (One-time Setup)
- Configure RubyGems Trusted Publishing:
- Go to RubyGems.org → Account Settings → Publishing
- Add trusted publisher:
- Repository:
huwd/wikidata_adaptor - Workflow:
release.yml - Environment: (leave empty)
- Repository:
Release Checklist
Update version:
# Edit lib/wikidata_adaptor/version.rb VERSION = "1.0.0"Update CHANGELOG.md:
## [1.0.0] - YYYY-MM-DD
### Added
- New feature X
### Changed
- Updated Y
### Fixed
- Bug Z ```
Commit changes:
git add lib/wikidata_adaptor/version.rb CHANGELOG.md git commit -m "chore: Prepare v1.0.0 release" git push origin mainCreate and push tag:
git tag v1.0.0 git push origin v1.0.0GitHub Actions automatically:
- Validates tag format matches semantic versioning
- Verifies tag matches
WikidataAdaptor::VERSION - Confirms CHANGELOG mentions version
- Runs full test suite
- Runs RuboCop
- Builds YARD documentation
- Builds gem package
- Tests gem installation
- Publishes to RubyGems.org
Verify release:
- Check GitHub Actions
- Verify on RubyGems.org
- Test installation:
gem install wikidata_adaptor
Dry Run (Testing Without Publishing)
To test the release process without publishing:
- Go to Actions → Release RubyGem
- Click "Run workflow"
- Select branch:
main - Set dry_run:
true - Click "Run workflow"
This runs all checks and builds the gem but skips publishing to RubyGems.
Version Numbering
Follow Semantic Versioning:
- MAJOR (e.g.,
1.0.0→2.0.0): Incompatible API changes - MINOR (e.g.,
1.0.0→1.1.0): Backwards-compatible new features - PATCH (e.g.,
1.1.0→1.1.1, or1.0.0→1.0.1): Backwards-compatible bug fixes - Pre-release (e.g.,
1.1.0-beta.1): Alpha, beta, or release candidate - Note: During initial development (
0.y.z), breaking changes may be introduced in minor versions; treat0.y.zas unstable.
Troubleshooting
Tag mismatch error: Ensure lib/wikidata_adaptor/version.rb matches the git tag (without the v prefix).
CHANGELOG error: Add an entry for the version in CHANGELOG.md following the format:
## [1.0.0] - YYYY-MM-DD
Tests fail: Fix failing tests before releasing. The release will not proceed if tests fail.
RuboCop errors: Fix linting errors before releasing.