-
Notifications
You must be signed in to change notification settings - Fork 37
/
remote_file_target.rb
121 lines (99 loc) · 3.47 KB
/
remote_file_target.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
require 'digest/md5'
module Sprout
class RemoteFileTarget < FileTarget
attr_accessor :archive_type
attr_accessor :url
attr_accessor :md5
def validate
super
raise Sprout::Errors::ValidationError.new "RemoteFileTarget.url is a required field" if url.nil?
raise Sprout::Errors::ValidationError.new "RemoteFileTarget.md5 is a required field" if md5.nil?
raise Sprout::Errors::ValidationError.new "RemoteFileTarget.archive_type is a required field" if archive_type.nil?
end
def resolve
validate
load_unpack_or_ignore_archive
self
end
##
# Do not cache this value...
#
# This response can change over time IF:
# - The downloaded bytes do not match the expected MD5
# - AND the user confirms the prompt that they are OK with this
def downloaded_file
File.join(Sprout.cache, pkg_name, "#{md5}.#{archive_type}")
end
def unpacked_file
upcased_pkg = pkg_name.upcase
upcased_version = pkg_version.upcase.gsub /\./, '_'
ENV["SPROUT_#{upcased_pkg}_#{upcased_version}"] ||
ENV["SPROUT_#{upcased_pkg}"] ||
ENV["#{upcased_pkg}_#{upcased_version}"] ||
ENV[upcased_pkg] ||
File.join(Sprout.cache, pkg_name, pkg_version)
end
protected
def logger
Sprout.stdout
end
def expand_local_path path
File.join unpacked_file, path
end
private
def load_unpack_or_ignore_archive
if(!unpacked_files_exist?)
if(!File.exists?(downloaded_file))
bytes = download_archive
write_archive bytes
end
# If we *just* downloaded the file,
# use the bytes directly, otherwise
# read them off disk from a previous
# download attempt:
bytes ||= File.open(downloaded_file, 'rb').read
if should_unpack?(bytes, md5)
unpack_archive
end
end
end
def unpacked_files_exist?
File.exists?(unpacked_file) && !Dir.empty?(unpacked_file)
end
def download_archive
Sprout::RemoteFileLoader.load url, pkg_name
end
def write_archive bytes
FileUtils.mkdir_p File.dirname(downloaded_file)
File.open downloaded_file, 'wb+' do |f|
f.write bytes
end
end
def should_unpack? bytes, expected_md5sum
if expected_md5sum
downloaded_md5 = Digest::MD5.new
downloaded_md5 << bytes
if(expected_md5sum != downloaded_md5.hexdigest)
return prompt_for_md5_failure downloaded_md5, expected_md5sum
end
end
return true
end
def prompt_for_md5_failure downloaded_md5, expected_md5sum
puts "The MD5 Sum of the downloaded file (#{downloaded_md5.hexdigest}) does not match what was expected (#{expected_md5sum})."
puts "Would you like to install anyway? [Yn]"
user_response = $stdin.gets.chomp!
if(user_response.downcase == 'y')
return true
else
raise Sprout::Errors::RemoteFileLoaderError.new('MD5 Checksum failed')
end
end
def unpack_archive
logger.puts "Unpacking archive at #{downloaded_file} now. This can take anywhere from a few seconds to many minutes depending on your OS and the size of the archive.\n\nIf you're on windows, consider using this ample time to look into improving the zip utils in Ruby..."
FileUtils.mkdir_p unpacked_file
unpacker = Sprout::ArchiveUnpacker.new
unpacker.unpack downloaded_file, unpacked_file, archive_type
end
end
end