add macos appstore
This commit is contained in:
parent
ee5f1cdab6
commit
0fcdbdd3ac
9 changed files with 1353 additions and 39 deletions
29
build.linux.sh
Normal file → Executable file
29
build.linux.sh
Normal file → Executable file
|
|
@ -1,4 +1,25 @@
|
||||||
wails build -platform linux/amd64 -s -o godoos-linux-amd64
|
#!/bin/bash
|
||||||
wails build -platform linux/arm64 -s -o godoos-linux-arm64
|
|
||||||
wails build -platform darwin/amd64 -s -o godoos-darwin-amd64
|
# 定义一个函数来执行压缩操作
|
||||||
wails build -platform darwin/arm64 -s -o godoos-darwin-arm64
|
compress_to_zip() {
|
||||||
|
local target_file="./build/bin/godoos$2"
|
||||||
|
local zip_name="./build/bin/$1.zip"
|
||||||
|
|
||||||
|
# 检查ZIP文件是否已经存在,如果存在则跳过压缩
|
||||||
|
if [ ! -f "$zip_name" ]; then
|
||||||
|
echo "Compressing $target_file to $zip_name"
|
||||||
|
zip -j "$zip_name" "$target_file"
|
||||||
|
else
|
||||||
|
echo "$zip_name already exists. Skipping compression."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 构建和压缩
|
||||||
|
wails build -platform linux/amd64 -s
|
||||||
|
compress_to_zip "godoos-linux-amd64" ""
|
||||||
|
wails build -platform linux/arm64 -s
|
||||||
|
compress_to_zip "godoos-linux-arm64" ""
|
||||||
|
wails build -platform darwin/amd64 -s
|
||||||
|
compress_to_zip "godoos-darwin-amd64" ".app"
|
||||||
|
wails build -platform darwin/arm64 -s
|
||||||
|
compress_to_zip "godoos-darwin-arm64" ".app"
|
||||||
|
|
@ -220,7 +220,7 @@ const comp = await fetch('http://localhost:56780/store/setting', {
|
||||||
2. `static`目录下的在执行install时文件会自动复制到`.godoos/static/`应用目录下
|
2. `static`目录下的在执行install时文件会自动复制到`.godoos/static/`应用目录下
|
||||||
3. `store.json`如果设置了`icon`,并且`static`目录下存在该文件,则应用图标为该文件。否则为`install.json`中的icon
|
3. `store.json`如果设置了`icon`,并且`static`目录下存在该文件,则应用图标为该文件。否则为`install.json`中的icon
|
||||||
|
|
||||||
### 内置应用说明
|
### `commands`内置函数说明
|
||||||
- 系统封装了一些用于处理进程控制和文件操作的功能函数,以下是各函数的详细描述:
|
- 系统封装了一些用于处理进程控制和文件操作的功能函数,以下是各函数的详细描述:
|
||||||
1. `start` 启动应用
|
1. `start` 启动应用
|
||||||
2. `stop` 停止应用
|
2. `stop` 停止应用
|
||||||
|
|
@ -235,6 +235,8 @@ const comp = await fetch('http://localhost:56780/store/setting', {
|
||||||
11. `startApp` 启动其他应用,content为应用名
|
11. `startApp` 启动其他应用,content为应用名
|
||||||
12. `stopApp` 停止其他应用,content为应用名
|
12. `stopApp` 停止其他应用,content为应用名
|
||||||
|
|
||||||
|
- 保留命令`uninstall`,如果设置了`uninstall`,系统在卸载的时候将会执行它
|
||||||
|
|
||||||
### 进阶操作
|
### 进阶操作
|
||||||
1. 下载[mysql8.0](https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.39-winx64.zip)
|
1. 下载[mysql8.0](https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.39-winx64.zip)
|
||||||
2. 参考demo下的mysql8.0目录,尝试自己制作安装包
|
2. 参考demo下的mysql8.0目录,尝试自己制作安装包
|
||||||
|
|
|
||||||
13
frontend/package-lock.json
generated
13
frontend/package-lock.json
generated
|
|
@ -1262,17 +1262,6 @@
|
||||||
"integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==",
|
"integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/core-js": {
|
|
||||||
"version": "3.37.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.37.1.tgz",
|
|
||||||
"integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"peer": true,
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/core-js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/core-util-is": {
|
"node_modules/core-util-is": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||||
|
|
@ -2191,7 +2180,7 @@
|
||||||
"version": "5.5.4",
|
"version": "5.5.4",
|
||||||
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.5.4.tgz",
|
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.5.4.tgz",
|
||||||
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
|
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
|
|
|
||||||
1100
godo/deps/darwin/brew-install.sh
Executable file
1100
godo/deps/darwin/brew-install.sh
Executable file
File diff suppressed because it is too large
Load diff
|
|
@ -3,6 +3,7 @@ module godo
|
||||||
go 1.22.5
|
go 1.22.5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/cavaliergopher/grab/v3 v3.0.1
|
||||||
github.com/fsnotify/fsnotify v1.7.0
|
github.com/fsnotify/fsnotify v1.7.0
|
||||||
github.com/gorilla/mux v1.8.1
|
github.com/gorilla/mux v1.8.1
|
||||||
github.com/minio/selfupdate v0.6.0
|
github.com/minio/selfupdate v0.6.0
|
||||||
|
|
@ -11,7 +12,6 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
aead.dev/minisign v0.2.0 // indirect
|
aead.dev/minisign v0.2.0 // indirect
|
||||||
github.com/cavaliergopher/grab/v3 v3.0.1 // indirect
|
|
||||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
github.com/stretchr/testify v1.9.0 // indirect
|
github.com/stretchr/testify v1.9.0 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.14 // indirect
|
github.com/tklauser/go-sysconf v0.3.14 // indirect
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
|
||||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
|
|
|
||||||
|
|
@ -30,19 +30,9 @@ func runStart(storeInfo StoreInfo) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
binPath := storeInfo.Setting.BinPath
|
cmd, err := GetRunCmd(storeInfo.Setting.BinPath, storeInfo.Start.StartCmds)
|
||||||
if !libs.PathExists(binPath) {
|
if err != nil {
|
||||||
return fmt.Errorf("script file %s does not exist", storeInfo.Setting.BinPath)
|
return fmt.Errorf("failed to get run cmd: %w", err)
|
||||||
}
|
|
||||||
var cmd *exec.Cmd
|
|
||||||
if len(storeInfo.Start.StartCmds) > 0 {
|
|
||||||
cmd = exec.Command(binPath, storeInfo.Start.StartCmds...)
|
|
||||||
} else {
|
|
||||||
cmd = exec.Command(binPath)
|
|
||||||
}
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
// 在Windows上,通过设置CreationFlags来隐藏窗口
|
|
||||||
cmd = SetHideConsoleCursor(cmd)
|
|
||||||
}
|
}
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
//log.Println("Error starting script:", err)
|
//log.Println("Error starting script:", err)
|
||||||
|
|
@ -69,9 +59,46 @@ func runStart(storeInfo StoreInfo) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func GetRunCmd(binPath string, cmds []string) (*exec.Cmd, error) {
|
||||||
|
var cmd *exec.Cmd
|
||||||
|
if binPath != "" {
|
||||||
|
if !libs.PathExists(binPath) {
|
||||||
|
return cmd, fmt.Errorf("script file %s does not exist", binPath)
|
||||||
|
}
|
||||||
|
// 如果是非Windows环境,设置可执行权限
|
||||||
|
if runtime.GOOS != "windows" {
|
||||||
|
// 设置文件权限,0755是一个常见的可执行文件权限掩码
|
||||||
|
if err := os.Chmod(binPath, 0755); err != nil {
|
||||||
|
return cmd, fmt.Errorf("failed to set executable permissions on %s: %w", binPath, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cmds) > 0 {
|
||||||
|
cmd = exec.Command(binPath, cmds...)
|
||||||
|
} else {
|
||||||
|
cmd = exec.Command(binPath)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(cmds) == 0 {
|
||||||
|
return cmd, fmt.Errorf("no commands provided")
|
||||||
|
}
|
||||||
|
if len(cmds) > 1 {
|
||||||
|
cmd = exec.Command(cmds[0], cmds[1:]...)
|
||||||
|
} else {
|
||||||
|
cmd = exec.Command(cmds[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
// 在Windows上,通过设置CreationFlags来隐藏窗口
|
||||||
|
cmd = SetHideConsoleCursor(cmd)
|
||||||
|
}
|
||||||
|
return cmd, nil
|
||||||
|
}
|
||||||
func RunStartApp(appName string) error {
|
func RunStartApp(appName string) error {
|
||||||
return ExecuteScript(appName)
|
return ExecuteScript(appName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunStopApp(appName string) error {
|
func RunStopApp(appName string) error {
|
||||||
return StopCmd(appName)
|
return StopCmd(appName)
|
||||||
}
|
}
|
||||||
|
|
@ -87,13 +114,12 @@ func runExec(storeInfo StoreInfo, cmdParam Cmd) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to set start environment variable %s: %w", storeInfo.Name, err)
|
return fmt.Errorf("failed to set start environment variable %s: %w", storeInfo.Name, err)
|
||||||
}
|
}
|
||||||
log.Printf("bin path:%v", cmdParam.BinPath)
|
|
||||||
log.Printf("cmds:%v", cmdParam.Cmds)
|
cmd, err := GetRunCmd(cmdParam.BinPath, cmdParam.Cmds)
|
||||||
cmd := exec.Command(cmdParam.BinPath, cmdParam.Cmds...)
|
if err != nil {
|
||||||
if runtime.GOOS == "windows" {
|
return fmt.Errorf("failed to get run cmd: %w", err)
|
||||||
// 在Windows上,通过设置CreationFlags来隐藏窗口
|
|
||||||
cmd = SetHideConsoleCursor(cmd)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return fmt.Errorf("failed to run exec process %s: %w", storeInfo.Name, err)
|
return fmt.Errorf("failed to run exec process %s: %w", storeInfo.Name, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,15 @@ func Uninstallation(pluginName string) error {
|
||||||
return fmt.Errorf("the app is being used by other applications: %v", hasDeps)
|
return fmt.Errorf("the app is being used by other applications: %v", hasDeps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
storeInfo, err := GetStoreInfo(pluginName)
|
||||||
|
if err == nil {
|
||||||
|
if _, ok := storeInfo.Commands["uninstall"]; ok {
|
||||||
|
replacePlaceholdersInCmds(&storeInfo)
|
||||||
|
if err := RunCmds(storeInfo, "uninstall"); err != nil {
|
||||||
|
return fmt.Errorf("error running uninstall command: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Remove the application directory
|
// Remove the application directory
|
||||||
exePath := GetExePath(pluginName)
|
exePath := GetExePath(pluginName)
|
||||||
if libs.PathExists(exePath) {
|
if libs.PathExists(exePath) {
|
||||||
|
|
@ -413,6 +422,22 @@ func replacePlaceholdersInCmds(storeInfo *StoreInfo) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if len(cmd.Cmds) > 0 {
|
||||||
|
for j, cmd := range cmd.Cmds {
|
||||||
|
strValue := convertValueToString(value)
|
||||||
|
// 使用正则表达式替换Content中的占位符
|
||||||
|
storeInfo.Commands[cmdGroupName][i].Cmds[j] = pattern.ReplaceAllStringFunc(
|
||||||
|
cmd,
|
||||||
|
func(match string) string {
|
||||||
|
// 检查占位符是否与Config中的键匹配
|
||||||
|
if strings.Trim(match, "{}") == key {
|
||||||
|
return strValue
|
||||||
|
}
|
||||||
|
return match
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
153
godo/store/os.go
Normal file
153
godo/store/os.go
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DetectOperatingSystem returns the operating system name and version.
|
||||||
|
func DetectOperatingSystem() (name string, version string, err error) {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin":
|
||||||
|
// macOS specific detection
|
||||||
|
cmd := exec.Command("sw_vers")
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
output := string(out)
|
||||||
|
lines := strings.Split(output, "\n")
|
||||||
|
if len(lines) >= 2 {
|
||||||
|
name = strings.TrimSpace(strings.Split(lines[0], ":")[1])
|
||||||
|
version = strings.TrimSpace(strings.Split(lines[1], ":")[1])
|
||||||
|
}
|
||||||
|
case "linux":
|
||||||
|
// Linux specific detection
|
||||||
|
file, err := os.Open("/etc/os-release")
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if strings.HasPrefix(line, "ID=") {
|
||||||
|
name = strings.TrimPrefix(line, "ID=")
|
||||||
|
name = strings.Trim(name, "\"")
|
||||||
|
} else if strings.HasPrefix(line, "VERSION_ID=") {
|
||||||
|
version = strings.TrimPrefix(line, "VERSION_ID=")
|
||||||
|
version = strings.Trim(version, "\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if name == "" || version == "" {
|
||||||
|
return "", "", fmt.Errorf("could not determine Linux distribution from /etc/os-release")
|
||||||
|
}
|
||||||
|
case "windows":
|
||||||
|
// Windows specific detection
|
||||||
|
cmd := exec.Command("cmd", "/c", "ver")
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
version = strings.TrimSpace(string(out))
|
||||||
|
name = "Windows"
|
||||||
|
default:
|
||||||
|
// For other operating systems, just return the GOOS value
|
||||||
|
name = runtime.GOOS
|
||||||
|
version = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return name, version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DetectPackageManager returns the package manager based on the detected operating system.
|
||||||
|
func DetectPackageManager() (pm string, err error) {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin":
|
||||||
|
// macOS specific detection
|
||||||
|
cmd := exec.Command("which", "brew")
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("homebrew not found: %w", err)
|
||||||
|
}
|
||||||
|
pm = strings.TrimSpace(string(out))
|
||||||
|
if pm != "" {
|
||||||
|
pm = "brew"
|
||||||
|
}
|
||||||
|
case "linux":
|
||||||
|
// Linux specific detection
|
||||||
|
file, err := os.Open("/etc/os-release")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if strings.HasPrefix(line, "ID=") {
|
||||||
|
id := strings.TrimPrefix(line, "ID=")
|
||||||
|
id = strings.Trim(id, "\"")
|
||||||
|
switch id {
|
||||||
|
case "debian", "ubuntu", "linuxmint", "elementary":
|
||||||
|
pm = "apt"
|
||||||
|
case "centos", "fedora", "rhel":
|
||||||
|
cmd := exec.Command("which", "dnf")
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
cmd = exec.Command("which", "yum")
|
||||||
|
out, err = cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("neither dnf nor yum found: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pm = strings.TrimSpace(string(out))
|
||||||
|
if pm != "" {
|
||||||
|
pm = "dnf"
|
||||||
|
} else {
|
||||||
|
pm = "yum"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
case "windows":
|
||||||
|
// Windows specific detection - Not applicable for this context
|
||||||
|
return "", fmt.Errorf("windows does not use apt, yum, or brew")
|
||||||
|
default:
|
||||||
|
// For other operating systems, just return an error
|
||||||
|
return "", fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pm, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckPathInstalled(execName string, execCommands string) bool {
|
||||||
|
cmd := exec.Command(execName, execCommands)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
// 如果命令执行失败,可能是因为brew没有安装
|
||||||
|
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||||
|
// 判断是否是因为找不到命令导致的错误
|
||||||
|
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok && status.ExitStatus() == 127 {
|
||||||
|
return false // brew没有安装
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Printf("Homebrew version: %s\n", out)
|
||||||
|
return true
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue