-
Notifications
You must be signed in to change notification settings - Fork 1
/
outdated_report.rb
executable file
·137 lines (111 loc) · 2.96 KB
/
outdated_report.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env ruby
# frozen_string_literal: true
# NOTE: DEPRECATED. We do not use this in any automated way.
###
# How to use this script
# From the command line run REPOS_PATH=./access ./outdated_report.rb
# By default this will clone all the repositories in the repo list,
# run the bundle outdated command, and return the data filtered by
# gems who have updates available but we've requested a version that may
# be preventing us from updating it.
#
# Since this data is modeled locally, it is possible to require this file
# (after commenting out the last line that causes the script to run) and
# do other useful things compare installed vs newest versions to report
# on all major or non-major version upgrades, etc.
###
##
# List of projects
class Projects
def self.call
File.open("#{ENV['REPOS_PATH']}/ruby").readlines.map(&:chomp)
end
end
##
# Model the bundle outdated return data to get at the various pieces of the string
class OutdatedData
MATCH_REGEX = /^(?<gem>\S+) \((?<updates>.*)\)( in groups "(?<groups>.*)")?/.freeze
attr_reader :content
def initialize(content)
@content = content
end
def to_s
content
end
def gem
matched_content[:gem]
end
def newest
updates[0].split(' ')[1]
end
def installed
updates[1].split(' ')[1]
end
def requested
_, *rest = (updates[2] || '').split(' ')
rest.join(' ')
end
def groups
(matched_content[:groups] || '').split(', ')
end
private
def updates
matched_content[:updates].split(', ')
end
def matched_content
content.match(MATCH_REGEX)
end
end
##
# Download list of projects and return all the bundle outdated output by project
class DownloadAndRunOutdated
def self.call
new.download_all_and_cache_outdated.cache
end
TEMP_DIR = '/tmp'
attr_reader :projects
def initialize(projects: Projects.call)
@projects = projects
end
def cache
@cache ||= {}
end
def download_all_and_cache_outdated
projects.map do |project|
project_dir = "#{TEMP_DIR}/outdated_reports/#{project}"
download_or_update(project, project_dir)
capture = `cd #{project_dir} && bundle outdated`.split("\n")
cache[project] = capture.map do |line|
next unless line.start_with?(' * ')
OutdatedData.new(line.sub(' * ', ''))
end.compact
end
self
end
def download_or_update(project, directory)
if Dir.exist?(directory)
`cd #{directory} && git fetch --all && git reset --hard origin/master`
else
`git clone [email protected]:sul-dlss/#{project} #{directory}`
end
end
end
##
# Print out outdated data filtered by
# the gems that have been requested
class OutdatedByRequest
attr_reader :data
def initialize(data = DownloadAndRunOutdated.call)
@data = data
end
def self.call
new.data.each do |project, updates|
puts project
updates.each do |update|
next if update.requested.empty?
puts "\t#{update}"
end
end
end
end
OutdatedByRequest.call