ice-cube-ruby/ice_cube
Ruby Date Recurrence Library - Allows easy creation of recurrence rules and fast querying
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 4mo ago
- ✓20 active contributors
- ✓Distributed ownership (top contributor 28% of recent commits)
Show 4 more →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
- ⚠Slowing — last commit 4mo ago
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/ice-cube-ruby/ice_cube)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/ice-cube-ruby/ice_cube on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: ice-cube-ruby/ice_cube
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/ice-cube-ruby/ice_cube shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 4mo ago
- 20 active contributors
- Distributed ownership (top contributor 28% of recent commits)
- MIT licensed
- CI configured
- Tests present
- ⚠ Slowing — last commit 4mo ago
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live ice-cube-ruby/ice_cube
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/ice-cube-ruby/ice_cube.
What it runs against: a local clone of ice-cube-ruby/ice_cube — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in ice-cube-ruby/ice_cube | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 140 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of ice-cube-ruby/ice_cube. If you don't
# have one yet, run these first:
#
# git clone https://github.com/ice-cube-ruby/ice_cube.git
# cd ice_cube
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of ice-cube-ruby/ice_cube and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "ice-cube-ruby/ice_cube(\\.git)?\\b" \\
&& ok "origin remote is ice-cube-ruby/ice_cube" \\
|| miss "origin remote is not ice-cube-ruby/ice_cube (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 140 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~110d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/ice-cube-ruby/ice_cube"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
ice_cube is a Ruby library for defining and querying recurring event schedules using an iCalendar-inspired API. It allows developers to specify complex recurrence rules (daily, weekly, monthly, yearly with multiple constraints), exception dates, and manually added occurrences, then efficiently query whether a schedule occurs on specific dates/times or generate lists of future occurrences. Single gem structure: lib/ice_cube/ contains core rule engine (rules/ subdirectory with DailyRule, WeeklyRule, etc.), parsers for multiple formats (hash, iCal, YAML in parsers/), builders for serialization (hash, iCal, string in builders/), and the main Schedule orchestrator. Rule and Occurrence classes abstract recurrence logic. Localization via i18n wrappers (i18n.rb, null_i18n.rb) with per-language YAML config.
👥Who it's for
Ruby developers building calendar, scheduling, or event management applications who need to handle repeating events (e.g., 'every Friday the 13th in October', 'daily except Tuesdays'). Typically used in web frameworks like Rails for appointment scheduling, recurring billing, or calendar sync features.
🌱Maturity & risk
Production-ready and actively maintained. The repo shows a clean CI/CD setup (GitHub Actions in .github/workflows/tests.yaml), comprehensive test coverage (inferred from .rspec config), multi-language locale support (11 languages in config/locales/), and a published gem on RubyGems. Recent commits and an UPGRADING.md file suggest ongoing development and careful API evolution.
Low risk for well-established use cases. The codebase appears single-maintainer (seejohnrun as author), but the gem has broad adoption in the Ruby community. No exotic dependencies visible—uses only core Ruby + optional ActiveSupport. Main risk is: timezone handling edge cases (common in recurrence libraries) and performance on very large date ranges or complex rule combinations (no visible caching layer in file structure).
Active areas of work
No PR or issue data provided in the repository snapshot, but the presence of .standard_todo.yml and CHANGELOG.md suggests active linting/style enforcement and documented version history. The UPGRADING.md file indicates recent API changes worth reviewing.
🚀Get running
Clone and install:
git clone https://github.com/seejohnrun/ice_cube.git
cd ice_cube
bundle install
bundle exec rspec
Daily commands: No dev server—this is a library. Run tests:
bundle exec rspec
Use in a script:
require 'ice_cube'
schedule = IceCube::Schedule.new(Time.now) do |s|
s.add_recurrence_rule(IceCube::Rule.daily.count(5))
end
puts schedule.occurrences(Time.now + 30.days)
🗺️Map of the codebase
- lib/ice_cube/schedule.rb: Main API entry point—orchestrates rules, exceptions, additions, and exposes occurrences, occurs_at?, occurs_on? methods
- lib/ice_cube/rule.rb: Base recurrence rule class with fluent builder methods; all recurrence logic depends on this abstraction
- lib/ice_cube/rules/: Frequency-specific rule implementations (daily, weekly, monthly, yearly, hourly, minutely, secondly) that handle constraint combinations
- lib/ice_cube/builders/ical_builder.rb: Serializes Schedule to iCalendar RRULE format; critical for interop with calendar apps
- lib/ice_cube/parsers/ical_parser.rb: Deserializes iCalendar RRULE strings back into Schedule objects; inverse of ical_builder
- lib/ice_cube/time_util.rb: Utility functions for date/time arithmetic and constraint evaluation across rules
- lib/ice_cube/occurrence.rb: Wraps a single occurrence time with metadata; returned by occurrences/first/next_occurrence methods
- config/locales/en.yml: English locale strings for rule descriptions; pattern replicated across 11 languages for i18n support
🛠️How to make changes
For common changes: (1) New recurrence frequency? Add lib/ice_cube/rules/your_rule.rb extending Rule, register in lib/ice_cube.rb. (2) New serialization format? Create lib/ice_cube/parsers/your_parser.rb and lib/ice_cube/builders/your_builder.rb following hash_parser.rb/hash_builder.rb patterns. (3) Locale strings? Edit config/locales/en.yml and other language files. (4) Core recurrence logic? Modify lib/ice_cube/rule.rb or lib/ice_cube/schedule.rb. (5) Add tests to spec/ (not visible in file list but RSpec config present).
🪤Traps & gotchas
Timezone handling: ice_cube respects the Time object's timezone, but DST transitions can cause subtle bugs—test with ActiveSupport::TimeZone if using Rails. RRULE compliance: iCal spec is complex; edge cases like BYDAY with BYMONTH or BYWEEKNO may not match all RFC 5545 implementations. Performance cliff: querying occurrences far in the future on non-terminating rules (no until/count) will hang or error—always provide an end_time or ensure rules have count/until. Leap seconds and Feb 29 behavior vary by rule type. Locale lookups silently fall back to English if i18n not initialized—no loud error.
💡Concepts to learn
- iCalendar RRULE (RFC 5545) — ice_cube's entire API and serialization model is based on iCalendar recurrence rules; understanding RRULE syntax (FREQ, BYDAY, BYMONTH, COUNT, UNTIL) is essential to use and extend the library correctly
- Fluent Builder Pattern — ice_cube uses fluent method chaining (Rule.weekly.day(:friday).count(10)) extensively; understanding this pattern helps modify and extend rule configuration APIs
- Recurrence Rule Precedence & Set Operations — Multiple rules in a schedule are combined via union; exception_times and recurrence_times override rules via set subtraction/addition—understanding the precedence model prevents logical errors in complex schedules
- Lazy Evaluation & Generator Patterns — ice_cube likely uses lazy evaluation to avoid computing all occurrences upfront; understanding when occurrences are materialized vs. generated on-demand is critical for performance on unbounded schedules
- I18n Locale Fallback & String Interpolation — The i18n.rb and null_i18n.rb provide rule descriptions in 11 languages via YAML config; understanding the fallback chain (requested locale → English) and key interpolation prevents silent translation failures
- Polymorphic Serialization (Hash, iCal, YAML) — ice_cube supports round-trip serialization across three formats (hash_parser/builder, ical_parser/builder, yaml_parser); understanding the schema design and format differences is essential for persistence and API design
- Constraint Satisfaction & Combinatorial Expansion — Rules combine multiple constraints (day_of_week, day_of_month, month_of_year) using AND logic; ice_cube must efficiently expand/filter dates matching all constraints—understanding the algorithm prevents performance regressions
🔗Related repos
ruby-icalendar/icalendar— Complementary gem for building full iCalendar (.ics) files; ice_cube focuses on recurrence rules, icalendar handles component structure and VCALENDAR wrappersjmettraux/rufus-scheduler— Job scheduling library for executing recurring tasks in Ruby; often paired with ice_cube to schedule jobs based on recurrence rulesmojombo/chronic— Natural language date parsing for Ruby; complementary to ice_cube for user-friendly input ('every Tuesday') before converting to recurrence rulesrails/rails— The dominant Rails ecosystem where ice_cube schedules are persisted in ActiveRecord models and integrated with ActionMailer for recurring notificationsdateutil/dateutil— Python equivalent with similar iCal-based RRULE parser; useful for cross-language scheduling systems or understanding recurrence algorithm design
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive test coverage for ice_cube/parsers directory
The repo has three parser implementations (hash_parser.rb, ical_parser.rb, yaml_parser.rb) but there's no visible spec directory structure in the file listing. These parsers are critical for converting between formats and deserializing schedules. Adding dedicated test files would ensure edge cases in parsing (malformed input, missing fields, timezone handling) are properly covered.
- [ ] Create spec/ice_cube/parsers/hash_parser_spec.rb with tests for various hash formats and edge cases
- [ ] Create spec/ice_cube/parsers/ical_parser_spec.rb with RFC 5545 compliance tests
- [ ] Create spec/ice_cube/parsers/yaml_parser_spec.rb with YAML serialization round-trip tests
- [ ] Add tests for error handling when required fields are missing from each format
- [ ] Run tests with
rspecand ensure they pass
Add missing validation rule tests in lib/ice_cube/validations
The validations directory contains 20+ specialized validation classes (by_set_pos_helper, daily_by_set_pos, hourly_by_set_pos, minutely_by_set_pos, month_of_year, etc.) but there's no evidence of corresponding spec files for each. These are core business logic for recurrence rules and need thorough test coverage for correctness across edge cases (leap years, DST transitions, boundary conditions).
- [ ] Create spec/ice_cube/validations/monthly_by_set_pos_spec.rb with tests for last-day-of-month, last-Friday scenarios
- [ ] Create spec/ice_cube/validations/day_of_week_spec.rb testing all weekday combinations and intervals
- [ ] Create spec/ice_cube/validations/month_of_year_spec.rb with multi-month selection tests
- [ ] Add DST transition tests in spec/ice_cube/validations/hourly_interval_spec.rb
- [ ] Ensure each validation file has tests for valid/invalid input states
Add GitHub Actions workflow for testing against multiple Ruby versions
The repo has .github/workflows/tests.yaml but it likely tests against a single Ruby version. ice_cube needs to maintain backward compatibility across Ruby 2.7, 3.0, 3.1, 3.2, and 3.3 (based on typical gem maintenance). The workflow should also test against different timezone databases and ActiveSupport versions since ice_cube integrates with Rails.
- [ ] Update .github/workflows/tests.yaml to use a matrix strategy testing Ruby versions: 2.7, 3.0, 3.1, 3.2, 3.3
- [ ] Add separate matrix jobs for different timezone handling (system tz vs TZInfo gem)
- [ ] Add optional test job for ActiveSupport integration with versions 6.0, 6.1, 7.0
- [ ] Ensure Gemfile and ice_cube.gemspec clearly document minimum Ruby version requirements
- [ ] Verify all tests pass on all matrix combinations before merge
🌿Good first issues
- Add comprehensive timezone test suite under spec/ (if not already present) covering DST transitions with ActiveSupport::TimeZone, since time_util.rb lacks explicit tz tests visible in file structure.
- Document the precedence of recurrence_rules vs. recurrence_times vs. exception_times with worked examples in README.md (currently only mentioned in passing)—add a dedicated 'Rule Precedence' section with code snippets.
- Extend the ical_parser.rb to handle TZID parameters in DTSTART (e.g., DTSTART;TZID=America/New_York:...) which is valid iCal but currently may not round-trip correctly.
⭐Top contributors
Click to expand
Top contributors
- @avit — 28 commits
- @seejohnrun — 26 commits
- @pacso — 22 commits
- @jakebrady5 — 3 commits
- @kogre — 3 commits
📝Recent commits
Click to expand
Recent commits
32ff145— Add backwards compatibility to Ruby 2.6 (#562) (scpike)ce99543— Update to BYSETPOS support (#449) (nehresma)83144a5— Update supported Rails and Ruby versions (#565) (nehresma)ee21ea6— Release 0.17.0 (#558) (pacso)f693b39— Fix documentation links in README.md (#527) (dalpo)62ee3fd— Add missing expects to specs (#530) (artofhuman)6b999d7— Day-of-week validation input checking (#554) (pacso)5eb51e3— Add basic dev container setup (#557) (pacso)ab36aba— Fix I18n.load_path injection (#546) (glaszig)621cef4— Update documentation links in gemspec (#553) (pacso)
🔒Security observations
The ice_cube library is a date recurrence utility with a relatively small attack surface. No critical vulnerabilities were identified from the static file structure analysis. The codebase follows good practices with proper code organization and testing infrastructure. Primary concerns are: (1) dependency management should be regularly audited, (2) parser implementations should validate inputs strictly, (3) YAML parsing must use safe loading methods. The library's focused scope (date recurrence) limits exposure to common web vulnerabilities like SQLi and XSS, though developers using this library should ensure proper input validation at application boundaries.
- Low · Dependency Management Configuration —
Gemfile, ice_cube.gemspec. The Gemfile and gemspec files are present but their contents were not provided for analysis. Unable to verify if dependencies have known CVEs or if versions are pinned appropriately. The gem.lock file (if it exists) should be checked for vulnerability scanning. Fix: Regularly run 'bundle audit' to check for known vulnerabilities in dependencies. Consider using automated tools like Dependabot to monitor and update dependencies. Pin dependency versions to prevent unexpected breaking changes. - Low · Internationalization (i18n) Input Handling —
lib/ice_cube/i18n.rb, config/locales/. The codebase contains i18n support with multiple locale files (en.yml, de.yml, etc.). While ice_cube is primarily a date recurrence library, i18n data could potentially be a vector if user input is directly interpolated into i18n strings without proper sanitization. Fix: Ensure that any user-provided data used in i18n context is properly sanitized. Avoid direct string interpolation with user input in translated strings. Use parameterized translation strings where applicable. - Low · Parser Input Validation —
lib/ice_cube/parsers/. Multiple parser implementations exist (hash_parser, ical_parser, yaml_parser). Without inspecting the actual parser code, there's potential risk if these parsers don't properly validate or sanitize incoming data before processing. Fix: Implement strict input validation in all parser classes. Validate data types, ranges, and formats before processing. Consider using schema validation libraries for structured inputs (YAML, JSON, iCal). - Low · YAML Deserialization —
lib/ice_cube/parsers/yaml_parser.rb, spec/data/issue40.yml. The presence of yaml_parser.rb and .yml files suggests YAML deserialization is used. Unsafe YAML deserialization can lead to arbitrary code execution if untrusted input is processed. Fix: Use safe YAML loading methods (YAML.safe_load) instead of YAML.load. Never deserialize YAML from untrusted sources. Specify allowed classes when using safe_load if needed.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.