-
Notifications
You must be signed in to change notification settings - Fork 70
Expand file tree
/
Copy pathcreate_zip.py
More file actions
executable file
·111 lines (94 loc) · 3.75 KB
/
create_zip.py
File metadata and controls
executable file
·111 lines (94 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python3
"""
Create a zip archive from a directory, compatible with unzip command.
This script replaces the zip command for environments where it's not available.
"""
import zipfile
import os
import sys
from pathlib import Path
def create_zip(source_dir, zip_path, exclude_patterns=None):
"""
Create a zip file from a directory with exclusion patterns.
Args:
source_dir: Path to the source directory
zip_path: Path where the zip file will be created
exclude_patterns: List of patterns to exclude (e.g., ["node_modules/*", ".git/*"])
"""
if exclude_patterns is None:
exclude_patterns = [
"node_modules/*", ".git/*", "*.log", ".DS_Store",
"dist/*", "build/*", ".next/*", "coverage/*",
".nyc_output/*", "*.tgz", "*.tar.gz",
".wrangler/*", ".dev.vars*", ".env.*"
]
source_path = Path(source_dir)
if not source_path.exists():
print(f"Error: Source directory '{source_dir}' does not exist", file=sys.stderr)
return False
try:
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED, compresslevel=9) as zipf:
for root, dirs, files in os.walk(source_path):
# Convert to relative path from source directory
rel_root = Path(root).relative_to(source_path)
# Filter directories and files based on exclusion patterns
dirs[:] = [d for d in dirs if not should_exclude(rel_root / d, exclude_patterns)]
files = [f for f in files if not should_exclude(rel_root / f, exclude_patterns)]
for file in files:
file_path = Path(root) / file
arc_path = rel_root / file if str(rel_root) != '.' else Path(file)
zipf.write(file_path, arc_path)
return True
except Exception as e:
print(f"Error creating zip file: {e}", file=sys.stderr)
return False
def should_exclude(path, exclude_patterns):
"""
Check if a path should be excluded based on patterns.
"""
path_str = str(path).replace('\\', '/')
for pattern in exclude_patterns:
if pattern.endswith('/*'):
# Directory pattern
dir_pattern = pattern[:-2]
if path_str.startswith(dir_pattern + '/') or path_str == dir_pattern:
return True
elif pattern.endswith('*'):
# Prefix pattern (e.g., '.env.*' or '.dev.vars*')
prefix = pattern[:-1]
if path_str.startswith(prefix):
return True
elif pattern.startswith('*.'):
# File extension pattern
if path_str.endswith(pattern[1:]):
return True
elif pattern in path_str:
# Simple substring match
return True
return False
def main():
if len(sys.argv) < 3:
print("Usage: python3 create_zip.py <source_directory> <output_zip_file>", file=sys.stderr)
sys.exit(1)
source_dir = sys.argv[1]
zip_file = sys.argv[2]
# Create parent directory if it doesn't exist
zip_dir = os.path.dirname(zip_file)
if zip_dir:
os.makedirs(zip_dir, exist_ok=True)
if create_zip(source_dir, zip_file):
# Get file size for output
size = os.path.getsize(zip_file)
if size < 1024:
size_str = f"{size}B"
elif size < 1024 * 1024:
size_str = f"{size // 1024}K"
else:
size_str = f"{size // (1024 * 1024)}M"
print(f"✅ Created {zip_file} ({size_str})")
sys.exit(0)
else:
print(f"❌ Failed to create {zip_file}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()