2009-07-31 02:51:17 +01:00
|
|
|
require 'pathname'
|
2012-05-25 23:44:11 -05:00
|
|
|
require 'mach'
|
2013-09-17 21:25:43 -05:00
|
|
|
require 'resource'
|
2014-06-07 17:49:07 -05:00
|
|
|
require 'metafiles'
|
2009-07-31 02:51:17 +01:00
|
|
|
|
|
|
|
# we enhance pathname to make our code more readable
|
|
|
|
class Pathname
|
2012-05-25 23:44:11 -05:00
|
|
|
include MachO
|
|
|
|
|
2013-03-09 17:34:25 -06:00
|
|
|
BOTTLE_EXTNAME_RX = /(\.[a-z_]+(32)?\.bottle\.(\d+\.)?tar\.gz)$/
|
2012-07-05 20:29:31 -05:00
|
|
|
|
2012-02-09 18:43:47 -08:00
|
|
|
def install *sources
|
|
|
|
sources.each do |src|
|
|
|
|
case src
|
2013-08-06 19:52:58 -07:00
|
|
|
when Resource
|
|
|
|
src.stage(self)
|
2013-09-17 21:25:43 -05:00
|
|
|
when Resource::Partial
|
|
|
|
src.resource.stage { install(*src.files) }
|
2012-02-09 18:43:47 -08:00
|
|
|
when Array
|
2012-03-30 22:34:42 -07:00
|
|
|
if src.empty?
|
2012-03-30 23:02:32 -07:00
|
|
|
opoo "tried to install empty array to #{self}"
|
2013-08-12 20:55:24 -07:00
|
|
|
return
|
2012-03-30 22:34:42 -07:00
|
|
|
end
|
2013-08-12 20:55:24 -07:00
|
|
|
src.each {|s| install_p(s) }
|
2012-02-09 18:43:47 -08:00
|
|
|
when Hash
|
2012-03-30 22:34:42 -07:00
|
|
|
if src.empty?
|
2012-03-30 23:02:32 -07:00
|
|
|
opoo "tried to install empty hash to #{self}"
|
2013-08-12 20:55:24 -07:00
|
|
|
return
|
2012-03-30 22:34:42 -07:00
|
|
|
end
|
2013-08-12 20:55:24 -07:00
|
|
|
src.each {|s, new_basename| install_p(s, new_basename) }
|
2012-02-09 18:43:47 -08:00
|
|
|
else
|
2013-08-12 20:55:24 -07:00
|
|
|
install_p(src)
|
2012-02-09 18:43:47 -08:00
|
|
|
end
|
2009-07-31 02:51:17 +01:00
|
|
|
end
|
|
|
|
end
|
2010-02-19 13:13:42 +00:00
|
|
|
|
|
|
|
def install_p src, new_basename = nil
|
|
|
|
if new_basename
|
|
|
|
new_basename = File.basename(new_basename) # rationale: see Pathname.+
|
|
|
|
dst = self+new_basename
|
|
|
|
else
|
|
|
|
dst = self
|
|
|
|
end
|
|
|
|
|
|
|
|
src = src.to_s
|
|
|
|
dst = dst.to_s
|
|
|
|
|
|
|
|
# if it's a symlink, don't resolve it to a file because if we are moving
|
|
|
|
# files one by one, it's likely we will break the symlink by moving what
|
|
|
|
# it points to before we move it
|
|
|
|
# and also broken symlinks are not the end of the world
|
|
|
|
raise "#{src} does not exist" unless File.symlink? src or File.exist? src
|
|
|
|
|
2013-10-06 22:04:46 +01:00
|
|
|
dst = yield(src, dst) if block_given?
|
|
|
|
|
2010-02-19 13:13:42 +00:00
|
|
|
mkpath
|
|
|
|
if File.symlink? src
|
|
|
|
# we use the BSD mv command because FileUtils copies the target and
|
|
|
|
# not the link! I'm beginning to wish I'd used Python quite honestly!
|
|
|
|
raise unless Kernel.system 'mv', src, dst
|
|
|
|
else
|
|
|
|
# we mv when possible as it is faster and you should only be using
|
|
|
|
# this function when installing from the temporary build directory
|
|
|
|
FileUtils.mv src, dst
|
|
|
|
end
|
|
|
|
end
|
2013-07-06 11:28:49 -05:00
|
|
|
protected :install_p
|
2010-02-19 13:13:42 +00:00
|
|
|
|
2012-02-12 10:36:16 -08:00
|
|
|
# Creates symlinks to sources in this folder.
|
|
|
|
def install_symlink *sources
|
|
|
|
sources.each do |src|
|
|
|
|
case src
|
|
|
|
when Array
|
2013-08-12 20:55:24 -07:00
|
|
|
src.each {|s| install_symlink_p(s) }
|
2012-02-12 10:36:16 -08:00
|
|
|
when Hash
|
2013-08-12 20:55:24 -07:00
|
|
|
src.each {|s, new_basename| install_symlink_p(s, new_basename) }
|
2012-02-12 10:36:16 -08:00
|
|
|
else
|
2013-08-12 20:55:24 -07:00
|
|
|
install_symlink_p(src)
|
2012-02-12 10:36:16 -08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-03-18 19:03:25 -05:00
|
|
|
def install_symlink_p src, new_basename=src
|
2014-03-19 15:56:51 -05:00
|
|
|
src = Pathname(src).expand_path(self)
|
2014-03-18 19:03:25 -05:00
|
|
|
dst = join File.basename(new_basename)
|
2012-02-12 10:36:16 -08:00
|
|
|
mkpath
|
2014-04-06 18:12:02 +01:00
|
|
|
FileUtils.ln_sf src.relative_path_from(dst.parent), dst
|
2012-02-12 10:36:16 -08:00
|
|
|
end
|
2013-07-06 11:28:49 -05:00
|
|
|
protected :install_symlink_p
|
2012-02-12 10:36:16 -08:00
|
|
|
|
2009-08-31 22:34:42 -06:00
|
|
|
# we assume this pathname object is a file obviously
|
2014-05-03 14:53:08 -05:00
|
|
|
alias_method :old_write, :write if method_defined?(:write)
|
2009-08-31 22:34:42 -06:00
|
|
|
def write content
|
2013-07-22 21:26:42 -05:00
|
|
|
raise "Will not overwrite #{to_s}" if exist?
|
2009-08-31 22:34:42 -06:00
|
|
|
dirname.mkpath
|
|
|
|
File.open(self, 'w') {|f| f.write content }
|
|
|
|
end
|
2009-07-31 02:51:17 +01:00
|
|
|
|
2012-03-16 12:58:39 +00:00
|
|
|
# NOTE always overwrites
|
|
|
|
def atomic_write content
|
2014-03-22 10:20:39 -05:00
|
|
|
require "tempfile"
|
|
|
|
tf = Tempfile.new(basename.to_s)
|
2014-03-26 13:45:46 -05:00
|
|
|
tf.binmode
|
2012-03-16 12:58:39 +00:00
|
|
|
tf.write(content)
|
|
|
|
tf.close
|
2014-03-22 10:20:39 -05:00
|
|
|
|
|
|
|
begin
|
|
|
|
old_stat = stat
|
|
|
|
rescue Errno::ENOENT
|
|
|
|
old_stat = default_stat
|
|
|
|
end
|
|
|
|
|
|
|
|
FileUtils.mv tf.path, self
|
|
|
|
|
2014-03-26 13:45:46 -05:00
|
|
|
uid = Process.uid
|
|
|
|
gid = Process.groups.delete(old_stat.gid) { Process.gid }
|
|
|
|
|
2014-03-22 10:20:39 -05:00
|
|
|
begin
|
2014-03-26 13:45:46 -05:00
|
|
|
chown(uid, gid)
|
2014-03-22 10:20:39 -05:00
|
|
|
chmod(old_stat.mode)
|
|
|
|
rescue Errno::EPERM
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def default_stat
|
|
|
|
sentinel = parent.join(".brew.#{Process.pid}.#{rand(Time.now.to_i)}")
|
|
|
|
sentinel.open("w") { }
|
|
|
|
sentinel.stat
|
|
|
|
ensure
|
|
|
|
sentinel.unlink
|
2012-03-16 12:58:39 +00:00
|
|
|
end
|
2014-03-22 10:20:39 -05:00
|
|
|
private :default_stat
|
2012-03-16 12:58:39 +00:00
|
|
|
|
2009-07-31 02:51:17 +01:00
|
|
|
def cp dst
|
|
|
|
if file?
|
|
|
|
FileUtils.cp to_s, dst
|
|
|
|
else
|
|
|
|
FileUtils.cp_r to_s, dst
|
|
|
|
end
|
2009-09-02 14:31:28 +01:00
|
|
|
return dst
|
2009-07-31 02:51:17 +01:00
|
|
|
end
|
|
|
|
|
2013-10-05 20:29:02 +01:00
|
|
|
def cp_path_sub pattern, replacement
|
|
|
|
raise "#{self} does not exist" unless self.exist?
|
|
|
|
|
|
|
|
src = self.to_s
|
|
|
|
dst = src.sub(pattern, replacement)
|
|
|
|
raise "#{src} is the same file as #{dst}" if src == dst
|
|
|
|
|
|
|
|
dst_path = Pathname.new dst
|
|
|
|
|
|
|
|
if self.directory?
|
|
|
|
dst_path.mkpath
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
dst_path.dirname.mkpath
|
|
|
|
|
|
|
|
dst = yield(src, dst) if block_given?
|
|
|
|
|
|
|
|
FileUtils.cp(src, dst)
|
|
|
|
end
|
|
|
|
|
2012-01-12 20:08:35 -06:00
|
|
|
# extended to support common double extensions
|
2012-04-30 14:17:56 +10:00
|
|
|
alias extname_old extname
|
2013-04-20 13:48:49 -05:00
|
|
|
def extname(path=to_s)
|
|
|
|
BOTTLE_EXTNAME_RX.match(path)
|
2012-07-05 20:29:31 -05:00
|
|
|
return $1 if $1
|
2013-11-29 10:10:28 -08:00
|
|
|
/(\.(tar|cpio|pax)\.(gz|bz2|lz|xz|Z))$/.match(path)
|
2009-07-31 02:51:17 +01:00
|
|
|
return $1 if $1
|
2013-04-20 13:48:49 -05:00
|
|
|
return File.extname(path)
|
2009-07-31 02:51:17 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
# for filetypes we support, basename without extension
|
|
|
|
def stem
|
2013-04-20 13:48:49 -05:00
|
|
|
File.basename((path = to_s), extname(path))
|
2009-07-31 02:51:17 +01:00
|
|
|
end
|
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
# I don't trust the children.length == 0 check particularly, not to mention
|
|
|
|
# it is slow to enumerate the whole directory just to see if it is empty,
|
|
|
|
# instead rely on good ol' libc and the filesystem
|
|
|
|
def rmdir_if_possible
|
|
|
|
rmdir
|
2009-09-02 14:31:28 +01:00
|
|
|
true
|
2013-04-27 15:21:05 -05:00
|
|
|
rescue Errno::ENOTEMPTY
|
|
|
|
if (ds_store = self+'.DS_Store').exist? && children.length == 1
|
|
|
|
ds_store.unlink
|
2012-11-11 11:39:09 -08:00
|
|
|
retry
|
2013-04-27 15:21:05 -05:00
|
|
|
else
|
|
|
|
false
|
2012-11-11 11:39:09 -08:00
|
|
|
end
|
2013-04-27 15:21:05 -05:00
|
|
|
rescue Errno::EACCES, Errno::ENOENT
|
2009-09-02 14:31:28 +01:00
|
|
|
false
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
2012-01-22 22:12:39 +01:00
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
def chmod_R perms
|
|
|
|
require 'fileutils'
|
|
|
|
FileUtils.chmod_R perms, to_s
|
|
|
|
end
|
|
|
|
|
2009-07-31 02:51:17 +01:00
|
|
|
def version
|
2012-07-09 23:24:27 -05:00
|
|
|
require 'version'
|
2012-07-10 16:01:02 -05:00
|
|
|
Version.parse(self)
|
2009-07-31 02:51:17 +01:00
|
|
|
end
|
2012-01-22 22:12:39 +01:00
|
|
|
|
2012-04-29 11:45:46 -07:00
|
|
|
def compression_type
|
2014-04-06 11:18:25 -05:00
|
|
|
case extname
|
|
|
|
when ".jar", ".war"
|
|
|
|
# Don't treat jars or wars as compressed
|
|
|
|
return
|
|
|
|
when ".gz"
|
|
|
|
# If the filename ends with .gz not preceded by .tar
|
|
|
|
# then we want to gunzip but not tar
|
|
|
|
return :gzip_only
|
2014-04-06 11:19:30 -05:00
|
|
|
when ".bz2"
|
|
|
|
return :bzip2_only
|
2014-04-06 11:18:25 -05:00
|
|
|
end
|
2013-06-08 10:27:47 -07:00
|
|
|
|
2012-05-03 20:31:00 -07:00
|
|
|
# Get enough of the file to detect common file types
|
|
|
|
# POSIX tar magic has a 257 byte offset
|
2012-04-29 11:45:46 -07:00
|
|
|
# magic numbers stolen from /usr/share/file/magic/
|
2013-09-16 12:50:31 -05:00
|
|
|
case open('rb') { |f| f.read(262) }
|
2013-04-03 23:30:32 -05:00
|
|
|
when /^PK\003\004/n then :zip
|
|
|
|
when /^\037\213/n then :gzip
|
|
|
|
when /^BZh/n then :bzip2
|
|
|
|
when /^\037\235/n then :compress
|
|
|
|
when /^.{257}ustar/n then :tar
|
|
|
|
when /^\xFD7zXZ\x00/n then :xz
|
2013-11-29 10:10:28 -08:00
|
|
|
when /^LZIP/n then :lzip
|
2013-04-03 23:30:32 -05:00
|
|
|
when /^Rar!/n then :rar
|
|
|
|
when /^7z\xBC\xAF\x27\x1C/n then :p7zip
|
2014-04-06 12:34:42 -05:00
|
|
|
when /^xar!/n then :xar
|
2012-04-29 11:45:46 -07:00
|
|
|
else
|
2012-08-22 09:33:10 -04:00
|
|
|
# This code so that bad-tarballs and zips produce good error messages
|
|
|
|
# when they don't unarchive properly.
|
|
|
|
case extname
|
2013-04-03 23:30:32 -05:00
|
|
|
when ".tar.gz", ".tgz", ".tar.bz2", ".tbz" then :tar
|
|
|
|
when ".zip" then :zip
|
2012-08-22 09:33:10 -04:00
|
|
|
end
|
2012-04-29 11:45:46 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-05-25 23:44:11 -05:00
|
|
|
def text_executable?
|
2012-09-27 17:03:43 -05:00
|
|
|
%r[^#!\s*\S+] === open('r') { |f| f.read(1024) }
|
2012-05-25 23:44:11 -05:00
|
|
|
end
|
|
|
|
|
2014-06-11 12:05:19 -05:00
|
|
|
def incremental_hash(klass)
|
|
|
|
digest = klass.new
|
|
|
|
if digest.respond_to?(:file)
|
|
|
|
digest.file(self)
|
|
|
|
else
|
|
|
|
buf = ""
|
|
|
|
open("rb") { |f| digest << buf while f.read(1024, buf) }
|
|
|
|
end
|
|
|
|
digest.hexdigest
|
2010-03-27 10:41:24 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def sha1
|
|
|
|
require 'digest/sha1'
|
|
|
|
incremental_hash(Digest::SHA1)
|
|
|
|
end
|
2012-01-22 22:12:39 +01:00
|
|
|
|
2013-10-14 22:05:30 -05:00
|
|
|
def sha256
|
2010-03-27 10:41:24 -05:00
|
|
|
require 'digest/sha2'
|
|
|
|
incremental_hash(Digest::SHA2)
|
2009-12-30 18:56:46 +00:00
|
|
|
end
|
2012-06-18 19:58:35 -05:00
|
|
|
|
|
|
|
def verify_checksum expected
|
|
|
|
raise ChecksumMissingError if expected.nil? or expected.empty?
|
|
|
|
actual = Checksum.new(expected.hash_type, send(expected.hash_type).downcase)
|
2014-02-18 13:27:35 -05:00
|
|
|
raise ChecksumMismatchError.new(self, expected, actual) unless expected == actual
|
2012-06-18 19:58:35 -05:00
|
|
|
end
|
2009-12-30 18:56:46 +00:00
|
|
|
|
2009-09-30 22:17:46 -05:00
|
|
|
if '1.9' <= RUBY_VERSION
|
|
|
|
alias_method :to_str, :to_s
|
|
|
|
end
|
2010-02-27 12:29:45 +00:00
|
|
|
|
|
|
|
def cd
|
|
|
|
Dir.chdir(self){ yield }
|
|
|
|
end
|
|
|
|
|
|
|
|
def subdirs
|
|
|
|
children.select{ |child| child.directory? }
|
|
|
|
end
|
2010-06-14 11:56:27 -07:00
|
|
|
|
2010-07-25 12:07:35 -07:00
|
|
|
def resolved_path
|
|
|
|
self.symlink? ? dirname+readlink : self
|
|
|
|
end
|
|
|
|
|
2010-06-14 11:56:27 -07:00
|
|
|
def resolved_path_exists?
|
2013-07-13 16:38:30 -05:00
|
|
|
link = readlink
|
|
|
|
rescue ArgumentError
|
|
|
|
# The link target contains NUL bytes
|
|
|
|
false
|
|
|
|
else
|
|
|
|
(dirname+link).exist?
|
2010-06-14 11:56:27 -07:00
|
|
|
end
|
2010-08-08 09:13:27 -07:00
|
|
|
|
2014-04-21 09:40:23 -05:00
|
|
|
def make_relative_symlink(src)
|
2014-03-27 18:39:54 -05:00
|
|
|
dirname.mkpath
|
2014-04-21 09:40:23 -05:00
|
|
|
File.symlink(src.relative_path_from(dirname), self)
|
2010-08-15 17:17:26 -07:00
|
|
|
end
|
2010-09-12 21:52:30 +01:00
|
|
|
|
2014-06-11 16:11:53 -05:00
|
|
|
def /(other)
|
|
|
|
unless other.respond_to?(:to_str) || other.respond_to?(:to_path)
|
|
|
|
opoo "Pathname#/ called on #{inspect} with #{other.inspect} as an argument"
|
|
|
|
puts "This behavior is deprecated, please pass either a String or a Pathname"
|
|
|
|
end
|
|
|
|
self + other.to_s
|
2014-05-05 15:30:28 -05:00
|
|
|
end unless method_defined?(:/)
|
2010-05-10 01:10:49 +01:00
|
|
|
|
|
|
|
def ensure_writable
|
2011-06-16 17:38:52 +01:00
|
|
|
saved_perms = nil
|
2012-07-28 11:36:08 -07:00
|
|
|
unless writable_real?
|
2011-06-16 17:38:52 +01:00
|
|
|
saved_perms = stat.mode
|
2010-05-10 01:10:49 +01:00
|
|
|
chmod 0644
|
|
|
|
end
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
chmod saved_perms if saved_perms
|
|
|
|
end
|
2012-01-21 00:51:20 +01:00
|
|
|
|
|
|
|
def install_info
|
2014-04-14 21:32:31 -05:00
|
|
|
quiet_system "/usr/bin/install-info", "--quiet", to_s, "#{dirname}/dir"
|
2012-01-21 00:51:20 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def uninstall_info
|
2014-04-14 21:32:31 -05:00
|
|
|
quiet_system "/usr/bin/install-info", "--delete", "--quiet", to_s, "#{dirname}/dir"
|
2012-01-21 00:51:20 +01:00
|
|
|
end
|
2012-03-02 20:28:54 +00:00
|
|
|
|
2012-03-16 17:24:46 +00:00
|
|
|
def find_formula
|
2014-06-09 14:54:49 -05:00
|
|
|
[join("Formula"), join("HomebrewFormula"), self].each do |d|
|
2012-03-16 21:31:18 +00:00
|
|
|
if d.exist?
|
2014-04-25 18:58:16 -05:00
|
|
|
d.children.each do |pn|
|
|
|
|
yield pn if pn.extname == ".rb"
|
2012-03-16 21:31:18 +00:00
|
|
|
end
|
2012-03-16 17:24:46 +00:00
|
|
|
break
|
2012-03-16 21:31:18 +00:00
|
|
|
end
|
2012-03-16 17:24:46 +00:00
|
|
|
end
|
|
|
|
end
|
2012-08-07 11:16:45 -07:00
|
|
|
|
|
|
|
# Writes an exec script in this folder for each target pathname
|
|
|
|
def write_exec_script *targets
|
2013-06-20 16:18:01 -05:00
|
|
|
targets.flatten!
|
2012-08-07 11:16:45 -07:00
|
|
|
if targets.empty?
|
2013-07-22 10:57:51 -07:00
|
|
|
opoo "tried to write exec scripts to #{self} for an empty list of targets"
|
2013-12-12 08:21:22 -08:00
|
|
|
return
|
2012-08-07 11:16:45 -07:00
|
|
|
end
|
|
|
|
targets.each do |target|
|
|
|
|
target = Pathname.new(target) # allow pathnames or strings
|
|
|
|
(self+target.basename()).write <<-EOS.undent
|
2013-12-12 08:21:22 -08:00
|
|
|
#!/bin/bash
|
|
|
|
exec "#{target}" "$@"
|
2012-08-07 11:16:45 -07:00
|
|
|
EOS
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-01-04 12:49:38 +00:00
|
|
|
# Writes an exec script that sets environment variables
|
|
|
|
def write_env_script target, env
|
|
|
|
env_export = ''
|
|
|
|
env.each {|key, value| env_export += "#{key}=\"#{value}\" "}
|
|
|
|
self.write <<-EOS.undent
|
|
|
|
#!/bin/bash
|
|
|
|
#{env_export}exec "#{target}" "$@"
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
|
|
|
# Writes a wrapper env script and moves all files to the dst
|
|
|
|
def env_script_all_files dst, env
|
|
|
|
dst.mkpath
|
2014-05-31 23:53:46 -05:00
|
|
|
Pathname.glob("#{self}/*") do |file|
|
2014-01-04 12:49:38 +00:00
|
|
|
dst.install_p file
|
|
|
|
new_file = dst+file.basename
|
|
|
|
file.write_env_script(new_file, env)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-08-07 11:16:45 -07:00
|
|
|
# Writes an exec script that invokes a java jar
|
|
|
|
def write_jar_script target_jar, script_name, java_opts=""
|
|
|
|
(self+script_name).write <<-EOS.undent
|
2013-12-12 08:21:22 -08:00
|
|
|
#!/bin/bash
|
|
|
|
exec java #{java_opts} -jar #{target_jar} "$@"
|
2012-08-07 11:16:45 -07:00
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
2014-06-07 17:52:11 -05:00
|
|
|
def install_metafiles from=Pathname.pwd
|
|
|
|
Pathname(from).children.each do |p|
|
2012-11-11 10:45:58 -08:00
|
|
|
next if p.directory?
|
2014-06-07 23:40:26 -05:00
|
|
|
next unless Metafiles.copy?(p.basename.to_s)
|
2012-11-11 10:45:58 -08:00
|
|
|
# Some software symlinks these files (see help2man.rb)
|
|
|
|
filename = p.resolved_path
|
2012-11-12 20:56:05 -08:00
|
|
|
# Some software links metafiles together, so by the time we iterate to one of them
|
|
|
|
# we may have already moved it. libxml2's COPYING and Copyright are affected by this.
|
|
|
|
next unless filename.exist?
|
2012-11-11 10:45:58 -08:00
|
|
|
filename.chmod 0644
|
2014-06-07 17:52:11 -05:00
|
|
|
install(filename)
|
2012-11-11 10:45:58 -08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-12-12 08:22:39 -08:00
|
|
|
def abv
|
|
|
|
out=''
|
|
|
|
n=`find #{to_s} -type f ! -name .DS_Store | wc -l`.to_i
|
|
|
|
out<<"#{n} files, " if n > 1
|
|
|
|
out<<`/usr/bin/du -hs #{to_s} | cut -d"\t" -f1`.strip
|
|
|
|
end
|
|
|
|
|
2013-04-14 22:27:11 -05:00
|
|
|
# We redefine these private methods in order to add the /o modifier to
|
|
|
|
# the Regexp literals, which forces string interpolation to happen only
|
|
|
|
# once instead of each time the method is called. This is fixed in 1.9+.
|
2013-04-14 21:50:57 -05:00
|
|
|
if RUBY_VERSION <= "1.8.7"
|
|
|
|
alias_method :old_chop_basename, :chop_basename
|
|
|
|
def chop_basename(path)
|
|
|
|
base = File.basename(path)
|
|
|
|
if /\A#{Pathname::SEPARATOR_PAT}?\z/o =~ base
|
|
|
|
return nil
|
|
|
|
else
|
|
|
|
return path[0, path.rindex(base)], base
|
|
|
|
end
|
|
|
|
end
|
|
|
|
private :chop_basename
|
2013-04-14 22:27:11 -05:00
|
|
|
|
|
|
|
alias_method :old_prepend_prefix, :prepend_prefix
|
|
|
|
def prepend_prefix(prefix, relpath)
|
|
|
|
if relpath.empty?
|
|
|
|
File.dirname(prefix)
|
|
|
|
elsif /#{SEPARATOR_PAT}/o =~ prefix
|
|
|
|
prefix = File.dirname(prefix)
|
|
|
|
prefix = File.join(prefix, "") if File.basename(prefix + 'a') != 'a'
|
|
|
|
prefix + relpath
|
|
|
|
else
|
|
|
|
prefix + relpath
|
|
|
|
end
|
|
|
|
end
|
|
|
|
private :prepend_prefix
|
2014-06-08 20:00:52 -05:00
|
|
|
elsif RUBY_VERSION == "2.0.0"
|
|
|
|
# https://bugs.ruby-lang.org/issues/9915
|
|
|
|
prepend Module.new {
|
|
|
|
def inspect
|
2014-06-08 20:04:16 -05:00
|
|
|
super.force_encoding(@path.encoding)
|
2014-06-08 20:00:52 -05:00
|
|
|
end
|
|
|
|
}
|
2013-04-14 21:50:57 -05:00
|
|
|
end
|
2009-07-31 02:51:17 +01:00
|
|
|
end
|
2009-08-10 16:48:30 +01:00
|
|
|
|
|
|
|
module ObserverPathnameExtension
|
2013-08-09 21:09:48 -05:00
|
|
|
class << self
|
|
|
|
attr_accessor :n, :d
|
|
|
|
|
|
|
|
def reset_counts!
|
|
|
|
@n = @d = 0
|
|
|
|
end
|
|
|
|
|
|
|
|
def total
|
|
|
|
n + d
|
|
|
|
end
|
|
|
|
|
|
|
|
def counts
|
|
|
|
[n, d]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
def unlink
|
|
|
|
super
|
|
|
|
puts "rm #{to_s}" if ARGV.verbose?
|
2013-08-09 21:09:48 -05:00
|
|
|
ObserverPathnameExtension.n += 1
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
|
|
|
def rmdir
|
|
|
|
super
|
|
|
|
puts "rmdir #{to_s}" if ARGV.verbose?
|
2013-08-09 21:09:48 -05:00
|
|
|
ObserverPathnameExtension.d += 1
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
|
|
|
def make_relative_symlink src
|
2010-08-15 17:17:26 -07:00
|
|
|
super
|
2014-04-21 09:40:23 -05:00
|
|
|
puts "ln -s #{src.relative_path_from(dirname)} #{basename}" if ARGV.verbose?
|
2013-08-09 21:09:48 -05:00
|
|
|
ObserverPathnameExtension.n += 1
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
2012-01-21 00:51:20 +01:00
|
|
|
def install_info
|
|
|
|
super
|
|
|
|
puts "info #{to_s}" if ARGV.verbose?
|
|
|
|
end
|
|
|
|
def uninstall_info
|
|
|
|
super
|
|
|
|
puts "uninfo #{to_s}" if ARGV.verbose?
|
|
|
|
end
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|