javan/whenever
66.4
Adequate · 26 September 2026
805
lines of production code
Ruby
primary language
4
measurements over time
What this system is
This system is a Ruby gem that generates and manages crontab entries for scheduled tasks. It provides a command-line interface to define job sequences, handle output redirection, and integrate with deployment tools like Capistrano v2 and v3. The library focuses on converting time definitions and task commands into valid cron syntax for server automation.
How it got here
2009 — Modernization and CLI refactoring
8 changes.
The project underwent a significant structural overhaul, migrating build tooling to Bundler, replacing the test suite with Minitest, and reorganizing the library into a modular namespace. Concurrently, the command-line interface was refactored to replace legacy Rake integration with granular options, while supporting newer Capistrano versions and introducing job sequencing features.
2010–2017 — Capistrano v3 integration and test expansion
5 changes.
This period focused on adding native support for Capistrano v3 while restructuring the existing v2 integration to handle deployment hooks and environment defaults more explicitly. Comprehensive functional and unit tests were added to verify command-line behavior, cron parsing, and job output generation across various scenarios. The project also expanded its dependency matrix to ensure compatibility with a wide range of Rails versions from 5.x through 8.1.
Features
Capistrano v3 integration for Whenever crontab management
Adds Capistrano v3 support for managing application crontabs via the Whenever gem. The new \whenever.rake\ task file defines \update\_crontab\ and \clear\_crontab\ tasks that run on specified roles (defaulting to \:db\) within the release path. It introduces configurable options for the Whenever command path, environment variables (including \RAILS\_ENV\ derived from Capistrano stage or Rails env), and custom load files, ensuring compatibility with Capistrano v3's SSHKit execution model.
lib/whenever/capistrano/v3 · high confidence
Removals
Removal of default and runner job types
The \lib/job\_types/default.rb\ and \lib/job\_types/runner.rb\ files have been deleted, removing the built-in support for the \Default\ and \Runner\ job types. This eliminates the ability to execute tasks via the Rails script runner with environment-specific path resolution, a capability that was previously handled by these classes.
_lib/job\types · high confidence
Removal of legacy Cron output class
The \lib/outputs/cron.rb\ file containing the \Whenever::Output::Cron\ class has been deleted. This removes the specific implementation responsible for converting job times and tasks into cron syntax strings, including the logic for parsing symbols, strings, and time intervals into cron fields. Users relying on this specific output class for cron generation will need to use the replacement output mechanism introduced in the same change set.
lib/outputs · high confidence
Behavioural changes
Capistrano v2 integration reorganized with new default environment handling
The Capistrano v2 integration has been restructured into separate hooks, recipes, and support modules. The deployment hooks now explicitly trigger crontab updates before finalize\_update and after rollback. The recipes define default configuration values, notably defaulting the \whenever\_environment\ to the \:stage\ Capistrano variable (falling back to "production"), and allow customizing the command path via \:whenever\_path\. The support module provides helper methods to determine target servers and roles, and handles rollback logic by pointing to the previous release's path.
lib/whenever/capistrano/v2 · high confidence
Refactor CLI interface and enhance wheneverize script
The \bin/whenever\ command-line tool has been refactored to replace the previous Rake-based execution with a new \CommandLine\ interface, introducing granular options for managing crontab schedules (such as \-i\ for updating, \-w\ for overwriting, and \-c\ for clearing), setting runtime variables (\--set\), specifying server roles (\--roles\), and customizing the crontab command. Additionally, the \bin/wheneverize\ script now automatically creates the \config/\ directory if it does not exist when generating the schedule file, and its generated template has been updated to include examples for output redirection and rake tasks.
bin · high confidence
Refactored library structure and removed legacy Rake integration
The library has been reorganized into a modular structure under the \whenever/\ namespace, replacing the previous monolithic \lib/base.rb\ and \lib/job\_list.rb\ with distinct files for jobs, sequences, and command-line execution. Legacy Rake tasks (\lib/tasks/whenever.rake\) have been removed in favor of direct command-line usage, and the gem no longer relies on \activesupport\ or \chronic\ at the top level, instead loading specific extensions like \whenever/numeric\ and \whenever/numeric\_seconds\ to support time definitions without external dependencies.
lib · high confidence
Whenever 1.1.3 release with Capistrano 3 support and job sequencing
This release updates the gem to version 1.1.3 and introduces support for Capistrano 3 by dynamically loading the appropriate integration tasks based on the installed Capistrano version. It adds the ability to define sequential jobs that run in a specific order, with an option to halt the sequence if a job fails. The release also includes improved handling of output redirection, allowing users to specify separate paths for standard output and error streams, and enhances the command-line interface with a new \--cut\ option to prune lines from the crontab.
lib/whenever · high confidence
Test coverage
Added functional tests for command-line operations and job output generation; Added unit tests for Capistrano integration, cron parsing, executable, and job handling; Migrate test suite from Test::Unit to Minitest.
Dependencies
Expanded Appraisal configurations for Rails 5.x through 8.1
The gemfiles directory now includes dedicated Appraisal configurations for ActiveSupport versions 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 7.2, 8.0, and 8.1. This allows the library to be tested against a broader range of Rails versions. Notably, the configurations for Rails 6.0 and 6.1 explicitly pin \concurrent-ruby\ to version 1.3.4 and include additional dependencies such as \base64\, \bigdecimal\, \mutex\_m\, \benchmark\, and \logger\ to ensure compatibility with those specific ActiveSupport versions.
gemfiles · high confidence
Migrate build tooling to Bundler and add multi-version ActiveSupport testing
The project has replaced the Jeweler gem with a self-managed gemspec and Bundler helpers, standardizing development commands via a new Makefile. To ensure compatibility across the Ruby ecosystem, Appraisals have been added to test against ActiveSupport versions 5.0 through 8.1, with specific dependency fixes (such as concurrent-ruby) for newer Rails and Ruby versions. Additionally, legacy RDoc documentation has been removed in favor of Markdown, and the Rakefile now uses standard Bundler test tasks.
(repo-wide) · high confidence
Migrate development dependencies to Gemfile and update gemspec metadata
Development dependencies (rake, mocha, minitest, appraisal) are now managed in the Gemfile rather than the gemspec, while the gemspec itself has been updated to include metadata fields (homepage, source code, changelog, and MFA requirements) and enforces a minimum Ruby version of 1.9.3.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 50 → 66 (+16.9)
- Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 98 → 98 (-0.6)
- Architecture 69 → 69 (+0.0)
- Maturity 61 → 55 (-5.2)
- Readiness 30 → 74 (+43.9)
- Security 68 → 93 (+25.3)
Resolved (10)
- Coverage not measured — test suite did not build
- Dimension evaluation failed
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- No exposed public API
- No tests found
- Test reliability not included
New (13)
- Ambiguous method signature for seconds. Whenever.seconds takes two arguments (number, units), while NumericSeconds.seconds is overloaded: it takes no arguments (presumably returning the stored number) or potentially one argument depending on implementation context, but the signature seconds(number, units) on the instance seems redundant or confusingly similar to the class method. More critically, NumericSeconds exposes seconds(), minutes(), hours(), etc., which are distinct operations, but the class method Whenever.seconds(number, units) duplicates the intent of creating a time interval object, likely returning a NumericSeconds instance. This creates a dual entry point for the same concept: Whenever.seconds(5, :minutes) vs 5.minutes (if NumericSeconds is extended onto Integer) or NumericSeconds.new(5).minutes. The inconsistency lies in the API surface: one is a factory method with explicit units, the other is an instance method chain. While distinct, the naming Whenever.seconds vs NumericSeconds.seconds is confusing.
- Cron.parse_time (cognitive 41) (lib/whenever/cron.rb)
- Cron.parse_time (cyclomatic 23) (lib/whenever/cron.rb)
- Documentation: no architecture or design documentation (README.md)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- Medium: security finding (details withheld)
- Medium: security finding (details withheld)
- Medium: security finding (details withheld)
- Off-boarding risk: anonymized user #1
- Orphaned files with no living knowledge
Changes since last survey
- 4 commits — 4 feature/other, 0 fixes
By area
- lib/whenever — 2 commits
- (repo) — 1 commit
- (root) — 1 commit
Notable commits
- change: Add support for sequential job definitions
- change: Allow sequential jobs to continue by default
- change: Bump to v1.1.3
- change: Merge pull request #854 from combinaut/add-support-for-sequential-job-definitions
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
javan/whenever was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 26 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit c9fd8c38d3a6ad2a69f3ed97a6a0d8ce7d785388 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-d0929f7ac71f.