configurationengine/source/testautomation/testautomation/zip_dir.py
changeset 0 2e8eeb919028
equal deleted inserted replaced
-1:000000000000 0:2e8eeb919028
       
     1 #
       
     2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description:
       
    15 #
       
    16 
       
    17 import os, re, zipfile
       
    18 
       
    19 SVN_IGNORE_PATTERN = r'(.*/|.*\\|^)\.svn(/.*|\\.*|$)'
       
    20 
       
    21 def zip_dir(source_dir, target_file, ignore_patterns=[]):
       
    22     """
       
    23     Archive the contents of a directory into a zip file.
       
    24     """
       
    25     if not os.path.isdir(source_dir):
       
    26         raise RuntimeError("'%s' does not exist or is not a directory" % dir)
       
    27 
       
    28     target_dir = os.path.dirname(target_file)
       
    29     if target_dir != '' and not os.path.exists(target_dir):
       
    30         os.makedirs(target_dir)
       
    31     
       
    32     def is_ignored(entry_name):
       
    33         for pat in ignore_patterns:
       
    34             if re.match(pat, entry_name) != None:
       
    35                 return True
       
    36         return False
       
    37     
       
    38     zf = zipfile.ZipFile(target_file, 'w', compression=zipfile.ZIP_DEFLATED)
       
    39     try:
       
    40         source_dir = os.path.abspath(source_dir).replace('\\', '/')
       
    41         if not source_dir.endswith('/'): source_dir += '/'
       
    42         
       
    43         empty_dirs = []
       
    44         for root, dirs, files in os.walk(source_dir):
       
    45             # Construct the ZIP entry name of the current directory
       
    46             root_dir_zip_name = root.replace('\\', '/')[len(source_dir):] + '/'
       
    47             
       
    48             if is_ignored(root_dir_zip_name):
       
    49                 continue
       
    50             
       
    51             # Create a dictionary of the files that should be written to the
       
    52             # ZIP file
       
    53             filtered_files = {}
       
    54             for fname in files:
       
    55                 if root_dir_zip_name == '/':    zip_name = fname
       
    56                 else:                           zip_name = root_dir_zip_name + fname
       
    57                 if not is_ignored(zip_name):
       
    58                     filtered_files[zip_name] = os.path.join(root, fname)
       
    59             
       
    60             # If the current directory is a sub-directory of an empty directory candidate,
       
    61             # remove the base directory from the sub-directory candidates
       
    62             empty_dirs = filter(lambda n: not root_dir_zip_name.startswith(n), empty_dirs)
       
    63             
       
    64             if len(filtered_files) == 0:
       
    65                 # If there are no files, the directory is possibly an empty directory
       
    66                 # (though it can still contain sub-directories that contain something)
       
    67                 empty_dirs.append(root_dir_zip_name)
       
    68             else:
       
    69                 for zip_name, path in filtered_files.iteritems():
       
    70                     zf.write(path, zip_name, zipfile.ZIP_DEFLATED)
       
    71             
       
    72         # Write empty directories
       
    73         for zip_name in empty_dirs:
       
    74             zf.writestr(zip_name, '')
       
    75     finally:
       
    76         zf.close()