diff --git a/linux/interface.go b/linux/interface.go new file mode 100644 index 0000000..9cac60b --- /dev/null +++ b/linux/interface.go @@ -0,0 +1,25 @@ +package linux + +import ( + "errors" +) + +type LinuxCommand struct { + Options CommandOptions +} + +type CommandOptions struct { + Env map[string]string + Sources map[string]string + Command string + Args []string + Cwd string + Shell string +} + +// Errors +var ( + ErrFetchingCwd = errors.New("error fetching cwd") + ErrRunningCmd = errors.New("error running command") + ErrCommandNotFound = errors.New("error command not found") +) diff --git a/linux/run.go b/linux/run.go new file mode 100644 index 0000000..321599b --- /dev/null +++ b/linux/run.go @@ -0,0 +1,73 @@ +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 { + + command := exec.Command(cmd.Options.Shell, "-c", cmd.Options.Command) + 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)) + } + + commandExists, err := cmd.doesCommandExist(cmd.Options.Command) + if err != nil { + return err + } + + if !commandExists { + return ErrCommandNotFound + } + + if err := command.Start(); err != nil { + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + if exitErr.ExitCode() == 127 { + return ErrCommandNotFound + } else { + return fmt.Errorf("%w: %w", ErrRunningCmd, err) + } + } + } + + if err := command.Start(); err != nil { + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + if exitErr.ExitCode() == 127 { + return ErrCommandNotFound + } else { + return fmt.Errorf("%w: %w", ErrRunningCmd, err) + } + } + } + + return nil + +} diff --git a/linux/utils.go b/linux/utils.go new file mode 100644 index 0000000..dcc5e87 --- /dev/null +++ b/linux/utils.go @@ -0,0 +1,37 @@ +package linux + +import ( + "errors" + "fmt" + "os/exec" +) + +func (cmd *LinuxCommand) doesCommandExist(command string) (bool, error) { + + shellCmd := exec.Command(cmd.Options.Shell, "-c", fmt.Sprintf("command -v %s", command)) + + if err := shellCmd.Start(); err != nil { + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + if exitErr.ExitCode() == 1 { + return false, nil + } else { + return false, ErrRunningCmd + } + } + } + + if err := shellCmd.Wait(); err != nil { + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + if exitErr.ExitCode() == 1 { + return false, nil + } else { + return false, ErrRunningCmd + } + } + } + + return true, nil + +}