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.
- package/README.md +41 -338
- package/bin/aws-lambda-layer-cli.js +183 -0
- package/completion/aws-lambda-layer-completion.bash +8 -4
- package/completion/aws-lambda-layer-completion.zsh +3 -3
- package/package.json +17 -3
- package/scripts/{aws-lambda-layer → aws-lambda-layer-cli} +133 -18
- package/scripts/build_pypi.sh +11 -3
- package/scripts/install.js +54 -16
- package/scripts/install.ps1 +662 -662
- package/scripts/install.sh +22 -11
- package/scripts/pypi_resources/cli.py +89 -1
- package/scripts/uninstall.js +47 -0
- package/scripts/uninstall.ps1 +209 -179
- package/scripts/uninstall.sh +72 -9
- package/bin/aws-lambda-layer.js +0 -89
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# AWS Lambda Layer CLI Tool
|
|
4
4
|
# Install: sudo ./scripts/install.sh
|
|
5
|
-
# Usage: aws-lambda-layer zip --nodejs express,axios -n my-layer
|
|
5
|
+
# Usage: aws-lambda-layer-cli zip --nodejs express,axios -n my-layer
|
|
6
6
|
|
|
7
7
|
set -e
|
|
8
8
|
set -u
|
|
@@ -26,7 +26,7 @@ STRIKETHROUGH='\033[9m'
|
|
|
26
26
|
|
|
27
27
|
# Paths
|
|
28
28
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
29
|
-
INSTALL_DIR="/usr/local/lib/aws-lambda-layer"
|
|
29
|
+
INSTALL_DIR="/usr/local/lib/aws-lambda-layer-cli"
|
|
30
30
|
|
|
31
31
|
# Determine script locations (prefer relative to script, fallback to global install)
|
|
32
32
|
if [ -f "$SCRIPT_DIR/create_nodejs_layer.sh" ]; then
|
|
@@ -54,16 +54,18 @@ show_help() {
|
|
|
54
54
|
printf "${BLUE}${BOLD}AWS Lambda Layer CLI Tool - ${version}${NC}\n\n"
|
|
55
55
|
|
|
56
56
|
printf "${BLUE}Usage:${NC}\n"
|
|
57
|
-
printf " aws-lambda-layer ${GREEN}zip${NC} ${YELLOW}--nodejs${NC} <packages> [options]\n"
|
|
58
|
-
printf " aws-lambda-layer ${GREEN}zip${NC} ${YELLOW}--python${NC} <packages> [options]\n"
|
|
59
|
-
printf " aws-lambda-layer ${GREEN}publish${NC} ${YELLOW}--nodejs${NC} <packages> [options]\n"
|
|
60
|
-
printf " aws-lambda-layer ${GREEN}publish${NC} ${YELLOW}--python${NC} <packages> [options]\n"
|
|
61
|
-
printf " aws-lambda-layer ${GREEN}help${NC}\n"
|
|
62
|
-
printf " aws-lambda-layer [options]\n\n"
|
|
57
|
+
printf " aws-lambda-layer-cli ${GREEN}zip${NC} ${YELLOW}--nodejs${NC} <packages> [options]\n"
|
|
58
|
+
printf " aws-lambda-layer-cli ${GREEN}zip${NC} ${YELLOW}--python${NC} <packages> [options]\n"
|
|
59
|
+
printf " aws-lambda-layer-cli ${GREEN}publish${NC} ${YELLOW}--nodejs${NC} <packages> [options]\n"
|
|
60
|
+
printf " aws-lambda-layer-cli ${GREEN}publish${NC} ${YELLOW}--python${NC} <packages> [options]\n"
|
|
61
|
+
printf " aws-lambda-layer-cli ${GREEN}help${NC}\n"
|
|
62
|
+
printf " aws-lambda-layer-cli [options]\n\n"
|
|
63
63
|
|
|
64
64
|
printf "${BLUE}Commands:${NC}\n"
|
|
65
65
|
printf " ${GREEN}zip${NC} Create and package a Lambda layer as zip file\n"
|
|
66
66
|
printf " ${GREEN}publish${NC} Create and publish a Lambda layer to AWS (uses IAM credentials)\n"
|
|
67
|
+
printf " ${GREEN}completion${NC} Generate shell completion scripts\n"
|
|
68
|
+
printf " ${GREEN}uninstall${NC} Uninstall the tool and remove all files\n"
|
|
67
69
|
printf " ${GREEN}help${NC} Show this help message\n\n"
|
|
68
70
|
|
|
69
71
|
printf "${BLUE}Runtime Options:${NC}\n"
|
|
@@ -80,6 +82,7 @@ show_help() {
|
|
|
80
82
|
printf " ${YELLOW}--profile${NC} AWS CLI profile to use (default: default profile)\n"
|
|
81
83
|
printf " ${YELLOW}--region${NC} AWS region (e.g., us-east-1, ap-east-1)\n"
|
|
82
84
|
printf "${BLUE}Other Options:${NC}\n"
|
|
85
|
+
printf " ${YELLOW}--version, -v${NC} Show tool version information\n"
|
|
83
86
|
printf " ${YELLOW}--node-version${NC} Node.js version (default: 24)\n"
|
|
84
87
|
printf " ${YELLOW}--python-version${NC} Python version (default: 3.14)\n"
|
|
85
88
|
printf " ${YELLOW}--no-uv${NC} Use pip/venv instead of uv\n\n"
|
|
@@ -89,12 +92,12 @@ show_help() {
|
|
|
89
92
|
printf " Python: numpy==1.26.0, pandas>=2.1.0, requests~=2.31.0\n\n"
|
|
90
93
|
|
|
91
94
|
printf "${MAGENTA}${UNDERLINE}Examples:${NC}\n"
|
|
92
|
-
printf " aws-lambda-layer ${GREEN}zip${NC} ${YELLOW}--nodejs${NC} express,lodash\n"
|
|
93
|
-
printf " aws-lambda-layer ${GREEN}zip${NC} ${YELLOW}--python${NC} \"numpy==1.26.0,pandas>=2.1.0\"\n"
|
|
94
|
-
printf " aws-lambda-layer ${GREEN}publish${NC} ${YELLOW}--nodejs${NC} express@4.18.2 ${YELLOW}--description${NC} \"Express layer\"\n"
|
|
95
|
-
printf " aws-lambda-layer ${GREEN}publish${NC} ${YELLOW}--python${NC} numpy==1.26.0 ${YELLOW}--description${NC} \"NumPy layer\"\n"
|
|
96
|
-
printf " aws-lambda-layer ${GREEN}publish${NC} ${YELLOW}--nodejs${NC} date-fns,uuid ${YELLOW}--name${NC} utility-layer ${YELLOW}--description${NC} \"Utility packages\"\n"
|
|
97
|
-
printf " aws-lambda-layer ${GREEN}publish${NC} ${YELLOW}--nodejs${NC} express@4.18.2 ${YELLOW}--profile${NC} production ${YELLOW}--region${NC} ap-east-1 ${YELLOW}--description${NC} \"Express layer\"\n\n"
|
|
95
|
+
printf " aws-lambda-layer-cli ${GREEN}zip${NC} ${YELLOW}--nodejs${NC} express,lodash\n"
|
|
96
|
+
printf " aws-lambda-layer-cli ${GREEN}zip${NC} ${YELLOW}--python${NC} \"numpy==1.26.0,pandas>=2.1.0\"\n"
|
|
97
|
+
printf " aws-lambda-layer-cli ${GREEN}publish${NC} ${YELLOW}--nodejs${NC} express@4.18.2 ${YELLOW}--description${NC} \"Express layer\"\n"
|
|
98
|
+
printf " aws-lambda-layer-cli ${GREEN}publish${NC} ${YELLOW}--python${NC} numpy==1.26.0 ${YELLOW}--description${NC} \"NumPy layer\"\n"
|
|
99
|
+
printf " aws-lambda-layer-cli ${GREEN}publish${NC} ${YELLOW}--nodejs${NC} date-fns,uuid ${YELLOW}--name${NC} utility-layer ${YELLOW}--description${NC} \"Utility packages\"\n"
|
|
100
|
+
printf " aws-lambda-layer-cli ${GREEN}publish${NC} ${YELLOW}--nodejs${NC} express@4.18.2 ${YELLOW}--profile${NC} production ${YELLOW}--region${NC} ap-east-1 ${YELLOW}--description${NC} \"Express layer\"\n\n"
|
|
98
101
|
|
|
99
102
|
printf "${YELLOW}${BOLD}Requirements for publish command:${NC}\n"
|
|
100
103
|
printf " - AWS CLI installed and configured\n"
|
|
@@ -458,7 +461,12 @@ handle_publish() {
|
|
|
458
461
|
done
|
|
459
462
|
|
|
460
463
|
# Parse runtime flag from remaining arguments
|
|
461
|
-
|
|
464
|
+
if [ ${#new_args[@]} -eq 0 ]; then
|
|
465
|
+
set --
|
|
466
|
+
else
|
|
467
|
+
set -- "${new_args[@]}"
|
|
468
|
+
fi
|
|
469
|
+
|
|
462
470
|
case "${1:-}" in
|
|
463
471
|
--nodejs|--node|-n)
|
|
464
472
|
runtime="nodejs"
|
|
@@ -753,6 +761,86 @@ handle_publish() {
|
|
|
753
761
|
printf "📁 Zip file saved: ${CYAN}$output_dir/$zip_file${NC}\n"
|
|
754
762
|
}
|
|
755
763
|
|
|
764
|
+
# Handle completion command
|
|
765
|
+
handle_completion() {
|
|
766
|
+
local shell=""
|
|
767
|
+
local show_help=false
|
|
768
|
+
|
|
769
|
+
if [ $# -eq 0 ]; then
|
|
770
|
+
show_help=true
|
|
771
|
+
fi
|
|
772
|
+
|
|
773
|
+
while [[ $# -gt 0 ]]; do
|
|
774
|
+
case "$1" in
|
|
775
|
+
--zsh)
|
|
776
|
+
shell="zsh"
|
|
777
|
+
shift
|
|
778
|
+
;;
|
|
779
|
+
--bash)
|
|
780
|
+
shell="bash"
|
|
781
|
+
shift
|
|
782
|
+
;;
|
|
783
|
+
--help|-h)
|
|
784
|
+
show_help=true
|
|
785
|
+
shift
|
|
786
|
+
;;
|
|
787
|
+
*)
|
|
788
|
+
shift
|
|
789
|
+
;;
|
|
790
|
+
esac
|
|
791
|
+
done
|
|
792
|
+
|
|
793
|
+
if [ "$show_help" = true ] || [ -z "$shell" ]; then
|
|
794
|
+
printf "${BLUE}Usage:${NC}\n"
|
|
795
|
+
printf " aws-lambda-layer-cli ${GREEN}completion${NC} [options]\n\n"
|
|
796
|
+
printf "${BLUE}Options:${NC}\n"
|
|
797
|
+
printf " ${YELLOW}--zsh${NC} Output zsh completion script\n"
|
|
798
|
+
printf " ${YELLOW}--bash${NC} Output bash completion script\n\n"
|
|
799
|
+
printf "${MAGENTA}${UNDERLINE}Examples:${NC}\n"
|
|
800
|
+
printf " # Load completion in current shell\n"
|
|
801
|
+
printf " source <(aws-lambda-layer-cli ${GREEN}completion${NC} ${YELLOW}--bash${NC})\n\n"
|
|
802
|
+
printf " # Add to .zshrc\n"
|
|
803
|
+
printf " aws-lambda-layer-cli ${GREEN}completion${NC} ${YELLOW}--zsh${NC} >> ~/.zshrc\n"
|
|
804
|
+
return 0
|
|
805
|
+
fi
|
|
806
|
+
|
|
807
|
+
# Find completion directory
|
|
808
|
+
# If running from source: ../completion
|
|
809
|
+
# If installed: $INSTALL_DIR/completion
|
|
810
|
+
local completion_dir=""
|
|
811
|
+
if [ -d "$SCRIPT_DIR/../completion" ]; then
|
|
812
|
+
completion_dir="$SCRIPT_DIR/../completion"
|
|
813
|
+
elif [ -d "$INSTALL_DIR/completion" ]; then
|
|
814
|
+
completion_dir="$INSTALL_DIR/completion"
|
|
815
|
+
else
|
|
816
|
+
printf "${RED}Error: Completion directory not found${NC}\n" >&2
|
|
817
|
+
return 1
|
|
818
|
+
fi
|
|
819
|
+
|
|
820
|
+
if [ "$shell" = "zsh" ]; then
|
|
821
|
+
local file="$completion_dir/aws-lambda-layer-completion.zsh"
|
|
822
|
+
if [ -f "$file" ]; then
|
|
823
|
+
# Remove the auto-execution line if present
|
|
824
|
+
sed 's/_aws-lambda-layer "\$@"//g' "$file"
|
|
825
|
+
printf "\n# Register completion\n"
|
|
826
|
+
printf "if type compdef &>/dev/null; then\n"
|
|
827
|
+
printf " compdef _aws-lambda-layer aws-lambda-layer\n"
|
|
828
|
+
printf "fi\n"
|
|
829
|
+
else
|
|
830
|
+
printf "${RED}Error: Completion script not found for zsh${NC}\n" >&2
|
|
831
|
+
return 1
|
|
832
|
+
fi
|
|
833
|
+
else
|
|
834
|
+
local file="$completion_dir/aws-lambda-layer-completion.bash"
|
|
835
|
+
if [ -f "$file" ]; then
|
|
836
|
+
cat "$file"
|
|
837
|
+
else
|
|
838
|
+
printf "${RED}Error: Completion script not found for bash${NC}\n" >&2
|
|
839
|
+
return 1
|
|
840
|
+
fi
|
|
841
|
+
fi
|
|
842
|
+
}
|
|
843
|
+
|
|
756
844
|
# Function to convert file paths for compatibility across environments
|
|
757
845
|
convert_path() {
|
|
758
846
|
local input_path="$1"
|
|
@@ -786,6 +874,25 @@ convert_path() {
|
|
|
786
874
|
esac
|
|
787
875
|
}
|
|
788
876
|
|
|
877
|
+
# Handle uninstall
|
|
878
|
+
handle_uninstall() {
|
|
879
|
+
local uninstall_script="$SCRIPT_DIR/uninstall.sh"
|
|
880
|
+
|
|
881
|
+
# Check if uninstall script exists in script dir
|
|
882
|
+
if [ ! -f "$uninstall_script" ]; then
|
|
883
|
+
# Check install dir
|
|
884
|
+
uninstall_script="$INSTALL_DIR/uninstall.sh"
|
|
885
|
+
fi
|
|
886
|
+
|
|
887
|
+
if [ -f "$uninstall_script" ]; then
|
|
888
|
+
exec "$uninstall_script" "$@"
|
|
889
|
+
else
|
|
890
|
+
printf "${RED}Error: Uninstall script not found${NC}\n" >&2
|
|
891
|
+
printf "Please run the uninstall script manually or remove the installation directory.\n" >&2
|
|
892
|
+
exit 1
|
|
893
|
+
fi
|
|
894
|
+
}
|
|
895
|
+
|
|
789
896
|
# Main command parsing
|
|
790
897
|
main() {
|
|
791
898
|
if [ $# -eq 0 ]; then
|
|
@@ -802,6 +909,14 @@ main() {
|
|
|
802
909
|
shift
|
|
803
910
|
handle_publish "$@"
|
|
804
911
|
;;
|
|
912
|
+
uninstall)
|
|
913
|
+
shift
|
|
914
|
+
handle_uninstall "$@"
|
|
915
|
+
;;
|
|
916
|
+
completion)
|
|
917
|
+
shift
|
|
918
|
+
handle_completion "$@"
|
|
919
|
+
;;
|
|
805
920
|
help|--help|-h)
|
|
806
921
|
show_help
|
|
807
922
|
;;
|
|
@@ -809,9 +924,9 @@ main() {
|
|
|
809
924
|
show_version
|
|
810
925
|
;;
|
|
811
926
|
*)
|
|
812
|
-
printf "${RED}Error: Unknown command '$1'${NC}\n"
|
|
813
|
-
printf "Available commands: zip, publish\n"
|
|
814
|
-
printf "Use --help for more information\n"
|
|
927
|
+
printf "${RED}Error: Unknown command '$1'${NC}\n" >&2
|
|
928
|
+
printf "Available commands: zip, publish\n" >&2
|
|
929
|
+
printf "Use --help for more information\n" >&2
|
|
815
930
|
exit 1
|
|
816
931
|
;;
|
|
817
932
|
esac
|
package/scripts/build_pypi.sh
CHANGED
|
@@ -5,6 +5,7 @@ set -e
|
|
|
5
5
|
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
6
6
|
BUILD_DIR="$BASE_DIR/aws_lambda_layer_cli"
|
|
7
7
|
ASSETS_DIR="$BUILD_DIR/assets"
|
|
8
|
+
COMPLETION_DIR="$BUILD_DIR/completion"
|
|
8
9
|
|
|
9
10
|
echo "Preparing PyPI package structure..."
|
|
10
11
|
|
|
@@ -13,6 +14,7 @@ rm -rf "$BUILD_DIR" "$BASE_DIR/dist" "$BASE_DIR/build" "$BASE_DIR/aws_lambda_lay
|
|
|
13
14
|
|
|
14
15
|
# Create package directories
|
|
15
16
|
mkdir -p "$ASSETS_DIR"
|
|
17
|
+
mkdir -p "$COMPLETION_DIR"
|
|
16
18
|
|
|
17
19
|
# Copy Python package files
|
|
18
20
|
cp "$BASE_DIR/scripts/pypi_resources/__init__.py" "$BUILD_DIR/"
|
|
@@ -20,18 +22,24 @@ cp "$BASE_DIR/scripts/pypi_resources/cli.py" "$BUILD_DIR/"
|
|
|
20
22
|
cp "$BASE_DIR/VERSION.txt" "$BUILD_DIR/"
|
|
21
23
|
|
|
22
24
|
# Copy assets (bash scripts)
|
|
23
|
-
cp "$BASE_DIR/scripts/aws-lambda-layer" "$ASSETS_DIR/"
|
|
25
|
+
cp "$BASE_DIR/scripts/aws-lambda-layer-cli" "$ASSETS_DIR/"
|
|
24
26
|
cp "$BASE_DIR/scripts/create_nodejs_layer.sh" "$ASSETS_DIR/"
|
|
25
27
|
cp "$BASE_DIR/scripts/create_python_layer.sh" "$ASSETS_DIR/"
|
|
28
|
+
cp "$BASE_DIR/scripts/uninstall.sh" "$ASSETS_DIR/"
|
|
26
29
|
|
|
27
|
-
#
|
|
30
|
+
# Copy completion files
|
|
31
|
+
cp "$BASE_DIR/completion/aws-lambda-layer-completion.bash" "$COMPLETION_DIR/"
|
|
32
|
+
cp "$BASE_DIR/completion/aws-lambda-layer-completion.zsh" "$COMPLETION_DIR/"
|
|
33
|
+
|
|
34
|
+
# Create __init__.py for assets and completion packages
|
|
28
35
|
touch "$ASSETS_DIR/__init__.py"
|
|
36
|
+
touch "$COMPLETION_DIR/__init__.py"
|
|
29
37
|
|
|
30
38
|
echo "Building PyPI package..."
|
|
31
39
|
cd "$BASE_DIR"
|
|
32
40
|
python3 -m build
|
|
33
41
|
|
|
34
42
|
echo "Cleaning up temporary package files..."
|
|
35
|
-
rm -rf "$BUILD_DIR" "$BASE_DIR/aws_lambda_layer_cli.egg-info" "$BASE_DIR/build"
|
|
43
|
+
# rm -rf "$BUILD_DIR" "$BASE_DIR/aws_lambda_layer_cli.egg-info" "$BASE_DIR/build"
|
|
36
44
|
|
|
37
45
|
echo "Build complete! Artifacts are in dist/"
|
package/scripts/install.js
CHANGED
|
@@ -3,32 +3,70 @@ const { execSync } = require('child_process');
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const os = require('os');
|
|
6
|
+
const readline = require('readline');
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const fullPath = path.join(__dirname, '..', scriptPath);
|
|
8
|
+
const isWindows = os.platform() === 'win32';
|
|
9
|
+
const scriptPath = isWindows ? path.join('scripts', 'install.ps1') : path.join('scripts', 'install.sh');
|
|
10
|
+
const fullPath = path.join(__dirname, '..', scriptPath);
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
if (!fs.existsSync(fullPath)) {
|
|
13
|
+
console.error(`Installation script not found: ${fullPath}`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function runInstall(useSudo) {
|
|
18
|
+
try {
|
|
19
|
+
const cmd = useSudo ? `sudo bash "${fullPath}"` : `bash "${fullPath}"`;
|
|
20
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
21
|
+
console.log('✓ Installation completed successfully');
|
|
22
|
+
process.exit(0);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error('✗ Installation failed:', error.message);
|
|
14
25
|
process.exit(1);
|
|
15
26
|
}
|
|
27
|
+
}
|
|
16
28
|
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
if (isWindows) {
|
|
30
|
+
try {
|
|
19
31
|
execSync(`powershell -ExecutionPolicy Bypass -File "${fullPath}"`, {
|
|
20
32
|
stdio: 'inherit',
|
|
21
33
|
shell: true
|
|
22
34
|
});
|
|
35
|
+
console.log('✓ Installation completed successfully');
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error('✗ Installation failed:', error.message);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
const isRoot = process.getuid && process.getuid() === 0;
|
|
42
|
+
|
|
43
|
+
if (isRoot) {
|
|
44
|
+
console.log('Running installation with root privileges...');
|
|
45
|
+
runInstall(false);
|
|
23
46
|
} else {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
47
|
+
console.log('Installation requires root privileges for system-wide components...');
|
|
48
|
+
// Check if interactive
|
|
49
|
+
if (!process.stdin.isTTY) {
|
|
50
|
+
console.log('Non-interactive environment detected. Skipping system-wide installation steps requiring sudo.');
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const rl = readline.createInterface({
|
|
55
|
+
input: process.stdin,
|
|
56
|
+
output: process.stdout
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
console.log('\nThis package includes optional system-wide components (shell completion, helper scripts).');
|
|
60
|
+
console.log('Installing them requires root privileges (sudo).');
|
|
61
|
+
|
|
62
|
+
rl.question('Do you want to install these components? [y/N] ', (answer) => {
|
|
63
|
+
rl.close();
|
|
64
|
+
if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
|
|
65
|
+
runInstall(true);
|
|
66
|
+
} else {
|
|
67
|
+
console.log('Skipping system-wide installation.');
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
27
70
|
});
|
|
28
71
|
}
|
|
29
|
-
|
|
30
|
-
console.log('✓ Installation completed successfully');
|
|
31
|
-
} catch (error) {
|
|
32
|
-
console.error('✗ Installation failed:', error.message);
|
|
33
|
-
process.exit(1);
|
|
34
72
|
}
|