Skip to content

Commit 0f509b2

Browse files
author
Anycodes
committed
feat: improve s command wrapper with smart lookup and better error messages
1 parent abcfdc4 commit 0f509b2

File tree

1 file changed

+136
-16
lines changed

1 file changed

+136
-16
lines changed

serverless_devs/__main__.py

Lines changed: 136 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,156 @@
11
"""
22
Serverless Devs 命令行入口
3-
调用已安装的 s 命令
3+
智能调用 s 命令(支持多种安装方式)
44
"""
55

66
import subprocess
77
import sys
88
import shutil
9+
import os
910

10-
def main():
11-
"""调用 s 命令"""
12-
# 查找 s 命令
11+
def find_s_command():
12+
"""
13+
智能查找 s 命令
14+
返回: (命令路径或可执行方式, 是否为 node 脚本)
15+
"""
16+
# 方法1: 直接在 PATH 中查找
1317
s_path = shutil.which('s')
18+
if s_path:
19+
return s_path, False
20+
21+
# 方法2: 通过 npm 查找全局安装
22+
try:
23+
result = subprocess.run(
24+
['npm', 'root', '-g'],
25+
capture_output=True,
26+
text=True,
27+
timeout=5,
28+
encoding='utf-8',
29+
errors='ignore'
30+
)
31+
if result.returncode == 0:
32+
npm_root = result.stdout.strip()
33+
s_js = os.path.join(npm_root, '@serverless-devs', 's', 'bin', 's.js')
34+
if os.path.exists(s_js):
35+
return s_js, True
36+
except Exception:
37+
pass
38+
39+
# 方法3: 检查常见安装位置
40+
home = os.path.expanduser('~')
41+
common_paths = [
42+
os.path.join(home, '.s', 'bin', 's'),
43+
'/usr/local/bin/s',
44+
os.path.join(home, '.local', 'bin', 's'),
45+
]
46+
47+
# Windows 特殊路径
48+
if sys.platform == 'win32':
49+
appdata = os.environ.get('APPDATA', '')
50+
if appdata:
51+
common_paths.extend([
52+
os.path.join(appdata, 'npm', 's.cmd'),
53+
os.path.join(appdata, 'npm', 's'),
54+
])
55+
56+
for path in common_paths:
57+
if os.path.exists(path):
58+
return path, False
59+
60+
return None, False
61+
62+
def show_help_message():
63+
"""显示帮助信息"""
64+
print("Error: 's' command not found", file=sys.stderr)
65+
print("", file=sys.stderr)
66+
print("This usually means Serverless Devs is not installed yet.", file=sys.stderr)
67+
print("", file=sys.stderr)
68+
print("Solutions:", file=sys.stderr)
69+
print(" 1. Reinstall this package:", file=sys.stderr)
70+
print(" pip install --force-reinstall serverless-devs", file=sys.stderr)
71+
print("", file=sys.stderr)
72+
print(" 2. Manual installation:", file=sys.stderr)
73+
print(" s-install", file=sys.stderr)
74+
print("", file=sys.stderr)
75+
print(" 3. Install via npm directly:", file=sys.stderr)
76+
print(" npm install -g @serverless-devs/s", file=sys.stderr)
77+
print("", file=sys.stderr)
78+
79+
# 尝试诊断问题
80+
if shutil.which('npm'):
81+
print("Diagnostics:", file=sys.stderr)
82+
try:
83+
result = subprocess.run(
84+
['npm', 'list', '-g', '@serverless-devs/s', '--depth=0'],
85+
capture_output=True,
86+
text=True,
87+
timeout=5,
88+
encoding='utf-8',
89+
errors='ignore'
90+
)
91+
if '@serverless-devs/s' in result.stdout:
92+
print(" - Serverless Devs is installed via npm", file=sys.stderr)
93+
94+
# 提示 PATH 问题
95+
npm_bin_result = subprocess.run(
96+
['npm', 'bin', '-g'],
97+
capture_output=True,
98+
text=True,
99+
timeout=5,
100+
encoding='utf-8',
101+
errors='ignore'
102+
)
103+
if npm_bin_result.returncode == 0:
104+
npm_bin = npm_bin_result.stdout.strip()
105+
print(f" - Add to PATH: {npm_bin}", file=sys.stderr)
106+
107+
if sys.platform == 'win32':
108+
print("", file=sys.stderr)
109+
print(" To add to PATH on Windows:", file=sys.stderr)
110+
print(f' setx PATH "%PATH%;{npm_bin}"', file=sys.stderr)
111+
else:
112+
shell_rc = '~/.bashrc'
113+
if os.path.exists(os.path.expanduser('~/.zshrc')):
114+
shell_rc = '~/.zshrc'
115+
print("", file=sys.stderr)
116+
print(f" To add to PATH on Unix:", file=sys.stderr)
117+
print(f' echo \'export PATH="{npm_bin}:$PATH"\' >> {shell_rc}', file=sys.stderr)
118+
print(f" source {shell_rc}", file=sys.stderr)
119+
else:
120+
print(" - Serverless Devs is NOT installed", file=sys.stderr)
121+
print(" - Run: s-install", file=sys.stderr)
122+
except Exception:
123+
pass
124+
else:
125+
print("Note: npm not found. Node.js may not be installed.", file=sys.stderr)
126+
print(" Download: https://nodejs.org/", file=sys.stderr)
127+
128+
def main():
129+
"""主入口:调用 s 命令"""
130+
s_path, is_node_script = find_s_command()
14131

15132
if s_path:
16133
try:
17-
# 调用实际的 s 命令,传递所有参数
18-
result = subprocess.run([s_path] + sys.argv[1:])
134+
if is_node_script:
135+
# Node.js 脚本,使用 node 执行
136+
cmd = ['node', s_path] + sys.argv[1:]
137+
else:
138+
# 可执行文件,直接执行
139+
cmd = [s_path] + sys.argv[1:]
140+
141+
result = subprocess.run(cmd)
19142
sys.exit(result.returncode)
143+
20144
except KeyboardInterrupt:
21-
sys.exit(130) # 128 + SIGINT
145+
# Ctrl+C 中断
146+
sys.exit(130)
22147
except Exception as e:
23-
print(f"错误: 执行 s 命令时出错: {e}", file=sys.stderr)
148+
print(f"Error: Failed to execute 's' command: {e}", file=sys.stderr)
24149
sys.exit(1)
25150
else:
26-
print("错误: 找不到 's' 命令", file=sys.stderr)
27-
print("", file=sys.stderr)
28-
print("请尝试以下解决方案:", file=sys.stderr)
29-
print(" 1. 重新安装: pip install --force-reinstall serverless-devs", file=sys.stderr)
30-
print(" 2. 手动安装: s-install", file=sys.stderr)
31-
print(" 3. 使用 npm: npm install -g @serverless-devs/s", file=sys.stderr)
32-
print(" 4. 重新加载环境变量: source ~/.bashrc (或 ~/.zshrc)", file=sys.stderr)
151+
# 找不到 s 命令
152+
show_help_message()
33153
sys.exit(1)
34154

35155
if __name__ == '__main__':
36-
main()
156+
main()

0 commit comments

Comments
 (0)