Module: BundleSafeUpdate::CLI::Output
- Included in:
- BundleSafeUpdate::CLI
- Defined in:
- lib/bundle_safe_update/cli/output.rb
Instance Method Summary collapse
- #blocked_reason(result, config) ⇒ Object
- #build_json_output(results, blocked, config) ⇒ Object
- #config_lines(config) ⇒ Object
- #config_values(config) ⇒ Object
- #dry_run_output(config) ⇒ Object
- #format_list(items) ⇒ Object
- #output_audit_result(result) ⇒ Object
- #output_human(results, blocked, config) ⇒ Object
- #output_json(results, blocked, config) ⇒ Object
- #output_risk_results(risk_results, options) ⇒ Object
- #print_audit_error(error) ⇒ Object
- #print_audit_results(vulnerabilities) ⇒ Object
- #print_audit_unavailable ⇒ Object
- #print_result(result, config) ⇒ Object
- #print_risk_result(result) ⇒ Object
- #print_risk_signal(result, signal) ⇒ Object
- #print_risk_summary(risk_results) ⇒ Object
- #print_skipped(blocked, risk_blocked_names) ⇒ Object
- #print_summary(blocked) ⇒ Object
- #print_update_result(success) ⇒ Object
- #print_update_start(gem_names, lock_only: false) ⇒ Object
- #print_vulnerability(vuln) ⇒ Object
Instance Method Details
#blocked_reason(result, config) ⇒ Object
55 56 57 58 |
# File 'lib/bundle_safe_update/cli/output.rb', line 55 def blocked_reason(result, config) age_info = result.age_days ? "published #{result.age_days} days ago" : result.reason "#{age_info} (< #{config.cooldown_days} required)" end |
#build_json_output(results, blocked, config) ⇒ Object
33 34 35 36 37 38 39 40 |
# File 'lib/bundle_safe_update/cli/output.rb', line 33 def build_json_output(results, blocked, config) { ok: blocked.empty?, cooldown_days: config.cooldown_days, checked: results.length, blocked: blocked.map { |r| { name: r.name, version: r.version, age_days: r.age_days } } } end |
#config_lines(config) ⇒ Object
11 12 13 |
# File 'lib/bundle_safe_update/cli/output.rb', line 11 def config_lines(config) config_values(config).map { |label, value| " #{label}: #{value}" } end |
#config_values(config) ⇒ Object
15 16 17 18 19 20 21 22 23 |
# File 'lib/bundle_safe_update/cli/output.rb', line 15 def config_values(config) { 'Cooldown days' => config.cooldown_days, 'Ignored gems' => format_list(config.ignore_gems), 'Ignored prefixes' => format_list(config.ignore_prefixes), 'Trusted sources' => format_list(config.trusted_sources), 'Trusted owners' => format_list(config.trusted_owners), 'Max threads' => config.max_threads, 'Audit' => config.audit, 'Update' => config.update, 'Lock only' => config.lock_only, 'Warn only' => config.warn_only, 'Verbose' => config.verbose } end |
#dry_run_output(config) ⇒ Object
6 7 8 9 |
# File 'lib/bundle_safe_update/cli/output.rb', line 6 def dry_run_output(config) puts('Configuration (dry-run):') config_lines(config).each { |line| puts(line) } end |
#format_list(items) ⇒ Object
25 26 27 |
# File 'lib/bundle_safe_update/cli/output.rb', line 25 def format_list(items) items.empty? ? '(none)' : items.join(', ') end |
#output_audit_result(result) ⇒ Object
69 70 71 72 73 74 |
# File 'lib/bundle_safe_update/cli/output.rb', line 69 def output_audit_result(result) return print_audit_unavailable unless result.available return print_audit_error(result.error) if result.error print_audit_results(result.vulnerabilities) end |
#output_human(results, blocked, config) ⇒ Object
42 43 44 45 |
# File 'lib/bundle_safe_update/cli/output.rb', line 42 def output_human(results, blocked, config) results.each { |result| print_result(result, config) } print_summary(blocked) end |
#output_json(results, blocked, config) ⇒ Object
29 30 31 |
# File 'lib/bundle_safe_update/cli/output.rb', line 29 def output_json(results, blocked, config) puts(JSON.pretty_generate(build_json_output(results, blocked, config))) end |
#output_risk_results(risk_results, options) ⇒ Object
102 103 104 105 106 107 108 109 |
# File 'lib/bundle_safe_update/cli/output.rb', line 102 def output_risk_results(risk_results, ) return if risk_results.empty? || [:json] puts puts(cyan('Risk signals:')) risk_results.each { |result| print_risk_result(result) } print_risk_summary(risk_results) end |
#print_audit_error(error) ⇒ Object
80 81 82 |
# File 'lib/bundle_safe_update/cli/output.rb', line 80 def print_audit_error(error) warn(red("Audit error: #{error}")) end |
#print_audit_results(vulnerabilities) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/bundle_safe_update/cli/output.rb', line 84 def print_audit_results(vulnerabilities) puts puts(cyan('Checking for vulnerabilities...')) if vulnerabilities.empty? puts(green('No vulnerabilities found.')) else vulnerabilities.each { |v| print_vulnerability(v) } puts puts(yellow("#{vulnerabilities.length} vulnerability(ies) found")) end end |
#print_audit_unavailable ⇒ Object
76 77 78 |
# File 'lib/bundle_safe_update/cli/output.rb', line 76 def print_audit_unavailable warn(yellow('Warning: bundler-audit not installed. Run: gem install bundler-audit')) end |
#print_result(result, config) ⇒ Object
47 48 49 50 51 52 53 |
# File 'lib/bundle_safe_update/cli/output.rb', line 47 def print_result(result, config) if result.allowed puts(green("OK: #{result.name} (#{result.version}) - #{result.reason}")) else puts(yellow("BLOCKED: #{result.name} (#{result.version}) - #{blocked_reason(result, config)}")) end end |
#print_risk_result(result) ⇒ Object
111 112 113 |
# File 'lib/bundle_safe_update/cli/output.rb', line 111 def print_risk_result(result) result.signals.each { |signal| print_risk_signal(result, signal) } end |
#print_risk_signal(result, signal) ⇒ Object
115 116 117 118 |
# File 'lib/bundle_safe_update/cli/output.rb', line 115 def print_risk_signal(result, signal) prefix = signal.mode == 'block' ? red('BLOCKED') : yellow('WARNING') puts("#{prefix}: #{result.gem_name} (#{result.version}) - #{signal.message}") end |
#print_risk_summary(risk_results) ⇒ Object
120 121 122 123 124 125 126 127 |
# File 'lib/bundle_safe_update/cli/output.rb', line 120 def print_risk_summary(risk_results) warnings = risk_results.sum { |r| r.signals.count { |s| s.mode == 'warn' } } blocks = risk_results.count(&:blocked) puts puts(yellow("#{blocks} gem(s) blocked by risk signals")) if blocks.positive? puts(yellow("#{warnings} risk warning(s)")) if warnings.positive? end |
#print_skipped(blocked, risk_blocked_names) ⇒ Object
144 145 146 147 148 149 150 151 152 |
# File 'lib/bundle_safe_update/cli/output.rb', line 144 def print_skipped(blocked, risk_blocked_names) total_skipped = blocked.length + risk_blocked_names.length return if total_skipped.zero? cooldown_names = blocked.map(&:name) all_skipped = (cooldown_names + risk_blocked_names).uniq.join(', ') puts puts(yellow("Skipped #{total_skipped} blocked gem(s): #{all_skipped}")) end |
#print_summary(blocked) ⇒ Object
60 61 62 63 64 65 66 67 |
# File 'lib/bundle_safe_update/cli/output.rb', line 60 def print_summary(blocked) puts if blocked.empty? puts(green('All gem versions satisfy minimum age requirements.')) else puts(yellow("#{blocked.length} gem(s) violate minimum release age")) end end |
#print_update_result(success) ⇒ Object
140 141 142 |
# File 'lib/bundle_safe_update/cli/output.rb', line 140 def print_update_result(success) puts(success ? green('Bundle updated successfully.') : red('Bundle update failed.')) end |
#print_update_start(gem_names, lock_only: false) ⇒ Object
129 130 131 132 133 134 135 136 137 138 |
# File 'lib/bundle_safe_update/cli/output.rb', line 129 def print_update_start(gem_names, lock_only: false) puts if lock_only puts(cyan("Updating lock file for #{gem_names.length} gem(s): #{gem_names.join(', ')}")) puts(cyan("Running: bundle lock --conservative --update #{gem_names.join(' ')}")) else puts(cyan("Updating #{gem_names.length} gem(s): #{gem_names.join(', ')}")) puts(cyan("Running: bundle update --conservative #{gem_names.join(' ')}")) end end |
#print_vulnerability(vuln) ⇒ Object
97 98 99 100 |
# File 'lib/bundle_safe_update/cli/output.rb', line 97 def print_vulnerability(vuln) puts(red("VULNERABLE: #{vuln.gem_name} (#{vuln.cve}) - #{vuln.title}")) puts(" Solution: #{vuln.solution}") if vuln.solution end |