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!