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 { 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) command.Dir = cmd.Options.Cwd 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)) } isCommandExecutable, err := cmd.isCommandExecutable(cmd.Options.Command) if err != nil { return err } if !isCommandExecutable { return ErrCommandNotExecutable } if err := command.Start(); err != nil { var exitErr *exec.ExitError if errors.As(err, &exitErr) { fmt.Println(exitErr.ExitCode()) if exitErr.ExitCode() == 127 { return ErrCommandNotFound } else { return fmt.Errorf("%s: %w", ErrRunningCmd.Error(), err) } } } if err := command.Wait(); err != nil { var exitErr *exec.ExitError if errors.As(err, &exitErr) { fmt.Println(exitErr.ExitCode()) if exitErr.ExitCode() == 127 { return ErrCommandNotFound } else { return fmt.Errorf("%s: %w", ErrRunningCmd.Error(), err) } } } return nil }