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