-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexecute.go
More file actions
123 lines (107 loc) · 2.76 KB
/
Copy pathexecute.go
File metadata and controls
123 lines (107 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main
import (
"fmt"
"os"
"os/exec"
"runtime"
"slices"
"strings"
)
type shellConfig struct {
path string
args []string
}
func fileExists(path string) bool {
// we are not using os.IsNotExist(err) to check for the error
// because fileExists("$@#\n") would return true
// since a new line would return a different error
if _, err := os.Stat(path); err != nil {
return false
}
return true
}
// toUnixPath converts Windows file paths to Unix-style paths for WSL.
// On non-Windows systems, it returns the path unchanged.
func toUnixPath(path string) string {
if runtime.GOOS != "windows" {
return path
}
cmds := []string{}
for arg := range strings.FieldsSeq(path) {
if fileExists(arg) {
arg = strings.ReplaceAll(path, "\\", "/")
}
cmds = append(cmds, arg)
}
return strings.Join(cmds, " ")
}
// getShellConfig creates a shellConfig based on the command and interactivity.
// It uses "SHELL" or "GAS_SHELL" environment variables for the shell path.
// Supports only unix and powershell.
func getShellConfig(command string, isInteractive bool) shellConfig {
var shellPath string
var cmdArgs []string
shellPath = loadEnvSetting("SHELL", "GAS_SHELL")
switch {
case slices.Contains([]string{"pwsh", "powershell"}, shellPath):
if isInteractive {
cmdArgs = []string{command}
} else {
cmdArgs = []string{"-NoProfile", command}
}
default:
command = toUnixPath(command)
if isInteractive {
cmdArgs = []string{"-i", "-c", command}
} else {
cmdArgs = []string{"-c", command}
}
}
return shellConfig{path: shellPath, args: cmdArgs}
}
func executeShellCommand(command TaskCommand, verbose bool) error {
shellOpt := getShellConfig(command.Cmd, command.UseInteractiveShell)
os.Chdir(command.Directory)
cmd := exec.Command(shellOpt.path, shellOpt.args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if command.Env != "" {
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, command.GetEnv()...)
}
if verbose {
fmt.Println(cmd)
}
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func processCommand(
db DatabaseHistory,
command TaskCommand,
verbose bool,
) {
if err := executeShellCommand(command, verbose); err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
command.ExitCode = exitErr.ExitCode()
command.Status = err.Error()
} else if strings.Contains(err.Error(), "executable file not found") {
command.ExitCode = 127
command.Status = "executable file not found"
} else {
command.ExitCode = 1 // Generic error
command.Status = err.Error()
}
// delete if it's a "not found" error
if command.ExitCode == 127 {
db.DeleteCommand(command)
return
}
} else {
command.Status = "success"
command.ExitCode = 0
}
db.UpdateCommandTimestamp(command)
db.UpsertCommand(command)
}