aws-lambda-layer-cli 2.0.4 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@ A command-line tool for creating and publishing AWS Lambda layers for Node.js an
4
4
 
5
5
  ## Features
6
6
 
7
- - Create and publish Lambda layers for Node.js (npm) and Python (uv/pip)
7
+ - Create and publish Lambda layers for Node.js (npm) and Python (pip)
8
8
  - Automatic version management and smart naming
9
9
  - Direct publishing to AWS with IAM credentials and region support
10
10
  - Support for multiple packages in a single layer
@@ -50,9 +50,10 @@ aws-lambda-layer-cli <command> [options]
50
50
  | `--description` | Layer description (publish only) |
51
51
  | `--profile` | AWS CLI profile (publish only) |
52
52
  | `--region` | AWS region (publish only) |
53
+ | `--architecture, -a` | Target architecture (`x86_64` or `arm64`) |
54
+ | `--platform` | Target platform tag (Python only, e.g. `manylinux_2_28_aarch64`) |
53
55
  | `--node-version` | Node.js version (default: 24) |
54
56
  | `--python-version` | Python version (default: 3.14) |
55
- | `--no-uv` | Use pip/venv instead of uv |
56
57
  | `-v, --version` | Show version |
57
58
 
58
59
  ## Examples
@@ -68,11 +69,11 @@ aws-lambda-layer-cli publish --nodejs lodash --profile prod --region us-east-1 -
68
69
 
69
70
  ### Python
70
71
  ```bash
71
- # Create local zip with specific python version
72
- aws-lambda-layer-cli zip --python numpy==1.26.0,pandas --python-version 3.12
72
+ # Create local zip with specific python version and architecture
73
+ aws-lambda-layer-cli zip --python numpy==1.26.0,pandas --python-version 3.12 --architecture arm64
73
74
 
74
- # Publish to AWS
75
- aws-lambda-layer-cli publish --python requests --name web-layer
75
+ # Publish to AWS with explicit platform tag (e.g. Amazon Linux 2023 / manylinux_2_28)
76
+ aws-lambda-layer-cli publish --python requests --name web-layer --platform manylinux_2_28_x86_64
76
77
  ```
77
78
 
78
79
  ## Shell Completion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aws-lambda-layer-cli",
3
- "version": "2.0.4",
3
+ "version": "2.1.3",
4
4
  "description": "CLI tool for creating and publishing AWS Lambda layers for Node.js and Python.",
5
5
  "keywords": [
6
6
  "aws",
@@ -47,7 +47,7 @@ COMPLETION_DIR="/etc/bash_completion.d"
47
47
  # Show help
48
48
  show_help() {
49
49
  local version_file="$SCRIPT_DIR/VERSION.txt"
50
- local version="2.0.4"
50
+ local version="2.1.3"
51
51
  if [ -f "$version_file" ]; then
52
52
  version=$(cat "$version_file")
53
53
  fi
@@ -85,7 +85,8 @@ show_help() {
85
85
  printf " ${YELLOW}--version, -v${NC} Show tool version information\n"
86
86
  printf " ${YELLOW}--node-version${NC} Node.js version (default: 24)\n"
87
87
  printf " ${YELLOW}--python-version${NC} Python version (default: 3.14)\n"
88
- printf " ${YELLOW}--no-uv${NC} Use pip/venv instead of uv\n\n"
88
+ printf " ${YELLOW}--architecture, -a${NC} Target architecture (x86_64, arm64)\n"
89
+ printf " ${YELLOW}--platform${NC} Target platform tag (Python only)\n\n"
89
90
 
90
91
  printf "${MAGENTA}${UNDERLINE}Package Version Examples:${NC}\n"
91
92
  printf " Node.js: express@^4.0.0, lodash@~4.17.0, axios@>=1.6.0\n"
@@ -113,7 +114,7 @@ show_version() {
113
114
  echo "v$version"
114
115
  else
115
116
  # Fallback if VERSION file is missing (e.g. during development or if moved)
116
- echo "v2.0.4"
117
+ echo "v2.1.3"
117
118
  fi
118
119
  }
119
120
 
@@ -251,7 +252,7 @@ get_aws_account_info() {
251
252
  # Determine compatible runtimes for AWS
252
253
  get_compatible_runtimes() {
253
254
  local runtime="$1"
254
- local version="2.0.4"
255
+ local version="2.1.3"
255
256
 
256
257
  case "$runtime" in
257
258
  nodejs)
@@ -659,7 +660,8 @@ handle_publish() {
659
660
  fi
660
661
 
661
662
  # Extract Python version for compatible runtimes
662
- local python_version=$(grep -o "Python: [0-9.]*" "build.log" | cut -d' ' -f2 | tail -1)
663
+ # Pattern matches "Python version: X.Y" or "Python Version: X.Y"
664
+ local python_version=$(grep -i "Python.*version: [0-9.]*" "build.log" | awk '{print $NF}' | tail -1)
663
665
  if [ -z "$python_version" ]; then
664
666
  python_version="3.14"
665
667
  fi
@@ -19,8 +19,11 @@ LAYER_NAME=""
19
19
  PYTHON_VERSION="3.14" # Default to Python 3.14
20
20
  PYTHON_VERSION_SPECIFIED=false
21
21
  VENV_DIR="python"
22
- USE_UV=true
23
22
  ORIGINAL_DIR=$(pwd)
23
+ PLATFORM="" # Optional platform targeting
24
+ IMPLEMENTATION="cp"
25
+ ABI=""
26
+ ARCHITECTURE="x86_64" # Default architecture
24
27
 
25
28
  # Colors for output
26
29
  RED='\033[0;31m'
@@ -137,26 +140,58 @@ while [[ $# -gt 0 ]]; do
137
140
  validate_python_version "$PYTHON_VERSION"
138
141
  shift
139
142
  ;;
140
- --no-uv)
141
- USE_UV=false
143
+ --platform)
144
+ if [[ -n "${2:-}" && "${2:-}" != -* ]]; then
145
+ PLATFORM="$2"
146
+ shift 2
147
+ else
148
+ printf "${RED}Error: $1 requires an argument${NC}\n"
149
+ printf "Example: $1 manylinux_2_28_x86_64\n"
150
+ exit 1
151
+ fi
152
+ ;;
153
+ --platform=*)
154
+ PLATFORM="${1#*=}"
155
+ shift
156
+ ;;
157
+ -a|--architecture)
158
+ if [[ -n "${2:-}" && "${2:-}" != -* ]]; then
159
+ ARCHITECTURE="$2"
160
+ shift 2
161
+ else
162
+ printf "${RED}Error: $1 requires an argument${NC}\n"
163
+ printf "Example: $1 arm64\n"
164
+ exit 1
165
+ fi
166
+ ;;
167
+ --architecture=*)
168
+ ARCHITECTURE="${1#*=}"
142
169
  shift
143
170
  ;;
144
171
  -h|--help)
145
172
  cat << 'EOF'
146
- Python Lambda Layer Creator with UV
173
+ Python Lambda Layer Creator
147
174
 
148
175
  Usage:
149
176
  ./create_python_layer.sh -i numpy==1.26.0,pandas==2.1.3
150
177
  ./create_python_layer.sh --packages=numpy==1.26.0,pandas,boto3==1.34.0 -n my-layer.zip
151
- ./create_python_layer.sh -i flask==3.0.0 --no-uv
152
178
 
153
179
  Options:
154
180
  -i, --packages Comma-separated list of Python packages (with optional versions)
155
181
  -n, --name Name of the output zip file
156
182
  --python-version Python version (default: 3.14)
157
- --no-uv Use pip/venv instead of uv
183
+ --platform Target platform tag (optional, overrides architecture)
184
+ -a, --architecture Target architecture (x86_64 or arm64, default: x86_64)
158
185
  -h, --help Show this help message
159
186
 
187
+ Supported Platforms (optional):
188
+ manylinux2014_x86_64 # Amazon Linux 2, RHEL 7+ (older)
189
+ manylinux2014_aarch64 # ARM64 architecture
190
+ manylinux_2_28_x86_64 # Amazon Linux 2023, RHEL 8+ (newer)
191
+ manylinux_2_28_aarch64 # ARM64 with newer glibc
192
+ linux_x86_64 # Generic Linux
193
+ linux_aarch64 # Generic ARM64 Linux
194
+
160
195
  Version Specification:
161
196
  Package versions can be specified using standard Python version specifiers:
162
197
  numpy==1.26.0 # Exact version
@@ -167,9 +202,14 @@ Version Specification:
167
202
  Django!=3.2.0 # Version exclusion
168
203
 
169
204
  Examples:
205
+ # Basic usage
170
206
  ./create_python_layer.sh -i numpy==1.26.0
171
- ./create_python_layer.sh -i requests==2.31.0,boto3==1.34.0 --python-version=3.14
172
- ./create_python_layer.sh --packages=pandas==2.1.3,scikit-learn==1.3.0 --no-uv -n ml-layer.zip
207
+
208
+ # With platform targeting for Amazon Linux 2023
209
+ ./create_python_layer.sh -i requests==2.31.0,boto3==1.34.0 --python-version=3.13 --platform=manylinux_2_28_x86_64
210
+
211
+ # With platform targeting for ARM64
212
+ ./create_python_layer.sh --packages=pandas==2.1.3,scikit-learn==1.3.0 --platform=manylinux_2_28_aarch64 -n ml-layer.zip
173
213
  EOF
174
214
  exit 0
175
215
  ;;
@@ -189,14 +229,6 @@ if [ -z "$PACKAGES" ]; then
189
229
  exit 1
190
230
  fi
191
231
 
192
- # Check if uv is available safely
193
- if [ "$USE_UV" = true ]; then
194
- if ! command -v uv >/dev/null 2>&1; then
195
- printf "${YELLOW}Warning: uv not found, falling back to pip/venv${NC}\n"
196
- USE_UV=false
197
- fi
198
- fi
199
-
200
232
  # Check dependencies
201
233
  if ! command -v zip &> /dev/null; then
202
234
  printf "${RED}Error: 'zip' command is not installed${NC}\n"
@@ -236,12 +268,29 @@ if [ "$PACKAGES" != "$SANITIZED_PACKAGES" ]; then
236
268
  PACKAGES="$SANITIZED_PACKAGES"
237
269
  fi
238
270
 
271
+ # Normalize Architecture
272
+ AWS_ARCH="$ARCHITECTURE"
273
+ if [ "$ARCHITECTURE" = "arm64" ]; then
274
+ ARCHITECTURE="aarch64"
275
+ AWS_ARCH="arm64"
276
+ elif [ "$ARCHITECTURE" = "amd64" ]; then
277
+ ARCHITECTURE="x86_64"
278
+ AWS_ARCH="x86_64"
279
+ elif [ "$ARCHITECTURE" = "x86_64" ]; then
280
+ AWS_ARCH="x86_64"
281
+ elif [ "$ARCHITECTURE" = "aarch64" ]; then
282
+ AWS_ARCH="arm64"
283
+ fi
284
+
239
285
  printf "${BLUE}=========================================${NC}\n"
240
286
  printf "${GREEN}Python Lambda Layer Creator${NC}\n"
241
287
  printf "${BLUE}=========================================${NC}\n"
242
288
  printf "Packages: $PACKAGES\n"
243
289
  printf "Python version: $PYTHON_VERSION\n"
244
- printf "Using UV: $USE_UV\n"
290
+ printf "Target Architecture: $AWS_ARCH\n"
291
+ if [ -n "$PLATFORM" ]; then
292
+ printf "Platform: $PLATFORM\n"
293
+ fi
245
294
  if [ -n "$LAYER_NAME" ]; then
246
295
  printf "Output name: $LAYER_NAME\n"
247
296
  fi
@@ -277,20 +326,12 @@ if ! command -v "$TARGET_PYTHON" >/dev/null 2>&1; then
277
326
  fi
278
327
  fi
279
328
 
280
- if [ "$USE_UV" = true ]; then
281
- printf " Using UV to create venv...\n"
282
- if ! uv venv --python "$TARGET_PYTHON" "$VENV_DIR"; then
283
- printf "${RED}Error: Failed to create venv with uv${NC}\n"
284
- exit 1
285
- fi
329
+ printf " Using venv module...\n"
330
+ if command -v "$TARGET_PYTHON" >/dev/null 2>&1; then
331
+ "$TARGET_PYTHON" -m venv "$VENV_DIR"
286
332
  else
287
- printf " Using venv module...\n"
288
- if command -v "$TARGET_PYTHON" >/dev/null 2>&1; then
289
- "$TARGET_PYTHON" -m venv "$VENV_DIR"
290
- else
291
- printf "${RED}Error: $TARGET_PYTHON not found${NC}\n"
292
- exit 1
293
- fi
333
+ printf "${RED}Error: $TARGET_PYTHON not found${NC}\n"
334
+ exit 1
294
335
  fi
295
336
 
296
337
  # Activate virtual environment
@@ -307,15 +348,53 @@ set -u
307
348
 
308
349
  # Step 3: Install packages with versions
309
350
  printf "[3/7] Installing packages...\n"
310
- if [ "$USE_UV" = true ]; then
311
- printf " Installing with UV...\n"
312
- # Convert to array for safe expansion
313
- IFS=',' read -ra PKG_ARRAY <<< "$PACKAGES"
314
- uv pip install "${PKG_ARRAY[@]}"
351
+
352
+ # Auto-detect platform if not specified
353
+ if [ -z "$PLATFORM" ]; then
354
+ # Calculate major/minor version
355
+ # PYTHON_VERSION is like 3.14 or 3.14.2
356
+ PY_VER_MAJOR=$(echo "$PYTHON_VERSION" | cut -d. -f1)
357
+ PY_VER_MINOR=$(echo "$PYTHON_VERSION" | cut -d. -f2)
358
+
359
+ # Default to manylinux2014 (Amazon Linux 2)
360
+ PLATFORM_PREFIX="manylinux2014"
361
+
362
+ # Legacy: We previously checked for AL2023 (manylinux_2_28) here, but forcing it
363
+ # causes issues with packages like NumPy that publish manylinux2014 or manylinux_2_17 wheels.
364
+ # Since AL2023 is backward compatible with manylinux2014, we stick to that for max compatibility.
365
+
366
+ PLATFORM="${PLATFORM_PREFIX}_${ARCHITECTURE}"
367
+ printf "Auto-detected platform: $PLATFORM (Python $PYTHON_VERSION, Arch $ARCHITECTURE)\n"
368
+ fi
369
+
370
+ # Prepare platform-specific options
371
+ INSTALL_OPTS=()
372
+ if [ -n "$PLATFORM" ]; then
373
+ # Calculate ABI tag based on Python version (e.g., 3.12 -> cp312)
374
+ # We use cut instead of potentially fragile regex
375
+ PY_MAJOR=$(echo "$PYTHON_VERSION" | cut -d. -f1)
376
+ PY_MINOR=$(echo "$PYTHON_VERSION" | cut -d. -f2)
377
+ ABI="cp${PY_MAJOR}${PY_MINOR}"
378
+
379
+ INSTALL_OPTS+=("--platform" "$PLATFORM")
380
+ INSTALL_OPTS+=("--implementation" "$IMPLEMENTATION")
381
+ INSTALL_OPTS+=("--python-version" "$PYTHON_VERSION")
382
+ INSTALL_OPTS+=("--abi" "$ABI")
383
+ INSTALL_OPTS+=("--only-binary=:all:")
384
+ printf " Using platform-specific installation: $PLATFORM\n"
385
+ printf " ABI tag: $ABI\n"
386
+ fi
387
+
388
+ printf " Installing with pip...\n"
389
+ # Convert to array for safe expansion
390
+ IFS=',' read -ra PKG_ARRAY <<< "$PACKAGES"
391
+ if [ ${#INSTALL_OPTS[@]} -gt 0 ]; then
392
+ # When using platform specific options, we must specify --target
393
+ # We use the site-packages directory of the current venv
394
+ SITE_PACKAGES=$(python -c "import site; print(site.getsitepackages()[0])")
395
+ printf " Targeting site-packages: $SITE_PACKAGES\n"
396
+ pip install "${PKG_ARRAY[@]}" "${INSTALL_OPTS[@]}" --target "$SITE_PACKAGES"
315
397
  else
316
- printf " Installing with pip...\n"
317
- # Convert to array for safe expansion
318
- IFS=',' read -ra PKG_ARRAY <<< "$PACKAGES"
319
398
  pip install "${PKG_ARRAY[@]}"
320
399
  fi
321
400
 
@@ -333,11 +412,7 @@ if [ -z "$LAYER_NAME" ]; then
333
412
  printf " Single package: $PKG_NAME\n"
334
413
 
335
414
  # Extract version from installed package
336
- if [ "$USE_UV" = true ]; then
337
- PKG_INFO=$(uv pip show "$PKG_NAME" 2>/dev/null || true)
338
- else
339
- PKG_INFO=$(pip show "$PKG_NAME" 2>/dev/null || true)
340
- fi
415
+ PKG_INFO=$(pip show "$PKG_NAME" 2>/dev/null || true)
341
416
 
342
417
  if [ -n "$PKG_INFO" ]; then
343
418
  # Use safer extraction methods
@@ -400,11 +475,7 @@ fi
400
475
 
401
476
  # Step 5: Show installed packages
402
477
  printf "[5/7] Listing installed packages...\n"
403
- if [ "$USE_UV" = true ]; then
404
- uv pip list --format freeze
405
- else
406
- pip list --format freeze
407
- fi
478
+ pip list --format freeze
408
479
 
409
480
  # Deactivate virtual environment
410
481
  set +u
@@ -433,7 +504,7 @@ printf "${GREEN}✅ SUCCESS: Python Lambda Layer Created${NC}\n"
433
504
  printf "${BLUE}=========================================${NC}\n"
434
505
  printf "📁 File: $ORIGINAL_DIR/$LAYER_NAME\n"
435
506
  printf "🐍 Python Version: $PYTHON_VERSION\n"
436
- printf "⚡ Tool: $(if [ "$USE_UV" = true ]; then echo "UV"; else echo "pip/venv"; fi)\n"
507
+ printf "⚡ Tool: pip/venv\n"
437
508
  printf "📦 Size: $(du -h "$ORIGINAL_DIR/$LAYER_NAME" | cut -f1)\n"
438
509
  printf "📊 Package Count: $PACKAGE_COUNT\n"
439
510
 
@@ -446,11 +517,7 @@ for pkg_full in "${PKG_ARRAY[@]}"; do
446
517
  pkg_name=$(extract_package_name "$pkg_full")
447
518
 
448
519
  # Get installed version from pip show or metadata
449
- if [ "$USE_UV" = true ]; then
450
- installed_ver=$(find . -type f -name "METADATA" -path "*/${pkg_name}-*.dist-info/METADATA" -exec grep -h "^Version:" {} \; | head -1 | cut -d' ' -f2)
451
- else
452
- installed_ver=$(find . -type f -name "METADATA" -path "*/${pkg_name}-*.dist-info/METADATA" -exec grep -h "^Version:" {} \; | head -1 | cut -d' ' -f2)
453
- fi
520
+ installed_ver=$(find . -type f -name "METADATA" -path "*/${pkg_name}-*.dist-info/METADATA" -exec grep -h "^Version:" {} \; | head -1 | cut -d' ' -f2)
454
521
 
455
522
  if [ -n "$installed_ver" ]; then
456
523
  if [ -n "$INSTALLED_PKGS" ]; then
@@ -0,0 +1,221 @@
1
+ #!/bin/bash
2
+
3
+ # Python Lambda Layer Creator from Wheel
4
+ # Usage:
5
+ # ./create_wheel_layer.sh -w mypackage.whl
6
+ # ./create_wheel_layer.sh -w mypackage.whl -i "pandas,boto3" -n my-layer.zip
7
+
8
+ set -e
9
+ set -u
10
+
11
+ # Default values
12
+ WHEEL_FILE=""
13
+ PACKAGES=""
14
+ LAYER_NAME=""
15
+ PYTHON_VERSION="3.12"
16
+ PLATFORM="manylinux2014_x86_64"
17
+ IMPLEMENTATION="cp"
18
+ ABI="cp312" # Default ABI tag
19
+
20
+ # Colors
21
+ RED='\033[0;31m'
22
+ GREEN='\033[0;32m'
23
+ YELLOW='\033[1;33m'
24
+ NC='\033[0m'
25
+
26
+ # Parse arguments
27
+ while [[ $# -gt 0 ]]; do
28
+ case "$1" in
29
+ -w|--wheel)
30
+ if [[ -n "${2:-}" && "${2:-}" != -* ]]; then
31
+ WHEEL_FILE="$2"
32
+ shift 2
33
+ else
34
+ printf "${RED}Error: $1 requires an argument${NC}\n"
35
+ exit 1
36
+ fi
37
+ ;;
38
+ --wheel=*)
39
+ WHEEL_FILE="${1#*=}"
40
+ shift
41
+ ;;
42
+ -i|--packages)
43
+ if [[ -n "${2:-}" && "${2:-}" != -* ]]; then
44
+ PACKAGES="$2"
45
+ shift 2
46
+ else
47
+ printf "${RED}Error: $1 requires an argument${NC}\n"
48
+ exit 1
49
+ fi
50
+ ;;
51
+ --packages=*)
52
+ PACKAGES="${1#*=}"
53
+ shift
54
+ ;;
55
+ -n|--name)
56
+ if [[ -n "${2:-}" && "${2:-}" != -* ]]; then
57
+ LAYER_NAME="$2"
58
+ shift 2
59
+ else
60
+ printf "${RED}Error: $1 requires an argument${NC}\n"
61
+ exit 1
62
+ fi
63
+ ;;
64
+ --name=*)
65
+ LAYER_NAME="${1#*=}"
66
+ shift
67
+ ;;
68
+ --python-version)
69
+ if [[ -n "${2:-}" && "${2:-}" != -* ]]; then
70
+ PYTHON_VERSION="$2"
71
+ shift 2
72
+ else
73
+ printf "${RED}Error: $1 requires an argument${NC}\n"
74
+ exit 1
75
+ fi
76
+ ;;
77
+ --python-version=*)
78
+ PYTHON_VERSION="${1#*=}"
79
+ shift
80
+ ;;
81
+ --platform)
82
+ if [[ -n "${2:-}" && "${2:-}" != -* ]]; then
83
+ PLATFORM="$2"
84
+ shift 2
85
+ else
86
+ printf "${RED}Error: $1 requires an argument${NC}\n"
87
+ exit 1
88
+ fi
89
+ ;;
90
+ --platform=*)
91
+ PLATFORM="${1#*=}"
92
+ shift
93
+ ;;
94
+ -h|--help)
95
+ cat << 'EOF'
96
+ Usage: ./create_wheel_layer.sh -w <wheel_file> [-i <packages>] [-n <zip_name>]
97
+
98
+ Options:
99
+ -w, --wheel Path to .whl file
100
+ -i, --packages Additional packages (comma or space separated)
101
+ -n, --name Output zip filename
102
+ --python-version Target Python version (default: 3.12)
103
+ --platform Target platform (default: manylinux2014_x86_64)
104
+
105
+ Supported Platforms:
106
+ manylinux2014_x86_64 # Amazon Linux 2, RHEL 7+ (older)
107
+ manylinux2014_aarch64 # ARM64 architecture
108
+ manylinux_2_28_x86_64 # Amazon Linux 2023, RHEL 8+ (newer)
109
+ manylinux_2_28_aarch64 # ARM64 with newer glibc
110
+ linux_x86_64 # Generic Linux
111
+ linux_aarch64 # Generic ARM64 Linux
112
+
113
+ Python Version Support:
114
+ 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
115
+
116
+ Examples:
117
+ # Build for Amazon Linux 2 (Python 3.12)
118
+ ./create_wheel_layer.sh -w mypackage.whl --python-version=3.12 --platform=manylinux2014_x86_64
119
+
120
+ # Build for Amazon Linux 2023 (Python 3.13)
121
+ ./create_wheel_layer.sh -w mypackage.whl --python-version=3.13 --platform=manylinux_2_28_x86_64
122
+
123
+ # Build with additional packages for ARM64
124
+ ./create_wheel_layer.sh -w mypackage.whl -i "numpy,pandas" --platform=manylinux_2_28_aarch64
125
+ EOF
126
+ exit 0
127
+ ;;
128
+ *)
129
+ printf "${RED}Unknown option: $1${NC}\n"
130
+ exit 1
131
+ ;;
132
+ esac
133
+ done
134
+
135
+ # Validation
136
+ if [ -z "$WHEEL_FILE" ]; then
137
+ printf "${RED}Error: Wheel file is required (-w)${NC}\n"
138
+ exit 1
139
+ fi
140
+
141
+ if [ ! -f "$WHEEL_FILE" ]; then
142
+ printf "${RED}Error: File $WHEEL_FILE not found${NC}\n"
143
+ exit 1
144
+ fi
145
+
146
+ # Determine ABI tag based on Python version
147
+ PY_MAJOR_MINOR=$(echo "$PYTHON_VERSION" | sed 's/\([0-9]\+\)\.\([0-9]\+\).*/\1\2/')
148
+ ABI="cp${PY_MAJOR_MINOR}"
149
+
150
+ if [ -z "$LAYER_NAME" ]; then
151
+ BASENAME=$(basename "$WHEEL_FILE" .whl)
152
+ LAYER_NAME="${BASENAME}_layer.zip"
153
+ fi
154
+
155
+ # Setup workspace
156
+ LAYER_DIR="layer_build_$(date +%s)"
157
+ ORIGINAL_DIR=$(pwd)
158
+
159
+ # Convert relative paths to absolute
160
+ if [[ "$WHEEL_FILE" != /* ]]; then
161
+ WHEEL_FILE="$ORIGINAL_DIR/$WHEEL_FILE"
162
+ fi
163
+
164
+ printf "${GREEN}Creating Lambda layer from wheel...${NC}\n"
165
+ printf "Wheel: $WHEEL_FILE\n"
166
+ if [ -n "$PACKAGES" ]; then
167
+ printf "Extra Packages: $PACKAGES\n"
168
+ fi
169
+ printf "Platform: $PLATFORM\n"
170
+ printf "Python: $PYTHON_VERSION\n"
171
+
172
+ mkdir -p "$LAYER_DIR/python"
173
+
174
+ # Install
175
+ printf "${GREEN}Installing packages...${NC}\n"
176
+ CMD=("pip" "install" "$WHEEL_FILE")
177
+
178
+ if [ -n "$PACKAGES" ]; then
179
+ # Replace commas with spaces
180
+ PKG_SPACE=$(echo "$PACKAGES" | tr ',' ' ')
181
+ # Split into array
182
+ read -ra PKG_ARRAY <<< "$PKG_SPACE"
183
+ CMD+=("${PKG_ARRAY[@]}")
184
+ fi
185
+
186
+ CMD+=("--target" "$LAYER_DIR/python")
187
+ CMD+=("--platform" "$PLATFORM")
188
+ CMD+=("--implementation" "$IMPLEMENTATION")
189
+ CMD+=("--python-version" "$PYTHON_VERSION")
190
+ CMD+=("--abi" "$ABI")
191
+ CMD+=("--only-binary=:all:")
192
+ CMD+=("--upgrade")
193
+
194
+ echo "Running: ${CMD[*]}"
195
+ if ! "${CMD[@]}"; then
196
+ printf "${RED}Installation failed${NC}\n"
197
+ rm -rf "$LAYER_DIR"
198
+ exit 1
199
+ fi
200
+
201
+ # Cleanup
202
+ printf "${GREEN}Removing cache and metadata...${NC}\n"
203
+ find "$LAYER_DIR" -type d -name "__pycache__" -exec rm -rf {} +
204
+ # Removing dist-info might break some packages (entry points, metadata), but user requested space saving
205
+ # Making it optional or just following user's script. Following user script:
206
+ find "$LAYER_DIR" -type d -name "*.dist-info" -exec rm -rf {} +
207
+
208
+ # Zip
209
+ printf "${GREEN}Zipping to $LAYER_NAME...${NC}\n"
210
+ cd "$LAYER_DIR"
211
+ if zip -r "$ORIGINAL_DIR/$LAYER_NAME" python > /dev/null; then
212
+ printf "${GREEN}✅ Done! Created $LAYER_NAME${NC}\n"
213
+ else
214
+ printf "${RED}Error creating zip file${NC}\n"
215
+ cd "$ORIGINAL_DIR"
216
+ rm -rf "$LAYER_DIR"
217
+ exit 1
218
+ fi
219
+
220
+ cd "$ORIGINAL_DIR"
221
+ rm -rf "$LAYER_DIR"
@@ -44,7 +44,7 @@ if ([string]::IsNullOrEmpty($InstallDir)) {
44
44
  # Configuration
45
45
  $RepoUrl = "https://github.com/yukcw/aws-lambda-layer-cli"
46
46
  $ToolName = "aws-lambda-layer-cli"
47
- $Version = "2.0.4" # Fallback version
47
+ $Version = "2.1.3" # Fallback version
48
48
 
49
49
  # Colors for output
50
50
  $Green = "Green"