| 
									
										
										
										
											2009-07-31 02:51:17 +01:00
										 |  |  | require 'pathname' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # we enhance pathname to make our code more readable | 
					
						
							|  |  |  | class Pathname | 
					
						
							|  |  |  |   def install src | 
					
						
							| 
									
										
										
										
											2010-02-19 13:13:42 +00:00
										 |  |  |     case src | 
					
						
							|  |  |  |     when Array | 
					
						
							|  |  |  |       src.collect {|src| install_p(src) } | 
					
						
							|  |  |  |     when Hash | 
					
						
							|  |  |  |       src.collect {|src, new_basename| install_p(src, new_basename) } | 
					
						
							| 
									
										
										
										
											2009-08-21 18:26:50 +01:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2010-02-19 13:13:42 +00:00
										 |  |  |       install_p(src) | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2010-03-08 23:42:01 -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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  |   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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # extended to support the double extensions .tar.gz and .tar.bz2 | 
					
						
							|  |  |  |   def extname | 
					
						
							|  |  |  |     /(\.tar\.(gz|bz2))$/.match to_s | 
					
						
							|  |  |  |     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 | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   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 | 
					
						
							| 
									
										
										
										
											2011-06-04 17:29:21 -07:00
										 |  |  |     %r[github.com/.*/(zip|tar)ball/v?((\d\.)+\d+)$].match to_s | 
					
						
							|  |  |  |     return $2 if $2 | 
					
						
							| 
									
										
										
										
											2009-09-11 12:51:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2011-06-04 17:29:21 -07:00
										 |  |  |     %r[github.com/.*/(zip|tar)ball/v?((\d\.)+\d+-(\d+))$].match to_s | 
					
						
							|  |  |  |     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 | 
					
						
							| 
									
										
										
										
											2011-06-04 17:29:21 -07:00
										 |  |  |     %r[github.com/.*/(zip|tar)ball/v?((\d\.)+\d+_(\d+))$].match to_s | 
					
						
							|  |  |  |     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 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2011-06-16 06:47:13 -07:00
										 |  |  |     /-((\d+\.)+\d+[abc]?)[-._](bin|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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-21 19:23:56 +01:00
										 |  |  |     # brew bottle style e.g. qt-4.7.3-bottle.tar.gz | 
					
						
							| 
									
										
										
										
											2011-06-21 18:40:07 +01:00
										 |  |  |     /-((\d+\.)*\d+)-bottle$/.match stem | 
					
						
							| 
									
										
										
										
											2011-06-21 19:23:56 +01:00
										 |  |  |     return $1 if $1 | 
					
						
							| 
									
										
										
										
											2011-06-21 18:40:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  |     nil | 
					
						
							| 
									
										
										
										
											2009-07-31 02:51:17 +01:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   def sha1 | 
					
						
							|  |  |  |     require 'digest/sha1' | 
					
						
							|  |  |  |     incremental_hash(Digest::SHA1) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   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 | 
					
						
							|  |  |  |     self.dirname.mkpath | 
					
						
							|  |  |  |     Dir.chdir self.dirname do | 
					
						
							|  |  |  |       # TODO use Ruby function so we get exceptions | 
					
						
							|  |  |  |       # NOTE Ruby functions may work, but I had a lot of problems | 
					
						
							| 
									
										
										
										
											2011-06-16 15:08:27 +01:00
										 |  |  |       rv = system 'ln', '-sf', src.relative_path_from(self.dirname), self.basename | 
					
						
							| 
									
										
										
										
											2010-08-15 17:17:26 -07:00
										 |  |  |       unless rv and $? == 0
 | 
					
						
							| 
									
										
										
										
											2010-09-12 21:52:30 +01:00
										 |  |  |         raise <<-EOS.undent
 | 
					
						
							|  |  |  |           Could not create symlink #{to_s}. | 
					
						
							|  |  |  |           Check that you have permssions on #{self.dirname} | 
					
						
							|  |  |  |           EOS | 
					
						
							| 
									
										
										
										
											2010-08-15 17:17:26 -07:00
										 |  |  |       end | 
					
						
							|  |  |  |     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 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $n=0
 | 
					
						
							|  |  |  | $d=0
 |