aws-lambda-layer-cli 1.4.1 → 2.0.2

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.
@@ -1,663 +1,663 @@
1
- #Requires -Version 5.1
2
-
3
- <#
4
- .SYNOPSIS
5
- AWS Lambda Layer CLI Tool Installer for Windows
6
-
7
- .DESCRIPTION
8
- Installs the AWS Lambda Layer CLI tool on Windows systems.
9
- This tool requires Windows Subsystem for Linux (WSL) or Git Bash.
10
-
11
- .PARAMETER InstallDir
12
- Directory where the tool will be installed (default: $env:USERPROFILE\.aws-lambda-layer)
13
-
14
- .PARAMETER Force
15
- Force reinstallation even if already installed
16
-
17
- .EXAMPLE
18
- # Install with default settings
19
- .\install.ps1
20
-
21
- .EXAMPLE
22
- # Install to custom directory
23
- .\install.ps1 -InstallDir "C:\Tools\aws-lambda-layer"
24
-
25
- .EXAMPLE
26
- # Force reinstall
27
- .\install.ps1 -Force
28
- #>
29
-
30
- param(
31
- [string]$InstallDir,
32
- [switch]$Force
33
- )
34
-
35
- # Set default InstallDir if not provided
36
- if ([string]::IsNullOrEmpty($InstallDir)) {
37
- if ($env:USERPROFILE) {
38
- $InstallDir = "$env:USERPROFILE\.aws-lambda-layer"
39
- } else {
40
- $InstallDir = "$env:HOME/.aws-lambda-layer"
41
- }
42
- }
43
-
44
- # Configuration
45
- $RepoUrl = "https://github.com/yukcw/aws-lambda-layer-cli"
46
- $ToolName = "aws-lambda-layer"
47
- $Version = "1.4.1" # Fallback version
48
-
49
- # Colors for output
50
- $Green = "Green"
51
- $Yellow = "Yellow"
52
- $Red = "Red"
53
- $Blue = "Blue"
54
- $Cyan = "Cyan"
55
- $White = "White"
56
- $Magenta = "Magenta"
57
-
58
- function Write-ColorOutput {
59
- param(
60
- [string]$Message,
61
- [string]$Color = $White
62
- )
63
- Write-Host $Message -ForegroundColor $Color
64
- }
65
-
66
- function Write-Header {
67
- Write-ColorOutput "`n=========================================" $Cyan
68
- Write-ColorOutput "AWS Lambda Layer CLI Tool Installer" $Cyan
69
- Write-ColorOutput "=========================================" $Cyan
70
- Write-ColorOutput "Version: $Version" $White
71
- Write-ColorOutput "Install Directory: $InstallDir" $White
72
- Write-ColorOutput ""
73
- }
74
-
75
-
76
-
77
- function Test-Prerequisites {
78
- Write-ColorOutput "Checking prerequisites..." $Yellow
79
-
80
- $hasWSL = $false
81
- $hasGitBash = $false
82
- $hasAwsCli = $false
83
-
84
- # Check for WSL
85
- try {
86
- $wslInstallStatus = wsl --status 2>$null
87
- if ($LASTEXITCODE -eq 0) {
88
- $hasWSL = $true
89
- Write-ColorOutput "✓ WSL found" $Green
90
- }
91
- } catch {
92
- Write-ColorOutput "! WSL not found or not accessible" $Yellow
93
- }
94
-
95
- # Check for Git Bash
96
- $gitBashPath = $null
97
- $possiblePaths = @(
98
- "$env:ProgramFiles\Git\bin\bash.exe",
99
- "${env:ProgramFiles(x86)}\Git\bin\bash.exe",
100
- "$env:LOCALAPPDATA\Programs\Git\bin\bash.exe"
101
- )
102
-
103
- foreach ($path in $possiblePaths) {
104
- if (Test-Path $path) {
105
- $gitBashPath = $path
106
- break
107
- }
108
- }
109
-
110
- # If not found in standard locations, check PATH
111
- if (-not $gitBashPath) {
112
- $bashCmd = Get-Command bash -ErrorAction SilentlyContinue
113
- if ($bashCmd) {
114
- $path = $bashCmd.Source
115
- # Filter out WSL bash (usually in System32)
116
- if ($path -notlike "*\System32\bash.exe") {
117
- $gitBashPath = $path
118
- }
119
- }
120
- }
121
-
122
- if ($gitBashPath) {
123
- $hasGitBash = $true
124
- Write-ColorOutput "✓ Git Bash found at $gitBashPath" $Green
125
- }
126
-
127
- if (-not $hasWSL -and -not $hasGitBash) {
128
- Write-ColorOutput "✗ Neither WSL nor Git Bash found!" $Red
129
- Write-ColorOutput ""
130
- Write-ColorOutput "This tool requires a bash environment. Please install one of:" $Yellow
131
- Write-ColorOutput "1. Windows Subsystem for Linux (WSL):" $White
132
- Write-ColorOutput " wsl --install" $Cyan
133
- Write-ColorOutput ""
134
- Write-ColorOutput "2. Git for Windows:" $White
135
- Write-ColorOutput " https://gitforwindows.org/" $Cyan
136
- Write-ColorOutput ""
137
- exit 1
138
- }
139
-
140
- # Check for AWS CLI
141
- try {
142
- $awsVersion = & aws --version 2>$null
143
- if ($LASTEXITCODE -eq 0) {
144
- $hasAwsCli = $true
145
- Write-ColorOutput "✓ AWS CLI found" $Green
146
- }
147
- } catch {
148
- Write-ColorOutput "! AWS CLI not found (optional for zip command)" $Yellow
149
- }
150
-
151
- # Check for other dependencies
152
- $hasZipWSL = $false
153
- $hasZipGitBash = $false
154
- $hasPythonWSL = $false
155
- $hasVenvWSL = $false
156
- $hasPipWSL = $false
157
- $hasPythonGitBash = $false
158
- $hasNodeWSL = $false
159
- $hasNodeGitBash = $false
160
-
161
- # Check for zip in WSL
162
- if ($hasWSL) {
163
- try {
164
- $wslZip = wsl zip --version 2>$null
165
- if ($LASTEXITCODE -eq 0) {
166
- $hasZipWSL = $true
167
- Write-ColorOutput "✓ zip found in WSL" $Green
168
- } else {
169
- Write-ColorOutput "! zip not found in WSL" $Yellow
170
- }
171
- } catch { Write-ColorOutput "! Failed to check zip in WSL" $Yellow }
172
-
173
- try {
174
- # Check for python3 or python
175
- $wslPython = wsl bash -c "command -v python3 || command -v python" 2>$null
176
- if ($LASTEXITCODE -eq 0) {
177
- $hasPythonWSL = $true
178
- Write-ColorOutput "✓ python found in WSL" $Green
179
- } else {
180
- Write-ColorOutput "! python not found in WSL" $Yellow
181
- }
182
- } catch { Write-ColorOutput "! Failed to check python in WSL" $Yellow }
183
-
184
- try {
185
- # Check for python3-venv
186
- $wslVenv = wsl bash -c "python3 -c 'import venv' 2>/dev/null || python -c 'import venv' 2>/dev/null" 2>$null
187
- if ($LASTEXITCODE -eq 0) {
188
- $hasVenvWSL = $true
189
- Write-ColorOutput "✓ python venv module found in WSL" $Green
190
- } else {
191
- Write-ColorOutput "! python venv module not found in WSL" $Yellow
192
- }
193
- } catch { Write-ColorOutput "! Failed to check python venv in WSL" $Yellow }
194
-
195
- try {
196
- # Check for pip
197
- $wslPip = wsl bash -c "python3 -m pip --version 2>/dev/null || python -m pip --version 2>/dev/null" 2>$null
198
- if ($LASTEXITCODE -eq 0) {
199
- $hasPipWSL = $true
200
- Write-ColorOutput "✓ python pip module found in WSL" $Green
201
- } else {
202
- Write-ColorOutput "! python pip module not found in WSL" $Yellow
203
- }
204
- } catch { Write-ColorOutput "! Failed to check python pip in WSL" $Yellow }
205
-
206
- try {
207
- $wslNode = wsl node --version 2>$null
208
- if ($LASTEXITCODE -eq 0) {
209
- $hasNodeWSL = $true
210
- Write-ColorOutput "✓ node found in WSL" $Green
211
- } else {
212
- Write-ColorOutput "! node not found in WSL" $Yellow
213
- }
214
- } catch { Write-ColorOutput "! Failed to check node in WSL" $Yellow }
215
- }
216
-
217
- # Check for dependencies in Windows (for Git Bash)
218
- if ($hasGitBash) {
219
- function Check-WindowsTool {
220
- param($Name, $ExeName)
221
- $cmd = Get-Command $ExeName -ErrorAction SilentlyContinue
222
- if ($cmd) {
223
- if ($cmd.Version -and $cmd.Version.ToString() -ne "0.0.0.0") {
224
- Write-ColorOutput "✓ $Name found ($($cmd.Version))" $Green
225
- return $true
226
- }
227
- }
228
- Write-ColorOutput "! $Name not found in Windows PATH" $Yellow
229
- return $false
230
- }
231
-
232
- $hasZipGitBash = Check-WindowsTool "zip" "zip.exe"
233
- $hasPythonGitBash = Check-WindowsTool "python" "python.exe"
234
- $hasNodeGitBash = Check-WindowsTool "node" "node.exe"
235
- }
236
-
237
- return @{
238
- WSL = $hasWSL
239
- GitBash = $hasGitBash
240
- GitBashPath = $gitBashPath
241
- AwsCli = $hasAwsCli
242
- ZipWSL = $hasZipWSL
243
- ZipGitBash = $hasZipGitBash
244
- PythonWSL = $hasPythonWSL
245
- VenvWSL = $hasVenvWSL
246
- PipWSL = $hasPipWSL
247
- PythonGitBash = $hasPythonGitBash
248
- NodeWSL = $hasNodeWSL
249
- NodeGitBash = $hasNodeGitBash
250
- }
251
- }
252
-
253
- function Install-Dependencies {
254
- param([hashtable]$Prereqs)
255
-
256
- # Handle WSL zip installation
257
- if ($Prereqs.WSL -and -not $Prereqs.ZipWSL) {
258
- $installZip = Read-Host "Zip not found in WSL. Try to install it? (Y/n)"
259
- if ($installZip -match "^[Yy]|^$") {
260
- Write-ColorOutput "Attempting to install zip in WSL (you may be asked for your sudo password)..." $Cyan
261
- try {
262
- # Try apt-get (Debian/Ubuntu)
263
- Write-ColorOutput "Running: wsl sudo apt-get update && sudo apt-get install -y zip" $White
264
- wsl sudo apt-get update
265
- wsl sudo apt-get install -y zip
266
-
267
- if ($LASTEXITCODE -eq 0) {
268
- Write-ColorOutput "✓ zip installed in WSL" $Green
269
- $Prereqs.ZipWSL = $true
270
- } else {
271
- Write-ColorOutput "✗ Failed to install zip automatically." $Red
272
- Write-ColorOutput "Please run 'sudo apt-get install zip' (or equivalent) inside WSL manually." $Yellow
273
- }
274
- } catch {
275
- Write-ColorOutput "✗ Failed to execute WSL commands." $Red
276
- }
277
- }
278
- }
279
-
280
- # Handle Git Bash zip installation
281
- if ($Prereqs.GitBash -and -not $Prereqs.ZipGitBash) {
282
- # Check if GnuWin32 is already installed but not in PATH
283
- $gnuWin32Path = "${env:ProgramFiles(x86)}\GnuWin32\bin"
284
- if (Test-Path $gnuWin32Path) {
285
- $currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
286
- if ($currentPath -notlike "*$gnuWin32Path*") {
287
- $newPath = "$currentPath;$gnuWin32Path"
288
- [Environment]::SetEnvironmentVariable("Path", $newPath, "User")
289
- Write-ColorOutput "✓ Found GnuWin32 Zip at $gnuWin32Path" $Green
290
- Write-ColorOutput "✓ Added GnuWin32 to user PATH" $Green
291
- Write-ColorOutput " Note: You may need to restart your terminal for PATH changes to take effect." $Yellow
292
- $Prereqs.ZipGitBash = $true
293
- }
294
- }
295
-
296
- if (-not $Prereqs.ZipGitBash) {
297
- $installZip = Read-Host "Zip not found in Git Bash. Try to install GnuWin32 Zip with winget? (Y/n)"
298
- if ($installZip -match "^[Yy]|^$") {
299
- Write-ColorOutput "Attempting to install GnuWin32 Zip..." $Cyan
300
- try {
301
- $wingetVersion = & winget --version 2>$null
302
- if ($LASTEXITCODE -eq 0) {
303
- & winget install --id GnuWin32.Zip -e --source winget
304
- if ($LASTEXITCODE -eq 0) {
305
- Write-ColorOutput "✓ GnuWin32 Zip installed" $Green
306
-
307
- # Add GnuWin32 to PATH
308
- if (Test-Path $gnuWin32Path) {
309
- $currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
310
- if ($currentPath -notlike "*$gnuWin32Path*") {
311
- $newPath = "$currentPath;$gnuWin32Path"
312
- [Environment]::SetEnvironmentVariable("Path", $newPath, "User")
313
- Write-ColorOutput "✓ Added $gnuWin32Path to user PATH" $Green
314
- }
315
- }
316
-
317
- Write-ColorOutput " Note: You may need to restart your terminal for PATH changes to take effect." $Yellow
318
- $Prereqs.ZipGitBash = $true
319
- } else {
320
- Write-ColorOutput "✗ Failed to install GnuWin32 Zip." $Red
321
- Write-ColorOutput "Please install 'zip' manually (e.g. 'winget install GnuWin32.Zip')." $Yellow
322
- }
323
- } else {
324
- Write-ColorOutput "winget not found. Please install 'zip' manually." $Yellow
325
- }
326
- } catch {
327
- Write-ColorOutput "Error running winget." $Red
328
- }
329
- }
330
- }
331
- }
332
-
333
- if (-not $Prereqs.PythonWSL -or -not $Prereqs.VenvWSL -or -not $Prereqs.PipWSL -or -not $Prereqs.NodeWSL -or -not $Prereqs.PythonGitBash -or -not $Prereqs.NodeGitBash -or -not $Prereqs.AwsCli) {
334
- Write-ColorOutput "`nChecking for missing dependencies..." $Yellow
335
-
336
- # Handle WSL dependencies
337
- if ($Prereqs.WSL) {
338
- if (-not $Prereqs.PythonWSL -or -not $Prereqs.VenvWSL -or -not $Prereqs.PipWSL -or -not $Prereqs.NodeWSL) {
339
- $installWslDeps = Read-Host "Missing dependencies in WSL. Try to install them? (Y/n)"
340
- if ($installWslDeps -match "^[Yy]|^$") {
341
- Write-ColorOutput "Attempting to install dependencies in WSL..." $Cyan
342
- try {
343
- Write-ColorOutput "Running: wsl sudo apt-get update" $White
344
- wsl sudo apt-get update
345
-
346
- if (-not $Prereqs.PythonWSL) {
347
- Write-ColorOutput "Installing Python in WSL..." $Cyan
348
- wsl sudo apt-get install -y python3 python3-pip python3-venv
349
- } elseif (-not $Prereqs.VenvWSL -or -not $Prereqs.PipWSL) {
350
- Write-ColorOutput "Installing Python venv/pip in WSL..." $Cyan
351
- wsl sudo apt-get install -y python3-venv python3-pip
352
- }
353
- if (-not $Prereqs.NodeWSL) {
354
- Write-ColorOutput "Installing Node.js in WSL..." $Cyan
355
- wsl sudo apt-get install -y nodejs npm
356
- }
357
- } catch {
358
- Write-ColorOutput "✗ Failed to execute WSL commands." $Red
359
- }
360
- }
361
- }
362
- }
363
-
364
- # Handle Git Bash / Windows dependencies
365
- # If Git Bash is present but missing deps, we install them in Windows so Git Bash inherits them
366
- if ($Prereqs.GitBash) {
367
- if (-not $Prereqs.PythonGitBash -or -not $Prereqs.NodeGitBash -or -not $Prereqs.AwsCli) {
368
- # Check if winget is available
369
- try {
370
- $wingetVersion = & winget --version 2>$null
371
- if ($LASTEXITCODE -eq 0) {
372
- $installDeps = Read-Host "Missing Windows dependencies (for Git Bash). Try to install them with winget? (Y/n)"
373
- if ($installDeps -match "^[Yy]|^$") {
374
- if (-not $Prereqs.PythonGitBash) {
375
- Write-ColorOutput "Installing Python..." $Cyan
376
- & winget install --id Python.Python.3.12 -e --source winget
377
- }
378
- if (-not $Prereqs.NodeGitBash) {
379
- Write-ColorOutput "Installing Node.js..." $Cyan
380
- & winget install --id OpenJS.NodeJS.LTS -e --source winget
381
- }
382
- if (-not $Prereqs.AwsCli) {
383
- Write-ColorOutput "Installing AWS CLI..." $Cyan
384
- & winget install --id Amazon.AWSCLI -e --source winget
385
- }
386
- Write-ColorOutput "Dependencies installed. You may need to restart your terminal." $Green
387
- }
388
- } else {
389
- Write-ColorOutput "winget not found. Please install missing dependencies manually." $Yellow
390
- }
391
- } catch {
392
- Write-ColorOutput "winget not found. Please install missing dependencies manually." $Yellow
393
- }
394
- }
395
- }
396
- }
397
- }
398
-
399
- function Install-Tool {
400
- param([hashtable]$Prereqs)
401
-
402
- # Create install directory
403
- if (Test-Path $InstallDir) {
404
- if ($Force) {
405
- Write-ColorOutput "Removing existing installation..." $Yellow
406
- Remove-Item $InstallDir -Recurse -Force
407
- } else {
408
- Write-ColorOutput "Installation directory already exists: $InstallDir" $Yellow
409
- $overwrite = Read-Host "Overwrite existing installation? (y/N)"
410
- if ($overwrite -notmatch "^[Yy]$") {
411
- Write-ColorOutput "Installation cancelled." $Red
412
- exit 0
413
- }
414
- Remove-Item $InstallDir -Recurse -Force
415
- }
416
- }
417
-
418
- New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
419
- Write-ColorOutput "Created install directory: $InstallDir" $Green
420
-
421
- # Download individual files
422
- Write-ColorOutput "Downloading files..." $Yellow
423
-
424
- $files = @(
425
- "VERSION.txt"
426
- )
427
-
428
- $scripts = @(
429
- "aws-lambda-layer",
430
- "create_nodejs_layer.sh",
431
- "create_python_layer.sh",
432
- "uninstall.sh",
433
- "uninstall.ps1"
434
- )
435
-
436
- $baseUrl = "https://raw.githubusercontent.com/yukcw/aws-lambda-layer-cli/main"
437
-
438
- foreach ($file in $files) {
439
- $outputPath = Join-Path $InstallDir $file
440
- $url = "$baseUrl/$file"
441
- try {
442
- Invoke-WebRequest -Uri $url -OutFile $outputPath
443
- Write-ColorOutput "✓ Downloaded $file" $Green
444
- } catch {
445
- Write-ColorOutput "✗ Failed to download $file" $Red
446
- Write-ColorOutput "Error: $($_.Exception.Message)" $Red
447
- return $false
448
- }
449
- }
450
-
451
- foreach ($script in $scripts) {
452
- $outputPath = Join-Path $InstallDir $script
453
- $url = "$baseUrl/scripts/$script"
454
- try {
455
- Invoke-WebRequest -Uri $url -OutFile $outputPath
456
- Write-ColorOutput "✓ Downloaded $script" $Green
457
- } catch {
458
- Write-ColorOutput "✗ Failed to download $script" $Red
459
- Write-ColorOutput "Error: $($_.Exception.Message)" $Red
460
- return $false
461
- }
462
- }
463
-
464
- # Download completion files
465
- $completionDir = Join-Path $InstallDir "completion"
466
- New-Item -ItemType Directory -Path $completionDir -Force | Out-Null
467
-
468
- $completionFiles = @(
469
- "completion/aws-lambda-layer-completion.bash",
470
- "completion/aws-lambda-layer-completion.zsh"
471
- )
472
-
473
- foreach ($file in $completionFiles) {
474
- $outputPath = Join-Path $InstallDir $file
475
- $url = "$baseUrl/$file"
476
- try {
477
- Invoke-WebRequest -Uri $url -OutFile $outputPath
478
- Write-ColorOutput "✓ Downloaded $file" $Green
479
- } catch {
480
- Write-ColorOutput "! Failed to download $file (optional)" $Yellow
481
- }
482
- }
483
-
484
- # Make scripts executable (for bash environment)
485
- Write-ColorOutput "Setting executable permissions..." $Yellow
486
- $scriptFiles = Get-ChildItem $InstallDir -Filter "*.sh" -File
487
- # Also include the main script
488
- $scriptFiles += Get-Item "$InstallDir\$ToolName" -ErrorAction SilentlyContinue
489
-
490
- foreach ($file in $scriptFiles) {
491
- try {
492
- # On Windows, we can't set +x directly, but we can ensure the file is readable
493
- # The bash environment will handle execution
494
- if ($file.Extension -eq ".sh" -or $file.Name -eq $ToolName) {
495
- # Ensure Unix line endings for bash scripts
496
- $content = Get-Content $file.FullName -Raw
497
- # Aggressively remove all carriage returns to ensure LF only
498
- $content = $content -replace "`r", ""
499
-
500
- # Write with UTF-8 (No BOM) to ensure compatibility
501
- $utf8NoBom = New-Object System.Text.UTF8Encoding $false
502
- [System.IO.File]::WriteAllText($file.FullName, $content, $utf8NoBom)
503
-
504
- # If not on Windows, set executable bit
505
- if (-not $IsWindows) {
506
- chmod +x $file.FullName
507
- }
508
-
509
- Write-ColorOutput "✓ Prepared $($file.Name)" $Green
510
- }
511
- } catch {
512
- Write-ColorOutput "! Could not prepare $($file.Name)" $Yellow
513
- }
514
- }
515
-
516
- return $true
517
- }
518
-
519
- function Setup-Path {
520
- param([hashtable]$Prereqs)
521
-
522
- Write-ColorOutput "Setting up PATH..." $Yellow
523
-
524
- # Add to PATH for current session
525
- $currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
526
- if ($currentPath -notlike "*$InstallDir*") {
527
- $newPath = "$currentPath;$InstallDir"
528
- [Environment]::SetEnvironmentVariable("Path", $newPath, "User")
529
- Write-ColorOutput "✓ Added $InstallDir to user PATH" $Green
530
- Write-ColorOutput " Note: Restart your terminal for PATH changes to take effect" $Yellow
531
- } else {
532
- Write-ColorOutput "✓ PATH already contains $InstallDir" $Green
533
- }
534
-
535
- # Create wrapper scripts for easier execution
536
- $wrapperScript = @"
537
- @echo off
538
- REM AWS Lambda Layer CLI Tool Wrapper for Windows
539
- REM This script helps run the tool in the appropriate bash environment
540
-
541
- setlocal enabledelayedexpansion
542
-
543
- set "WIN_PATH=$InstallDir"
544
-
545
- REM Detect which bash is being used to determine path style
546
- set "IS_WSL=0"
547
- for /f "delims=" %%i in ('where bash') do (
548
- echo "%%i" | findstr /i "System32" >nul
549
- if !ERRORLEVEL! EQU 0 set "IS_WSL=1"
550
- goto :DETECT_DONE
551
- )
552
- :DETECT_DONE
553
-
554
- if "!IS_WSL!"=="1" (
555
- REM WSL Environment - use wslpath
556
- where wsl >nul 2>nul
557
- if !ERRORLEVEL! EQU 0 (
558
- for /f "delims=" %%i in ('wsl wslpath -a "!WIN_PATH!"') do set "UNIX_PATH=%%i"
559
- ) else (
560
- REM Fallback for WSL if wsl.exe missing - assume /mnt/c/ style
561
- set "UNIX_PATH=!WIN_PATH:\=/!"
562
- if "!UNIX_PATH:~1,1!"==":" (
563
- set "DRIVE=!UNIX_PATH:~0,1!"
564
- REM Simple lowercase for common drives
565
- if /i "!DRIVE!"=="C" set "DRIVE=c"
566
- if /i "!DRIVE!"=="D" set "DRIVE=d"
567
- set "UNIX_PATH=/mnt/!DRIVE!!UNIX_PATH:~2!"
568
- )
569
- )
570
- ) else (
571
- REM Git Bash / Cygwin Environment
572
- where cygpath >nul 2>nul
573
- if !ERRORLEVEL! EQU 0 (
574
- for /f "delims=" %%i in ('cygpath "!WIN_PATH!"') do set "UNIX_PATH=%%i"
575
- ) else (
576
- REM Manual conversion fallback (Git Bash style /c/...)
577
- set "UNIX_PATH=!WIN_PATH:\=/!"
578
- if "!UNIX_PATH:~1,1!"==":" (
579
- set "UNIX_PATH=/!UNIX_PATH:~0,1!!UNIX_PATH:~2!"
580
- )
581
- )
582
- )
583
-
584
- where bash >nul 2>nul
585
- if %ERRORLEVEL% EQU 0 (
586
- REM Try to run with bash
587
- bash "!UNIX_PATH!/$ToolName" %*
588
- if !ERRORLEVEL! NEQ 0 (
589
- echo Error: Failed to execute aws-lambda-layer
590
- echo Please check that the script exists and is executable
591
- echo Script path: !UNIX_PATH!/$ToolName
592
- pause
593
- exit /b 1
594
- )
595
- ) else (
596
- echo Error: bash not found in PATH
597
- echo Please install Git for Windows or WSL
598
- echo https://gitforwindows.org/
599
- echo.
600
- echo Alternatively, you can run the script directly with:
601
- echo bash "!UNIX_PATH!/$ToolName" [arguments]
602
- pause
603
- exit /b 1
604
- )
605
- "@
606
-
607
- $wrapperPath = "$InstallDir\$ToolName.cmd"
608
- $wrapperScript | Out-File -FilePath $wrapperPath -Encoding ASCII
609
- Write-ColorOutput "✓ Created Windows wrapper script: $wrapperPath" $Green
610
- }
611
-
612
- function Show-PostInstall {
613
- Write-ColorOutput "`n=========================================" $Cyan
614
- Write-ColorOutput "Installation Complete!" $Green
615
- Write-ColorOutput "=========================================" $Cyan
616
- Write-ColorOutput ""
617
- Write-ColorOutput "The AWS Lambda Layer CLI tool has been installed to:" $White
618
- Write-ColorOutput " $InstallDir" $Cyan
619
- Write-ColorOutput ""
620
- Write-ColorOutput "Usage examples:" $Magenta
621
- Write-Host " aws-lambda-layer " -NoNewline -ForegroundColor $White
622
- Write-Host "zip " -NoNewline -ForegroundColor $Green
623
- Write-Host "--nodejs " -NoNewline -ForegroundColor $Yellow
624
- Write-Host """express@^4.0.0,lodash@~4.17.0""" -ForegroundColor $White
625
- Write-Host " aws-lambda-layer " -NoNewline -ForegroundColor $White
626
- Write-Host "zip " -NoNewline -ForegroundColor $Green
627
- Write-Host "--python " -NoNewline -ForegroundColor $Yellow
628
- Write-Host """numpy==1.26.0,pandas>=2.1.0""" -ForegroundColor $White
629
- Write-ColorOutput ""
630
- Write-ColorOutput "For more information:" $Yellow
631
- Write-Host " aws-lambda-layer " -NoNewline -ForegroundColor $White
632
- Write-ColorOutput "help" $Green
633
-
634
- Write-ColorOutput ""
635
- Write-ColorOutput "Repository: $RepoUrl" $White
636
- }
637
-
638
- # Main installation process
639
- function Main {
640
- Write-Header
641
-
642
- # Check prerequisites
643
- $prereqs = Test-Prerequisites
644
-
645
- # Install dependencies if needed
646
- Install-Dependencies -Prereqs $prereqs
647
-
648
- # Install the tool
649
- $installSuccess = Install-Tool -Prereqs $prereqs
650
- if (-not $installSuccess) {
651
- Write-ColorOutput "`nInstallation failed!" $Red
652
- exit 1
653
- }
654
-
655
- # Setup PATH and wrappers
656
- Setup-Path -Prereqs $prereqs
657
-
658
- # Show post-installation information
659
- Show-PostInstall
660
- }
661
-
662
- # Run main function
1
+ #Requires -Version 5.1
2
+
3
+ <#
4
+ .SYNOPSIS
5
+ AWS Lambda Layer CLI Tool Installer for Windows
6
+
7
+ .DESCRIPTION
8
+ Installs the AWS Lambda Layer CLI tool on Windows systems.
9
+ This tool requires Windows Subsystem for Linux (WSL) or Git Bash.
10
+
11
+ .PARAMETER InstallDir
12
+ Directory where the tool will be installed (default: $env:USERPROFILE\.aws-lambda-layer-cli)
13
+
14
+ .PARAMETER Force
15
+ Force reinstallation even if already installed
16
+
17
+ .EXAMPLE
18
+ # Install with default settings
19
+ .\install.ps1
20
+
21
+ .EXAMPLE
22
+ # Install to custom directory
23
+ .\install.ps1 -InstallDir "C:\Tools\aws-lambda-layer"
24
+
25
+ .EXAMPLE
26
+ # Force reinstall
27
+ .\install.ps1 -Force
28
+ #>
29
+
30
+ param(
31
+ [string]$InstallDir,
32
+ [switch]$Force
33
+ )
34
+
35
+ # Set default InstallDir if not provided
36
+ if ([string]::IsNullOrEmpty($InstallDir)) {
37
+ if ($env:USERPROFILE) {
38
+ $InstallDir = "$env:USERPROFILE\.aws-lambda-layer-cli"
39
+ } else {
40
+ $InstallDir = "$env:HOME/.aws-lambda-layer-cli"
41
+ }
42
+ }
43
+
44
+ # Configuration
45
+ $RepoUrl = "https://github.com/yukcw/aws-lambda-layer-cli"
46
+ $ToolName = "aws-lambda-layer-cli"
47
+ $Version = "1.4.1" # Fallback version
48
+
49
+ # Colors for output
50
+ $Green = "Green"
51
+ $Yellow = "Yellow"
52
+ $Red = "Red"
53
+ $Blue = "Blue"
54
+ $Cyan = "Cyan"
55
+ $White = "White"
56
+ $Magenta = "Magenta"
57
+
58
+ function Write-ColorOutput {
59
+ param(
60
+ [string]$Message,
61
+ [string]$Color = $White
62
+ )
63
+ Write-Host $Message -ForegroundColor $Color
64
+ }
65
+
66
+ function Write-Header {
67
+ Write-ColorOutput "`n=========================================" $Cyan
68
+ Write-ColorOutput "AWS Lambda Layer CLI Tool Installer" $Cyan
69
+ Write-ColorOutput "=========================================" $Cyan
70
+ Write-ColorOutput "Version: $Version" $White
71
+ Write-ColorOutput "Install Directory: $InstallDir" $White
72
+ Write-ColorOutput ""
73
+ }
74
+
75
+
76
+
77
+ function Test-Prerequisites {
78
+ Write-ColorOutput "Checking prerequisites..." $Yellow
79
+
80
+ $hasWSL = $false
81
+ $hasGitBash = $false
82
+ $hasAwsCli = $false
83
+
84
+ # Check for WSL
85
+ try {
86
+ $wslInstallStatus = wsl --status 2>$null
87
+ if ($LASTEXITCODE -eq 0) {
88
+ $hasWSL = $true
89
+ Write-ColorOutput "✓ WSL found" $Green
90
+ }
91
+ } catch {
92
+ Write-ColorOutput "! WSL not found or not accessible" $Yellow
93
+ }
94
+
95
+ # Check for Git Bash
96
+ $gitBashPath = $null
97
+ $possiblePaths = @(
98
+ "$env:ProgramFiles\Git\bin\bash.exe",
99
+ "${env:ProgramFiles(x86)}\Git\bin\bash.exe",
100
+ "$env:LOCALAPPDATA\Programs\Git\bin\bash.exe"
101
+ )
102
+
103
+ foreach ($path in $possiblePaths) {
104
+ if (Test-Path $path) {
105
+ $gitBashPath = $path
106
+ break
107
+ }
108
+ }
109
+
110
+ # If not found in standard locations, check PATH
111
+ if (-not $gitBashPath) {
112
+ $bashCmd = Get-Command bash -ErrorAction SilentlyContinue
113
+ if ($bashCmd) {
114
+ $path = $bashCmd.Source
115
+ # Filter out WSL bash (usually in System32)
116
+ if ($path -notlike "*\System32\bash.exe") {
117
+ $gitBashPath = $path
118
+ }
119
+ }
120
+ }
121
+
122
+ if ($gitBashPath) {
123
+ $hasGitBash = $true
124
+ Write-ColorOutput "✓ Git Bash found at $gitBashPath" $Green
125
+ }
126
+
127
+ if (-not $hasWSL -and -not $hasGitBash) {
128
+ Write-ColorOutput "✗ Neither WSL nor Git Bash found!" $Red
129
+ Write-ColorOutput ""
130
+ Write-ColorOutput "This tool requires a bash environment. Please install one of:" $Yellow
131
+ Write-ColorOutput "1. Windows Subsystem for Linux (WSL):" $White
132
+ Write-ColorOutput " wsl --install" $Cyan
133
+ Write-ColorOutput ""
134
+ Write-ColorOutput "2. Git for Windows:" $White
135
+ Write-ColorOutput " https://gitforwindows.org/" $Cyan
136
+ Write-ColorOutput ""
137
+ exit 1
138
+ }
139
+
140
+ # Check for AWS CLI
141
+ try {
142
+ $awsVersion = & aws --version 2>$null
143
+ if ($LASTEXITCODE -eq 0) {
144
+ $hasAwsCli = $true
145
+ Write-ColorOutput "✓ AWS CLI found" $Green
146
+ }
147
+ } catch {
148
+ Write-ColorOutput "! AWS CLI not found (optional for zip command)" $Yellow
149
+ }
150
+
151
+ # Check for other dependencies
152
+ $hasZipWSL = $false
153
+ $hasZipGitBash = $false
154
+ $hasPythonWSL = $false
155
+ $hasVenvWSL = $false
156
+ $hasPipWSL = $false
157
+ $hasPythonGitBash = $false
158
+ $hasNodeWSL = $false
159
+ $hasNodeGitBash = $false
160
+
161
+ # Check for zip in WSL
162
+ if ($hasWSL) {
163
+ try {
164
+ $wslZip = wsl zip --version 2>$null
165
+ if ($LASTEXITCODE -eq 0) {
166
+ $hasZipWSL = $true
167
+ Write-ColorOutput "✓ zip found in WSL" $Green
168
+ } else {
169
+ Write-ColorOutput "! zip not found in WSL" $Yellow
170
+ }
171
+ } catch { Write-ColorOutput "! Failed to check zip in WSL" $Yellow }
172
+
173
+ try {
174
+ # Check for python3 or python
175
+ $wslPython = wsl bash -c "command -v python3 || command -v python" 2>$null
176
+ if ($LASTEXITCODE -eq 0) {
177
+ $hasPythonWSL = $true
178
+ Write-ColorOutput "✓ python found in WSL" $Green
179
+ } else {
180
+ Write-ColorOutput "! python not found in WSL" $Yellow
181
+ }
182
+ } catch { Write-ColorOutput "! Failed to check python in WSL" $Yellow }
183
+
184
+ try {
185
+ # Check for python3-venv
186
+ $wslVenv = wsl bash -c "python3 -c 'import venv' 2>/dev/null || python -c 'import venv' 2>/dev/null" 2>$null
187
+ if ($LASTEXITCODE -eq 0) {
188
+ $hasVenvWSL = $true
189
+ Write-ColorOutput "✓ python venv module found in WSL" $Green
190
+ } else {
191
+ Write-ColorOutput "! python venv module not found in WSL" $Yellow
192
+ }
193
+ } catch { Write-ColorOutput "! Failed to check python venv in WSL" $Yellow }
194
+
195
+ try {
196
+ # Check for pip
197
+ $wslPip = wsl bash -c "python3 -m pip --version 2>/dev/null || python -m pip --version 2>/dev/null" 2>$null
198
+ if ($LASTEXITCODE -eq 0) {
199
+ $hasPipWSL = $true
200
+ Write-ColorOutput "✓ python pip module found in WSL" $Green
201
+ } else {
202
+ Write-ColorOutput "! python pip module not found in WSL" $Yellow
203
+ }
204
+ } catch { Write-ColorOutput "! Failed to check python pip in WSL" $Yellow }
205
+
206
+ try {
207
+ $wslNode = wsl node --version 2>$null
208
+ if ($LASTEXITCODE -eq 0) {
209
+ $hasNodeWSL = $true
210
+ Write-ColorOutput "✓ node found in WSL" $Green
211
+ } else {
212
+ Write-ColorOutput "! node not found in WSL" $Yellow
213
+ }
214
+ } catch { Write-ColorOutput "! Failed to check node in WSL" $Yellow }
215
+ }
216
+
217
+ # Check for dependencies in Windows (for Git Bash)
218
+ if ($hasGitBash) {
219
+ function Check-WindowsTool {
220
+ param($Name, $ExeName)
221
+ $cmd = Get-Command $ExeName -ErrorAction SilentlyContinue
222
+ if ($cmd) {
223
+ if ($cmd.Version -and $cmd.Version.ToString() -ne "0.0.0.0") {
224
+ Write-ColorOutput "✓ $Name found ($($cmd.Version))" $Green
225
+ return $true
226
+ }
227
+ }
228
+ Write-ColorOutput "! $Name not found in Windows PATH" $Yellow
229
+ return $false
230
+ }
231
+
232
+ $hasZipGitBash = Check-WindowsTool "zip" "zip.exe"
233
+ $hasPythonGitBash = Check-WindowsTool "python" "python.exe"
234
+ $hasNodeGitBash = Check-WindowsTool "node" "node.exe"
235
+ }
236
+
237
+ return @{
238
+ WSL = $hasWSL
239
+ GitBash = $hasGitBash
240
+ GitBashPath = $gitBashPath
241
+ AwsCli = $hasAwsCli
242
+ ZipWSL = $hasZipWSL
243
+ ZipGitBash = $hasZipGitBash
244
+ PythonWSL = $hasPythonWSL
245
+ VenvWSL = $hasVenvWSL
246
+ PipWSL = $hasPipWSL
247
+ PythonGitBash = $hasPythonGitBash
248
+ NodeWSL = $hasNodeWSL
249
+ NodeGitBash = $hasNodeGitBash
250
+ }
251
+ }
252
+
253
+ function Install-Dependencies {
254
+ param([hashtable]$Prereqs)
255
+
256
+ # Handle WSL zip installation
257
+ if ($Prereqs.WSL -and -not $Prereqs.ZipWSL) {
258
+ $installZip = Read-Host "Zip not found in WSL. Try to install it? (Y/n)"
259
+ if ($installZip -match "^[Yy]|^$") {
260
+ Write-ColorOutput "Attempting to install zip in WSL (you may be asked for your sudo password)..." $Cyan
261
+ try {
262
+ # Try apt-get (Debian/Ubuntu)
263
+ Write-ColorOutput "Running: wsl sudo apt-get update && sudo apt-get install -y zip" $White
264
+ wsl sudo apt-get update
265
+ wsl sudo apt-get install -y zip
266
+
267
+ if ($LASTEXITCODE -eq 0) {
268
+ Write-ColorOutput "✓ zip installed in WSL" $Green
269
+ $Prereqs.ZipWSL = $true
270
+ } else {
271
+ Write-ColorOutput "✗ Failed to install zip automatically." $Red
272
+ Write-ColorOutput "Please run 'sudo apt-get install zip' (or equivalent) inside WSL manually." $Yellow
273
+ }
274
+ } catch {
275
+ Write-ColorOutput "✗ Failed to execute WSL commands." $Red
276
+ }
277
+ }
278
+ }
279
+
280
+ # Handle Git Bash zip installation
281
+ if ($Prereqs.GitBash -and -not $Prereqs.ZipGitBash) {
282
+ # Check if GnuWin32 is already installed but not in PATH
283
+ $gnuWin32Path = "${env:ProgramFiles(x86)}\GnuWin32\bin"
284
+ if (Test-Path $gnuWin32Path) {
285
+ $currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
286
+ if ($currentPath -notlike "*$gnuWin32Path*") {
287
+ $newPath = "$currentPath;$gnuWin32Path"
288
+ [Environment]::SetEnvironmentVariable("Path", $newPath, "User")
289
+ Write-ColorOutput "✓ Found GnuWin32 Zip at $gnuWin32Path" $Green
290
+ Write-ColorOutput "✓ Added GnuWin32 to user PATH" $Green
291
+ Write-ColorOutput " Note: You may need to restart your terminal for PATH changes to take effect." $Yellow
292
+ $Prereqs.ZipGitBash = $true
293
+ }
294
+ }
295
+
296
+ if (-not $Prereqs.ZipGitBash) {
297
+ $installZip = Read-Host "Zip not found in Git Bash. Try to install GnuWin32 Zip with winget? (Y/n)"
298
+ if ($installZip -match "^[Yy]|^$") {
299
+ Write-ColorOutput "Attempting to install GnuWin32 Zip..." $Cyan
300
+ try {
301
+ $wingetVersion = & winget --version 2>$null
302
+ if ($LASTEXITCODE -eq 0) {
303
+ & winget install --id GnuWin32.Zip -e --source winget
304
+ if ($LASTEXITCODE -eq 0) {
305
+ Write-ColorOutput "✓ GnuWin32 Zip installed" $Green
306
+
307
+ # Add GnuWin32 to PATH
308
+ if (Test-Path $gnuWin32Path) {
309
+ $currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
310
+ if ($currentPath -notlike "*$gnuWin32Path*") {
311
+ $newPath = "$currentPath;$gnuWin32Path"
312
+ [Environment]::SetEnvironmentVariable("Path", $newPath, "User")
313
+ Write-ColorOutput "✓ Added $gnuWin32Path to user PATH" $Green
314
+ }
315
+ }
316
+
317
+ Write-ColorOutput " Note: You may need to restart your terminal for PATH changes to take effect." $Yellow
318
+ $Prereqs.ZipGitBash = $true
319
+ } else {
320
+ Write-ColorOutput "✗ Failed to install GnuWin32 Zip." $Red
321
+ Write-ColorOutput "Please install 'zip' manually (e.g. 'winget install GnuWin32.Zip')." $Yellow
322
+ }
323
+ } else {
324
+ Write-ColorOutput "winget not found. Please install 'zip' manually." $Yellow
325
+ }
326
+ } catch {
327
+ Write-ColorOutput "Error running winget." $Red
328
+ }
329
+ }
330
+ }
331
+ }
332
+
333
+ if (-not $Prereqs.PythonWSL -or -not $Prereqs.VenvWSL -or -not $Prereqs.PipWSL -or -not $Prereqs.NodeWSL -or -not $Prereqs.PythonGitBash -or -not $Prereqs.NodeGitBash -or -not $Prereqs.AwsCli) {
334
+ Write-ColorOutput "`nChecking for missing dependencies..." $Yellow
335
+
336
+ # Handle WSL dependencies
337
+ if ($Prereqs.WSL) {
338
+ if (-not $Prereqs.PythonWSL -or -not $Prereqs.VenvWSL -or -not $Prereqs.PipWSL -or -not $Prereqs.NodeWSL) {
339
+ $installWslDeps = Read-Host "Missing dependencies in WSL. Try to install them? (Y/n)"
340
+ if ($installWslDeps -match "^[Yy]|^$") {
341
+ Write-ColorOutput "Attempting to install dependencies in WSL..." $Cyan
342
+ try {
343
+ Write-ColorOutput "Running: wsl sudo apt-get update" $White
344
+ wsl sudo apt-get update
345
+
346
+ if (-not $Prereqs.PythonWSL) {
347
+ Write-ColorOutput "Installing Python in WSL..." $Cyan
348
+ wsl sudo apt-get install -y python3 python3-pip python3-venv
349
+ } elseif (-not $Prereqs.VenvWSL -or -not $Prereqs.PipWSL) {
350
+ Write-ColorOutput "Installing Python venv/pip in WSL..." $Cyan
351
+ wsl sudo apt-get install -y python3-venv python3-pip
352
+ }
353
+ if (-not $Prereqs.NodeWSL) {
354
+ Write-ColorOutput "Installing Node.js in WSL..." $Cyan
355
+ wsl sudo apt-get install -y nodejs npm
356
+ }
357
+ } catch {
358
+ Write-ColorOutput "✗ Failed to execute WSL commands." $Red
359
+ }
360
+ }
361
+ }
362
+ }
363
+
364
+ # Handle Git Bash / Windows dependencies
365
+ # If Git Bash is present but missing deps, we install them in Windows so Git Bash inherits them
366
+ if ($Prereqs.GitBash) {
367
+ if (-not $Prereqs.PythonGitBash -or -not $Prereqs.NodeGitBash -or -not $Prereqs.AwsCli) {
368
+ # Check if winget is available
369
+ try {
370
+ $wingetVersion = & winget --version 2>$null
371
+ if ($LASTEXITCODE -eq 0) {
372
+ $installDeps = Read-Host "Missing Windows dependencies (for Git Bash). Try to install them with winget? (Y/n)"
373
+ if ($installDeps -match "^[Yy]|^$") {
374
+ if (-not $Prereqs.PythonGitBash) {
375
+ Write-ColorOutput "Installing Python..." $Cyan
376
+ & winget install --id Python.Python.3.12 -e --source winget
377
+ }
378
+ if (-not $Prereqs.NodeGitBash) {
379
+ Write-ColorOutput "Installing Node.js..." $Cyan
380
+ & winget install --id OpenJS.NodeJS.LTS -e --source winget
381
+ }
382
+ if (-not $Prereqs.AwsCli) {
383
+ Write-ColorOutput "Installing AWS CLI..." $Cyan
384
+ & winget install --id Amazon.AWSCLI -e --source winget
385
+ }
386
+ Write-ColorOutput "Dependencies installed. You may need to restart your terminal." $Green
387
+ }
388
+ } else {
389
+ Write-ColorOutput "winget not found. Please install missing dependencies manually." $Yellow
390
+ }
391
+ } catch {
392
+ Write-ColorOutput "winget not found. Please install missing dependencies manually." $Yellow
393
+ }
394
+ }
395
+ }
396
+ }
397
+ }
398
+
399
+ function Install-Tool {
400
+ param([hashtable]$Prereqs)
401
+
402
+ # Create install directory
403
+ if (Test-Path $InstallDir) {
404
+ if ($Force) {
405
+ Write-ColorOutput "Removing existing installation..." $Yellow
406
+ Remove-Item $InstallDir -Recurse -Force
407
+ } else {
408
+ Write-ColorOutput "Installation directory already exists: $InstallDir" $Yellow
409
+ $overwrite = Read-Host "Overwrite existing installation? (y/N)"
410
+ if ($overwrite -notmatch "^[Yy]$") {
411
+ Write-ColorOutput "Installation cancelled." $Red
412
+ exit 0
413
+ }
414
+ Remove-Item $InstallDir -Recurse -Force
415
+ }
416
+ }
417
+
418
+ New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
419
+ Write-ColorOutput "Created install directory: $InstallDir" $Green
420
+
421
+ # Download individual files
422
+ Write-ColorOutput "Downloading files..." $Yellow
423
+
424
+ $files = @(
425
+ "VERSION.txt"
426
+ )
427
+
428
+ $scripts = @(
429
+ "aws-lambda-layer-cli",
430
+ "create_nodejs_layer.sh",
431
+ "create_python_layer.sh",
432
+ "uninstall.sh",
433
+ "uninstall.ps1"
434
+ )
435
+
436
+ $baseUrl = "https://raw.githubusercontent.com/yukcw/aws-lambda-layer-cli/main"
437
+
438
+ foreach ($file in $files) {
439
+ $outputPath = Join-Path $InstallDir $file
440
+ $url = "$baseUrl/$file"
441
+ try {
442
+ Invoke-WebRequest -Uri $url -OutFile $outputPath
443
+ Write-ColorOutput "✓ Downloaded $file" $Green
444
+ } catch {
445
+ Write-ColorOutput "✗ Failed to download $file" $Red
446
+ Write-ColorOutput "Error: $($_.Exception.Message)" $Red
447
+ return $false
448
+ }
449
+ }
450
+
451
+ foreach ($script in $scripts) {
452
+ $outputPath = Join-Path $InstallDir $script
453
+ $url = "$baseUrl/scripts/$script"
454
+ try {
455
+ Invoke-WebRequest -Uri $url -OutFile $outputPath
456
+ Write-ColorOutput "✓ Downloaded $script" $Green
457
+ } catch {
458
+ Write-ColorOutput "✗ Failed to download $script" $Red
459
+ Write-ColorOutput "Error: $($_.Exception.Message)" $Red
460
+ return $false
461
+ }
462
+ }
463
+
464
+ # Download completion files
465
+ $completionDir = Join-Path $InstallDir "completion"
466
+ New-Item -ItemType Directory -Path $completionDir -Force | Out-Null
467
+
468
+ $completionFiles = @(
469
+ "completion/aws-lambda-layer-completion.bash",
470
+ "completion/aws-lambda-layer-completion.zsh"
471
+ )
472
+
473
+ foreach ($file in $completionFiles) {
474
+ $outputPath = Join-Path $InstallDir $file
475
+ $url = "$baseUrl/$file"
476
+ try {
477
+ Invoke-WebRequest -Uri $url -OutFile $outputPath
478
+ Write-ColorOutput "✓ Downloaded $file" $Green
479
+ } catch {
480
+ Write-ColorOutput "! Failed to download $file (optional)" $Yellow
481
+ }
482
+ }
483
+
484
+ # Make scripts executable (for bash environment)
485
+ Write-ColorOutput "Setting executable permissions..." $Yellow
486
+ $scriptFiles = Get-ChildItem $InstallDir -Filter "*.sh" -File
487
+ # Also include the main script
488
+ $scriptFiles += Get-Item "$InstallDir\$ToolName" -ErrorAction SilentlyContinue
489
+
490
+ foreach ($file in $scriptFiles) {
491
+ try {
492
+ # On Windows, we can't set +x directly, but we can ensure the file is readable
493
+ # The bash environment will handle execution
494
+ if ($file.Extension -eq ".sh" -or $file.Name -eq $ToolName) {
495
+ # Ensure Unix line endings for bash scripts
496
+ $content = Get-Content $file.FullName -Raw
497
+ # Aggressively remove all carriage returns to ensure LF only
498
+ $content = $content -replace "`r", ""
499
+
500
+ # Write with UTF-8 (No BOM) to ensure compatibility
501
+ $utf8NoBom = New-Object System.Text.UTF8Encoding $false
502
+ [System.IO.File]::WriteAllText($file.FullName, $content, $utf8NoBom)
503
+
504
+ # If not on Windows, set executable bit
505
+ if (-not $IsWindows) {
506
+ chmod +x $file.FullName
507
+ }
508
+
509
+ Write-ColorOutput "✓ Prepared $($file.Name)" $Green
510
+ }
511
+ } catch {
512
+ Write-ColorOutput "! Could not prepare $($file.Name)" $Yellow
513
+ }
514
+ }
515
+
516
+ return $true
517
+ }
518
+
519
+ function Setup-Path {
520
+ param([hashtable]$Prereqs)
521
+
522
+ Write-ColorOutput "Setting up PATH..." $Yellow
523
+
524
+ # Add to PATH for current session
525
+ $currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
526
+ if ($currentPath -notlike "*$InstallDir*") {
527
+ $newPath = "$currentPath;$InstallDir"
528
+ [Environment]::SetEnvironmentVariable("Path", $newPath, "User")
529
+ Write-ColorOutput "✓ Added $InstallDir to user PATH" $Green
530
+ Write-ColorOutput " Note: Restart your terminal for PATH changes to take effect" $Yellow
531
+ } else {
532
+ Write-ColorOutput "✓ PATH already contains $InstallDir" $Green
533
+ }
534
+
535
+ # Create wrapper scripts for easier execution
536
+ $wrapperScript = @"
537
+ @echo off
538
+ REM AWS Lambda Layer CLI Tool Wrapper for Windows
539
+ REM This script helps run the tool in the appropriate bash environment
540
+
541
+ setlocal enabledelayedexpansion
542
+
543
+ set "WIN_PATH=$InstallDir"
544
+
545
+ REM Detect which bash is being used to determine path style
546
+ set "IS_WSL=0"
547
+ for /f "delims=" %%i in ('where bash') do (
548
+ echo "%%i" | findstr /i "System32" >nul
549
+ if !ERRORLEVEL! EQU 0 set "IS_WSL=1"
550
+ goto :DETECT_DONE
551
+ )
552
+ :DETECT_DONE
553
+
554
+ if "!IS_WSL!"=="1" (
555
+ REM WSL Environment - use wslpath
556
+ where wsl >nul 2>nul
557
+ if !ERRORLEVEL! EQU 0 (
558
+ for /f "delims=" %%i in ('wsl wslpath -a "!WIN_PATH!"') do set "UNIX_PATH=%%i"
559
+ ) else (
560
+ REM Fallback for WSL if wsl.exe missing - assume /mnt/c/ style
561
+ set "UNIX_PATH=!WIN_PATH:\=/!"
562
+ if "!UNIX_PATH:~1,1!"==":" (
563
+ set "DRIVE=!UNIX_PATH:~0,1!"
564
+ REM Simple lowercase for common drives
565
+ if /i "!DRIVE!"=="C" set "DRIVE=c"
566
+ if /i "!DRIVE!"=="D" set "DRIVE=d"
567
+ set "UNIX_PATH=/mnt/!DRIVE!!UNIX_PATH:~2!"
568
+ )
569
+ )
570
+ ) else (
571
+ REM Git Bash / Cygwin Environment
572
+ where cygpath >nul 2>nul
573
+ if !ERRORLEVEL! EQU 0 (
574
+ for /f "delims=" %%i in ('cygpath "!WIN_PATH!"') do set "UNIX_PATH=%%i"
575
+ ) else (
576
+ REM Manual conversion fallback (Git Bash style /c/...)
577
+ set "UNIX_PATH=!WIN_PATH:\=/!"
578
+ if "!UNIX_PATH:~1,1!"==":" (
579
+ set "UNIX_PATH=/!UNIX_PATH:~0,1!!UNIX_PATH:~2!"
580
+ )
581
+ )
582
+ )
583
+
584
+ where bash >nul 2>nul
585
+ if %ERRORLEVEL% EQU 0 (
586
+ REM Try to run with bash
587
+ bash "!UNIX_PATH!/$ToolName" %*
588
+ if !ERRORLEVEL! NEQ 0 (
589
+ echo Error: Failed to execute aws-lambda-layer-cli
590
+ echo Please check that the script exists and is executable
591
+ echo Script path: !UNIX_PATH!/$ToolName
592
+ pause
593
+ exit /b 1
594
+ )
595
+ ) else (
596
+ echo Error: bash not found in PATH
597
+ echo Please install Git for Windows or WSL
598
+ echo https://gitforwindows.org/
599
+ echo.
600
+ echo Alternatively, you can run the script directly with:
601
+ echo bash "!UNIX_PATH!/$ToolName" [arguments]
602
+ pause
603
+ exit /b 1
604
+ )
605
+ "@
606
+
607
+ $wrapperPath = "$InstallDir\$ToolName.cmd"
608
+ $wrapperScript | Out-File -FilePath $wrapperPath -Encoding ASCII
609
+ Write-ColorOutput "✓ Created Windows wrapper script: $wrapperPath" $Green
610
+ }
611
+
612
+ function Show-PostInstall {
613
+ Write-ColorOutput "`n=========================================" $Cyan
614
+ Write-ColorOutput "Installation Complete!" $Green
615
+ Write-ColorOutput "=========================================" $Cyan
616
+ Write-ColorOutput ""
617
+ Write-ColorOutput "The AWS Lambda Layer CLI tool has been installed to:" $White
618
+ Write-ColorOutput " $InstallDir" $Cyan
619
+ Write-ColorOutput ""
620
+ Write-ColorOutput "Usage examples:" $Magenta
621
+ Write-Host " aws-lambda-layer-cli " -NoNewline -ForegroundColor $White
622
+ Write-Host "zip " -NoNewline -ForegroundColor $Green
623
+ Write-Host "--nodejs " -NoNewline -ForegroundColor $Yellow
624
+ Write-Host """express@^4.0.0,lodash@~4.17.0""" -ForegroundColor $White
625
+ Write-Host " aws-lambda-layer-cli " -NoNewline -ForegroundColor $White
626
+ Write-Host "zip " -NoNewline -ForegroundColor $Green
627
+ Write-Host "--python " -NoNewline -ForegroundColor $Yellow
628
+ Write-Host """numpy==1.26.0,pandas>=2.1.0""" -ForegroundColor $White
629
+ Write-ColorOutput ""
630
+ Write-ColorOutput "For more information:" $Yellow
631
+ Write-Host " aws-lambda-layer-cli " -NoNewline -ForegroundColor $White
632
+ Write-ColorOutput "help" $Green
633
+
634
+ Write-ColorOutput ""
635
+ Write-ColorOutput "Repository: $RepoUrl" $White
636
+ }
637
+
638
+ # Main installation process
639
+ function Main {
640
+ Write-Header
641
+
642
+ # Check prerequisites
643
+ $prereqs = Test-Prerequisites
644
+
645
+ # Install dependencies if needed
646
+ Install-Dependencies -Prereqs $prereqs
647
+
648
+ # Install the tool
649
+ $installSuccess = Install-Tool -Prereqs $prereqs
650
+ if (-not $installSuccess) {
651
+ Write-ColorOutput "`nInstallation failed!" $Red
652
+ exit 1
653
+ }
654
+
655
+ # Setup PATH and wrappers
656
+ Setup-Path -Prereqs $prereqs
657
+
658
+ # Show post-installation information
659
+ Show-PostInstall
660
+ }
661
+
662
+ # Run main function
663
663
  Main