# Path: elbepack/filesystem.py
# class TmpdirFilesystem (Filesystem):
#     def __init__(self, debug=False):
#         tmpdir = mkdtemp()
#         Filesystem.__init__(self, tmpdir)
#         self.debug = debug
# 
#     def __del__(self):
#         # dont delete files in debug mode
#         if self.debug:
#             print('leaving TmpdirFilesystem in "%s"' % self.path)
#         else:
#             self.delete()
# 
#     def delete(self):
#         shutil.rmtree(self.path, True)
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, exec_type, exec_value, tb):
#         shutil.rmtree(self.path)
#         return False
# 
# Path: elbepack/efilesystem.py
# def copy_filelist(src, file_lst, dst):
# 
#     # pylint: disable=too-many-branches
# 
#     files  = set()
#     copied = set()
# 
#     # Make sure to copy parent directories
#     #
#     # For example, if file_lst = ['/usr/bin/bash'],
#     # we might get {'/usr/bin', '/usr', '/usr/bin/bash'}
#     for f in file_lst:
#         parts = f.rstrip('\n')
#         while parts != os.sep:
#             files.add(parts)
#             parts, _ = os.path.split(parts)
# 
#     # Start from closest to root first
#     files = list(files)
#     files.sort()
#     files.reverse()
# 
#     while files:
# 
#         f = files.pop()
#         copied.add(f)
# 
#         if src.islink(f):
# 
#             tgt = src.readlink(f)
# 
#             if not src.lexists(tgt):
#                 dst.symlink(tgt, f, allow_exists=True)
#                 continue
# 
#             # If the target is not yet in the destination RFS, we need
#             # to defer the copy of the symlink after the target is
#             # resolved.  Thus, we recusively call copy_filelist
#             #
#             # Not that this will result in an infinite loop for
#             # circular symlinks
#             if not dst.lexists(tgt):
#                 if not os.path.isabs(tgt):
#                     lst = [os.path.join(os.path.dirname(f), tgt)]
#                 else:
#                     lst = [tgt]
#                 copy_filelist(src, lst, dst)
# 
#             dst.symlink(tgt, f, allow_exists=True)
# 
#         elif src.isdir(f):
#             if not dst.isdir(f):
#                 dst.mkdir(f)
#             st = src.stat(f)
#             dst.chown(f, st.st_uid, st.st_gid)
# 
#         else:
#             try:
#                 system('cp -a --reflink=auto "%s" "%s"' % (src.realpath(f),
#                                                            dst.realpath(f)))
#             except CommandError as E:
#                 logging.warning("Error while copying from %s to %s of file %s - %s",
#                                 src.path, dst.path, f, E)
# 
#     # update utime which will change after a file has been copied into
#     # the directory
#     for f in copied:
#         if src.isdir(f) and not src.islink(f):
#             shutil.copystat(src.fname(f), dst.fname(f))


import unittest
from elbepack.filesystem import TmpdirFilesystem
from elbepack.efilesystem import copy_filelist
        self.assertEqual(self.src.read_file('/usr/bin/bla'),
                         self.dst.read_file('/usr/bin/bla'))

    def test_usrmerge_rel(self):

        self.src.mkdir_p('/usr/bin')

        # create a proper relative path, that should
        # work fine from inside.
        self.src.symlink('usr/bin', '/bin')

        self.src.write_file('/bin/bla', 0o644, 'bla')

        copy_filelist(self.src, ['/bin/bla'], self.dst)

        # We should now have the same content from /SRC/usr/bin/bla in
        # /DST/usr/bin/bla
        self.assertEqual(self.src.read_file('/usr/bin/bla'),
                         self.dst.read_file('/usr/bin/bla'))

    def test_deeplinks(self):

        self.src.mkdir_p('/a/b/c')

        # c <- /a/b/d
        self.src.symlink('c', '/a/b/d')

        # This write into /a/b/c/bla (c instead of d)
        self.src.write_file('/a/b/d/bla', 0o644, 'bla')


# Path: elbepack/filesystem.py
# class TmpdirFilesystem (Filesystem):
#     def __init__(self, debug=False):
#         tmpdir = mkdtemp()
#         Filesystem.__init__(self, tmpdir)
#         self.debug = debug
# 
#     def __del__(self):
#         # dont delete files in debug mode
#         if self.debug:
#             print('leaving TmpdirFilesystem in "%s"' % self.path)
#         else:
#             self.delete()
# 
#     def delete(self):
#         shutil.rmtree(self.path, True)
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, exec_type, exec_value, tb):
#         shutil.rmtree(self.path)
#         return False
# 
# Path: elbepack/efilesystem.py
# def copy_filelist(src, file_lst, dst):
# 
#     # pylint: disable=too-many-branches
# 
#     files  = set()
#     copied = set()
# 
#     # Make sure to copy parent directories
#     #
#     # For example, if file_lst = ['/usr/bin/bash'],
#     # we might get {'/usr/bin', '/usr', '/usr/bin/bash'}
#     for f in file_lst:
#         parts = f.rstrip('\n')
#         while parts != os.sep:
#             files.add(parts)
#             parts, _ = os.path.split(parts)
# 
#     # Start from closest to root first
#     files = list(files)
#     files.sort()
#     files.reverse()
# 
#     while files:
# 
#         f = files.pop()
#         copied.add(f)
# 
#         if src.islink(f):
# 
#             tgt = src.readlink(f)
# 
#             if not src.lexists(tgt):
#                 dst.symlink(tgt, f, allow_exists=True)
#                 continue
# 
#             # If the target is not yet in the destination RFS, we need
#             # to defer the copy of the symlink after the target is
#             # resolved.  Thus, we recusively call copy_filelist
#             #
#             # Not that this will result in an infinite loop for
#             # circular symlinks
#             if not dst.lexists(tgt):
#                 if not os.path.isabs(tgt):
#                     lst = [os.path.join(os.path.dirname(f), tgt)]
#                 else:
#                     lst = [tgt]
#                 copy_filelist(src, lst, dst)
# 
#             dst.symlink(tgt, f, allow_exists=True)
# 
#         elif src.isdir(f):
#             if not dst.isdir(f):
#                 dst.mkdir(f)
#             st = src.stat(f)
#             dst.chown(f, st.st_uid, st.st_gid)
# 
#         else:
#             try:
#                 system('cp -a --reflink=auto "%s" "%s"' % (src.realpath(f),
#                                                            dst.realpath(f)))
#             except CommandError as E:
#                 logging.warning("Error while copying from %s to %s of file %s - %s",
#                                 src.path, dst.path, f, E)
# 
#     # update utime which will change after a file has been copied into
#     # the directory
#     for f in copied:
#         if src.isdir(f) and not src.islink(f):
#             shutil.copystat(src.fname(f), dst.fname(f))


# Path: elbepack/tests/test_efilesystem.py
import unittest
from elbepack.filesystem import TmpdirFilesystem
from elbepack.efilesystem import copy_filelist

        self.assertEqual(self.src.read_file('/usr/bin/bla'),
                         self.dst.read_file('/usr/bin/bla'))

    def test_usrmerge_rel(self):

        self.src.mkdir_p('/usr/bin')

        # create a proper relative path, that should
        # work fine from inside.
        self.src.symlink('usr/bin', '/bin')

        self.src.write_file('/bin/bla', 0o644, 'bla')

        copy_filelist(self.src, ['/bin/bla'], self.dst)

        # We should now have the same content from /SRC/usr/bin/bla in
        # /DST/usr/bin/bla
        self.assertEqual(self.src.read_file('/usr/bin/bla'),
                         self.dst.read_file('/usr/bin/bla'))

    def test_deeplinks(self):

        self.src.mkdir_p('/a/b/c')

        # c <- /a/b/d
        self.src.symlink('c', '/a/b/d')

        # This write into /a/b/c/bla (c instead of d)
        self.src.write_file('/a/b/d/bla', 0o644, 'bla')


        copy_filelist(self.src, ['/a/b/d/bla'], self.dst)