|
1
|
1 |
|
require_relative "../output" |
|
2
|
1 |
|
require_relative "exceptions" |
|
3
|
1 |
|
require_relative "exception_suppressor" |
|
4
|
|
|
|
|
5
|
1 |
|
module Resume |
|
6
|
1 |
|
module CLI |
|
7
|
|
|
# Module concerned with the installation and dependency checking |
|
8
|
|
|
# of Ruby gems on to the system in order to generate the resume. |
|
9
|
|
|
# |
|
10
|
|
|
# @author Paul Fioravanti |
|
11
|
1 |
|
class GemInstaller |
|
12
|
1 |
|
extend Forwardable |
|
13
|
|
|
|
|
14
|
|
|
# @!attribute gems [r] |
|
15
|
|
|
# @return [Hash] The hash of gems to install. |
|
16
|
1 |
|
attr_reader :gems |
|
17
|
|
|
|
|
18
|
1 |
|
def self.gem_already_installed?(name, version) |
|
19
|
3 |
|
Gem::Specification.find_by_name(name).version == |
|
20
|
|
|
Gem::Version.new(version) |
|
21
|
|
|
end |
|
22
|
1 |
|
private_class_method :gem_already_installed? |
|
23
|
|
|
|
|
24
|
|
|
# Initialises a new instance of a Gem Installer. |
|
25
|
|
|
# |
|
26
|
|
|
# @param gems [Hash] |
|
27
|
|
|
# A hash containing the gem dependencies for the resume. |
|
28
|
|
|
# @return [GemInstaller] |
|
29
|
|
|
# The gem installer object. |
|
30
|
1 |
|
def initialize(gems) |
|
31
|
10 |
|
@gems = gems |
|
32
|
|
|
end |
|
33
|
|
|
|
|
34
|
|
|
# Audits the local system to see if the necessary gems are installed. |
|
35
|
|
|
# |
|
36
|
|
|
# @return [Hash] The list of remaining gem dependencies to install. |
|
37
|
1 |
|
def audit_gem_dependencies |
|
38
|
3 |
|
gems.each do |name, version| |
|
39
|
|
|
# if gem not installed: leave in the gems list |
|
40
|
4 |
|
ExceptionSuppressor.suppress(Gem::LoadError, -> { next }) do |
|
41
|
3 |
|
if self.class.__send__(:gem_already_installed?, name, version) |
|
42
|
|
|
# remove dependency to install |
|
43
|
1 |
|
self.gems -= [[name, version]] |
|
44
|
|
|
end |
|
45
|
|
|
end |
|
46
|
|
|
end |
|
47
|
|
|
end |
|
48
|
|
|
|
|
49
|
|
|
# Outputs the name and version of the gems that must be installed |
|
50
|
|
|
# in order to generate the resume. |
|
51
|
|
|
# |
|
52
|
|
|
# @return [Hash] The list of dependencies to install. |
|
53
|
1 |
|
def output_gem_dependencies |
|
54
|
2 |
|
return if gems.none? |
|
55
|
|
|
|
|
56
|
1 |
|
Output.warning(:ruby_gems) |
|
57
|
1 |
|
gems.each do |name, version| |
|
58
|
1 |
|
Output.plain(:gem_name_and_version, name: name, version: version) |
|
59
|
|
|
end |
|
60
|
|
|
end |
|
61
|
|
|
|
|
62
|
|
|
# Attempts to install gem dependencies and reports back on |
|
63
|
|
|
# whether it was successful. |
|
64
|
|
|
# |
|
65
|
|
|
# @raise [NetworkConnectionError] |
|
66
|
|
|
# if an internet connection is unavailable to download gems. |
|
67
|
|
|
# @return [true] |
|
68
|
|
|
# if gem dependencies were successfully installed. |
|
69
|
|
|
# @return [false] |
|
70
|
|
|
# if gem dependencies were not successfully installed. |
|
71
|
1 |
|
def gems_successfully_installed? |
|
72
|
5 |
|
return true if gems.none? |
|
73
|
|
|
|
|
74
|
4 |
|
Output.plain(:installing_ruby_gems) |
|
75
|
4 |
|
gems.all? do |gem_name, version| |
|
76
|
4 |
|
Kernel.system("gem", "install", gem_name, "-v", version) |
|
77
|
|
|
end |
|
78
|
|
|
rescue SocketError, Errno::ECONNREFUSED |
|
79
|
2 |
|
raise NetworkConnectionError |
|
80
|
|
|
ensure |
|
81
|
|
|
# Reset dir and path values so just-installed gems can |
|
82
|
|
|
# be required, but also have this here so that the |
|
83
|
|
|
# return value for this method is a boolean |
|
84
|
5 |
|
Gem.clear_paths |
|
85
|
|
|
end |
|
86
|
|
|
|
|
87
|
1 |
|
private |
|
88
|
|
|
|
|
89
|
1 |
|
attr_writer :gems |
|
90
|
|
|
end |
|
91
|
|
|
end |
|
92
|
|
|
end |
|
93
|
|
|
|