Phase 1: Multi-platform support — Python implementation + compatibility test harness - #49
Merged
Merged
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the Gradle application plugin and Clikt 4.4.0 so the JVM implementation can be invoked as a subprocess via ./gradlew :esque-core:run --args="...". CLI accepts --es-url, --migrations-dir, --migration-key, --migration-user, --lock-timeout-minutes, and repeatable --property flags. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
17 test scenarios covering initialization, execution, idempotency, key independence, history metadata, user recording, template substitution, integrity verification, and numeric version ordering. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…f get_url ElasticSearchContainer in testcontainers-python 4.x has no get_url(). Construct the URL from get_container_host_ip() and get_exposed_port(9200). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- requires-python bumped to >=3.14 - ruff (0.11+) and ty (0.0.49) added as dev dependencies - ruff configured with E/W/F/I/N/UP/B/RUF rules, line-length 120 - subprocess.CompletedProcess[str], list[dict[str, Any]] type params added - Iterator[str] return type on es_url fixture - Guard added for impl.task None case in run() - Unused assert_index_absent import removed from test file - zip() given strict=True, bare f-string prefix removed - Import blocks sorted per isort Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ty has no --strict flag; warn-level rules are explicitly set to error in [tool.ty.rules] to match the strictness intent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- pyright 1.1.410 added as dev dependency with typeCheckingMode = "strict" - reportMissingTypeStubs disabled (testcontainers has no py.typed) - default_factory=list -> lambda: [] to resolve list[Unknown] in strict mode Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves esque-core/ to implementations/jvm/ and updates settings.gradle.kts to remap the :esque-core project directory. Removes esque-examples/ (not published, not needed for the multi-platform effort). Maven artifact ID org.loesak:esque-core is unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switches checksum serialization from YAML to compact JSON with alphabetically sorted keys and nulls omitted. Both produce identical MD5-first-4-bytes integers, but JSON canonical form is language-neutral and precisely replicable in any implementation without a YAML dependency. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ests Python implementation in implementations/python/ uses Click for CLI, httpx for ES REST calls, and PyYAML for migration file parsing. Implements the full Esque behavioral contract: initialization, file loading, template resolution, checksum (JSON canonical matching the JVM), distributed locking via ES op_type=create, integrity verification, and idempotent execution. All 34 compatibility tests pass (17 scenarios × 2 implementations). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ci.yml runs on every push and PR: build-jvm (ktfmtCheck + detekt + test), build-python (ruff + pyright), and compatibility-tests (34 scenarios via testcontainers, parametrized over both implementations). Jobs build-jvm and build-python run in parallel; compatibility-tests gates on both. release.yml runs only on published GitHub releases: publish-jvm to Maven Central (unchanged) and publish-python to PyPI via UV_PUBLISH_TOKEN. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Relocates gradlew, gradlew.bat, gradle/, gradle.properties, detekt.yml, and settings.gradle.kts from the repo root into implementations/jvm/. Merges the root build.gradle.kts (plugin declarations, group/version, kotlin toolchain, detekt config, repositories) into implementations/jvm/ build.gradle.kts so it stands as a self-contained single-project build. Updates .githooks/pre-commit, CI workflows, and the test harness implementations.yml/helpers.py to cd into implementations/jvm (or use gradle_dir) when invoking Gradle. All 34 compatibility tests still pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pre-commit now runs three stages in sequence: [1/3] JVM: ktfmtCheck + detekt + test [2/3] Python: ruff check + ruff format --check + pyright [3/3] Compatibility tests: pytest (34 scenarios × 2 implementations) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Python) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…, classifiers, URLs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
implementations/python/) mirroring the JVM structure: class-basedEsqueorchestrator,EsqueConfiguration,elasticsearch-pyclient, distributed locking, template resolution, and canonical checksumtests/) that runs all registered implementations via CLI against a shared Elasticsearch testcontainer and asserts behavioral equivalency across 35 scenariosimplementations/jvm/as a single-project Gradle build and replaces the monolithic CI with splitci.yml+release.ymlTest plan
uv run esque --helpworks fromimplementations/python/./gradlew run --args="--help"works fromimplementations/jvm/🤖 Generated with Claude Code