2024-07-04 22:40:13 +02:00
|
|
|
package linux
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
)
|
|
|
|
|
|
|
|
func NewCommand(options CommandOptions) (*LinuxCommand, error) {
|
|
|
|
|
|
|
|
if len(options.Shell) == 0 {
|
|
|
|
options.Shell = "/bin/bash"
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(options.Cwd) == 0 {
|
|
|
|
cwd, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
return nil, ErrFetchingCwd
|
|
|
|
}
|
|
|
|
options.Cwd = cwd
|
|
|
|
}
|
|
|
|
|
|
|
|
return &LinuxCommand{
|
|
|
|
Options: options,
|
|
|
|
}, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cmd *LinuxCommand) Run() error {
|
|
|
|
|
2024-07-05 00:08:45 +02:00
|
|
|
var sourceCommand string
|
|
|
|
for _, value := range cmd.Options.Sources {
|
|
|
|
sourceCommand += fmt.Sprintf("source %s && ", value)
|
|
|
|
}
|
|
|
|
|
|
|
|
command := exec.Command(cmd.Options.Shell, "-c", sourceCommand+cmd.Options.Command)
|
2024-07-04 23:27:41 +02:00
|
|
|
command.Dir = cmd.Options.Cwd
|
2024-07-04 22:40:13 +02:00
|
|
|
command.Args = append(command.Args, cmd.Options.Args...)
|
|
|
|
|
|
|
|
// Loop through env to format and add them to the command.
|
|
|
|
for key, value := range cmd.Options.Env {
|
|
|
|
command.Env = append(command.Env, fmt.Sprintf("%s=%s", key, value))
|
|
|
|
}
|
|
|
|
|
2024-07-04 23:14:10 +02:00
|
|
|
isCommandExecutable, err := cmd.isCommandExecutable(cmd.Options.Command)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if !isCommandExecutable {
|
|
|
|
return ErrCommandNotExecutable
|
|
|
|
}
|
|
|
|
|
2024-07-04 22:40:13 +02:00
|
|
|
if err := command.Start(); err != nil {
|
|
|
|
var exitErr *exec.ExitError
|
|
|
|
if errors.As(err, &exitErr) {
|
|
|
|
if exitErr.ExitCode() == 127 {
|
|
|
|
return ErrCommandNotFound
|
2024-07-05 01:40:33 +02:00
|
|
|
} else if _, ok := cmd.Options.CustomErrors[int8(exitErr.ExitCode())]; ok {
|
|
|
|
return cmd.Options.CustomErrors[int8(exitErr.ExitCode())]
|
2024-07-04 22:40:13 +02:00
|
|
|
} else {
|
2024-07-04 23:16:13 +02:00
|
|
|
return fmt.Errorf("%s: %w", ErrRunningCmd.Error(), err)
|
2024-07-04 22:40:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-04 23:14:10 +02:00
|
|
|
if err := command.Wait(); err != nil {
|
2024-07-04 22:40:13 +02:00
|
|
|
var exitErr *exec.ExitError
|
|
|
|
if errors.As(err, &exitErr) {
|
|
|
|
if exitErr.ExitCode() == 127 {
|
|
|
|
return ErrCommandNotFound
|
2024-07-05 01:40:33 +02:00
|
|
|
} else if _, ok := cmd.Options.CustomErrors[int8(exitErr.ExitCode())]; ok {
|
|
|
|
return cmd.Options.CustomErrors[int8(exitErr.ExitCode())]
|
2024-07-04 22:40:13 +02:00
|
|
|
} else {
|
2024-07-04 23:16:13 +02:00
|
|
|
return fmt.Errorf("%s: %w", ErrRunningCmd.Error(), err)
|
2024-07-04 22:40:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|