| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- package main
- import (
- "encoding/json"
- "os"
- "os/exec"
- "path/filepath"
- "strings"
- "sync"
- )
- const dshPackage = "@deepseek-ai/dsh"
- var (
- npmRootOnce sync.Once
- npmRootPath string
- )
- // npmGlobalRoot 执行 npm root -g(隐藏窗口),结果缓存(仅首次调用起子进程)。
- func npmGlobalRoot() string {
- npmRootOnce.Do(func() {
- exe, args := npmCommandFor("root", "-g")
- cmd := exec.Command(exe, args...)
- hideWindow(cmd)
- out, err := cmd.Output()
- if err != nil {
- return
- }
- npmRootPath = strings.TrimSpace(string(out))
- })
- return npmRootPath
- }
- // npmCommandFor 组装 npm 调用:优先 node + npm-cli.js(无 shell),回退 cmd /c npm。
- func npmCommandFor(args ...string) (string, []string) {
- if node, err := exec.LookPath("node"); err == nil {
- if cli := detectNpmCLI(node); cli != "" {
- return node, append([]string{cli}, args...)
- }
- }
- return "cmd.exe", append([]string{"/c", "npm"}, args...)
- }
- func detectNpmCLI(node string) string {
- base := filepath.Dir(node)
- candidates := []string{
- filepath.Join(base, "node_modules", "npm", "bin", "npm-cli.js"),
- filepath.Join(base, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
- }
- for _, c := range candidates {
- if fileExists(c) {
- return c
- }
- }
- return ""
- }
- // readPackageVersion 读取 package.json 的 version 字段。
- func readPackageVersion(path string) string {
- data, err := os.ReadFile(path)
- if err != nil {
- return ""
- }
- var v struct {
- Version string `json:"version"`
- }
- if err := json.Unmarshal(data, &v); err != nil {
- return ""
- }
- return v.Version
- }
|