|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Ruby SDK for the [CloudEvents](https://cloudevents.io/) specification (CNCF). Gem name: `cloud_events`. Supports CloudEvents spec versions 0.3 and 1.0. Zero runtime dependencies; Ruby 2.7+. |
| 8 | + |
| 9 | +## Development Commands |
| 10 | + |
| 11 | +This project uses [Toys](https://github.com/dazuma/toys) as the task runner (not Rake). |
| 12 | + |
| 13 | +```bash |
| 14 | +bundle install # Install dependencies |
| 15 | +gem install toys # Install task runner (required) |
| 16 | + |
| 17 | +toys test # Run minitest unit tests |
| 18 | +toys cucumber # Run Cucumber conformance tests |
| 19 | +toys rubocop # Run linter |
| 20 | +toys yardoc # Generate YARD documentation |
| 21 | +toys build # Build .gem file into pkg/ |
| 22 | +toys install # Build and install gem locally |
| 23 | +toys ci # Run full CI suite (test + cucumber + rubocop + yard + build) |
| 24 | +toys ci --only --test # Run only minitest |
| 25 | +toys ci --only --cucumber # Run only Cucumber tests |
| 26 | +toys ci --only --rubocop # Run only linter |
| 27 | +``` |
| 28 | + |
| 29 | +To focus a single test, add `focus` before a test method (requires `minitest-focus` gem from the bundle). |
| 30 | + |
| 31 | +## Code Style |
| 32 | + |
| 33 | +Enforced by Rubocop (`.rubocop.yml`): |
| 34 | +- Double-quoted strings |
| 35 | +- Trailing commas in multiline arrays/hashes |
| 36 | +- 120 character line limit |
| 37 | +- `[:symbol]` array style (not `%i`) |
| 38 | +- `["word"]` array style (not `%w`) |
| 39 | +- All source files require `# frozen_string_literal: true` |
| 40 | + |
| 41 | +## Architecture |
| 42 | + |
| 43 | +### Event Model |
| 44 | + |
| 45 | +`CloudEvents::Event` is both a module (included by all event classes) and a factory via `Event.create(spec_version:, **attrs)`. |
| 46 | + |
| 47 | +- **`Event::V1`** — CloudEvents 1.0 (primary). Immutable (frozen), Ractor-shareable on Ruby 3+. |
| 48 | +- **`Event::V0`** — CloudEvents 0.3 (legacy). |
| 49 | +- **`Event::Opaque`** — Wrapper for events that couldn't be fully decoded. |
| 50 | + |
| 51 | +V1 has a dual data model: `data` holds the decoded Ruby object, `data_encoded` holds the serialized string/bytes. Formatters use `data_encoded` if present, otherwise encode `data`. |
| 52 | + |
| 53 | +### HTTP Binding (`HttpBinding`) |
| 54 | + |
| 55 | +Handles encoding/decoding CloudEvents to/from HTTP (Rack env hashes). Supports: |
| 56 | +- **Binary content mode** — event attributes as `CE-*` headers, data in body |
| 57 | +- **Structured content mode** — entire event serialized in body (e.g., JSON) |
| 58 | +- **Batch mode** — array of events in body |
| 59 | + |
| 60 | +`HttpBinding.default` returns a singleton with `JsonFormat` and `TextFormat` pre-registered. Custom formatters are registered via `register_formatter`. |
| 61 | + |
| 62 | +### Format Layer |
| 63 | + |
| 64 | +- **`JsonFormat`** — Encodes/decodes `application/cloudevents+json` and batch format. Also handles JSON data encoding/decoding for binary mode. |
| 65 | +- **`TextFormat`** — Handles `text/*` data. |
| 66 | +- **`Format::Multi`** — Composite that tries multiple formatters in registration order. |
| 67 | + |
| 68 | +Formatters implement up to four methods: `decode_event`, `encode_event`, `decode_data`, `encode_data`. Return `nil` to decline handling (next formatter is tried). |
| 69 | + |
| 70 | +### Content-Type Parser (`ContentType`) |
| 71 | + |
| 72 | +RFC 2045 compliant parser. Handles charset defaults: `text/plain` defaults to `us-ascii`, other `text/*` and JSON types default to `utf-8`. |
| 73 | + |
| 74 | +### Error Hierarchy |
| 75 | + |
| 76 | +All errors inherit from `CloudEventsError`: `NotCloudEventError`, `UnsupportedFormatError`, `FormatSyntaxError`, `SpecVersionError`, `AttributeError`. |
| 77 | + |
| 78 | +## Contributing |
| 79 | + |
| 80 | +- Conventional Commits format required (`fix:`, `feat:`, `docs:`, etc.) |
| 81 | +- Commits must be signed off (`git commit --signoff`) |
| 82 | +- Run `toys ci` before submitting PRs |
0 commit comments