Last active
August 5, 2025 12:36
-
-
Save vitroz/e03e14464e6555fcb91a84180f360260 to your computer and use it in GitHub Desktop.
libyears report
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
| #!/usr/bin/env ruby | |
| require "fileutils" | |
| require "open3" | |
| require "date" | |
| class LibyearReportGenerator | |
| REPOSITORIES = [ | |
| "/Users/vitorqueiroz/dev/smile-core", | |
| "/Users/vitorqueiroz/dev/smile-data-ingestion-endpoints", | |
| "/Users/vitorqueiroz/dev/smile-data-ingestion-pipeline", | |
| "/Users/vitorqueiroz/dev/smile-ruby-monitoring" | |
| ].freeze | |
| def initialize | |
| @current_dir = Dir.pwd | |
| end | |
| def generate_reports | |
| puts "Starting libyear-bundler report generation for #{REPOSITORIES.size} repositories..." | |
| puts "=" * 60 | |
| # Use threads to process repos in parallel | |
| threads = REPOSITORIES.map do |repo_path| | |
| Thread.new { process_repository(repo_path) } | |
| end | |
| threads.each(&:join) | |
| puts "\n" + "=" * 60 | |
| puts "All reports generated successfully!" | |
| puts "Reports saved in: #{@current_dir}" | |
| end | |
| private | |
| def process_repository(repo_path) | |
| repo_name = File.basename(repo_path) | |
| puts "\nProcessing #{repo_name}..." | |
| unless Dir.exist?(repo_path) | |
| puts " β Repository not found: #{repo_path}" | |
| return | |
| end | |
| begin | |
| Dir.chdir(repo_path) do | |
| # Git operations | |
| puts " π Switching to main branch and pulling latest changes..." | |
| run_command("git checkout main") | |
| run_command("git pull") | |
| # Run libyear-bundler commands | |
| puts " π Running libyear-bundler analysis..." | |
| # Special handling for smile-ruby-monitoring repo | |
| if repo_name == "smile-ruby-monitoring" | |
| libyear_output = run_command("libyear-bundler") | |
| version_output = run_command("libyear-bundler --versions") | |
| else | |
| libyear_output = run_command("smile-cli run libyear-bundler") | |
| version_output = run_command("smile-cli run libyear-bundler --versions") | |
| end | |
| # Generate report | |
| generate_report_file(repo_name, libyear_output, version_output) | |
| puts " β Report generated for #{repo_name}" | |
| end | |
| rescue => e | |
| puts " β Error processing #{repo_name}: #{e.message}" | |
| end | |
| end | |
| def run_command(command) | |
| stdout, stderr, status = Open3.capture3(command) | |
| unless status.success? | |
| raise "Command failed: #{command}\nError: #{stderr}" | |
| end | |
| stdout | |
| end | |
| def generate_report_file(repo_name, libyear_output, version_output) | |
| filename = "#{@current_dir}/#{repo_name}_libyear_bundler_report.txt" | |
| # Parse the outputs for summary | |
| summary = parse_libyear_summary(libyear_output, version_output) | |
| File.open(filename, "w") do |file| | |
| file.puts "LIBYEAR-BUNDLER REPORT FOR #{repo_name.upcase}" | |
| file.puts "=" * 50 | |
| file.puts "Generated on: #{DateTime.now.strftime("%Y-%m-%d %H:%M:%S")}" | |
| file.puts "" | |
| # Summary section | |
| file.puts "SUMMARY:" | |
| file.puts "-" * 20 | |
| file.puts summary | |
| file.puts "" | |
| # Version information | |
| file.puts "VERSION INFORMATION:" | |
| file.puts "-" * 20 | |
| file.puts version_output.strip | |
| file.puts "" | |
| # Full libyear-bundler output | |
| file.puts "FULL LIBYEAR-BUNDLER OUTPUT:" | |
| file.puts "-" * 20 | |
| file.puts libyear_output | |
| end | |
| end | |
| def parse_libyear_summary(libyear_output, version_output) | |
| summary = [] | |
| # Extract critical version information first (most important) | |
| versions_behind = parse_versions_behind(version_output) | |
| summary << versions_behind if versions_behind | |
| # Extract total libyears from output | |
| if libyear_output =~ /Total: ([\d.]+) libyears?/ | |
| total_libyears = $1 | |
| summary << "Total Libyears: #{total_libyears}" | |
| else | |
| # Try to find libyears mentioned in the output | |
| libyear_lines = libyear_output.scan(/[\d.]+\s+libyears?/) | |
| summary << if libyear_lines.any? | |
| "Libyears found in output: #{libyear_lines.join(", ")}" | |
| else | |
| "Total Libyears: Unable to parse from output" | |
| end | |
| end | |
| # Add gem count if available | |
| gem_count = count_outdated_gems(libyear_output) | |
| summary << "Outdated gems analyzed: #{gem_count}" if gem_count > 0 | |
| summary.join("\n") | |
| end | |
| def parse_versions_behind(version_output) | |
| # Look for the critical pattern: "Major, minor, patch versions behind: 3, 91, 13" | |
| if version_output =~ /Major, minor, patch versions behind:\s*(\d+),\s*(\d+),\s*(\d+)/i | |
| major, minor, patch = $1, $2, $3 | |
| "Major, minor, patch versions behind: #{major}, #{minor}, #{patch}" | |
| elsif version_output =~ /(\d+)\s+major.*?(\d+)\s+minor.*?(\d+)\s+patch/im | |
| major, minor, patch = $1, $2, $3 | |
| "Major, minor, patch versions behind: #{major}, #{minor}, #{patch}" | |
| end | |
| end | |
| def count_outdated_gems(output) | |
| # Count lines that look like gem entries (typically have version numbers) | |
| gem_lines = output.lines.select do |line| | |
| line.match?(/\d+\.\d+/) && !line.match?(/^(Total|Checked)/) | |
| end | |
| gem_lines.size | |
| end | |
| end | |
| # Run the script | |
| if __FILE__ == $0 | |
| begin | |
| generator = LibyearReportGenerator.new | |
| generator.generate_reports | |
| rescue Interrupt | |
| puts "\n\nβ οΈ Script interrupted by user" | |
| exit 1 | |
| rescue => e | |
| puts "\nβ Script failed: #{e.message}" | |
| puts e.backtrace.first(5).join("\n") if ENV["DEBUG"] | |
| exit 1 | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment