2009-07-31 02:51:17 +01:00
|
|
|
require 'pathname'
|
2012-03-07 21:30:03 -05:00
|
|
|
require 'bottles'
|
2009-07-31 02:51:17 +01:00
|
|
|
|
|
|
|
# we enhance pathname to make our code more readable
|
|
|
|
class Pathname
|
2012-02-09 18:43:47 -08:00
|
|
|
def install *sources
|
2012-02-17 23:07:16 -08:00
|
|
|
results = []
|
2012-02-09 18:43:47 -08:00
|
|
|
sources.each do |src|
|
|
|
|
case src
|
|
|
|
when Array
|
2012-02-17 23:07:16 -08:00
|
|
|
src.each {|s| results << install_p(s) }
|
2012-02-09 18:43:47 -08:00
|
|
|
when Hash
|
2012-02-17 23:07:16 -08:00
|
|
|
src.each {|s, new_basename| results << install_p(s, new_basename) }
|
2012-02-09 18:43:47 -08:00
|
|
|
else
|
2012-02-17 23:07:16 -08:00
|
|
|
results << install_p(src)
|
2012-02-09 18:43:47 -08:00
|
|
|
end
|
2009-07-31 02:51:17 +01:00
|
|
|
end
|
2012-02-17 23:07:16 -08:00
|
|
|
return results
|
2009-07-31 02:51:17 +01:00
|
|
|
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
|
2012-02-08 21:58:46 -08:00
|
|
|
return_value = Pathname.new(dst)
|
2010-02-19 13:13:42 +00:00
|
|
|
else
|
|
|
|
dst = self
|
2010-03-08 23:42:01 -08:00
|
|
|
return_value = self+File.basename(src)
|
2010-02-19 13:13:42 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2010-03-08 23:42:01 -08:00
|
|
|
return return_value
|
2010-02-19 13:13:42 +00:00
|
|
|
end
|
|
|
|
|
2012-02-12 10:36:16 -08:00
|
|
|
# Creates symlinks to sources in this folder.
|
|
|
|
def install_symlink *sources
|
2012-02-17 23:07:16 -08:00
|
|
|
results = []
|
2012-02-12 10:36:16 -08:00
|
|
|
sources.each do |src|
|
|
|
|
case src
|
|
|
|
when Array
|
2012-02-17 23:07:16 -08:00
|
|
|
src.each {|s| results << install_symlink_p(s) }
|
2012-02-12 10:36:16 -08:00
|
|
|
when Hash
|
2012-02-17 23:07:16 -08:00
|
|
|
src.each {|s, new_basename| results << install_symlink_p(s, new_basename) }
|
2012-02-12 10:36:16 -08:00
|
|
|
else
|
2012-02-17 23:07:16 -08:00
|
|
|
results << install_symlink_p(src)
|
2012-02-12 10:36:16 -08:00
|
|
|
end
|
|
|
|
end
|
2012-02-17 23:07:16 -08:00
|
|
|
return results
|
2012-02-12 10:36:16 -08:00
|
|
|
end
|
|
|
|
|
|
|
|
def install_symlink_p src, new_basename = nil
|
|
|
|
if new_basename.nil?
|
|
|
|
dst = self+File.basename(src)
|
|
|
|
else
|
|
|
|
dst = self+File.basename(new_basename)
|
|
|
|
end
|
|
|
|
|
|
|
|
src = src.to_s
|
|
|
|
dst = dst.to_s
|
|
|
|
|
|
|
|
mkpath
|
|
|
|
FileUtils.ln_s src, dst
|
|
|
|
|
|
|
|
return dst
|
|
|
|
end
|
|
|
|
|
2009-08-31 22:34:42 -06:00
|
|
|
# we assume this pathname object is a file obviously
|
|
|
|
def write content
|
2009-09-02 14:31:28 +01:00
|
|
|
raise "Will not overwrite #{to_s}" if exist? and not ARGV.force?
|
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
|
|
|
|
require 'tempfile'
|
|
|
|
tf = Tempfile.new(self.basename.to_s)
|
|
|
|
tf.write(content)
|
|
|
|
tf.close
|
|
|
|
FileUtils.mv tf.path, self.to_s
|
|
|
|
end
|
|
|
|
|
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
|
|
|
|
|
2012-01-12 20:08:35 -06:00
|
|
|
# extended to support common double extensions
|
2009-07-31 02:51:17 +01:00
|
|
|
def extname
|
2012-03-07 21:30:03 -05:00
|
|
|
return $1 if to_s =~ bottle_regex
|
2012-03-07 20:44:19 -05:00
|
|
|
# old brew bottle style
|
2012-03-07 21:30:03 -05:00
|
|
|
return $1 if to_s =~ old_bottle_regex
|
2012-02-08 21:08:18 -08:00
|
|
|
/(\.(tar|cpio)\.(gz|bz2|xz|Z))$/.match to_s
|
2009-07-31 02:51:17 +01:00
|
|
|
return $1 if $1
|
|
|
|
return File.extname(to_s)
|
|
|
|
end
|
|
|
|
|
|
|
|
# for filetypes we support, basename without extension
|
|
|
|
def stem
|
|
|
|
return File.basename(to_s, extname)
|
|
|
|
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
|
2009-08-10 16:48:30 +01:00
|
|
|
rescue SystemCallError => e
|
2009-08-11 00:27:43 +01:00
|
|
|
raise unless e.errno == Errno::ENOTEMPTY::Errno or e.errno == Errno::EACCES::Errno
|
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
|
|
|
|
|
|
|
|
def abv
|
2009-09-02 14:31:28 +01:00
|
|
|
out=''
|
2010-09-02 11:47:18 -04:00
|
|
|
n=`find #{to_s} -type f ! -name .DS_Store | wc -l`.to_i
|
2009-09-02 14:31:28 +01:00
|
|
|
out<<"#{n} files, " if n > 1
|
2010-01-03 02:59:16 +00:00
|
|
|
out<<`/usr/bin/du -hd0 #{to_s} | cut -d"\t" -f1`.strip
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
|
|
|
|
2009-09-11 12:51:36 +01:00
|
|
|
# attempts to retrieve the version component of this path, so generally
|
|
|
|
# you'll call it on tarballs or extracted tarball directories, if you add
|
|
|
|
# to this please provide amend the unittest
|
2009-07-31 02:51:17 +01:00
|
|
|
def version
|
2009-08-12 13:43:20 +01:00
|
|
|
if directory?
|
|
|
|
# directories don't have extnames
|
|
|
|
stem=basename.to_s
|
|
|
|
else
|
2011-01-09 22:41:03 -05:00
|
|
|
# sourceforge /download
|
|
|
|
if %r[((?:sourceforge.net|sf.net)/.*)/download$].match to_s
|
|
|
|
stem=Pathname.new(dirname).stem
|
|
|
|
else
|
|
|
|
stem=self.stem
|
|
|
|
end
|
2009-08-12 13:43:20 +01:00
|
|
|
end
|
|
|
|
|
2010-11-07 11:25:20 -08:00
|
|
|
# github tarballs, like v1.2.3
|
2012-03-11 14:37:44 -07:00
|
|
|
%r[github.com/.*/(zip|tar)ball/v?((\d+\.)+\d+)$].match to_s
|
2011-06-04 17:29:21 -07:00
|
|
|
return $2 if $2
|
2009-09-11 12:51:36 +01:00
|
|
|
|
2012-01-14 03:46:25 +00:00
|
|
|
# eg. https://github.com/sam-github/libnet/tarball/libnet-1.1.4
|
2012-03-11 14:37:44 -07:00
|
|
|
%r[github.com/.*/(zip|tar)ball/.*-((\d+\.)+\d+)$].match to_s
|
2012-01-14 03:46:25 +00:00
|
|
|
return $2 if $2
|
|
|
|
|
2010-11-07 11:25:20 -08:00
|
|
|
# dashed version
|
2010-10-26 23:32:33 -07:00
|
|
|
# eg. github.com/isaacs/npm/tarball/v0.2.5-1
|
2012-03-11 14:37:44 -07:00
|
|
|
%r[github.com/.*/(zip|tar)ball/v?((\d+\.)+\d+-(\d+))$].match to_s
|
2011-06-04 17:29:21 -07:00
|
|
|
return $2 if $2
|
2010-10-26 23:32:33 -07:00
|
|
|
|
2010-11-07 11:25:20 -08:00
|
|
|
# underscore version
|
|
|
|
# eg. github.com/petdance/ack/tarball/1.93_02
|
2012-03-11 14:37:44 -07:00
|
|
|
%r[github.com/.*/(zip|tar)ball/v?((\d+\.)+\d+_(\d+))$].match to_s
|
2011-06-04 17:29:21 -07:00
|
|
|
return $2 if $2
|
2010-11-07 11:25:20 -08:00
|
|
|
|
2009-07-31 02:51:17 +01:00
|
|
|
# eg. boost_1_39_0
|
|
|
|
/((\d+_)+\d+)$/.match stem
|
|
|
|
return $1.gsub('_', '.') if $1
|
|
|
|
|
|
|
|
# eg. foobar-4.5.1-1
|
2009-08-30 15:49:38 +01:00
|
|
|
# eg. ruby-1.9.1-p243
|
2010-07-04 14:01:48 -07:00
|
|
|
/-((\d+\.)*\d\.\d+-(p|rc|RC)?\d+)$/.match stem
|
2009-07-31 02:51:17 +01:00
|
|
|
return $1 if $1
|
2012-01-22 22:12:39 +01:00
|
|
|
|
2009-09-11 12:51:36 +01:00
|
|
|
# eg. lame-398-1
|
|
|
|
/-((\d)+-\d)/.match stem
|
|
|
|
return $1 if $1
|
2009-07-31 02:51:17 +01:00
|
|
|
|
|
|
|
# eg. foobar-4.5.1
|
|
|
|
/-((\d+\.)*\d+)$/.match stem
|
|
|
|
return $1 if $1
|
|
|
|
|
|
|
|
# eg. foobar-4.5.1b
|
2010-07-04 14:01:48 -07:00
|
|
|
/-((\d+\.)*\d+([abc]|rc|RC)\d*)$/.match stem
|
2009-07-31 02:51:17 +01:00
|
|
|
return $1 if $1
|
|
|
|
|
2010-08-27 08:42:50 +02:00
|
|
|
# eg foobar-4.5.0-beta1, or foobar-4.50-beta
|
|
|
|
/-((\d+\.)*\d+-beta(\d+)?)$/.match stem
|
2009-07-31 02:51:17 +01:00
|
|
|
return $1 if $1
|
|
|
|
|
|
|
|
# eg. foobar4.5.1
|
|
|
|
/((\d+\.)*\d+)$/.match stem
|
|
|
|
return $1 if $1
|
2009-09-23 07:56:07 -07:00
|
|
|
|
2009-09-06 00:43:00 -04:00
|
|
|
# eg foobar-4.5.0-bin
|
2012-02-11 15:33:30 -08:00
|
|
|
/-((\d+\.)+\d+[abc]?)[-._](bin|dist|stable|src|sources?)$/.match stem
|
2009-09-06 00:43:00 -04:00
|
|
|
return $1 if $1
|
2009-09-23 07:56:07 -07:00
|
|
|
|
2010-07-06 13:12:29 -07:00
|
|
|
# Debian style eg dash_0.5.5.1.orig.tar.gz
|
|
|
|
/_((\d+\.)+\d+[abc]?)[.]orig$/.match stem
|
|
|
|
return $1 if $1
|
|
|
|
|
2009-07-31 02:51:17 +01:00
|
|
|
# eg. otp_src_R13B (this is erlang's style)
|
|
|
|
# eg. astyle_1.23_macosx.tar.gz
|
2010-10-25 21:12:41 -07:00
|
|
|
stem.scan(/_([^_]+)/) do |match|
|
2009-07-31 02:51:17 +01:00
|
|
|
return match.first if /\d/.match $1
|
|
|
|
end
|
2009-08-22 15:53:35 +01:00
|
|
|
|
2012-03-07 20:44:19 -05:00
|
|
|
# old erlang bottle style e.g. erlang-R14B03-bottle.tar.gz
|
|
|
|
/-([^-]+)/.match stem
|
2011-08-30 15:58:27 +02:00
|
|
|
return $1 if $1
|
|
|
|
|
2009-08-22 15:53:35 +01:00
|
|
|
nil
|
2009-07-31 02:51:17 +01:00
|
|
|
end
|
2012-01-22 22:12:39 +01:00
|
|
|
|
2010-03-27 10:41:24 -05:00
|
|
|
def incremental_hash(hasher)
|
|
|
|
incr_hash = hasher.new
|
2010-03-23 19:56:20 -05:00
|
|
|
self.open('r') do |f|
|
2010-03-27 10:41:24 -05:00
|
|
|
while(buf = f.read(1024))
|
|
|
|
incr_hash << buf
|
2010-03-23 19:56:20 -05:00
|
|
|
end
|
|
|
|
end
|
2010-03-27 10:41:24 -05:00
|
|
|
incr_hash.hexdigest
|
|
|
|
end
|
|
|
|
|
|
|
|
def md5
|
|
|
|
require 'digest/md5'
|
|
|
|
incremental_hash(Digest::MD5)
|
|
|
|
end
|
2012-01-22 22:12:39 +01:00
|
|
|
|
2010-03-27 10:41:24 -05:00
|
|
|
def sha1
|
|
|
|
require 'digest/sha1'
|
|
|
|
incremental_hash(Digest::SHA1)
|
|
|
|
end
|
2012-01-22 22:12:39 +01:00
|
|
|
|
2010-03-27 10:41:24 -05:00
|
|
|
def sha2
|
|
|
|
require 'digest/sha2'
|
|
|
|
incremental_hash(Digest::SHA2)
|
2009-12-30 18:56:46 +00:00
|
|
|
end
|
|
|
|
|
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?
|
|
|
|
(dirname+readlink).exist?
|
|
|
|
end
|
2010-08-08 09:13:27 -07:00
|
|
|
|
2010-09-12 21:52:30 +01:00
|
|
|
# perhaps confusingly, this Pathname object becomes the symlink pointing to
|
|
|
|
# the src paramter.
|
2010-08-15 17:17:26 -07:00
|
|
|
def make_relative_symlink src
|
2012-02-21 12:45:45 +00:00
|
|
|
src = Pathname.new(src) unless src.kind_of? Pathname
|
|
|
|
|
2010-08-15 17:17:26 -07:00
|
|
|
self.dirname.mkpath
|
|
|
|
Dir.chdir self.dirname do
|
2012-03-06 13:02:10 +00:00
|
|
|
# NOTE only system ln -s will create RELATIVE symlinks
|
|
|
|
system 'ln', '-s', src.relative_path_from(self.dirname), self.basename
|
|
|
|
# ln outputs useful error message for us
|
|
|
|
raise "Could not create symlink: #{to_s}." unless $?.success?
|
2010-08-15 17:17:26 -07:00
|
|
|
end
|
|
|
|
end
|
2010-09-12 21:52:30 +01:00
|
|
|
|
|
|
|
def / that
|
|
|
|
join that.to_s
|
|
|
|
end
|
2010-05-10 01:10:49 +01:00
|
|
|
|
|
|
|
def ensure_writable
|
2011-06-16 17:38:52 +01:00
|
|
|
saved_perms = nil
|
|
|
|
unless writable?
|
|
|
|
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
|
|
|
|
unless self.symlink?
|
|
|
|
raise "Cannot install info entry for unbrewed info file '#{self}'"
|
|
|
|
end
|
2012-02-10 13:02:47 -06:00
|
|
|
system '/usr/bin/install-info', '--quiet', self.to_s, (self.dirname+'dir').to_s
|
2012-01-21 00:51:20 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def uninstall_info
|
|
|
|
unless self.symlink?
|
|
|
|
raise "Cannot uninstall info entry for unbrewed info file '#{self}'"
|
|
|
|
end
|
|
|
|
system '/usr/bin/install-info', '--delete', '--quiet', self.to_s, (self.dirname+'dir').to_s
|
|
|
|
end
|
2012-03-02 20:28:54 +00:00
|
|
|
|
2012-03-16 17:24:46 +00:00
|
|
|
def all_formula pwd = self
|
2012-03-02 20:28:54 +00:00
|
|
|
children.map{ |child| child.relative_path_from(pwd) }.each do |pn|
|
|
|
|
yield pn if pn.to_s =~ /.rb$/
|
|
|
|
end
|
|
|
|
children.each do |child|
|
2012-03-16 17:24:46 +00:00
|
|
|
child.all_formula(pwd) do |pn|
|
2012-03-02 20:28:54 +00:00
|
|
|
yield pn
|
|
|
|
end if child.directory?
|
|
|
|
end
|
|
|
|
end
|
2012-03-16 17:24:46 +00:00
|
|
|
|
|
|
|
def find_formula
|
|
|
|
# remove special casing once tap is established and alt removed
|
|
|
|
if self == HOMEBREW_LIBRARY/"Taps/adamv-alt"
|
|
|
|
all_formula do |file|
|
|
|
|
yield file
|
|
|
|
end
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
[self/:Formula, self/:HomebrewFormula, self].each do |d|
|
2012-03-16 21:31:18 +00:00
|
|
|
if d.exist?
|
|
|
|
d.children.map{ |child| child.relative_path_from(self) }.each do |pn|
|
|
|
|
yield pn if pn.to_s =~ /.rb$/
|
|
|
|
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
|
2009-07-31 02:51:17 +01:00
|
|
|
end
|
2009-08-10 16:48:30 +01:00
|
|
|
|
|
|
|
# sets $n and $d so you can observe creation of stuff
|
|
|
|
module ObserverPathnameExtension
|
|
|
|
def unlink
|
|
|
|
super
|
|
|
|
puts "rm #{to_s}" if ARGV.verbose?
|
|
|
|
$n+=1
|
|
|
|
end
|
|
|
|
def rmdir
|
|
|
|
super
|
|
|
|
puts "rmdir #{to_s}" if ARGV.verbose?
|
|
|
|
$d+=1
|
|
|
|
end
|
|
|
|
def mkpath
|
|
|
|
super
|
|
|
|
puts "mkpath #{to_s}" if ARGV.verbose?
|
|
|
|
$d+=1
|
|
|
|
end
|
|
|
|
def make_relative_symlink src
|
2010-08-15 17:17:26 -07:00
|
|
|
super
|
|
|
|
puts "ln #{to_s}" if ARGV.verbose?
|
|
|
|
$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
|
|
|
|
|
|
|
|
$n=0
|
|
|
|
$d=0
|