aws-lambda-layer-cli 1.4.1 → 2.0.1

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
@@ -17,7 +17,7 @@ A command-line tool for creating and publishing AWS Lambda layers for Node.js an
17
17
 
18
18
  ## Installation
19
19
 
20
- ### Package managers (recommended)
20
+ ### Package Managers (Recommended)
21
21
 
22
22
  These installs do **not** write to `/usr/local` and do **not** require `sudo`.
23
23
 
@@ -25,28 +25,30 @@ These installs do **not** write to `/usr/local` and do **not** require `sudo`.
25
25
 
26
26
  ```bash
27
27
  npm i -g aws-lambda-layer-cli
28
- aws-lambda-layer --help
28
+ aws-lambda-layer-cli --help
29
29
  ```
30
30
 
31
31
  #### pip (Python)
32
32
 
33
33
  ```bash
34
34
  python -m pip install --user aws-lambda-layer-cli
35
- aws-lambda-layer --help
35
+ aws-lambda-layer-cli --help
36
36
  ```
37
37
 
38
38
  #### uv (Python)
39
39
 
40
40
  ```bash
41
41
  uv tool install aws-lambda-layer-cli
42
- aws-lambda-layer --help
42
+ aws-lambda-layer-cli --help
43
43
  ```
44
44
 
45
- ### Linux/macOS
45
+ ### Native Installation
46
+
47
+ #### Linux/macOS
46
48
 
47
49
  ```bash
48
50
  # Clone or download the repository
49
- git clone <repository-url>
51
+ git clone https://github.com/yukcw/aws-lambda-layer-cli.git
50
52
  cd aws-lambda-layer-cli
51
53
 
52
54
  # Run installation script (requires sudo)
@@ -54,13 +56,13 @@ sudo ./scripts/install.sh
54
56
  ```
55
57
 
56
58
  The installation will:
57
- - Copy scripts to `/usr/local/lib/aws-lambda-layer`
59
+ - Copy scripts to `/usr/local/lib/aws-lambda-layer-cli`
58
60
  - Create a symlink in `/usr/local/bin` for global access
59
61
  - Install shell completions for bash and zsh
60
62
 
61
- ### Windows
63
+ #### Windows
62
64
 
63
- #### Option 1: PowerShell (Recommended)
65
+ ##### Option 1: PowerShell
64
66
 
65
67
  ```powershell
66
68
  # One-liner installation
@@ -78,11 +80,11 @@ Invoke-WebRequest -Uri "https://raw.githubusercontent.com/yukcw/aws-lambda-layer
78
80
  ```
79
81
 
80
82
  This will:
81
- - Download the tool to `%USERPROFILE%\.aws-lambda-layer`
83
+ - Download the tool to `%USERPROFILE%\.aws-lambda-layer-cli`
82
84
  - Add it to your PATH
83
85
  - Create Windows wrapper scripts
84
86
 
85
- #### Option 2: Manual Installation
87
+ ##### Option 2: Manual Installation
86
88
 
87
89
  1. Install prerequisites:
88
90
  - [Git for Windows](https://gitforwindows.org/) (includes Git Bash)
@@ -148,7 +150,7 @@ If you encounter issues:
148
150
  - Restart PowerShell/Command Prompt after installation
149
151
 
150
152
  2. **"No such file or directory"**
151
- - Try running: `bash "$env:USERPROFILE\.aws-lambda-layer\aws-lambda-layer" --help`
153
+ - Try running: `bash "$env:USERPROFILE\.aws-lambda-layer-cli\aws-lambda-layer-cli" --help`
152
154
  - Or reinstall: `powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/yukcw/aws-lambda-layer-cli/main/scripts/install.ps1 | iex"`
153
155
 
154
156
  3. **Permission issues**
@@ -0,0 +1,183 @@
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';
4
+
5
+ const { spawnSync } = require('child_process');
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+
9
+ function which(cmd) {
10
+ const isWin = process.platform === 'win32';
11
+ const exts = isWin ? (process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM').split(';') : [''];
12
+ const paths = (process.env.PATH || '').split(path.delimiter);
13
+
14
+ for (const p of paths) {
15
+ if (!p) continue;
16
+ for (const ext of exts) {
17
+ const full = path.join(p, isWin ? cmd + ext.toLowerCase() : cmd);
18
+ if (fs.existsSync(full)) return full;
19
+ // Also check original case on Windows
20
+ const full2 = path.join(p, cmd + ext);
21
+ if (fs.existsSync(full2)) return full2;
22
+ }
23
+ }
24
+ return null;
25
+ }
26
+
27
+ function shQuote(s) {
28
+ // Single-quote for bash -lc
29
+ return `'${String(s).replace(/'/g, `'\\''`)}'`;
30
+ }
31
+
32
+ function windowsPathToWsl(p) {
33
+ // C:\Users\me\x -> /mnt/c/Users/me/x
34
+ const m = /^([a-zA-Z]):\\(.*)$/.exec(p);
35
+ if (!m) return null;
36
+ return `/mnt/${m[1].toLowerCase()}/${m[2].replace(/\\/g, '/')}`;
37
+ }
38
+
39
+ function cygpathConvert(mode, p) {
40
+ const cygpath = which('cygpath');
41
+ if (!cygpath) return null;
42
+ const res = spawnSync(cygpath, [mode, p], { encoding: 'utf8' });
43
+ if (res.status !== 0) return null;
44
+ return (res.stdout || '').trim();
45
+ }
46
+
47
+ function run(cmd, args) {
48
+ const res = spawnSync(cmd, args, { stdio: 'inherit' });
49
+ process.exit(res.status ?? 1);
50
+ }
51
+
52
+ const args = process.argv.slice(2);
53
+
54
+ if (args[0] === 'completion') {
55
+ const hasZsh = args.includes('--zsh');
56
+ const hasBash = args.includes('--bash');
57
+
58
+ if (args.includes('--help') || args.includes('-h') || (!hasZsh && !hasBash)) {
59
+ const GREEN = '\x1b[0;32m';
60
+ const YELLOW = '\x1b[0;33m';
61
+ const BLUE = '\x1b[0;34m';
62
+ const MAGENTA = '\x1b[0;35m';
63
+ const NC = '\x1b[0m';
64
+ const UNDERLINE = '\x1b[4m';
65
+
66
+ console.log(`${BLUE}Usage:${NC}`);
67
+ console.log(` aws-lambda-layer-cli ${GREEN}completion${NC} [options]`);
68
+ console.log('');
69
+ console.log(`${BLUE}Options:${NC}`);
70
+ console.log(` ${YELLOW}--zsh${NC} Output zsh completion script`);
71
+ console.log(` ${YELLOW}--bash${NC} Output bash completion script`);
72
+ console.log('');
73
+ console.log(`${MAGENTA}${UNDERLINE}Examples:${NC}`);
74
+ console.log(' # Load completion in current shell');
75
+ console.log(` source <(aws-lambda-layer-cli ${GREEN}completion${NC} ${YELLOW}--bash${NC})`);
76
+ console.log('');
77
+ console.log(' # Add to .zshrc');
78
+ console.log(` aws-lambda-layer-cli ${GREEN}completion${NC} ${YELLOW}--zsh${NC} >> ~/.zshrc`);
79
+ process.exit(0);
80
+ }
81
+
82
+ const completionDir = path.resolve(__dirname, '..', 'completion');
83
+ let shell = '';
84
+
85
+ if (hasZsh) {
86
+ shell = 'zsh';
87
+ } else if (hasBash) {
88
+ shell = 'bash';
89
+ }
90
+
91
+ if (shell === 'zsh') {
92
+ const file = path.join(completionDir, 'aws-lambda-layer-completion.zsh');
93
+ if (fs.existsSync(file)) {
94
+ let content = fs.readFileSync(file, 'utf8');
95
+ // Remove the auto-execution line if present, to make it safe for sourcing
96
+ content = content.replace(/_aws-lambda-layer-cli "\$@"\s*$/, '');
97
+ console.log(content);
98
+ console.log('\n# Register completion');
99
+ console.log('if type compdef &>/dev/null; then');
100
+ console.log(' compdef _aws-lambda-layer-cli aws-lambda-layer-cli');
101
+ console.log('fi');
102
+ } else {
103
+ console.error('Completion script not found for zsh');
104
+ process.exit(1);
105
+ }
106
+ } else {
107
+ // bash
108
+ const file = path.join(completionDir, 'aws-lambda-layer-completion.bash');
109
+ if (fs.existsSync(file)) {
110
+ console.log(fs.readFileSync(file, 'utf8'));
111
+ } else {
112
+ console.error('Completion script not found for bash');
113
+ process.exit(1);
114
+ }
115
+ }
116
+ process.exit(0);
117
+ }
118
+
119
+ if (args[0] === 'uninstall') {
120
+ if (args.includes('--help') || args.includes('-h')) {
121
+ const GREEN = '\x1b[0;32m';
122
+ const BLUE = '\x1b[0;34m';
123
+ const NC = '\x1b[0m';
124
+
125
+ console.log(`${BLUE}Usage:${NC}`);
126
+ console.log(` aws-lambda-layer-cli ${GREEN}uninstall${NC}`);
127
+ console.log('');
128
+ console.log(`${BLUE}Description:${NC}`);
129
+ console.log(' Uninstalls the AWS Lambda Layer CLI tool and removes all associated files.');
130
+ console.log(' This includes:');
131
+ console.log(' - The CLI executable and symlinks');
132
+ console.log(' - The installation directory');
133
+ console.log(' - Shell completion scripts');
134
+ process.exit(0);
135
+ }
136
+
137
+ const uninstallScript = path.resolve(__dirname, '..', 'scripts', 'uninstall.js');
138
+ if (fs.existsSync(uninstallScript)) {
139
+ run(process.execPath, [uninstallScript, ...args.slice(1)]);
140
+ } else {
141
+ console.error('Uninstall script not found');
142
+ process.exit(1);
143
+ }
144
+ return;
145
+ }
146
+
147
+ const bashScript = path.resolve(__dirname, '..', 'scripts', 'aws-lambda-layer-cli');
148
+
149
+ if (!fs.existsSync(bashScript)) {
150
+ console.error('Error: packaged bash script not found:', bashScript);
151
+ process.exit(1);
152
+ }
153
+
154
+ // POSIX platforms
155
+ if (process.platform !== 'win32') {
156
+ run('bash', [bashScript, ...args]);
157
+ }
158
+
159
+ // Windows platforms:
160
+ // - Prefer Git Bash / MSYS / Cygwin: convert to POSIX path using cygpath -u
161
+ // - Else attempt WSL: convert to /mnt/<drive>/... and run via wsl.exe
162
+ // - Else give a clear message
163
+
164
+ const posixPath = cygpathConvert('-u', bashScript);
165
+ if (posixPath) {
166
+ run('bash', [posixPath, ...args]);
167
+ }
168
+
169
+ const wsl = which('wsl.exe') || which('wsl');
170
+ if (wsl) {
171
+ const wslPath = windowsPathToWsl(bashScript);
172
+ if (!wslPath) {
173
+ console.error('Error: unable to convert path for WSL:', bashScript);
174
+ process.exit(1);
175
+ }
176
+
177
+ const cmd = `bash ${shQuote(wslPath)} ${args.map(shQuote).join(' ')}`.trim();
178
+ run(wsl, ['bash', '-lc', cmd]);
179
+ }
180
+
181
+ console.error('Error: no compatible bash found on Windows.');
182
+ console.error('Install and run this tool inside WSL, or install Git Bash and ensure `bash`/`cygpath` are on PATH.');
183
+ process.exit(1);
@@ -1,8 +1,12 @@
1
- # bash completion for aws-lambda-layer
1
+ # bash completion for aws-lambda-layer-cli
2
2
 
3
- _aws_lambda_layer() {
3
+ _aws_lambda_layer_cli() {
4
4
  local cur prev words cword
5
- _init_completion || return
5
+ # Use fallback variables for older bash versions
6
+ cur="${COMP_WORDS[COMP_CWORD]}"
7
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
8
+ words=("${COMP_WORDS[@]}")
9
+ cword=$COMP_CWORD
6
10
 
7
11
  local commands="zip publish help --help --version"
8
12
  local runtime_opts="--nodejs --node -n --python --py -p --runtime"
@@ -98,4 +102,4 @@ _aws_lambda_layer() {
98
102
  esac
99
103
  }
100
104
 
101
- complete -F _aws_lambda_layer aws-lambda-layer
105
+ complete -F _aws_lambda_layer_cli aws-lambda-layer-cli
@@ -1,6 +1,6 @@
1
- #compdef aws-lambda-layer
1
+ #compdef aws-lambda-layer-cli
2
2
 
3
- _aws-lambda-layer() {
3
+ _aws-lambda-layer-cli() {
4
4
  local -a commands runtime_opts common_opts node_opts python_opts
5
5
 
6
6
  commands=(
@@ -107,4 +107,4 @@ _aws-lambda-layer() {
107
107
  esac
108
108
  }
109
109
 
110
- _aws-lambda-layer "$@"
110
+ # _aws-lambda-layer-cli "$@"
package/package.json CHANGED
@@ -1,7 +1,19 @@
1
1
  {
2
2
  "name": "aws-lambda-layer-cli",
3
- "version": "1.4.1",
3
+ "version": "2.0.1",
4
4
  "description": "CLI tool for creating and publishing AWS Lambda layers for Node.js and Python.",
5
+ "keywords": [
6
+ "aws",
7
+ "lambda",
8
+ "nodejs",
9
+ "serverless",
10
+ "amazon",
11
+ "cli",
12
+ "zip",
13
+ "publish",
14
+ "layer",
15
+ "tools"
16
+ ],
5
17
  "license": "MIT",
6
18
  "repository": {
7
19
  "type": "git",
@@ -13,10 +25,12 @@
13
25
  "homepage": "https://github.com/yukcw/aws-lambda-layer-cli#readme",
14
26
  "scripts": {
15
27
  "sync-version": "node scripts/sync_version.js",
16
- "prepublishOnly": "npm run sync-version"
28
+ "prepublishOnly": "npm run sync-version",
29
+ "postinstall": "node scripts/install.js",
30
+ "preuninstall": "node scripts/uninstall.js"
17
31
  },
18
32
  "bin": {
19
- "aws-lambda-layer": "bin/aws-lambda-layer.js"
33
+ "aws-lambda-layer-cli": "bin/aws-lambda-layer-cli.js"
20
34
  },
21
35
  "engines": {
22
36
  "node": ">=18"
@@ -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"
@@ -89,12 +91,12 @@ show_help() {
89
91
  printf " Python: numpy==1.26.0, pandas>=2.1.0, requests~=2.31.0\n\n"
90
92
 
91
93
  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"
94
+ printf " aws-lambda-layer-cli ${GREEN}zip${NC} ${YELLOW}--nodejs${NC} express,lodash\n"
95
+ printf " aws-lambda-layer-cli ${GREEN}zip${NC} ${YELLOW}--python${NC} \"numpy==1.26.0,pandas>=2.1.0\"\n"
96
+ printf " aws-lambda-layer-cli ${GREEN}publish${NC} ${YELLOW}--nodejs${NC} express@4.18.2 ${YELLOW}--description${NC} \"Express layer\"\n"
97
+ printf " aws-lambda-layer-cli ${GREEN}publish${NC} ${YELLOW}--python${NC} numpy==1.26.0 ${YELLOW}--description${NC} \"NumPy layer\"\n"
98
+ 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"
99
+ 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
100
 
99
101
  printf "${YELLOW}${BOLD}Requirements for publish command:${NC}\n"
100
102
  printf " - AWS CLI installed and configured\n"
@@ -458,7 +460,12 @@ handle_publish() {
458
460
  done
459
461
 
460
462
  # Parse runtime flag from remaining arguments
461
- set -- "${new_args[@]}"
463
+ if [ ${#new_args[@]} -eq 0 ]; then
464
+ set --
465
+ else
466
+ set -- "${new_args[@]}"
467
+ fi
468
+
462
469
  case "${1:-}" in
463
470
  --nodejs|--node|-n)
464
471
  runtime="nodejs"
@@ -753,6 +760,86 @@ handle_publish() {
753
760
  printf "📁 Zip file saved: ${CYAN}$output_dir/$zip_file${NC}\n"
754
761
  }
755
762
 
763
+ # Handle completion command
764
+ handle_completion() {
765
+ local shell=""
766
+ local show_help=false
767
+
768
+ if [ $# -eq 0 ]; then
769
+ show_help=true
770
+ fi
771
+
772
+ while [[ $# -gt 0 ]]; do
773
+ case "$1" in
774
+ --zsh)
775
+ shell="zsh"
776
+ shift
777
+ ;;
778
+ --bash)
779
+ shell="bash"
780
+ shift
781
+ ;;
782
+ --help|-h)
783
+ show_help=true
784
+ shift
785
+ ;;
786
+ *)
787
+ shift
788
+ ;;
789
+ esac
790
+ done
791
+
792
+ if [ "$show_help" = true ] || [ -z "$shell" ]; then
793
+ printf "${BLUE}Usage:${NC}\n"
794
+ printf " aws-lambda-layer-cli ${GREEN}completion${NC} [options]\n\n"
795
+ printf "${BLUE}Options:${NC}\n"
796
+ printf " ${YELLOW}--zsh${NC} Output zsh completion script\n"
797
+ printf " ${YELLOW}--bash${NC} Output bash completion script\n\n"
798
+ printf "${MAGENTA}${UNDERLINE}Examples:${NC}\n"
799
+ printf " # Load completion in current shell\n"
800
+ printf " source <(aws-lambda-layer-cli ${GREEN}completion${NC} ${YELLOW}--bash${NC})\n\n"
801
+ printf " # Add to .zshrc\n"
802
+ printf " aws-lambda-layer-cli ${GREEN}completion${NC} ${YELLOW}--zsh${NC} >> ~/.zshrc\n"
803
+ return 0
804
+ fi
805
+
806
+ # Find completion directory
807
+ # If running from source: ../completion
808
+ # If installed: $INSTALL_DIR/completion
809
+ local completion_dir=""
810
+ if [ -d "$SCRIPT_DIR/../completion" ]; then
811
+ completion_dir="$SCRIPT_DIR/../completion"
812
+ elif [ -d "$INSTALL_DIR/completion" ]; then
813
+ completion_dir="$INSTALL_DIR/completion"
814
+ else
815
+ printf "${RED}Error: Completion directory not found${NC}\n" >&2
816
+ return 1
817
+ fi
818
+
819
+ if [ "$shell" = "zsh" ]; then
820
+ local file="$completion_dir/aws-lambda-layer-completion.zsh"
821
+ if [ -f "$file" ]; then
822
+ # Remove the auto-execution line if present
823
+ sed 's/_aws-lambda-layer "\$@"//g' "$file"
824
+ printf "\n# Register completion\n"
825
+ printf "if type compdef &>/dev/null; then\n"
826
+ printf " compdef _aws-lambda-layer aws-lambda-layer\n"
827
+ printf "fi\n"
828
+ else
829
+ printf "${RED}Error: Completion script not found for zsh${NC}\n" >&2
830
+ return 1
831
+ fi
832
+ else
833
+ local file="$completion_dir/aws-lambda-layer-completion.bash"
834
+ if [ -f "$file" ]; then
835
+ cat "$file"
836
+ else
837
+ printf "${RED}Error: Completion script not found for bash${NC}\n" >&2
838
+ return 1
839
+ fi
840
+ fi
841
+ }
842
+
756
843
  # Function to convert file paths for compatibility across environments
757
844
  convert_path() {
758
845
  local input_path="$1"
@@ -786,6 +873,25 @@ convert_path() {
786
873
  esac
787
874
  }
788
875
 
876
+ # Handle uninstall
877
+ handle_uninstall() {
878
+ local uninstall_script="$SCRIPT_DIR/uninstall.sh"
879
+
880
+ # Check if uninstall script exists in script dir
881
+ if [ ! -f "$uninstall_script" ]; then
882
+ # Check install dir
883
+ uninstall_script="$INSTALL_DIR/uninstall.sh"
884
+ fi
885
+
886
+ if [ -f "$uninstall_script" ]; then
887
+ exec "$uninstall_script" "$@"
888
+ else
889
+ printf "${RED}Error: Uninstall script not found${NC}\n" >&2
890
+ printf "Please run the uninstall script manually or remove the installation directory.\n" >&2
891
+ exit 1
892
+ fi
893
+ }
894
+
789
895
  # Main command parsing
790
896
  main() {
791
897
  if [ $# -eq 0 ]; then
@@ -802,6 +908,14 @@ main() {
802
908
  shift
803
909
  handle_publish "$@"
804
910
  ;;
911
+ uninstall)
912
+ shift
913
+ handle_uninstall "$@"
914
+ ;;
915
+ completion)
916
+ shift
917
+ handle_completion "$@"
918
+ ;;
805
919
  help|--help|-h)
806
920
  show_help
807
921
  ;;
@@ -809,9 +923,9 @@ main() {
809
923
  show_version
810
924
  ;;
811
925
  *)
812
- printf "${RED}Error: Unknown command '$1'${NC}\n"
813
- printf "Available commands: zip, publish\n"
814
- printf "Use --help for more information\n"
926
+ printf "${RED}Error: Unknown command '$1'${NC}\n" >&2
927
+ printf "Available commands: zip, publish\n" >&2
928
+ printf "Use --help for more information\n" >&2
815
929
  exit 1
816
930
  ;;
817
931
  esac
@@ -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
- # Create __init__.py for assets package
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/"
@@ -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
- try {
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);
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
- if (!fs.existsSync(fullPath)) {
13
- console.error(`Installation script not found: ${fullPath}`);
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
- if (isWindows) {
18
- // Run PowerShell script with proper execution policy
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
- // Run bash script
25
- execSync(`bash "${fullPath}"`, {
26
- stdio: 'inherit'
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
  }
@@ -9,7 +9,7 @@
9
9
  This tool requires Windows Subsystem for Linux (WSL) or Git Bash.
10
10
 
11
11
  .PARAMETER InstallDir
12
- Directory where the tool will be installed (default: $env:USERPROFILE\.aws-lambda-layer)
12
+ Directory where the tool will be installed (default: $env:USERPROFILE\.aws-lambda-layer-cli)
13
13
 
14
14
  .PARAMETER Force
15
15
  Force reinstallation even if already installed
@@ -35,15 +35,15 @@ param(
35
35
  # Set default InstallDir if not provided
36
36
  if ([string]::IsNullOrEmpty($InstallDir)) {
37
37
  if ($env:USERPROFILE) {
38
- $InstallDir = "$env:USERPROFILE\.aws-lambda-layer"
38
+ $InstallDir = "$env:USERPROFILE\.aws-lambda-layer-cli"
39
39
  } else {
40
- $InstallDir = "$env:HOME/.aws-lambda-layer"
40
+ $InstallDir = "$env:HOME/.aws-lambda-layer-cli"
41
41
  }
42
42
  }
43
43
 
44
44
  # Configuration
45
45
  $RepoUrl = "https://github.com/yukcw/aws-lambda-layer-cli"
46
- $ToolName = "aws-lambda-layer"
46
+ $ToolName = "aws-lambda-layer-cli"
47
47
  $Version = "1.4.1" # Fallback version
48
48
 
49
49
  # Colors for output
@@ -426,7 +426,7 @@ function Install-Tool {
426
426
  )
427
427
 
428
428
  $scripts = @(
429
- "aws-lambda-layer",
429
+ "aws-lambda-layer-cli",
430
430
  "create_nodejs_layer.sh",
431
431
  "create_python_layer.sh",
432
432
  "uninstall.sh",
@@ -586,7 +586,7 @@ if %ERRORLEVEL% EQU 0 (
586
586
  REM Try to run with bash
587
587
  bash "!UNIX_PATH!/$ToolName" %*
588
588
  if !ERRORLEVEL! NEQ 0 (
589
- echo Error: Failed to execute aws-lambda-layer
589
+ echo Error: Failed to execute aws-lambda-layer-cli
590
590
  echo Please check that the script exists and is executable
591
591
  echo Script path: !UNIX_PATH!/$ToolName
592
592
  pause
@@ -618,17 +618,17 @@ function Show-PostInstall {
618
618
  Write-ColorOutput " $InstallDir" $Cyan
619
619
  Write-ColorOutput ""
620
620
  Write-ColorOutput "Usage examples:" $Magenta
621
- Write-Host " aws-lambda-layer " -NoNewline -ForegroundColor $White
621
+ Write-Host " aws-lambda-layer-cli " -NoNewline -ForegroundColor $White
622
622
  Write-Host "zip " -NoNewline -ForegroundColor $Green
623
623
  Write-Host "--nodejs " -NoNewline -ForegroundColor $Yellow
624
624
  Write-Host """express@^4.0.0,lodash@~4.17.0""" -ForegroundColor $White
625
- Write-Host " aws-lambda-layer " -NoNewline -ForegroundColor $White
625
+ Write-Host " aws-lambda-layer-cli " -NoNewline -ForegroundColor $White
626
626
  Write-Host "zip " -NoNewline -ForegroundColor $Green
627
627
  Write-Host "--python " -NoNewline -ForegroundColor $Yellow
628
628
  Write-Host """numpy==1.26.0,pandas>=2.1.0""" -ForegroundColor $White
629
629
  Write-ColorOutput ""
630
630
  Write-ColorOutput "For more information:" $Yellow
631
- Write-Host " aws-lambda-layer " -NoNewline -ForegroundColor $White
631
+ Write-Host " aws-lambda-layer-cli " -NoNewline -ForegroundColor $White
632
632
  Write-ColorOutput "help" $Green
633
633
 
634
634
  Write-ColorOutput ""
@@ -24,7 +24,11 @@ printf "${CYAN}${BOLD}Installing AWS Lambda Layer CLI Tool...${NC}\n"
24
24
  # Check if running as root
25
25
  if [ "$EUID" -ne 0 ]; then
26
26
  if command -v sudo &> /dev/null; then
27
- printf "${YELLOW}Warning: Not running as root. Using sudo for installation.${NC}\n"
27
+ # Check if we need a password
28
+ if ! sudo -n true 2>/dev/null; then
29
+ printf "${YELLOW}This script requires root privileges to install to /usr/local/lib.${NC}\n"
30
+ printf "${YELLOW}Please enter your password if prompted.${NC}\n"
31
+ fi
28
32
  SUDO="sudo"
29
33
  else
30
34
  SUDO=""
@@ -36,7 +40,7 @@ fi
36
40
  # Get script directory
37
41
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
38
42
  BASE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
39
- INSTALL_DIR="/usr/local/lib/aws-lambda-layer"
43
+ INSTALL_DIR="/usr/local/lib/aws-lambda-layer-cli"
40
44
  BIN_DIR="/usr/local/bin"
41
45
  COMPLETION_DIR="/etc/bash_completion.d"
42
46
 
@@ -46,29 +50,36 @@ $SUDO mkdir -p "$INSTALL_DIR"
46
50
 
47
51
  # Copy scripts
48
52
  printf "${BLUE}Copying scripts...${NC}\n"
49
- $SUDO cp "$SCRIPT_DIR/aws-lambda-layer" "$INSTALL_DIR/"
53
+ $SUDO cp "$SCRIPT_DIR/aws-lambda-layer-cli" "$INSTALL_DIR/"
50
54
  $SUDO cp "$SCRIPT_DIR/create_nodejs_layer.sh" "$INSTALL_DIR/"
51
55
  $SUDO cp "$SCRIPT_DIR/create_python_layer.sh" "$INSTALL_DIR/"
56
+ $SUDO cp "$SCRIPT_DIR/uninstall.sh" "$INSTALL_DIR/"
52
57
  $SUDO cp "$BASE_DIR/VERSION.txt" "$INSTALL_DIR/"
53
58
 
59
+ # Copy completion files for the CLI to use
60
+ printf "${BLUE}Copying completion files...${NC}\n"
61
+ $SUDO mkdir -p "$INSTALL_DIR/completion"
62
+ $SUDO cp "$BASE_DIR/completion/aws-lambda-layer-completion.bash" "$INSTALL_DIR/completion/"
63
+ $SUDO cp "$BASE_DIR/completion/aws-lambda-layer-completion.zsh" "$INSTALL_DIR/completion/"
64
+
54
65
  # Make scripts executable
55
66
  printf "${BLUE}Setting executable permissions...${NC}\n"
56
- $SUDO chmod +x "$INSTALL_DIR/aws-lambda-layer"
67
+ $SUDO chmod +x "$INSTALL_DIR/aws-lambda-layer-cli"
57
68
  $SUDO chmod +x "$INSTALL_DIR/create_nodejs_layer.sh"
58
69
  $SUDO chmod +x "$INSTALL_DIR/create_python_layer.sh"
59
70
 
60
71
  # Create symlink in bin directory
61
72
  printf "${BLUE}Creating symlink in $BIN_DIR...${NC}\n"
62
- $SUDO ln -sf "$INSTALL_DIR/aws-lambda-layer" "$BIN_DIR/aws-lambda-layer"
73
+ $SUDO ln -sf "$INSTALL_DIR/aws-lambda-layer-cli" "$BIN_DIR/aws-lambda-layer-cli"
63
74
 
64
75
  # Install bash completion
65
76
  printf "${BLUE}Installing bash completion...${NC}\n"
66
77
  if [ -d "$COMPLETION_DIR" ]; then
67
- $SUDO cp "$BASE_DIR/completion/aws-lambda-layer-completion.bash" "$COMPLETION_DIR/aws-lambda-layer"
78
+ $SUDO cp "$BASE_DIR/completion/aws-lambda-layer-completion.bash" "$COMPLETION_DIR/aws-lambda-layer-cli"
68
79
  # Source the completion script
69
80
  if [ -f "$HOME/.bashrc" ]; then
70
- if ! grep -q "aws-lambda-layer" "$HOME/.bashrc"; then
71
- printf "\n# AWS Lambda Layer CLI completion\nsource $COMPLETION_DIR/aws-lambda-layer\n" >> "$HOME/.bashrc"
81
+ if ! grep -q "aws-lambda-layer-cli" "$HOME/.bashrc"; then
82
+ printf "\n# AWS Lambda Layer CLI completion\nsource $COMPLETION_DIR/aws-lambda-layer-cli\n" >> "$HOME/.bashrc"
72
83
  fi
73
84
  fi
74
85
  printf "${GREEN}Bash completion installed.${NC}\n"
@@ -92,14 +103,14 @@ else
92
103
  fi
93
104
 
94
105
  if [ -n "$ZSH_COMPLETION_DIR" ]; then
95
- $SUDO cp "$BASE_DIR/completion/aws-lambda-layer-completion.zsh" "$ZSH_COMPLETION_DIR/_aws-lambda-layer"
106
+ $SUDO cp "$BASE_DIR/completion/aws-lambda-layer-completion.zsh" "$ZSH_COMPLETION_DIR/_aws-lambda-layer-cli"
96
107
  printf "${GREEN}Zsh completion installed to: $ZSH_COMPLETION_DIR${NC}\n"
97
108
  fi
98
109
 
99
110
  printf "${GREEN}${BOLD}✅ Installation complete!${NC}\n\n"
100
111
  printf "${MAGENTA}${UNDERLINE}Usage examples:${NC}\n"
101
- printf " aws-lambda-layer ${GREEN}zip${NC} ${YELLOW}--nodejs${NC} \"express@^4.0.0,lodash@~4.17.0\"\n"
102
- printf " aws-lambda-layer ${GREEN}zip${NC} ${YELLOW}--python${NC} \"numpy==1.26.0,pandas>=2.1.0\"\n\n"
112
+ printf " aws-lambda-layer-cli ${GREEN}zip${NC} ${YELLOW}--nodejs${NC} \"express@^4.0.0,lodash@~4.17.0\"\n"
113
+ printf " aws-lambda-layer-cli ${GREEN}zip${NC} ${YELLOW}--python${NC} \"numpy==1.26.0,pandas>=2.1.0\"\n\n"
103
114
  printf "${YELLOW}To enable tab completion, restart your shell:${NC}\n"
104
115
  printf " For bash: source ~/.bashrc\n"
105
116
  printf " For zsh: exec zsh\n\n"
@@ -49,12 +49,100 @@ def main() -> None:
49
49
  else:
50
50
  assets_dir = Path(__file__).resolve().parent / "assets"
51
51
 
52
- script_path = assets_dir / "aws-lambda-layer"
52
+ script_path = assets_dir / "aws-lambda-layer-cli"
53
53
  if not script_path.exists():
54
54
  raise SystemExit(f"Packaged script missing: {script_path}")
55
55
 
56
56
  args = sys.argv[1:]
57
57
 
58
+ # Handle uninstall command
59
+ if args and args[0] == "uninstall":
60
+ if "--help" in args or "-h" in args:
61
+ GREEN = '\033[0;32m'
62
+ BLUE = '\033[0;34m'
63
+ NC = '\033[0m'
64
+
65
+ print(f"{BLUE}Usage:{NC}")
66
+ print(f" aws-lambda-layer-cli {GREEN}uninstall{NC}")
67
+ print("")
68
+ print(f"{BLUE}Description:{NC}")
69
+ print(" Uninstalls the AWS Lambda Layer CLI tool and removes all associated files.")
70
+ print(" This includes:")
71
+ print(" - The CLI executable and symlinks")
72
+ print(" - The installation directory")
73
+ print(" - Shell completion scripts")
74
+ raise SystemExit(0)
75
+
76
+ uninstall_script = assets_dir / "uninstall.sh"
77
+ if not uninstall_script.exists():
78
+ raise SystemExit(f"Uninstall script missing: {uninstall_script}")
79
+
80
+ # Use the same execution logic as the main script, but pointing to uninstall.sh
81
+ script_path = uninstall_script
82
+ # Remove 'uninstall' from args
83
+ args = args[1:]
84
+
85
+ # Handle completion command
86
+ if args and args[0] == "completion":
87
+ has_zsh = "--zsh" in args
88
+ has_bash = "--bash" in args
89
+
90
+ if "--help" in args or "-h" in args or (not has_zsh and not has_bash):
91
+ GREEN = '\033[0;32m'
92
+ YELLOW = '\033[0;33m'
93
+ BLUE = '\033[0;34m'
94
+ MAGENTA = '\033[0;35m'
95
+ NC = '\033[0m'
96
+ UNDERLINE = '\033[4m'
97
+
98
+ print(f"{BLUE}Usage:{NC}")
99
+ print(f" aws-lambda-layer-cli {GREEN}completion{NC} [options]")
100
+ print("")
101
+ print(f"{BLUE}Options:{NC}")
102
+ print(f" {YELLOW}--zsh{NC} Output zsh completion script")
103
+ print(f" {YELLOW}--bash{NC} Output bash completion script")
104
+ print("")
105
+ print(f"{MAGENTA}{UNDERLINE}Examples:{NC}")
106
+ print(" # Load completion in current shell")
107
+ print(f" source <(aws-lambda-layer-cli {GREEN}completion{NC} {YELLOW}--bash{NC})")
108
+ print("")
109
+ print(" # Add to .zshrc")
110
+ print(f" aws-lambda-layer-cli {GREEN}completion{NC} {YELLOW}--zsh{NC} >> ~/.zshrc")
111
+ raise SystemExit(0)
112
+
113
+ completion_dir = assets_dir.parent / "completion"
114
+ shell = ""
115
+
116
+ if has_zsh:
117
+ shell = "zsh"
118
+ elif has_bash:
119
+ shell = "bash"
120
+
121
+ if shell == "zsh":
122
+ file = completion_dir / "aws-lambda-layer-completion.zsh"
123
+ if file.exists():
124
+ content = file.read_text(encoding="utf-8")
125
+ # Remove the auto-execution line if present
126
+ import re
127
+ content = re.sub(r'_aws-lambda-layer-cli "\$@"\s*$', "", content)
128
+ print(content)
129
+ print("\n# Register completion")
130
+ print("if type compdef &>/dev/null; then")
131
+ print(" compdef _aws-lambda-layer-cli aws-lambda-layer-cli")
132
+ print("fi")
133
+ else:
134
+ print("Completion script not found for zsh", file=sys.stderr)
135
+ raise SystemExit(1)
136
+ else:
137
+ # bash
138
+ file = completion_dir / "aws-lambda-layer-completion.bash"
139
+ if file.exists():
140
+ print(file.read_text(encoding="utf-8"))
141
+ else:
142
+ print("Completion script not found for bash", file=sys.stderr)
143
+ raise SystemExit(1)
144
+ raise SystemExit(0)
145
+
58
146
  # POSIX
59
147
  if os.name != "nt":
60
148
  raise SystemExit(_run(["bash", str(script_path), *args]))
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ const { execSync } = require('child_process');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+
7
+ try {
8
+ const isWindows = os.platform() === 'win32';
9
+ const scriptPath = isWindows ? path.join('scripts', 'uninstall.ps1') : path.join('scripts', 'uninstall.sh');
10
+ const fullPath = path.join(__dirname, '..', scriptPath);
11
+ const args = process.argv.slice(2).map(arg => `"${arg}"`).join(' ');
12
+
13
+ if (!fs.existsSync(fullPath)) {
14
+ console.error(`Uninstallation script not found: ${fullPath}`);
15
+ process.exit(1);
16
+ }
17
+
18
+ if (isWindows) {
19
+ // Run PowerShell script with proper execution policy
20
+ execSync(`powershell -ExecutionPolicy Bypass -File "${fullPath}" ${args}`, {
21
+ stdio: 'inherit',
22
+ shell: true
23
+ });
24
+ } else {
25
+ // Check if we are root
26
+ const isRoot = process.getuid && process.getuid() === 0;
27
+
28
+ if (!isRoot) {
29
+ console.log('This script requires root privileges to uninstall from /usr/local/lib.');
30
+ console.log('Requesting sudo permissions...');
31
+ // Run with sudo directly from node
32
+ execSync(`sudo bash "${fullPath}" ${args}`, {
33
+ stdio: 'inherit'
34
+ });
35
+ } else {
36
+ // Already root, just run it
37
+ execSync(`bash "${fullPath}" ${args}`, {
38
+ stdio: 'inherit'
39
+ });
40
+ }
41
+ }
42
+
43
+ console.log('✓ Uninstallation completed successfully');
44
+ } catch (error) {
45
+ console.error('✗ Uninstallation failed:', error.message);
46
+ process.exit(1);
47
+ }
@@ -8,7 +8,7 @@
8
8
  Uninstalls the AWS Lambda Layer CLI tool from Windows systems.
9
9
 
10
10
  .PARAMETER InstallDir
11
- Directory where the tool is installed (default: $env:USERPROFILE\.aws-lambda-layer)
11
+ Directory where the tool is installed (default: $env:USERPROFILE\.aws-lambda-layer-cli)
12
12
 
13
13
  .PARAMETER Force
14
14
  Force uninstallation without confirmation
@@ -34,9 +34,9 @@ param(
34
34
  # Determine InstallDir if not provided
35
35
  if ([string]::IsNullOrEmpty($InstallDir)) {
36
36
  if ($env:USERPROFILE) {
37
- $InstallDir = Join-Path $env:USERPROFILE ".aws-lambda-layer"
37
+ $InstallDir = Join-Path $env:USERPROFILE ".aws-lambda-layer-cli"
38
38
  } elseif ($env:HOME) {
39
- $InstallDir = Join-Path $env:HOME ".aws-lambda-layer"
39
+ $InstallDir = Join-Path $env:HOME ".aws-lambda-layer-cli"
40
40
  } else {
41
41
  Write-Error "Could not determine home directory. Please specify -InstallDir."
42
42
  exit 1
@@ -75,7 +75,7 @@ function Test-Installation {
75
75
  return $false
76
76
  }
77
77
 
78
- $mainScript = Join-Path $InstallDir "aws-lambda-layer"
78
+ $mainScript = Join-Path $InstallDir "aws-lambda-layer-cli"
79
79
  if (-not (Test-Path $mainScript)) {
80
80
  Write-ColorOutput "Main script not found: $mainScript" $Yellow
81
81
  Write-ColorOutput "This doesn't look like a valid installation." $White
@@ -140,6 +140,26 @@ function Show-PostUninstall {
140
140
  function Main {
141
141
  Write-Header
142
142
 
143
+ # Check NPM
144
+ if (Get-Command npm -ErrorAction SilentlyContinue) {
145
+ $npmList = npm list -g aws-lambda-layer-cli --depth=0 2>$null
146
+ if ($npmList -match "aws-lambda-layer-cli@") {
147
+ Write-ColorOutput "Detected NPM installation." $Yellow
148
+ Write-ColorOutput "Removing NPM package..." $White
149
+ npm uninstall -g aws-lambda-layer-cli
150
+ }
151
+ }
152
+
153
+ # Check PyPI
154
+ if (Get-Command pip -ErrorAction SilentlyContinue) {
155
+ pip show aws-lambda-layer-cli 2>$null | Out-Null
156
+ if ($LASTEXITCODE -eq 0) {
157
+ Write-ColorOutput "Detected PyPI installation." $Yellow
158
+ Write-ColorOutput "Removing PyPI package..." $White
159
+ pip uninstall -y aws-lambda-layer-cli
160
+ }
161
+ }
162
+
143
163
  # Check if tool is installed
144
164
  $isInstalled = Test-Installation
145
165
  if (-not $isInstalled) {
@@ -11,23 +11,77 @@ YELLOW='\033[1;33m'
11
11
  BLUE='\033[0;34m'
12
12
  NC='\033[0m'
13
13
 
14
+ # Check for help flag
15
+ if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
16
+ printf "${BLUE}Usage:${NC}\n"
17
+ printf " aws-lambda-layer-cli ${GREEN}uninstall${NC}\n\n"
18
+ printf "${BLUE}Description:${NC}\n"
19
+ printf " Uninstalls the AWS Lambda Layer CLI tool and removes all associated files.\n"
20
+ printf " This includes:\n"
21
+ printf " - The CLI executable and symlinks\n"
22
+ printf " - The installation directory (/usr/local/lib/aws-lambda-layer-cli)\n"
23
+ printf " - Shell completion scripts\n"
24
+ exit 0
25
+ fi
26
+
14
27
  printf "${RED}Uninstalling AWS Lambda Layer CLI Tool...${NC}\n"
15
28
 
29
+ # Check for other installation sources
30
+ printf "\n${BLUE}Checking installation sources...${NC}\n"
31
+
32
+ # Check NPM
33
+ if command -v npm &> /dev/null; then
34
+ if npm list -g aws-lambda-layer-cli --depth=0 &> /dev/null; then
35
+ printf "${YELLOW}Detected NPM installation.${NC}\n"
36
+ printf " Removing NPM package...\n"
37
+ npm uninstall -g aws-lambda-layer-cli
38
+ fi
39
+ fi
40
+
41
+ # Check PyPI (pip)
42
+ if command -v pip &> /dev/null || command -v pip3 &> /dev/null; then
43
+ # Try pip then pip3
44
+ PIP_CMD="pip"
45
+ if ! command -v pip &> /dev/null; then
46
+ PIP_CMD="pip3"
47
+ fi
48
+
49
+ if $PIP_CMD show aws-lambda-layer-cli &> /dev/null; then
50
+ printf "${YELLOW}Detected PyPI installation.${NC}\n"
51
+ printf " Removing PyPI package...\n"
52
+ $PIP_CMD uninstall -y aws-lambda-layer-cli
53
+ fi
54
+ fi
55
+
56
+ # Check Native (System)
57
+ if [ -d "/usr/local/lib/aws-lambda-layer-cli" ]; then
58
+ printf "${YELLOW}Detected Native/System installation.${NC}\n"
59
+ printf " Proceeding with removal of system files...\n"
60
+ else
61
+ printf "No Native/System installation found at /usr/local/lib/aws-lambda-layer-cli.\n"
62
+ fi
63
+
64
+ printf "\n"
65
+
16
66
  # Check if running as root
17
67
  if [ "$EUID" -ne 0 ]; then
18
- printf "${YELLOW}Warning: Not running as root. Using sudo for uninstallation.${NC}\n"
68
+ # Check if we need a password (sudo -n true returns 0 if we have access, 1 if we need password)
69
+ if ! sudo -n true 2>/dev/null; then
70
+ printf "${YELLOW}This script requires root privileges to uninstall from /usr/local/lib.${NC}\n"
71
+ printf "${YELLOW}Please enter your password if prompted.${NC}\n"
72
+ fi
19
73
  SUDO="sudo"
20
74
  else
21
75
  SUDO=""
22
76
  fi
23
77
 
24
- INSTALL_DIR="/usr/local/lib/aws-lambda-layer"
78
+ INSTALL_DIR="/usr/local/lib/aws-lambda-layer-cli"
25
79
  BIN_DIR="/usr/local/bin"
26
80
  COMPLETION_DIR="/etc/bash_completion.d"
27
81
 
28
82
  # Remove symlink
29
83
  printf "${BLUE}Removing symlink...${NC}\n"
30
- $SUDO rm -f "$BIN_DIR/aws-lambda-layer"
84
+ $SUDO rm -f "$BIN_DIR/aws-lambda-layer-cli"
31
85
 
32
86
  # Remove installation directory
33
87
  printf "${BLUE}Removing installation directory...${NC}\n"
@@ -35,24 +89,24 @@ $SUDO rm -rf "$INSTALL_DIR"
35
89
 
36
90
  # Remove bash completion
37
91
  printf "${BLUE}Removing bash completion...${NC}\n"
38
- $SUDO rm -f "$COMPLETION_DIR/aws-lambda-layer"
92
+ $SUDO rm -f "$COMPLETION_DIR/aws-lambda-layer-cli"
39
93
 
40
94
  # Remove zsh completion
41
- if [ -f "/usr/local/share/zsh/site-functions/_aws-lambda-layer" ]; then
95
+ if [ -f "/usr/local/share/zsh/site-functions/_aws-lambda-layer-cli" ]; then
42
96
  printf "${BLUE}Removing zsh completion (standard)...${NC}\n"
43
- $SUDO rm -f "/usr/local/share/zsh/site-functions/_aws-lambda-layer"
97
+ $SUDO rm -f "/usr/local/share/zsh/site-functions/_aws-lambda-layer-cli"
44
98
  fi
45
99
 
46
- if [ -f "/opt/homebrew/share/zsh/site-functions/_aws-lambda-layer" ]; then
100
+ if [ -f "/opt/homebrew/share/zsh/site-functions/_aws-lambda-layer-cli" ]; then
47
101
  printf "${BLUE}Removing zsh completion (Homebrew)...${NC}\n"
48
- $SUDO rm -f "/opt/homebrew/share/zsh/site-functions/_aws-lambda-layer"
102
+ $SUDO rm -f "/opt/homebrew/share/zsh/site-functions/_aws-lambda-layer-cli"
49
103
  fi
50
104
 
51
105
  # Remove from .bashrc
52
106
  if [ -f "$HOME/.bashrc" ]; then
53
107
  printf "${BLUE}Cleaning up .bashrc...${NC}\n"
54
108
  $SUDO sed -i '/# AWS Lambda Layer CLI completion/d' "$HOME/.bashrc"
55
- $SUDO sed -i '/source.*aws-lambda-layer/d' "$HOME/.bashrc"
109
+ $SUDO sed -i '/source.*aws-lambda-layer-cli/d' "$HOME/.bashrc"
56
110
  fi
57
111
 
58
112
  printf "${GREEN}✅ Uninstallation complete!${NC}\n"
@@ -1,89 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- 'use strict';
4
-
5
- const { spawnSync } = require('child_process');
6
- const fs = require('fs');
7
- const path = require('path');
8
-
9
- function which(cmd) {
10
- const isWin = process.platform === 'win32';
11
- const exts = isWin ? (process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM').split(';') : [''];
12
- const paths = (process.env.PATH || '').split(path.delimiter);
13
-
14
- for (const p of paths) {
15
- if (!p) continue;
16
- for (const ext of exts) {
17
- const full = path.join(p, isWin ? cmd + ext.toLowerCase() : cmd);
18
- if (fs.existsSync(full)) return full;
19
- // Also check original case on Windows
20
- const full2 = path.join(p, cmd + ext);
21
- if (fs.existsSync(full2)) return full2;
22
- }
23
- }
24
- return null;
25
- }
26
-
27
- function shQuote(s) {
28
- // Single-quote for bash -lc
29
- return `'${String(s).replace(/'/g, `'\\''`)}'`;
30
- }
31
-
32
- function windowsPathToWsl(p) {
33
- // C:\Users\me\x -> /mnt/c/Users/me/x
34
- const m = /^([a-zA-Z]):\\(.*)$/.exec(p);
35
- if (!m) return null;
36
- return `/mnt/${m[1].toLowerCase()}/${m[2].replace(/\\/g, '/')}`;
37
- }
38
-
39
- function cygpathConvert(mode, p) {
40
- const cygpath = which('cygpath');
41
- if (!cygpath) return null;
42
- const res = spawnSync(cygpath, [mode, p], { encoding: 'utf8' });
43
- if (res.status !== 0) return null;
44
- return (res.stdout || '').trim();
45
- }
46
-
47
- function run(cmd, args) {
48
- const res = spawnSync(cmd, args, { stdio: 'inherit' });
49
- process.exit(res.status ?? 1);
50
- }
51
-
52
- const args = process.argv.slice(2);
53
- const bashScript = path.resolve(__dirname, '..', 'scripts', 'aws-lambda-layer');
54
-
55
- if (!fs.existsSync(bashScript)) {
56
- console.error('Error: packaged bash script not found:', bashScript);
57
- process.exit(1);
58
- }
59
-
60
- // POSIX platforms
61
- if (process.platform !== 'win32') {
62
- run('bash', [bashScript, ...args]);
63
- }
64
-
65
- // Windows platforms:
66
- // - Prefer Git Bash / MSYS / Cygwin: convert to POSIX path using cygpath -u
67
- // - Else attempt WSL: convert to /mnt/<drive>/... and run via wsl.exe
68
- // - Else give a clear message
69
-
70
- const posixPath = cygpathConvert('-u', bashScript);
71
- if (posixPath) {
72
- run('bash', [posixPath, ...args]);
73
- }
74
-
75
- const wsl = which('wsl.exe') || which('wsl');
76
- if (wsl) {
77
- const wslPath = windowsPathToWsl(bashScript);
78
- if (!wslPath) {
79
- console.error('Error: unable to convert path for WSL:', bashScript);
80
- process.exit(1);
81
- }
82
-
83
- const cmd = `bash ${shQuote(wslPath)} ${args.map(shQuote).join(' ')}`.trim();
84
- run(wsl, ['bash', '-lc', cmd]);
85
- }
86
-
87
- console.error('Error: no compatible bash found on Windows.');
88
- console.error('Install and run this tool inside WSL, or install Git Bash and ensure `bash`/`cygpath` are on PATH.');
89
- process.exit(1);