0
|
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() |