Skip to content

Commit

Permalink
Move shell package from libmachine to crc
Browse files Browse the repository at this point in the history
This is the only location where this package is used.
  • Loading branch information
guillaumerose authored and praveenkumar committed Dec 4, 2020
1 parent 1630ee2 commit b5773ad
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 92 deletions.
4 changes: 1 addition & 3 deletions pkg/os/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package shell
import (
"fmt"
"strings"

"github.com/code-ready/machine/libmachine/shell"
)

type Config struct {
Expand All @@ -21,7 +19,7 @@ func GetShell(userShell string) (string, error) {
}
return userShell, nil
}
return shell.Detect()
return Detect()
}

func isSupportedShell(userShell string) bool {
Expand Down
30 changes: 30 additions & 0 deletions pkg/os/shell/shell_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// +build !windows

package shell

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
)

func TestDetectBash(t *testing.T) {
defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL"))
os.Setenv("SHELL", "/bin/bash")

shell, err := Detect()

assert.Equal(t, "bash", shell)
assert.NoError(t, err)
}

func TestDetectFish(t *testing.T) {
defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL"))
os.Setenv("SHELL", "/bin/fish")

shell, err := Detect()

assert.Equal(t, "fish", shell)
assert.NoError(t, err)
}
File renamed without changes.
20 changes: 20 additions & 0 deletions pkg/os/shell/shell_unix_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// +build !windows

package shell

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
)

func TestUnknownShell(t *testing.T) {
defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL"))
os.Setenv("SHELL", "")

shell, err := Detect()

assert.Equal(t, err, ErrUnknownShell)
assert.Empty(t, shell)
}
85 changes: 85 additions & 0 deletions pkg/os/shell/shell_windows.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,90 @@
package shell

import (
"os"
"path/filepath"
"strings"
"syscall"
"unsafe"
)

var (
supportedShell = []string{"cmd", "powershell"}
)

// re-implementation of private function in https://github.com/golang/go/blob/master/src/syscall/syscall_windows.go
func getProcessEntry(pid int) (pe *syscall.ProcessEntry32, err error) {
snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
if err != nil {
return nil, err
}
defer func() {
_ = syscall.CloseHandle(syscall.Handle(snapshot))
}()

var processEntry syscall.ProcessEntry32
processEntry.Size = uint32(unsafe.Sizeof(processEntry))
err = syscall.Process32First(snapshot, &processEntry)
if err != nil {
return nil, err
}

for {
if processEntry.ProcessID == uint32(pid) {
pe = &processEntry
return
}

err = syscall.Process32Next(snapshot, &processEntry)
if err != nil {
return nil, err
}
}
}

// getNameAndItsPpid returns the exe file name its parent process id.
func getNameAndItsPpid(pid int) (exefile string, parentid int, err error) {
pe, err := getProcessEntry(pid)
if err != nil {
return "", 0, err
}

name := syscall.UTF16ToString(pe.ExeFile[:])
return name, int(pe.ParentProcessID), nil
}

func Detect() (string, error) {
shell := os.Getenv("SHELL")

if shell == "" {
shell, shellppid, err := getNameAndItsPpid(os.Getppid())
if err != nil {
return "cmd", err // defaulting to cmd
}
switch {
case strings.Contains(strings.ToLower(shell), "powershell"):
return "powershell", nil
case strings.Contains(strings.ToLower(shell), "cmd"):
return "cmd", nil
default:
shell, _, err := getNameAndItsPpid(shellppid)
if err != nil {
return "cmd", err // defaulting to cmd
}
switch {
case strings.Contains(strings.ToLower(shell), "powershell"):
return "powershell", nil
case strings.Contains(strings.ToLower(shell), "cmd"):
return "cmd", nil
default:
return "cmd", nil // this could be either powershell or cmd, defaulting to cmd
}
}
}

if os.Getenv("__fish_bin_dir") != "" {
return "fish", nil
}

return filepath.Base(shell), nil
}
41 changes: 41 additions & 0 deletions pkg/os/shell/shell_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package shell

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
)

func TestDetect(t *testing.T) {
defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL"))
os.Setenv("SHELL", "")

shell, err := Detect()

assert.Equal(t, "powershell", shell)
assert.NoError(t, err)
}

func TestGetNameAndItsPpidOfCurrent(t *testing.T) {
shell, shellppid, err := getNameAndItsPpid(os.Getpid())

assert.Equal(t, "shell.test.exe", shell)
assert.Equal(t, os.Getppid(), shellppid)
assert.NoError(t, err)
}

func TestGetNameAndItsPpidOfParent(t *testing.T) {
shell, _, err := getNameAndItsPpid(os.Getppid())

assert.Equal(t, "go.exe", shell)
assert.NoError(t, err)
}

func TestGetNameAndItsPpidOfGrandParent(t *testing.T) {
_, shellppid, _ := getNameAndItsPpid(os.Getppid())
shell, _, err := getNameAndItsPpid(shellppid)

assert.Equal(t, "powershell.exe", shell)
assert.NoError(t, err)
}

This file was deleted.

1 change: 0 additions & 1 deletion vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ github.com/code-ready/machine/libmachine/mcnerror
github.com/code-ready/machine/libmachine/mcnflag
github.com/code-ready/machine/libmachine/mcnutils
github.com/code-ready/machine/libmachine/persist
github.com/code-ready/machine/libmachine/shell
github.com/code-ready/machine/libmachine/state
github.com/code-ready/machine/libmachine/swarm
github.com/code-ready/machine/libmachine/version
Expand Down

0 comments on commit b5773ad

Please sign in to comment.