163 lines
4.7 KiB
Ruby
Raw Normal View History

2016-08-18 22:11:42 +03:00
require "yaml"
require "open3"
require "stringio"
require "hbc/utils/file"
PREBUG_URL = "https://github.com/caskroom/homebrew-cask/blob/master/doc/reporting_bugs/pre_bug_report.md".freeze
2016-08-18 22:11:42 +03:00
ISSUES_URL = "https://github.com/caskroom/homebrew-cask#reporting-bugs".freeze
# monkeypatch Object - not a great idea
class Object
def utf8_inspect
return inspect unless defined?(Encoding)
return map(&:utf8_inspect) if respond_to?(:map)
inspect.force_encoding("UTF-8").sub(/\A"(.*)"\Z/, '\1')
2016-08-18 22:11:42 +03:00
end
end
class Buffer < StringIO
def initialize(tty = false)
super()
@tty = tty
end
def tty?
@tty
end
end
# global methods
def odebug(title, *sput)
2016-09-20 15:11:33 +02:00
return unless Hbc.respond_to?(:debug)
return unless Hbc.debug
2016-08-30 21:38:13 +02:00
puts Formatter.headline(title, color: :magenta)
2016-09-20 15:11:33 +02:00
puts sput unless sput.empty?
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
module Hbc
module Utils
def self.gain_permissions_remove(path, command: SystemCommand)
if path.respond_to?(:rmtree) && path.exist?
gain_permissions(path, ["-R"], command, &:rmtree)
elsif File.symlink?(path)
gain_permissions(path, ["-h"], command, &FileUtils.method(:rm_f))
end
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
def self.gain_permissions(path, command_args, command)
tried_permissions = false
tried_ownership = false
begin
yield path
rescue StandardError
# in case of permissions problems
unless tried_permissions
# TODO: Better handling for the case where path is a symlink.
# The -h and -R flags cannot be combined, and behavior is
# dependent on whether the file argument has a trailing
# slash. This should do the right thing, but is fragile.
command.run("/usr/bin/chflags",
must_succeed: false,
args: command_args + ["--", "000", path])
command.run("/bin/chmod",
must_succeed: false,
args: command_args + ["--", "u+rwx", path])
command.run("/bin/chmod",
must_succeed: false,
args: command_args + ["-N", path])
tried_permissions = true
retry # rmtree
end
unless tried_ownership
# in case of ownership problems
# TODO: Further examine files to see if ownership is the problem
# before using sudo+chown
ohai "Using sudo to gain ownership of path '#{path}'"
command.run("/usr/sbin/chown",
args: command_args + ["--", current_user, path],
sudo: true)
tried_ownership = true
# retry chflags/chmod after chown
tried_permissions = false
retry # rmtree
end
end
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
def self.current_user
Etc.getpwuid(Process.euid).name
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
# paths that "look" descendant (textually) will still
# return false unless both the given paths exist
def self.file_is_descendant(file, dir)
file = Pathname.new(file)
dir = Pathname.new(dir)
return false unless file.exist? && dir.exist?
unless dir.directory?
onoe "Argument must be a directory: '#{dir}'"
return false
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
unless file.absolute? && dir.absolute?
onoe "Both arguments must be absolute: '#{file}', '#{dir}'"
return false
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
while file.parent != file
return true if File.identical?(file, dir)
file = file.parent
end
false
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
def self.path_occupied?(path)
File.exist?(path) || File.symlink?(path)
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
def self.error_message_with_suggestions
<<-EOS.undent
Follow the instructions here:
#{Formatter.url(PREBUG_URL)}
2016-08-18 22:11:42 +03:00
2016-08-26 16:04:47 +02:00
If this doesnt fix the problem, please report this bug:
2016-08-30 21:38:13 +02:00
#{Formatter.url(ISSUES_URL)}
2016-08-18 22:11:42 +03:00
2016-09-24 13:52:43 +02:00
EOS
end
2016-08-18 22:11:42 +03:00
2016-09-24 13:52:43 +02:00
def self.method_missing_message(method, token, section = nil)
poo = []
poo << "Unexpected method '#{method}' called"
poo << "during #{section}" if section
poo << "on Cask #{token}."
2016-08-18 22:11:42 +03:00
2016-09-24 13:52:43 +02:00
opoo(poo.join(" ") + "\n" + error_message_with_suggestions)
end
2016-08-18 22:11:42 +03:00
2016-09-24 13:52:43 +02:00
def self.nowstamp_metadata_path(container_path)
@timenow ||= Time.now.gmtime
2016-10-24 17:07:57 +02:00
return unless container_path.respond_to?(:join)
precision = 3
timestamp = @timenow.strftime("%Y%m%d%H%M%S")
fraction = format("%.#{precision}f", @timenow.to_f - @timenow.to_i)[1..-1]
timestamp.concat(fraction)
container_path.join(timestamp)
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
def self.size_in_bytes(files)
Array(files).reduce(0) { |acc, elem| acc + (File.size?(elem) || 0) }
2016-09-24 13:52:43 +02:00
end
2016-08-18 22:11:42 +03:00
2016-09-24 13:52:43 +02:00
def self.capture_stderr
previous_stderr = $stderr
$stderr = StringIO.new
yield
$stderr.string
ensure
$stderr = previous_stderr
end
2016-08-18 22:11:42 +03:00
end
end