feat: add mix hammer.install Igniter task - #194
Merged
Conversation
Add an Igniter-based installer so `mix igniter.install hammer` (or `mix hammer.install` on an existing project) generates a `MyApp.RateLimit` module using `use Hammer, backend: ...` and adds it to the application's supervision tree. `--backend` (`-b`) accepts `ets` (default), `atomic` or `redis`; the `redis` option also adds the `hammer_backend_redis` dependency since that backend lives in a separate package. Unknown backends are reported as an Igniter issue and the run is idempotent. Igniter is declared as an optional dependency; without it the task prints instructions to install Igniter, following Igniter's own optional-dependency template. Refs: #157 Co-Authored-By: Emmanuel Pinault <dev@pinault-family.us> Claude-Session: https://claude.ai/code/session_01JckHuT8GcW8Gzsai7vcpvT
4 tasks
epinault
pushed a commit
that referenced
this pull request
Aug 29, 2026
Since #194 the repo ships a Mix task; without :mix in the PLT dialyzer reports Mix.Task callback info as missing. Dialyzer now passes clean. Co-Authored-By: Emmanuel Pinault <dev@pinault-family.us> Claude-Session: https://claude.ai/code/session_01JckHuT8GcW8Gzsai7vcpvT
5 tasks
epinault
added a commit
that referenced
this pull request
Sep 2, 2026
…196) erlex is a transitive dev/test-only dependency of dialyxir; 0.2.9 rewrites the type-grammar precedence and adds mix erlex.typecheck. Since #194 the repo ships a Mix task; without :mix in the PLT dialyzer reports Mix.Task callback info as missing. Dialyzer now passes clean. Verified: mix compile --warnings-as-errors, mix test (142 tests), mix dialyzer, mix deps.unlock --check-unused. Claude-Session: https://claude.ai/code/session_01JckHuT8GcW8Gzsai7vcpvT Co-authored-by: epinault <dev@pinault-family.us>
epinault
added a commit
that referenced
this pull request
Sep 2, 2026
- Bump version 7.4.1 -> 7.5.0 in mix.exs - Promote Unreleased changelog section to 7.5.0 (#194, #197, #198) Minor bump: the release adds the mix hammer.install Igniter task and carries two TokenBucket ETS fixes, one of which changes the deny wait from a flat 1000ms to the real time-to-next-token. Claude-Session: https://claude.ai/code/session_011dH6kRtZqUkVpoGo79CKYG Co-authored-by: epinault <dev@pinault-family.us>
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
mix igniter.install hammer(ormix hammer.installon a project that already has Hammer) generates aMyApp.RateLimitmodule and adds it to the application's supervision tree.--backend/-bacceptsets(default),atomicorredis. Because the Redis backend lives in the separatehammer_backend_redispackage,--backend redisalso adds that dependency and generatesuse Hammer, backend: Hammer.Rediswith aurl:child spec.mix hammer.installprints instructions to install Igniter (following Igniter's own optional-dependency template). No runtime impact for existing users.This is part 1 of #157 (installer). It deliberately does not attempt the "patch my controller functions" half of that issue: Hammer has no global/per-route config — limits are defined at each call site via
hit(key, scale, limit)— so a patcher can't know the key derivation, limits, or 429 handling a given app needs. The README addition points users at the Tutorial for that.Changes
lib/mix/tasks/hammer.install.ex- theMix.Tasks.Hammer.Installtask (+.Docsmodule, non-Igniter fallback)test/mix/tasks/hammer.install_test.exs-Igniter.Testcoverage: all three backends, dep added / not duplicated for redis, unknown backend reported as an issue, idempotent re-runmix.exs/mix.lock-{:igniter, "~> 0.8", optional: true}README.md- "Installing with Igniter" subsectionCHANGELOG.md- Unreleased entryGenerated output for
--backend etsin an app namedMyApp:Test Plan
mix test --warnings-as-errors --cover— 142 tests, 0 failures, 93.2% total coverage (task at 100%)mix credo --strict,mix format --check-formatted,mix deps.unlock --check-unusedmix new --supproject with{:hammer, path: ...}:mix hammer.installgenerates the module + child spec, andMyApp.RateLimit.hit/3returns{:allow, 1},{:allow, 2},{:deny, _}with limit 2mix hammer.install --backend redis: adds{:hammer_backend_redis, "~> 7.0"}, generated module compiles againsthammer_backend_redis 7.1.1Ticket
Refs: #157
🤖 Generated with Claude Code by Emmanuel Pinault
https://claude.ai/code/session_01JckHuT8GcW8Gzsai7vcpvT