diff --git a/src/vcs/command.go b/src/vcs/cmd/command.go similarity index 50% rename from src/vcs/command.go rename to src/vcs/cmd/command.go index 9c59a228..a2d86f1b 100644 --- a/src/vcs/command.go +++ b/src/vcs/cmd/command.go @@ -20,18 +20,46 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package vcs +package cmd -import "os/exec" +import ( + "github.com/codeskyblue/go-sh" + "github.com/murex/tcr/report" + "os/exec" +) -// IsCommandAvailable indicates if the provided command is available in the path -func IsCommandAvailable(command string) bool { - _, err := exec.LookPath(command) +// ShellCommand is a command that can be launched from a shell +type ShellCommand struct { + name string +} + +// New creates a new shell command instance +func New(name string) *ShellCommand { + return &ShellCommand{name: name} +} + +// IsInPath indicates if the command can be found in the path +func (sc *ShellCommand) IsInPath() bool { + _, err := exec.LookPath(sc.name) return err == nil } -// GetCommandPath returns the full path to the provided command -func GetCommandPath(command string) string { - path, _ := exec.LookPath(command) +// GetFullPath returns the full path for this command +func (sc *ShellCommand) GetFullPath() string { + path, _ := exec.LookPath(sc.name) return path } + +// Run calls the command with the provided parameters in a separate process and returns its output traces combined +func (sc *ShellCommand) Run(params ...string) (output []byte, err error) { + return sh.Command(sc.name, params).CombinedOutput() +} + +// Trace calls the command with the provided parameters and reports its output traces +func (sc *ShellCommand) Trace(params ...string) error { + output, err := sc.Run(params...) + if len(output) > 0 { + report.PostText(string(output)) + } + return err +} diff --git a/src/vcs/command_test.go b/src/vcs/cmd/command_test.go similarity index 51% rename from src/vcs/command_test.go rename to src/vcs/cmd/command_test.go index c6f3968a..9f4b5ce9 100644 --- a/src/vcs/command_test.go +++ b/src/vcs/cmd/command_test.go @@ -20,28 +20,57 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package vcs +package cmd import ( + "github.com/murex/tcr/report" "github.com/stretchr/testify/assert" "path/filepath" "strings" "testing" ) -func Test_check_command_is_available_for_a_valid_command(t *testing.T) { - assert.True(t, IsCommandAvailable("ls")) +func Test_is_in_path_for_a_valid_command(t *testing.T) { + assert.True(t, New("ls").IsInPath()) } -func Test_check_command_is_available_for_an_invalid_command(t *testing.T) { - assert.False(t, IsCommandAvailable("unknown-command")) +func Test_is_in_path_for_an_invalid_command(t *testing.T) { + assert.False(t, New("unknown-command").IsInPath()) } -func Test_check_command_path_for_a_valid_command(t *testing.T) { - base := filepath.Base(GetCommandPath("ls")) +func Test_get_full_path_for_a_valid_command(t *testing.T) { + base := filepath.Base(New("ls").GetFullPath()) assert.Equal(t, strings.TrimSuffix(base, ".exe"), "ls") } -func Test_check_command_path_for_an_invalid_command(t *testing.T) { - assert.Zero(t, GetCommandPath("unknown-command")) +func Test_get_full_path_for_an_invalid_command(t *testing.T) { + assert.Zero(t, New("unknown-command").GetFullPath()) +} + +func Test_run_valid_command(t *testing.T) { + output, err := New("pwd").Run() + assert.NoError(t, err) + assert.NotZero(t, output) +} + +func Test_run_invalid_command(t *testing.T) { + output, err := New("unknown-command").Run() + assert.Error(t, err) + assert.Zero(t, output) +} + +func Test_trace_valid_command(t *testing.T) { + sniffer := report.NewSniffer() + err := New("pwd").Trace() + sniffer.Stop() + assert.NoError(t, err) + assert.Equal(t, 1, sniffer.GetMatchCount()) +} + +func Test_trace_invalid_command(t *testing.T) { + sniffer := report.NewSniffer() + err := New("unknown-command").Trace() + sniffer.Stop() + assert.Error(t, err) + assert.Equal(t, 0, sniffer.GetMatchCount()) }