homebrew-cask/lib/cask/utils.rb

153 lines
3.9 KiB
Ruby

# see Homebrew Library/Homebrew/utils.rb
require 'yaml'
require 'open3'
require 'stringio'
# monkeypatch Object - not a great idea
class Object
def utf8_inspect
if not defined?(Encoding)
self.inspect
else
if self.respond_to?(:map)
self.map do |sub_elt|
sub_elt.utf8_inspect
end
else
self.inspect.force_encoding('UTF-8').sub(%r{\A"(.*)"\Z}, '\1')
end
end
end
end
# monkeypatch Tty
class Tty
class << self
def magenta; color 35; end
end
end
# monkeypatch Hash
class Hash
def assert_valid_keys(*valid_keys)
unknown_keys = self.keys - valid_keys
unless unknown_keys.empty?
raise CaskError.new %Q{Unknown keys: #{unknown_keys.inspect}. Running "brew update && brew upgrade brew-cask && brew cleanup && brew cask cleanup" will likely fix it.}
end
end
end
# monkeypatch Pathname
class Pathname
# our own version of Homebrew's abv, with better defenses
# against unusual filenames
def cabv
out=''
n = Cask::SystemCommand.run!('/usr/bin/find',
:args => [self.realpath, *%w[-type f ! -name .DS_Store]],
:print_stderr => false).stdout.count("\n")
out << "#{n} files, " if n > 1
out << Cask::SystemCommand.run!('/usr/bin/du',
:args => ['-hs', '--', self.to_s],
:print_stderr => false).stdout.split("\t").first.strip
end
end
class Buffer < StringIO
def initialize(tty = false)
super()
@tty = tty
end
def tty?
@tty
end
end
# global methods
def odebug title, *sput
if Cask.respond_to?(:debug) and Cask.debug
width = Tty.width * 4 - 6
if $stdout.tty? and title.to_s.length > width
title = title.to_s[0, width - 3] + '...'
end
puts "#{Tty.magenta}==>#{Tty.white} #{title}#{Tty.reset}"
puts sput unless sput.empty?
end
end
module Cask::Utils
def dumpcask
if Cask.respond_to?(:debug) and Cask.debug
odebug "Cask instance dumps in YAML:"
odebug "Cask instance toplevel:", self.to_yaml
[
:homepage,
:url,
:appcast,
:version,
:license,
:tags,
:sums,
:artifacts,
:caveats,
:depends_on_formula,
:conflicts_with,
:container_type,
:gpg,
].each do |method|
odebug "Cask instance method '#{method}':", self.send(method).to_yaml
end
end
end
# from Homebrew puts_columns
def self.stringify_columns items, star_items=[]
return if items.empty?
if star_items && star_items.any?
items = items.map{|item| star_items.include?(item) ? "#{item}*" : item}
end
if $stdout.tty?
# determine the best width to display for different console sizes
console_width = Cask::SystemCommand.run("/bin/stty", :args => ["size"]).stdout.chomp.split(" ").last.to_i
console_width = 80 if console_width <= 0
else
console_width = 80
end
longest = items.sort_by { |item| item.length }.last
optimal_col_width = (console_width.to_f / (longest.length + 2).to_f).floor
cols = optimal_col_width > 1 ? optimal_col_width : 1
Open3.popen3('/usr/bin/pr', "-#{cols}", '-t', "-w#{console_width}") do |stdin, stdout, stderr|
stdin.puts(items)
stdin.close
stdout.read
end
end
# 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? and dir.exist?
unless dir.directory?
onoe "Argument must be a directory: '#{dir}'"
return false
end
unless file.absolute? and dir.absolute?
onoe "Both arguments must be absolute: '#{file}', '#{dir}'"
return false
end
while file.parent != file
return true if File.identical?(file, dir)
file = file.parent
end
return false
end
end