summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Graaff <graaff@gentoo.org>2012-01-06 07:35:54 +0000
committerHans de Graaff <graaff@gentoo.org>2012-01-06 07:35:54 +0000
commit55ebbe4a2012cb14c2a1acb2d4cce89b3e288dd8 (patch)
tree0167e724e7a61f386a19d33301f550948b10c6ee /dev-ruby/fakefs
parentFix another glib-2.31 linking problem (bug #395777 comment 5, thanks to Alpha... (diff)
downloadhistorical-55ebbe4a2012cb14c2a1acb2d4cce89b3e288dd8.tar.gz
historical-55ebbe4a2012cb14c2a1acb2d4cce89b3e288dd8.tar.bz2
historical-55ebbe4a2012cb14c2a1acb2d4cce89b3e288dd8.zip
Add a host of patches from upstream's tracker for Ruby 1.9.3.
Package-Manager: portage-2.1.10.41/cvs/Linux x86_64
Diffstat (limited to 'dev-ruby/fakefs')
-rw-r--r--dev-ruby/fakefs/ChangeLog13
-rw-r--r--dev-ruby/fakefs/Manifest26
-rw-r--r--dev-ruby/fakefs/fakefs-0.4.0-r1.ebuild39
-rw-r--r--dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-advise.patch42
-rw-r--r--dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-pathname.patch57
-rw-r--r--dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-ruby-pathname.patch880
-rw-r--r--dev-ruby/fakefs/files/fakefs-0.4.0-ruby193.patch195
7 files changed, 1235 insertions, 17 deletions
diff --git a/dev-ruby/fakefs/ChangeLog b/dev-ruby/fakefs/ChangeLog
index 4c6f561bfcd5..0fb508ce4510 100644
--- a/dev-ruby/fakefs/ChangeLog
+++ b/dev-ruby/fakefs/ChangeLog
@@ -1,6 +1,15 @@
# ChangeLog for dev-ruby/fakefs
-# Copyright 1999-2011 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/dev-ruby/fakefs/ChangeLog,v 1.21 2011/12/05 13:04:28 naota Exp $
+# Copyright 1999-2012 Gentoo Foundation; Distributed under the GPL v2
+# $Header: /var/cvsroot/gentoo-x86/dev-ruby/fakefs/ChangeLog,v 1.22 2012/01/06 07:35:54 graaff Exp $
+
+*fakefs-0.4.0-r1 (06 Jan 2012)
+
+ 06 Jan 2012; Hans de Graaff <graaff@gentoo.org> +fakefs-0.4.0-r1.ebuild,
+ +files/fakefs-0.4.0-ruby193-advise.patch,
+ +files/fakefs-0.4.0-ruby193-pathname.patch,
+ +files/fakefs-0.4.0-ruby193-ruby-pathname.patch,
+ +files/fakefs-0.4.0-ruby193.patch:
+ Add a host of patches from upstream's tracker for Ruby 1.9.3.
05 Dec 2011; Naohiro Aota <naota@gentoo.org> fakefs-0.2.1-r1.ebuild:
Add ~x86-fbsd.
diff --git a/dev-ruby/fakefs/Manifest b/dev-ruby/fakefs/Manifest
index d45baaa559b2..4afd56d5d356 100644
--- a/dev-ruby/fakefs/Manifest
+++ b/dev-ruby/fakefs/Manifest
@@ -2,25 +2,21 @@
Hash: SHA256
AUX fakefs-0.2.1-ruby19.patch 707 RMD160 f0bf05202c07e6b1170904a9effd5fe8143db198 SHA1 eceae253cf102fb5ee011c3048156c8dc6a4c2a6 SHA256 1c63a39d47c862a3a925efd848330898d33572b128355ded235b9e6c16691211
+AUX fakefs-0.4.0-ruby193-advise.patch 1023 RMD160 d90b1234b91d0ee9434c2e58fed2ca82a5fc49fc SHA1 514f580f2654056146593037cb45d3ee3cc1306f SHA256 c84b2a675e269f2f4bc562357d7ef8ab4d6be0350b1fb6ba35af8dbcc3ace5d5
+AUX fakefs-0.4.0-ruby193-pathname.patch 1751 RMD160 6a4220275af41dfe4ded24610d00f081ba1b6d31 SHA1 961e7a526438fd42fceefaeb3d3f00e3f9c70782 SHA256 5d3dc1233d3d296c8e89ff8aa933749284f5b641cd550a86a5e02b36c3ab7f98
+AUX fakefs-0.4.0-ruby193-ruby-pathname.patch 28924 RMD160 7e40775d98a49ab912722aef08c89394a012ea80 SHA1 720ee16279561d4325ef26b01121218e66dce415 SHA256 f97576b29908be04ef27c7f5e29a5575205fabc19d77bfd91070908c18c3e49e
+AUX fakefs-0.4.0-ruby193.patch 6364 RMD160 03b26e6336bba9412af2ff3cc62ca9b605cce147 SHA1 320f4296320002d23e39730763199b7e6a8135ca SHA256 bc365513d05b7b4be5232adabffad5cbd4ff10e7fd2c342594969d63f2740e89
DIST fakefs-0.2.1.gem 17408 RMD160 0d15c94d7d5864ad72abbcc5509f3eb720de2974 SHA1 7181b2dfaa1b81149ec59cf065577a31d16f7b8e SHA256 1acb4fb80abee462b4c58679bf8d528a9094f79a81ece4c91e7647d6e853517f
+DIST fakefs-0.4.0.gem 24064 RMD160 a58f0fb1f963c47fd318611c64afe996e7c4a7a1 SHA1 2a1a34ec200650b1cdfa04778f251c967248138c SHA256 d5e26fc81facfdcdb5b31732358c6b3d86c8b53c91e2359b9d5b1cc68665b00a
EBUILD fakefs-0.2.1-r1.ebuild 824 RMD160 8d4a746294f5069096ffd6549771f9ef7755e10e SHA1 942cec74a60859c3c69c0ac2c4849f38ee85ed3b SHA256 d6381365fbc975e63b2d8bbee700168d2db6cd9a18fc44b05baf62ec5123011a
EBUILD fakefs-0.2.1.ebuild 713 RMD160 d39f556881de25441b0d1d6fb3dd53888e91a297 SHA1 75dc0e3c4c5ea4dc557c8f14da35e6f1ba3a9dd7 SHA256 f282dde87205847b92def2b4e274ee7554a54740e09ae684af694d74259bddaf
-MISC ChangeLog 2627 RMD160 b7d3dceecdcc981a2e41a50470f4c990bec8ce57 SHA1 e267fdce612a4c5a954e1582da3e9a94b7d7a635 SHA256 b40b284a2a14afdebf11b5a18a5fc5f2373b51105b2ad66eef41fa824d972ed6
+EBUILD fakefs-0.4.0-r1.ebuild 1101 RMD160 4bb76ddbdf8ced6fc170244d412726d3fc1cfcbd SHA1 316f45d9c67b9dc9619bd795ae2965bef1bb907f SHA256 b3140eb0b942a4dd627690f8fcdcf5b616494555e0799fabf0e647c2ffc903e6
+MISC ChangeLog 2978 RMD160 413775797d1c09313c52aabe7593be01bc081b56 SHA1 ebb10d439188782e09b2451fd33fcf98ac315006 SHA256 b85e8588df3d8393b48483111466c1e1afc8b59be1ea2ee35677254f51de4643
MISC metadata.xml 157 RMD160 5d9e2c7ecba96ffebd936d38acedf859cdea84e1 SHA1 8ce15dcc608eeb5616aeec610dc695cbe6f93e02 SHA256 11fba03a217e2d996f5cd8895493a5692ece8ddac2c1a2dfc71d0e830555121c
-----BEGIN PGP SIGNATURE-----
-Version: GnuPG v2.0.18 (GNU/Linux)
+Version: GnuPG v2.0.17 (GNU/Linux)
-iQIcBAEBCAAGBQJO3MFcAAoJEDYO1FT4VRUUYJcP/3JjMlvbTIiOddrJ14Z6DVMz
-T2bRmYHBIrlsCvaI1oMeltS3SpF8KWOmr+A+eQ0EGQPytEOpkxVskrt6PZZMY0uv
-p2XfE5qklmgfozSNyCGmga9JAiscm/j4eUfRCHKE1BWYf70tujjZv/XLsYdAvQnx
-MjybpemJ4xYL/UZV5UGr9yO0ZTigmgXu4X+ndgiBWdikyVYLDDfCDtB2zU4qfjoS
-RPtGW6p0L1G9EJwaxFRNTz+6EaHl66EHOANZktcpRN8ttjmslSuWQeP+E/Qdn5mN
-C5m/bG5ewJhpp2Q3RfZs9P0YHT7eBRwdWuZZB8JZ1pS7GOxBwSHxBhgAdrBkd3UN
-e6tPpqw9urg3MmmS4Zzko14g9d/g7i+56XbarLJF9tliX1VC2unZou2bg6B4ZfjT
-JtzweMZDE3bTzVLX2ZBCQ6nGH1GjoXFLjgRSkWdI4nRGfMGyBtDIVDv3JPs3muJq
-+Z5LpdWG52D/Xfsx87pVuOEPe8wyx/dWgfJ5ZaGa8N1TYUpsH/GRqyk1/GW5mHIm
-wlbB1GCtEGhdZe4Ho4BLhflXcliaGtBrIgsCXs3dU/FRUPFz9t7HglX0yfOBLfqR
-3K1wx8b9fo9PgJOkPmiZPz5TQVLEFfYfri3HNAJBgbnriG2rGGHn4/KNKUCZ1W4N
-2sPQakxY5r6Jnqi3igt/
-=nQ0E
+iF4EAREIAAYFAk8GpGUACgkQiIP6VqMIqNcnWAD8C4yw7xc8Nnlir8CX/rVoiWWR
+XXfR8RgdMc8m3evDNhIA/2chm+QgOHZdxGbQ6zWUC3V1Kfy4Z/2fsKr4/I/4MrD4
+=/f2C
-----END PGP SIGNATURE-----
diff --git a/dev-ruby/fakefs/fakefs-0.4.0-r1.ebuild b/dev-ruby/fakefs/fakefs-0.4.0-r1.ebuild
new file mode 100644
index 000000000000..303f3627eb68
--- /dev/null
+++ b/dev-ruby/fakefs/fakefs-0.4.0-r1.ebuild
@@ -0,0 +1,39 @@
+# Copyright 1999-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/dev-ruby/fakefs/fakefs-0.4.0-r1.ebuild,v 1.1 2012/01/06 07:35:54 graaff Exp $
+
+EAPI=2
+
+# jruby → Marshal/DeMarshal to clone directories fail; tests fail in
+# release 0.2.1
+USE_RUBY="ruby18 ree18 ruby19"
+
+RUBY_FAKEGEM_TASK_TEST="test spec"
+
+# requires sdoc
+RUBY_FAKEGEM_TASK_DOC=""
+
+RUBY_FAKEGEM_EXTRADOC="CONTRIBUTORS README.markdown"
+
+inherit ruby-fakegem eutils
+
+DESCRIPTION="A fake filesystem. Use it in your tests."
+HOMEPAGE="http://github.com/defunkt/fakefs"
+
+LICENSE="as-is" # truly
+SLOT="0"
+KEYWORDS="~amd64 ~hppa ~ia64 ~ppc ~ppc64 ~sparc ~x86 ~x86-fbsd ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~x64-solaris ~x86-solaris"
+IUSE=""
+
+ruby_add_bdepend "test? ( dev-ruby/rspec:2 )"
+
+all_ruby_prepare() {
+ # Remove bundler
+ rm Gemfile || die
+
+ epatch "${FILESDIR}/${P}-ruby193.patch"
+ epatch "${FILESDIR}/${P}-ruby193-advise.patch"
+ epatch "${FILESDIR}/${P}-ruby193-pathname.patch"
+ epatch "${FILESDIR}/${P}-ruby193-ruby-pathname.patch"
+
+}
diff --git a/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-advise.patch b/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-advise.patch
new file mode 100644
index 000000000000..a69100292b38
--- /dev/null
+++ b/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-advise.patch
@@ -0,0 +1,42 @@
+commit 332735b52720466ca8eb9e089cc42f128d54b644
+Author: Lukas Oberhuber <lukaso@gmail.com>
+Date: Tue Dec 20 09:19:05 2011 +0000
+
+ Add advise function to File which is in ruby 1.9.3. As it is only a hint to the
+ os in some cases, the function does nothing.
+
+diff --git a/lib/fakefs/file.rb b/lib/fakefs/file.rb
+index 5684ede..ebc3ff8 100644
+--- a/lib/fakefs/file.rb
++++ b/lib/fakefs/file.rb
+@@ -392,6 +392,11 @@ module FakeFS
+ end
+ end
+
++ if RUBY_VERSION >= "1.9.3"
++ def advise(advice, offset=0, len=0)
++ end
++ end
++
+ private
+
+ def check_modes!
+diff --git a/test/fakefs_test.rb b/test/fakefs_test.rb
+index 0f34950..1d5bf7a 100644
+--- a/test/fakefs_test.rb
++++ b/test/fakefs_test.rb
+@@ -1861,4 +1861,14 @@ class FakeFSTest < Test::Unit::TestCase
+ end
+ end
+ end
++
++ if RUBY_VERSION >= "1.9.3"
++ def test_advise
++ File.open("foo", 'w') do |f|
++ assert_nothing_raised do
++ f.advise(:normal, 0, 0)
++ end
++ end
++ end
++ end
+ end
diff --git a/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-pathname.patch b/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-pathname.patch
new file mode 100644
index 000000000000..e93cdca2a478
--- /dev/null
+++ b/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-pathname.patch
@@ -0,0 +1,57 @@
+commit dcc2ad6952e334b91f0f044a1f1083c99949d840
+Author: Lukas Oberhuber <lukaso@gmail.com>
+Date: Wed Dec 21 16:55:19 2011 +0000
+
+ Substitute Pathname to get tests to pass in ruby 1.9.3
+
+diff --git a/lib/fakefs/base.rb b/lib/fakefs/base.rb
+index 7e83e76..6c1741a 100644
+--- a/lib/fakefs/base.rb
++++ b/lib/fakefs/base.rb
+@@ -2,6 +2,7 @@ RealFile = File
+ RealFileTest = FileTest
+ RealFileUtils = FileUtils
+ RealDir = Dir
++RealPathname = Pathname
+
+ module FakeFS
+ def self.activate!
+@@ -10,11 +11,14 @@ module FakeFS
+ remove_const(:File)
+ remove_const(:FileTest)
+ remove_const(:FileUtils)
++ remove_const(:Pathname) if RUBY_VERSION >= "1.9.3"
++
+
+ const_set(:Dir, FakeFS::Dir)
+ const_set(:File, FakeFS::File)
+ const_set(:FileUtils, FakeFS::FileUtils)
+ const_set(:FileTest, FakeFS::FileTest)
++ const_set(:Pathname, FakeFS::Pathname) if RUBY_VERSION >= "1.9.3"
+ end
+ true
+ end
+@@ -25,11 +29,13 @@ module FakeFS
+ remove_const(:File)
+ remove_const(:FileTest)
+ remove_const(:FileUtils)
++ remove_const(:Pathname) if RUBY_VERSION >= "1.9.3"
+
+ const_set(:Dir, RealDir)
+ const_set(:File, RealFile)
+ const_set(:FileTest, RealFileTest)
+ const_set(:FileUtils, RealFileUtils)
++ const_set(:Pathname, RealPathname) if RUBY_VERSION >= "1.9.3"
+ end
+ true
+ end
+diff --git a/lib/fakefs/safe.rb b/lib/fakefs/safe.rb
+index a1b804c..783de74 100644
+--- a/lib/fakefs/safe.rb
++++ b/lib/fakefs/safe.rb
+@@ -9,3 +9,5 @@ require 'fakefs/fileutils'
+ require 'fakefs/file'
+ require 'fakefs/file_test'
+ require 'fakefs/dir'
++require 'fakefs/pathname' if RUBY_VERSION >= "1.9.3"
++
diff --git a/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-ruby-pathname.patch b/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-ruby-pathname.patch
new file mode 100644
index 000000000000..68b067ca631e
--- /dev/null
+++ b/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193-ruby-pathname.patch
@@ -0,0 +1,880 @@
+commit cf580c9274ff774f540b374e07ed348916c14518
+Author: Lukas Oberhuber <lukaso@gmail.com>
+Date: Wed Dec 21 17:27:26 2011 +0000
+
+ Bumped version.
+ Moved pathname.rb from ruby 1.9.2 into project in order to continue compatibility to 1.9.3 where
+ the functionality has been moved into c. In the c version of the file, the unset_const trick
+ doesn't work because the constant rb_cFile in the c file is never modified. I think this is
+ actually a bug in how ruby MRI operates, but the fix is a little bit complicated.
+
+diff --git a/lib/fakefs/pathname.rb b/lib/fakefs/pathname.rb
+new file mode 100644
+index 0000000..181af36
+--- /dev/null
++++ lib/fakefs/pathname.rb
+@@ -0,0 +1,864 @@
++module FakeFS
++ if RUBY_VERSION >= "1.9.3"
++
++ #
++ # = pathname.rb - From MRI 1.9.2
++ #
++ # Object-Oriented Pathname Class
++ #
++ # Author:: Tanaka Akira <akr@m17n.org>
++ # Documentation:: Author and Gavin Sinclair
++ #
++ # For documentation, see class Pathname.
++ #
++ class Pathname
++
++ # to_path is implemented so Pathname objects are usable with File.open, etc.
++ TO_PATH = :to_path
++
++ SAME_PATHS = if File::FNM_SYSCASE.nonzero?
++ proc {|a, b| a.casecmp(b).zero?}
++ else
++ proc {|a, b| a == b}
++ end
++
++ # :startdoc:
++
++ #
++ # Create a Pathname object from the given String (or String-like object).
++ # If +path+ contains a NUL character (<tt>\0</tt>), an ArgumentError is raised.
++ #
++ def initialize(path)
++ path = path.__send__(TO_PATH) if path.respond_to? TO_PATH
++ @path = path.dup
++
++ if /\0/ =~ @path
++ raise ArgumentError, "pathname contains \\0: #{@path.inspect}"
++ end
++
++ self.taint if @path.tainted?
++ end
++
++ def freeze() super; @path.freeze; self end
++ def taint() super; @path.taint; self end
++ def untaint() super; @path.untaint; self end
++
++ #
++ # Compare this pathname with +other+. The comparison is string-based.
++ # Be aware that two different paths (<tt>foo.txt</tt> and <tt>./foo.txt</tt>)
++ # can refer to the same file.
++ #
++ def ==(other)
++ return false unless Pathname === other
++ other.to_s == @path
++ end
++ alias === ==
++ alias eql? ==
++
++ # Provides for comparing pathnames, case-sensitively.
++ def <=>(other)
++ return nil unless Pathname === other
++ @path.tr('/', "\0") <=> other.to_s.tr('/', "\0")
++ end
++
++ def hash # :nodoc:
++ @path.hash
++ end
++
++ # Return the path as a String.
++ def to_s
++ @path.dup
++ end
++
++ # to_path is implemented so Pathname objects are usable with File.open, etc.
++ alias_method TO_PATH, :to_s
++
++ def inspect # :nodoc:
++ "#<#{self.class}:#{@path}>"
++ end
++
++ # Return a pathname which is substituted by String#sub.
++ def sub(pattern, *rest, &block)
++ if block
++ path = @path.sub(pattern, *rest) {|*args|
++ begin
++ old = Thread.current[:pathname_sub_matchdata]
++ Thread.current[:pathname_sub_matchdata] = $~
++ eval("$~ = Thread.current[:pathname_sub_matchdata]", block.binding)
++ ensure
++ Thread.current[:pathname_sub_matchdata] = old
++ end
++ yield(*args)
++ }
++ else
++ path = @path.sub(pattern, *rest)
++ end
++ self.class.new(path)
++ end
++
++ if File::ALT_SEPARATOR
++ SEPARATOR_LIST = "#{Regexp.quote File::ALT_SEPARATOR}#{Regexp.quote File::SEPARATOR}"
++ SEPARATOR_PAT = /[#{SEPARATOR_LIST}]/
++ else
++ SEPARATOR_LIST = "#{Regexp.quote File::SEPARATOR}"
++ SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/
++ end
++
++ # Return a pathname which the extension of the basename is substituted by
++ # <i>repl</i>.
++ #
++ # If self has no extension part, <i>repl</i> is appended.
++ def sub_ext(repl)
++ ext = File.extname(@path)
++ self.class.new(@path.chomp(ext) + repl)
++ end
++
++ # chop_basename(path) -> [pre-basename, basename] or nil
++ def chop_basename(path)
++ base = File.basename(path)
++ if /\A#{SEPARATOR_PAT}?\z/o =~ base
++ return nil
++ else
++ return path[0, path.rindex(base)], base
++ end
++ end
++ private :chop_basename
++
++ # split_names(path) -> prefix, [name, ...]
++ def split_names(path)
++ names = []
++ while r = chop_basename(path)
++ path, basename = r
++ names.unshift basename
++ end
++ return path, names
++ end
++ private :split_names
++
++ 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
++
++ # Returns clean pathname of +self+ with consecutive slashes and useless dots
++ # removed. The filesystem is not accessed.
++ #
++ # If +consider_symlink+ is +true+, then a more conservative algorithm is used
++ # to avoid breaking symbolic linkages. This may retain more <tt>..</tt>
++ # entries than absolutely necessary, but without accessing the filesystem,
++ # this can't be avoided. See #realpath.
++ #
++ def cleanpath(consider_symlink=false)
++ if consider_symlink
++ cleanpath_conservative
++ else
++ cleanpath_aggressive
++ end
++ end
++
++ #
++ # Clean the path simply by resolving and removing excess "." and ".." entries.
++ # Nothing more, nothing less.
++ #
++ def cleanpath_aggressive
++ path = @path
++ names = []
++ pre = path
++ while r = chop_basename(pre)
++ pre, base = r
++ case base
++ when '.'
++ when '..'
++ names.unshift base
++ else
++ if names[0] == '..'
++ names.shift
++ else
++ names.unshift base
++ end
++ end
++ end
++ if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
++ names.shift while names[0] == '..'
++ end
++ self.class.new(prepend_prefix(pre, File.join(*names)))
++ end
++ private :cleanpath_aggressive
++
++ # has_trailing_separator?(path) -> bool
++ def has_trailing_separator?(path)
++ if r = chop_basename(path)
++ pre, basename = r
++ pre.length + basename.length < path.length
++ else
++ false
++ end
++ end
++ private :has_trailing_separator?
++
++ # add_trailing_separator(path) -> path
++ def add_trailing_separator(path)
++ if File.basename(path + 'a') == 'a'
++ path
++ else
++ File.join(path, "") # xxx: Is File.join is appropriate to add separator?
++ end
++ end
++ private :add_trailing_separator
++
++ def del_trailing_separator(path)
++ if r = chop_basename(path)
++ pre, basename = r
++ pre + basename
++ elsif /#{SEPARATOR_PAT}+\z/o =~ path
++ $` + File.dirname(path)[/#{SEPARATOR_PAT}*\z/o]
++ else
++ path
++ end
++ end
++ private :del_trailing_separator
++
++ def cleanpath_conservative
++ path = @path
++ names = []
++ pre = path
++ while r = chop_basename(pre)
++ pre, base = r
++ names.unshift base if base != '.'
++ end
++ if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
++ names.shift while names[0] == '..'
++ end
++ if names.empty?
++ self.class.new(File.dirname(pre))
++ else
++ if names.last != '..' && File.basename(path) == '.'
++ names << '.'
++ end
++ result = prepend_prefix(pre, File.join(*names))
++ if /\A(?:\.|\.\.)\z/ !~ names.last && has_trailing_separator?(path)
++ self.class.new(add_trailing_separator(result))
++ else
++ self.class.new(result)
++ end
++ end
++ end
++ private :cleanpath_conservative
++
++ #
++ # Returns the real (absolute) pathname of +self+ in the actual
++ # filesystem not containing symlinks or useless dots.
++ #
++ # All components of the pathname must exist when this method is
++ # called.
++ #
++ def realpath(basedir=nil)
++ self.class.new(File.realpath(@path, basedir))
++ end
++
++ #
++ # Returns the real (absolute) pathname of +self+ in the actual filesystem.
++ # The real pathname doesn't contain symlinks or useless dots.
++ #
++ # The last component of the real pathname can be nonexistent.
++ #
++ def realdirpath(basedir=nil)
++ self.class.new(File.realdirpath(@path, basedir))
++ end
++
++ # #parent returns the parent directory.
++ #
++ # This is same as <tt>self + '..'</tt>.
++ def parent
++ self + '..'
++ end
++
++ # #mountpoint? returns +true+ if <tt>self</tt> points to a mountpoint.
++ def mountpoint?
++ begin
++ stat1 = self.lstat
++ stat2 = self.parent.lstat
++ stat1.dev == stat2.dev && stat1.ino == stat2.ino ||
++ stat1.dev != stat2.dev
++ rescue Errno::ENOENT
++ false
++ end
++ end
++
++ #
++ # #root? is a predicate for root directories. I.e. it returns +true+ if the
++ # pathname consists of consecutive slashes.
++ #
++ # It doesn't access actual filesystem. So it may return +false+ for some
++ # pathnames which points to roots such as <tt>/usr/..</tt>.
++ #
++ def root?
++ !!(chop_basename(@path) == nil && /#{SEPARATOR_PAT}/o =~ @path)
++ end
++
++ # Predicate method for testing whether a path is absolute.
++ # It returns +true+ if the pathname begins with a slash.
++ def absolute?
++ !relative?
++ end
++
++ # The opposite of #absolute?
++ def relative?
++ path = @path
++ while r = chop_basename(path)
++ path, basename = r
++ end
++ path == ''
++ end
++
++ #
++ # Iterates over each component of the path.
++ #
++ # Pathname.new("/usr/bin/ruby").each_filename {|filename| ... }
++ # # yields "usr", "bin", and "ruby".
++ #
++ def each_filename # :yield: filename
++ return to_enum(__method__) unless block_given?
++ prefix, names = split_names(@path)
++ names.each {|filename| yield filename }
++ nil
++ end
++
++ # Iterates over and yields a new Pathname object
++ # for each element in the given path in descending order.
++ #
++ # Pathname.new('/path/to/some/file.rb').descend {|v| p v}
++ # #<Pathname:/>
++ # #<Pathname:/path>
++ # #<Pathname:/path/to>
++ # #<Pathname:/path/to/some>
++ # #<Pathname:/path/to/some/file.rb>
++ #
++ # Pathname.new('path/to/some/file.rb').descend {|v| p v}
++ # #<Pathname:path>
++ # #<Pathname:path/to>
++ # #<Pathname:path/to/some>
++ # #<Pathname:path/to/some/file.rb>
++ #
++ # It doesn't access actual filesystem.
++ #
++ # This method is available since 1.8.5.
++ #
++ def descend
++ vs = []
++ ascend {|v| vs << v }
++ vs.reverse_each {|v| yield v }
++ nil
++ end
++
++ # Iterates over and yields a new Pathname object
++ # for each element in the given path in ascending order.
++ #
++ # Pathname.new('/path/to/some/file.rb').ascend {|v| p v}
++ # #<Pathname:/path/to/some/file.rb>
++ # #<Pathname:/path/to/some>
++ # #<Pathname:/path/to>
++ # #<Pathname:/path>
++ # #<Pathname:/>
++ #
++ # Pathname.new('path/to/some/file.rb').ascend {|v| p v}
++ # #<Pathname:path/to/some/file.rb>
++ # #<Pathname:path/to/some>
++ # #<Pathname:path/to>
++ # #<Pathname:path>
++ #
++ # It doesn't access actual filesystem.
++ #
++ # This method is available since 1.8.5.
++ #
++ def ascend
++ path = @path
++ yield self
++ while r = chop_basename(path)
++ path, name = r
++ break if path.empty?
++ yield self.class.new(del_trailing_separator(path))
++ end
++ end
++
++ #
++ # Pathname#+ appends a pathname fragment to this one to produce a new Pathname
++ # object.
++ #
++ # p1 = Pathname.new("/usr") # Pathname:/usr
++ # p2 = p1 + "bin/ruby" # Pathname:/usr/bin/ruby
++ # p3 = p1 + "/etc/passwd" # Pathname:/etc/passwd
++ #
++ # This method doesn't access the file system; it is pure string manipulation.
++ #
++ def +(other)
++ other = Pathname.new(other) unless Pathname === other
++ Pathname.new(plus(@path, other.to_s))
++ end
++
++ def plus(path1, path2) # -> path
++ prefix2 = path2
++ index_list2 = []
++ basename_list2 = []
++ while r2 = chop_basename(prefix2)
++ prefix2, basename2 = r2
++ index_list2.unshift prefix2.length
++ basename_list2.unshift basename2
++ end
++ return path2 if prefix2 != ''
++ prefix1 = path1
++ while true
++ while !basename_list2.empty? && basename_list2.first == '.'
++ index_list2.shift
++ basename_list2.shift
++ end
++ break unless r1 = chop_basename(prefix1)
++ prefix1, basename1 = r1
++ next if basename1 == '.'
++ if basename1 == '..' || basename_list2.empty? || basename_list2.first != '..'
++ prefix1 = prefix1 + basename1
++ break
++ end
++ index_list2.shift
++ basename_list2.shift
++ end
++ r1 = chop_basename(prefix1)
++ if !r1 && /#{SEPARATOR_PAT}/o =~ File.basename(prefix1)
++ while !basename_list2.empty? && basename_list2.first == '..'
++ index_list2.shift
++ basename_list2.shift
++ end
++ end
++ if !basename_list2.empty?
++ suffix2 = path2[index_list2.first..-1]
++ r1 ? File.join(prefix1, suffix2) : prefix1 + suffix2
++ else
++ r1 ? prefix1 : File.dirname(prefix1)
++ end
++ end
++ private :plus
++
++ #
++ # Pathname#join joins pathnames.
++ #
++ # <tt>path0.join(path1, ..., pathN)</tt> is the same as
++ # <tt>path0 + path1 + ... + pathN</tt>.
++ #
++ def join(*args)
++ args.unshift self
++ result = args.pop
++ result = Pathname.new(result) unless Pathname === result
++ return result if result.absolute?
++ args.reverse_each {|arg|
++ arg = Pathname.new(arg) unless Pathname === arg
++ result = arg + result
++ return result if result.absolute?
++ }
++ result
++ end
++
++ #
++ # Returns the children of the directory (files and subdirectories, not
++ # recursive) as an array of Pathname objects. By default, the returned
++ # pathnames will have enough information to access the files. If you set
++ # +with_directory+ to +false+, then the returned pathnames will contain the
++ # filename only.
++ #
++ # For example:
++ # pn = Pathname("/usr/lib/ruby/1.8")
++ # pn.children
++ # # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,
++ # Pathname:/usr/lib/ruby/1.8/Env.rb,
++ # Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]
++ # pn.children(false)
++ # # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ]
++ #
++ # Note that the result never contain the entries <tt>.</tt> and <tt>..</tt> in
++ # the directory because they are not children.
++ #
++ # This method has existed since 1.8.1.
++ #
++ def children(with_directory=true)
++ with_directory = false if @path == '.'
++ result = []
++ Dir.foreach(@path) {|e|
++ next if e == '.' || e == '..'
++ if with_directory
++ result << self.class.new(File.join(@path, e))
++ else
++ result << self.class.new(e)
++ end
++ }
++ result
++ end
++
++ # Iterates over the children of the directory
++ # (files and subdirectories, not recursive).
++ # It yields Pathname object for each child.
++ # By default, the yielded pathnames will have enough information to access the files.
++ # If you set +with_directory+ to +false+, then the returned pathnames will contain the filename only.
++ #
++ # Pathname("/usr/local").each_child {|f| p f }
++ # #=> #<Pathname:/usr/local/share>
++ # # #<Pathname:/usr/local/bin>
++ # # #<Pathname:/usr/local/games>
++ # # #<Pathname:/usr/local/lib>
++ # # #<Pathname:/usr/local/include>
++ # # #<Pathname:/usr/local/sbin>
++ # # #<Pathname:/usr/local/src>
++ # # #<Pathname:/usr/local/man>
++ #
++ # Pathname("/usr/local").each_child(false) {|f| p f }
++ # #=> #<Pathname:share>
++ # # #<Pathname:bin>
++ # # #<Pathname:games>
++ # # #<Pathname:lib>
++ # # #<Pathname:include>
++ # # #<Pathname:sbin>
++ # # #<Pathname:src>
++ # # #<Pathname:man>
++ #
++ def each_child(with_directory=true, &b)
++ children(with_directory).each(&b)
++ end
++
++ #
++ # #relative_path_from returns a relative path from the argument to the
++ # receiver. If +self+ is absolute, the argument must be absolute too. If
++ # +self+ is relative, the argument must be relative too.
++ #
++ # #relative_path_from doesn't access the filesystem. It assumes no symlinks.
++ #
++ # ArgumentError is raised when it cannot find a relative path.
++ #
++ # This method has existed since 1.8.1.
++ #
++ def relative_path_from(base_directory)
++ dest_directory = self.cleanpath.to_s
++ base_directory = base_directory.cleanpath.to_s
++ dest_prefix = dest_directory
++ dest_names = []
++ while r = chop_basename(dest_prefix)
++ dest_prefix, basename = r
++ dest_names.unshift basename if basename != '.'
++ end
++ base_prefix = base_directory
++ base_names = []
++ while r = chop_basename(base_prefix)
++ base_prefix, basename = r
++ base_names.unshift basename if basename != '.'
++ end
++ unless SAME_PATHS[dest_prefix, base_prefix]
++ raise ArgumentError, "different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}"
++ end
++ while !dest_names.empty? &&
++ !base_names.empty? &&
++ SAME_PATHS[dest_names.first, base_names.first]
++ dest_names.shift
++ base_names.shift
++ end
++ if base_names.include? '..'
++ raise ArgumentError, "base_directory has ..: #{base_directory.inspect}"
++ end
++ base_names.fill('..')
++ relpath_names = base_names + dest_names
++ if relpath_names.empty?
++ Pathname.new('.')
++ else
++ Pathname.new(File.join(*relpath_names))
++ end
++ end
++ end
++
++ class Pathname # * IO *
++ #
++ # #each_line iterates over the line in the file. It yields a String object
++ # for each line.
++ #
++ # This method has existed since 1.8.1.
++ #
++ def each_line(*args, &block) # :yield: line
++ IO.foreach(@path, *args, &block)
++ end
++
++ # See <tt>IO.read</tt>. Returns all data from the file, or the first +N+ bytes
++ # if specified.
++ def read(*args) IO.read(@path, *args) end
++
++ # See <tt>IO.binread</tt>. Returns all the bytes from the file, or the first +N+
++ # if specified.
++ def binread(*args) IO.binread(@path, *args) end
++
++ # See <tt>IO.readlines</tt>. Returns all the lines from the file.
++ def readlines(*args) IO.readlines(@path, *args) end
++
++ # See <tt>IO.sysopen</tt>.
++ def sysopen(*args) IO.sysopen(@path, *args) end
++ end
++
++
++ class Pathname # * File *
++
++ # See <tt>File.atime</tt>. Returns last access time.
++ def atime() File.atime(@path) end
++
++ # See <tt>File.ctime</tt>. Returns last (directory entry, not file) change time.
++ def ctime() File.ctime(@path) end
++
++ # See <tt>File.mtime</tt>. Returns last modification time.
++ def mtime() File.mtime(@path) end
++
++ # See <tt>File.chmod</tt>. Changes permissions.
++ def chmod(mode) File.chmod(mode, @path) end
++
++ # See <tt>File.lchmod</tt>.
++ def lchmod(mode) File.lchmod(mode, @path) end
++
++ # See <tt>File.chown</tt>. Change owner and group of file.
++ def chown(owner, group) File.chown(owner, group, @path) end
++
++ # See <tt>File.lchown</tt>.
++ def lchown(owner, group) File.lchown(owner, group, @path) end
++
++ # See <tt>File.fnmatch</tt>. Return +true+ if the receiver matches the given
++ # pattern.
++ def fnmatch(pattern, *args) File.fnmatch(pattern, @path, *args) end
++
++ # See <tt>File.fnmatch?</tt> (same as #fnmatch).
++ def fnmatch?(pattern, *args) File.fnmatch?(pattern, @path, *args) end
++
++ # See <tt>File.ftype</tt>. Returns "type" of file ("file", "directory",
++ # etc).
++ def ftype() File.ftype(@path) end
++
++ # See <tt>File.link</tt>. Creates a hard link.
++ def make_link(old) File.link(old, @path) end
++
++ # See <tt>File.open</tt>. Opens the file for reading or writing.
++ def open(*args, &block) # :yield: file
++ File.open(@path, *args, &block)
++ end
++
++ # See <tt>File.readlink</tt>. Read symbolic link.
++ def readlink() self.class.new(File.readlink(@path)) end
++
++ # See <tt>File.rename</tt>. Rename the file.
++ def rename(to) File.rename(@path, to) end
++
++ # See <tt>File.stat</tt>. Returns a <tt>File::Stat</tt> object.
++ def stat() File.stat(@path) end
++
++ # See <tt>File.lstat</tt>.
++ def lstat() File.lstat(@path) end
++
++ # See <tt>File.symlink</tt>. Creates a symbolic link.
++ def make_symlink(old) File.symlink(old, @path) end
++
++ # See <tt>File.truncate</tt>. Truncate the file to +length+ bytes.
++ def truncate(length) File.truncate(@path, length) end
++
++ # See <tt>File.utime</tt>. Update the access and modification times.
++ def utime(atime, mtime) File.utime(atime, mtime, @path) end
++
++ # See <tt>File.basename</tt>. Returns the last component of the path.
++ def basename(*args) self.class.new(File.basename(@path, *args)) end
++
++ # See <tt>File.dirname</tt>. Returns all but the last component of the path.
++ def dirname() self.class.new(File.dirname(@path)) end
++
++ # See <tt>File.extname</tt>. Returns the file's extension.
++ def extname() File.extname(@path) end
++
++ # See <tt>File.expand_path</tt>.
++ def expand_path(*args) self.class.new(File.expand_path(@path, *args)) end
++
++ # See <tt>File.split</tt>. Returns the #dirname and the #basename in an
++ # Array.
++ def split() File.split(@path).map {|f| self.class.new(f) } end
++ end
++
++
++ class Pathname # * FileTest *
++
++ # See <tt>FileTest.blockdev?</tt>.
++ def blockdev?() FileTest.blockdev?(@path) end
++
++ # See <tt>FileTest.chardev?</tt>.
++ def chardev?() FileTest.chardev?(@path) end
++
++ # See <tt>FileTest.executable?</tt>.
++ def executable?() FileTest.executable?(@path) end
++
++ # See <tt>FileTest.executable_real?</tt>.
++ def executable_real?() FileTest.executable_real?(@path) end
++
++ # See <tt>FileTest.exist?</tt>.
++ def exist?() FileTest.exist?(@path) end
++
++ # See <tt>FileTest.grpowned?</tt>.
++ def grpowned?() FileTest.grpowned?(@path) end
++
++ # See <tt>FileTest.directory?</tt>.
++ def directory?() FileTest.directory?(@path) end
++
++ # See <tt>FileTest.file?</tt>.
++ def file?() FileTest.file?(@path) end
++
++ # See <tt>FileTest.pipe?</tt>.
++ def pipe?() FileTest.pipe?(@path) end
++
++ # See <tt>FileTest.socket?</tt>.
++ def socket?() FileTest.socket?(@path) end
++
++ # See <tt>FileTest.owned?</tt>.
++ def owned?() FileTest.owned?(@path) end
++
++ # See <tt>FileTest.readable?</tt>.
++ def readable?() FileTest.readable?(@path) end
++
++ # See <tt>FileTest.world_readable?</tt>.
++ def world_readable?() FileTest.world_readable?(@path) end
++
++ # See <tt>FileTest.readable_real?</tt>.
++ def readable_real?() FileTest.readable_real?(@path) end
++
++ # See <tt>FileTest.setuid?</tt>.
++ def setuid?() FileTest.setuid?(@path) end
++
++ # See <tt>FileTest.setgid?</tt>.
++ def setgid?() FileTest.setgid?(@path) end
++
++ # See <tt>FileTest.size</tt>.
++ def size() FileTest.size(@path) end
++
++ # See <tt>FileTest.size?</tt>.
++ def size?() FileTest.size?(@path) end
++
++ # See <tt>FileTest.sticky?</tt>.
++ def sticky?() FileTest.sticky?(@path) end
++
++ # See <tt>FileTest.symlink?</tt>.
++ def symlink?() FileTest.symlink?(@path) end
++
++ # See <tt>FileTest.writable?</tt>.
++ def writable?() FileTest.writable?(@path) end
++
++ # See <tt>FileTest.world_writable?</tt>.
++ def world_writable?() FileTest.world_writable?(@path) end
++
++ # See <tt>FileTest.writable_real?</tt>.
++ def writable_real?() FileTest.writable_real?(@path) end
++
++ # See <tt>FileTest.zero?</tt>.
++ def zero?() FileTest.zero?(@path) end
++ end
++
++
++ class Pathname # * Dir *
++ # See <tt>Dir.glob</tt>. Returns or yields Pathname objects.
++ def Pathname.glob(*args) # :yield: pathname
++ if block_given?
++ Dir.glob(*args) {|f| yield self.new(f) }
++ else
++ Dir.glob(*args).map {|f| self.new(f) }
++ end
++ end
++
++ # See <tt>Dir.getwd</tt>. Returns the current working directory as a Pathname.
++ def Pathname.getwd() self.new(Dir.getwd) end
++ class << self; alias pwd getwd end
++
++ # Return the entries (files and subdirectories) in the directory, each as a
++ # Pathname object.
++ def entries() Dir.entries(@path).map {|f| self.class.new(f) } end
++
++ # Iterates over the entries (files and subdirectories) in the directory. It
++ # yields a Pathname object for each entry.
++ #
++ # This method has existed since 1.8.1.
++ def each_entry(&block) # :yield: pathname
++ Dir.foreach(@path) {|f| yield self.class.new(f) }
++ end
++
++ # See <tt>Dir.mkdir</tt>. Create the referenced directory.
++ def mkdir(*args) Dir.mkdir(@path, *args) end
++
++ # See <tt>Dir.rmdir</tt>. Remove the referenced directory.
++ def rmdir() Dir.rmdir(@path) end
++
++ # See <tt>Dir.open</tt>.
++ def opendir(&block) # :yield: dir
++ Dir.open(@path, &block)
++ end
++ end
++
++
++ class Pathname # * Find *
++ #
++ # Pathname#find is an iterator to traverse a directory tree in a depth first
++ # manner. It yields a Pathname for each file under "this" directory.
++ #
++ # Since it is implemented by <tt>find.rb</tt>, <tt>Find.prune</tt> can be used
++ # to control the traverse.
++ #
++ # If +self+ is <tt>.</tt>, yielded pathnames begin with a filename in the
++ # current directory, not <tt>./</tt>.
++ #
++ def find(&block) # :yield: pathname
++ require 'find'
++ if @path == '.'
++ Find.find(@path) {|f| yield self.class.new(f.sub(%r{\A\./}, '')) }
++ else
++ Find.find(@path) {|f| yield self.class.new(f) }
++ end
++ end
++ end
++
++
++ class Pathname # * FileUtils *
++ # See <tt>FileUtils.mkpath</tt>. Creates a full path, including any
++ # intermediate directories that don't yet exist.
++ def mkpath
++ require 'fileutils'
++ FileUtils.mkpath(@path)
++ nil
++ end
++
++ # See <tt>FileUtils.rm_r</tt>. Deletes a directory and all beneath it.
++ def rmtree
++ # The name "rmtree" is borrowed from File::Path of Perl.
++ # File::Path provides "mkpath" and "rmtree".
++ require 'fileutils'
++ FileUtils.rm_r(@path)
++ nil
++ end
++ end
++
++
++ class Pathname # * mixed *
++ # Removes a file or directory, using <tt>File.unlink</tt> or
++ # <tt>Dir.unlink</tt> as necessary.
++ def unlink()
++ begin
++ Dir.unlink @path
++ rescue Errno::ENOTDIR
++ File.unlink @path
++ end
++ end
++ alias delete unlink
++ end
++
++ class Pathname
++ undef =~
++ end
++ end # RUBY_VERSION >= 1.9.3
++end
++
diff --git a/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193.patch b/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193.patch
new file mode 100644
index 000000000000..b427befa2629
--- /dev/null
+++ b/dev-ruby/fakefs/files/fakefs-0.4.0-ruby193.patch
@@ -0,0 +1,195 @@
+commit af733ea5606391c594fb5e228fc1e94515c1e7e4
+Author: Mateusz Juraszek <meceo00@gmail.com>
+Date: Tue Jan 3 11:00:56 2012 +0100
+
+ add external encoding as default to File @content string,
+ handle hash as second parameter to File::new,
+ extend FakeFS::FileSystem::clone method to accept 'target' as a optional parameter,
+ fix Dir::mkdir for nested structure
+
+diff --git a/lib/fakefs/dir.rb b/lib/fakefs/dir.rb
+index 628626f..ed571ff 100644
+--- a/lib/fakefs/dir.rb
++++ b/lib/fakefs/dir.rb
+@@ -105,7 +105,7 @@ module FakeFS
+ parent = string.split('/')
+ parent.pop
+
+- joined_parent_path = parent.join
++ joined_parent_path = parent.join("/")
+
+ _check_for_valid_file(joined_parent_path) unless joined_parent_path == ""
+ raise Errno::EEXIST, "File exists - #{string}" if File.exists?(string)
+diff --git a/lib/fakefs/fake/file.rb b/lib/fakefs/fake/file.rb
+index 10bdf7f..22f32d9 100644
+--- a/lib/fakefs/fake/file.rb
++++ b/lib/fakefs/fake/file.rb
+@@ -5,7 +5,8 @@ module FakeFS
+
+ class Inode
+ def initialize(file_owner)
+- @content = ""
++ #1.9.3 when possible set default external encoding
++ @content = "".respond_to?(:encode) ? "".encode(Encoding.default_external) : ""
+ @links = [file_owner]
+ end
+
+diff --git a/lib/fakefs/file.rb b/lib/fakefs/file.rb
+index 5684ede..5f36376 100644
+--- a/lib/fakefs/file.rb
++++ b/lib/fakefs/file.rb
+@@ -275,7 +275,7 @@ module FakeFS
+
+ def initialize(path, mode = READ_ONLY, perm = nil)
+ @path = path
+- @mode = mode
++ @mode = mode.is_a?(Hash) ? (mode[:mode] || READ_ONLY) : mode
+ @file = FileSystem.find(path)
+ @autoclose = true
+
+@@ -283,7 +283,7 @@ module FakeFS
+
+ file_creation_mode? ? create_missing_file : check_file_existence!
+
+- super(@file.content, mode)
++ super(@file.content, @mode)
+ end
+
+ def exists?
+diff --git a/lib/fakefs/file_system.rb b/lib/fakefs/file_system.rb
+index a5c8087..da58ad9 100644
+--- a/lib/fakefs/file_system.rb
++++ b/lib/fakefs/file_system.rb
+@@ -46,19 +46,20 @@ module FakeFS
+
+ # copies directories and files from the real filesystem
+ # into our fake one
+- def clone(path)
++ def clone(path, target = nil)
+ path = File.expand_path(path)
+ pattern = File.join(path, '**', '*')
+ files = RealFile.file?(path) ? [path] : [path] + RealDir.glob(pattern, RealFile::FNM_DOTMATCH)
+
+ files.each do |f|
++ target_path = target ? f.gsub(path, target) : f
+ if RealFile.file?(f)
+ FileUtils.mkdir_p(File.dirname(f))
+- File.open(f, File::WRITE_ONLY) do |g|
++ File.open(target_path, File::WRITE_ONLY) do |g|
+ g.print RealFile.open(f){|h| h.read }
+ end
+ elsif RealFile.directory?(f)
+- FileUtils.mkdir_p(f)
++ FileUtils.mkdir_p(target_path)
+ elsif RealFile.symlink?(f)
+ FileUtils.ln_s()
+ end
+diff --git a/test/fakefs_test.rb b/test/fakefs_test.rb
+index 0f34950..7e2b8dc 100644
+--- a/test/fakefs_test.rb
++++ b/test/fakefs_test.rb
+@@ -647,6 +647,21 @@ class FakeFSTest < Test::Unit::TestCase
+ assert_equal "Yatta!", File.new(path).read
+ end
+
++ if RUBY_VERSION >= "1.9"
++ def test_file_object_has_default_external_encoding
++ Encoding.default_external = "UTF-8"
++ path = 'file.txt'
++ File.open(path, 'w'){|f| f.write 'Yatta!' }
++ assert_equal "UTF-8", File.new(path).read.encoding.name
++ end
++ end
++
++ def test_file_object_initialization_with_mode_in_hash_parameter
++ assert_nothing_raised do
++ File.open("file.txt", {:mode => "w"}){ |f| f.write 'Yatta!' }
++ end
++ end
++
+ def test_file_read_errors_appropriately
+ assert_raise Errno::ENOENT do
+ File.read('anything')
+@@ -1132,24 +1147,18 @@ class FakeFSTest < Test::Unit::TestCase
+ end
+
+ def test_clone_clones_directories
+- FakeFS.deactivate!
+- RealFileUtils.mkdir_p(here('subdir'))
+- FakeFS.activate!
++ act_on_real_fs { RealFileUtils.mkdir_p(here('subdir')) }
+
+ FileSystem.clone(here('subdir'))
+
+ assert File.exists?(here('subdir')), 'subdir was cloned'
+ assert File.directory?(here('subdir')), 'subdir is a directory'
+ ensure
+- FakeFS.deactivate!
+- RealFileUtils.rm_rf(here('subdir'))
+- FakeFS.activate!
++ act_on_real_fs { RealFileUtils.rm_rf(here('subdir')) }
+ end
+
+ def test_clone_clones_dot_files_even_hard_to_find_ones
+- FakeFS.deactivate!
+- RealFileUtils.mkdir_p(here('subdir/.bar/baz/.quux/foo'))
+- FakeFS.activate!
++ act_on_real_fs { RealFileUtils.mkdir_p(here('subdir/.bar/baz/.quux/foo')) }
+
+ assert !File.exists?(here('subdir'))
+
+@@ -1157,9 +1166,20 @@ class FakeFSTest < Test::Unit::TestCase
+ assert_equal ['.bar'], FileSystem.find(here('subdir')).keys
+ assert_equal ['foo'], FileSystem.find(here('subdir/.bar/baz/.quux')).keys
+ ensure
+- FakeFS.deactivate!
+- RealFileUtils.rm_rf(here('subdir'))
+- FakeFS.activate!
++ act_on_real_fs { RealFileUtils.rm_rf(here('subdir')) }
++ end
++
++ def test_clone_with_target_specified
++ act_on_real_fs { RealFileUtils.mkdir_p(here('subdir/.bar/baz/.quux/foo')) }
++
++ assert !File.exists?(here('subdir'))
++
++ FileSystem.clone(here('subdir'), here('subdir2'))
++ assert !File.exists?(here('subdir'))
++ assert_equal ['.bar'], FileSystem.find(here('subdir2')).keys
++ assert_equal ['foo'], FileSystem.find(here('subdir2/.bar/baz/.quux')).keys
++ ensure
++ act_on_real_fs { RealFileUtils.rm_rf(here('subdir')) }
+ end
+
+ def test_putting_a_dot_at_end_copies_the_contents
+@@ -1464,6 +1484,12 @@ class FakeFSTest < Test::Unit::TestCase
+ assert File.exists?('/path')
+ end
+
++ def test_directory_mkdir_nested
++ Dir.mkdir("/tmp")
++ Dir.mkdir("/tmp/stream20120103-11847-xc8pb.lock")
++ assert File.exists?("/tmp/stream20120103-11847-xc8pb.lock")
++ end
++
+ def test_directory_mkdir_relative
+ FileUtils.mkdir_p('/new/root')
+ FileSystem.chdir('/new/root')
+diff --git a/test/test_helper.rb b/test/test_helper.rb
+index c41dd67..b6596fa 100644
+--- a/test/test_helper.rb
++++ b/test/test_helper.rb
+@@ -5,4 +5,11 @@ require 'test/unit'
+ begin
+ require 'redgreen'
+ rescue LoadError
+-end
+\ No newline at end of file
++end
++
++def act_on_real_fs
++ raise ArgumentError unless block_given?
++ FakeFS.deactivate!
++ yield
++ FakeFS.activate!
++end