Track End-of-Life dates for your tech stack and stay ahead of deprecations.
Harbinger is a CLI tool that scans your Ruby, Rails, Python, Node.js, Rust, Go, PostgreSQL, MySQL, Redis, and MongoDB versions, and warns you about upcoming EOL (End-of-Life) dates. Never get caught off-guard by unsupported dependencies again.
- π Auto-detects versions from
.ruby-version,Gemfile,Gemfile.lock,.nvmrc,.python-version,pyproject.toml,package.json,rust-toolchain,Cargo.toml,go.mod,config/database.yml, anddocker-compose.yml - π Database detection for PostgreSQL, MySQL, Redis, and MongoDB
- π Multi-language support - Ruby, Python, Node.js, Rust, Go
- π Ecosystem-grouped dashboard - Projects organized by language ecosystem with relevant components only
- π Fetches EOL data from endoflife.date
- π¨ Color-coded warnings (red: already EOL, yellow: <6 months, green: safe)
- β‘ Smart caching (24-hour cache, works offline after first fetch)
- π Bulk operations with
--recursivescan andrescancommand - π€ Export to JSON/CSV for reporting and automation
- π Zero configuration - just run
harbinger scan
brew tap RichD/harbinger
brew install stackharbingergem install stackharbingerOr add to your Gemfile:
gem 'stackharbinger'The command is harbinger (shorter to type).
# Scan current directory
harbinger scan
# Scan specific project
harbinger scan --path ~/Projects/my-rails-app
# Save project for tracking
harbinger scan --save
# Scan all Ruby projects in a directory recursively
harbinger scan --path ~/Projects --recursive --saveExample output:
Scanning /Users/you/Projects/my-app...
Detected versions:
Ruby: 3.2.0
Rails: 7.0.8
PostgreSQL: 16.11
Fetching EOL data...
Ruby 3.2.0:
EOL Date: 2026-03-31
Status: 437 days remaining
Rails 7.0.8:
EOL Date: 2025-06-01
Status: ALREADY EOL (474 days ago)
PostgreSQL 16.11:
EOL Date: 2028-11-09
Status: 1026 days remaining
# Show dashboard of all tracked projects
harbinger show
# Filter to specific project(s) by name or path
harbinger show budget
harbinger show job
# Show project paths with verbose mode
harbinger show -v
harbinger show job --verbose# Export to JSON (stdout)
harbinger show --format json
# Export to CSV (stdout)
harbinger show --format csv
# Save to file
harbinger show --format json -o report.json
harbinger show --format csv --output eol-report.csv
# Export filtered projects
harbinger show myproject --format jsonExample output:
Tracked Projects (12)
Ruby Ecosystem (7)
================================================================================
βββββββββββββββββββ¬ββββββββ¬βββββββββββ¬βββββββββββββ¬ββββββββ¬ββββββββββββββββββ
β Project β Ruby β Rails β PostgreSQL β Redis β Status β
βββββββββββββββββββΌββββββββΌβββββββββββΌβββββββββββββΌββββββββΌββββββββββββββββββ€
β shop-api β 3.2.0 β 6.1.7 β 15.0 β - β β Rails EOL β
β blog-engine β 3.3.0 β 7.0.8 β 16.0 β 7.0 β β Rails EOL β
β analytics-app β 3.3.0 β 8.0.1 β 16.0 β - β β Current β
β admin-portal β 3.3.0 β 8.0.4 β 16.11 β 7.2 β β Current β
β billing-service β 3.4.1 β 8.1.0 β 17.0 β - β β Current β
βββββββββββββββββββ΄ββββββββ΄βββββββββββ΄βββββββββββββ΄ββββββββ΄ββββββββββββββββββ
Python Ecosystem (3)
================================================================================
ββββββββββββββββ¬βββββββββ¬βββββββββββββ¬ββββββββββββ
β Project β Python β PostgreSQL β Status β
ββββββββββββββββΌβββββββββΌβββββββββββββΌββββββββββββ€
β ml-pipeline β 3.11 β 16.0 β β Current β
β data-scraper β 3.12 β - β β Current β
β ai-worker β 3.13 β 15.0 β β Current β
ββββββββββββββββ΄βββββββββ΄βββββββββββββ΄ββββββββββββ
Node.js Ecosystem (2)
================================================================================
ββββββββββββββββ¬ββββββββββ¬βββββββββββββ¬ββββββββββββββββββββββββ
β Project β Node.js β PostgreSQL β Status β
ββββββββββββββββΌββββββββββΌβββββββββββββΌββββββββββββββββββββββββ€
β frontend-app β 18.0 β - β β Node.js ending soon β
β realtime-api β 22.0 β 16.0 β β Current β
ββββββββββββββββ΄ββββββββββ΄βββββββββββββ΄ββββββββββββββββββββββββ
Projects are grouped by their primary programming language ecosystem. Each ecosystem only displays relevant components (e.g., Python projects don't show Ruby/Rails columns).
# Update all tracked projects with latest versions
harbinger rescan
# Show detailed output for each project
harbinger rescan --verbose# Remove a project from tracking
harbinger remove my-project# Force refresh EOL data from endoflife.date
harbinger updateharbinger version-
Detection: Harbinger looks for version info in your project:
- Ruby:
.ruby-version,Gemfile(ruby "x.x.x"),Gemfile.lock(RUBY VERSION) - Rails:
Gemfile.lock(rails gem) - Python:
.python-version,pyproject.toml,docker-compose.yml, orpython --version - Node.js:
.nvmrc,.node-version,package.jsonengines,docker-compose.yml, ornode --version - Rust:
rust-toolchain,rust-toolchain.toml,Cargo.toml(rust-version),docker-compose.yml, orrustc --version - Go:
go.mod,go.work,.go-version,docker-compose.yml, orgo version - PostgreSQL:
config/database.yml(adapter check) +psql --versionorpggem - MySQL:
config/database.yml(mysql2/trilogy adapter) +mysql --versionor gem version - Redis:
docker-compose.yml+redis-server --versionorredisgem - MongoDB:
docker-compose.yml+mongod --versionormongoid/mongogem
- Ruby:
-
EOL Data: Fetches official EOL dates from endoflife.date API
-
Caching: Stores data in
~/.harbinger/data/for 24 hours (works offline) -
Analysis: Compares your versions against EOL dates and color-codes the urgency
.ruby-versionfile (highest priority)ruby "x.x.x"declaration in GemfileRUBY VERSIONsection in Gemfile.lock
If Harbinger detects a Ruby project but no version:
Ruby: Present (version not specified - add .ruby-version or ruby declaration in Gemfile)
Parses Gemfile.lock for the rails gem version.
- Checks
config/database.ymlforadapter: postgresql - Tries
psql --versionfor local databases (skips for remote hosts) - Falls back to
pggem version fromGemfile.lock
Note: For remote databases (AWS RDS, etc.), shows gem version since shell command would give local client version, not server version.
- Checks
config/database.ymlforadapter: mysql2oradapter: trilogy - Tries
mysql --versionormysqld --versionfor local databases - Falls back to
mysql2ortrilogygem version fromGemfile.lock
Supported adapters: mysql2 (traditional) and trilogy (Rails 7.1+)
- Checks
docker-compose.ymlfor redis image with version tag - Tries
redis-server --versionfor local installations - Falls back to
redisgem version fromGemfile.lock
- Checks
docker-compose.ymlfor mongo image with version tag - Tries
mongod --versionfor local installations - Falls back to
mongoidormongogem version fromGemfile.lock
.python-versionfile (highest priority)pyproject.toml(requires-pythonfield)- Docker Compose
python:*images python --versionfor system installation
.nvmrcor.node-versionfiles (highest priority - explicit version specification)package.jsonengines.nodefield (e.g., ">=18.0.0")- Docker Compose
node:*images node --versionfor system installation
Version Normalization: Handles constraint operators (>=, ^, ~), LTS names (lts/hydrogen), and version ranges
rust-toolchainorrust-toolchain.tomlfiles (highest priority - explicit toolchain specification)Cargo.tomlrust-versionfield (MSRV - Minimum Supported Rust Version)- Docker Compose
rust:*images rustc --versionfor system installation (only when Rust project files exist)
Note: Symbolic channels like "stable", "beta", "nightly" are skipped as they don't provide specific versions.
go.modfile (highest priority - standard Go module version specification)go.workfile (Go workspace format).go-versionfile- Docker Compose
golang:*images go versionfor system installation (only when Go project files exist)
Note: Shell fallback only executes when Go project files are detected, preventing unnecessary command execution.
- Ruby >= 3.1.0
- Internet connection (for initial EOL data fetch)
# Clone the repo
git clone https://github.com/RichD/harbinger.git
cd harbinger
# Install dependencies
bundle install
# Run tests
bundle exec rspec
# Run locally
bundle exec exe/harbinger scan .- β Ruby, Rails, Python, Node.js, Rust, Go version detection
- β PostgreSQL, MySQL, Redis, MongoDB version detection
- β Ecosystem-grouped dashboard with smart component display
- β Export reports to JSON/CSV
- β
Bulk scanning with
--recursiveandrescancommands - β 24-hour smart caching for offline support
- β Color-coded EOL warnings
- π· TypeScript version detection
- π― Framework detection (Django, Flask, Express, Gin)
- π¦ Package manager detection (npm, yarn, pip, bundler, go modules versions)
- π Dependency vulnerability scanning integration
- π€ AI-powered upgrade summaries and breaking change analysis
- π§ Email/Slack notifications for approaching EOL dates
- βοΈ Cloud platform detection (AWS, Heroku, Render)
- π₯ Team collaboration features (shared dashboards)
- π Historical tracking and trends
Contributions welcome! Please:
- Fork the repo
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Ensure all tests pass (
bundle exec rspec) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This gem is available as open source under the terms of the MIT License.
- EOL data provided by endoflife.date
- Built with β€οΈ using Ruby and Thor
- Website: stackharbinger.com
- GitHub: github.com/RichD/harbinger
- RubyGems: rubygems.org/gems/stackharbinger
Like Harbinger? Give it a β on GitHub!