diff --git a/.github/workflows/pr_test.yml b/.github/workflows/pr_audit.yml similarity index 54% rename from .github/workflows/pr_test.yml rename to .github/workflows/pr_audit.yml index aaf06f1..3cc16c1 100644 --- a/.github/workflows/pr_test.yml +++ b/.github/workflows/pr_audit.yml @@ -1,10 +1,10 @@ -name: pr_test +name: pr_audit on: pull_request: branches: [main] jobs: - build: - name: Run tests + audit: + name: Audit runs-on: ubuntu-latest steps: - name: Check out source code @@ -24,5 +24,19 @@ jobs: run: go install github.com/vektra/mockery/v2@v2.20.0 - name: Run go generate run: go generate ./... - - name: Run go test - run: go test ./... + - name: Verify dependencies + run: go mod verify + - name: Build + run: go build -v ./... + - name: Run go vet + run: go vet ./... + - name: Install staticcheck + run: go install honnef.co/go/tools/cmd/staticcheck@latest + - name: Run staticcheck + run: staticcheck ./... + - name: Install golint + run: go install golang.org/x/lint/golint@latest + - name: Run golint + run: golint -set_exit_status ./... + - name: Run tests + run: go test -race -vet=off ./... diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0a9ea1a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +internal/prompt/mocks +internal/container/mocks diff --git a/cmd/main/main.go b/cmd/main/main.go index a112155..d7e68e3 100644 --- a/cmd/main/main.go +++ b/cmd/main/main.go @@ -1,14 +1,13 @@ package main import ( + "dex/internal/container" + "dex/internal/prompt" "fmt" "os" "strings" "github.com/containerd/console" - - "dex/internal/container" - "dex/internal/prompt" ) func main() { @@ -35,8 +34,8 @@ func main() { } func run( - containerService container.ContainerService, - promptService prompt.PromptService, + containerService container.Service, + promptService prompt.Service, ) error { containers, err := containerService.GetAll() if err != nil { @@ -74,8 +73,8 @@ func run( func containersToPromptOptions( dockerContainers []container.Container, -) []prompt.PromptOption { - var options []prompt.PromptOption +) []prompt.Option { + var options []prompt.Option for _, container := range dockerContainers { var names []string @@ -90,7 +89,7 @@ func containersToPromptOptions( container.ID[0:12], ) - option := prompt.PromptOption{ + option := prompt.Option{ Label: label, Value: container.ID, } diff --git a/cmd/main/main_test.go b/cmd/main/main_test.go index b33d905..6c464e9 100644 --- a/cmd/main/main_test.go +++ b/cmd/main/main_test.go @@ -17,10 +17,10 @@ import ( func TestRun(t *testing.T) { t.Run("FailsIfErrorWhenGettingContainers", func(t *testing.T) { expectedError := errors.New("Mock Error") - mockContainerService := containermocks.NewContainerService(t) + mockContainerService := containermocks.NewService(t) mockContainerService.On("GetAll").Return([]container.Container{}, expectedError) - mockPromptService := promptmocks.NewPromptService(t) + mockPromptService := promptmocks.NewService(t) actualError := run(mockContainerService, mockPromptService) @@ -28,12 +28,12 @@ func TestRun(t *testing.T) { }) t.Run("FailsSilentlyIfErrorWhenDisplayingContainerSelectPrompt", func(t *testing.T) { - mockContainerService := containermocks.NewContainerService(t) + mockContainerService := containermocks.NewService(t) mockContainerService.On("GetAll").Return(containersData(), nil) - mockPromptService := promptmocks.NewPromptService(t) + mockPromptService := promptmocks.NewService(t) mockPromptService.On("DisplaySelect", mock.Anything, promptOptionsData()). - Return(prompt.PromptOption{}, errors.New("Mock Error")) + Return(prompt.Option{}, errors.New("Mock Error")) mockPromptService.AssertNotCalled(t, "DisplayPrompt", mock.Anything) actualError := run(mockContainerService, mockPromptService) @@ -42,13 +42,13 @@ func TestRun(t *testing.T) { }) t.Run("FailsSilentlyIfErrorWhenDisplayingCommandPrompt", func(t *testing.T) { - mockContainerService := containermocks.NewContainerService(t) + mockContainerService := containermocks.NewService(t) mockContainerService.On("GetAll").Return(containersData(), nil) mockContainerService.AssertNotCalled(t, "RunCommand", mock.Anything, mock.Anything) - mockPromptService := promptmocks.NewPromptService(t) + mockPromptService := promptmocks.NewService(t) mockPromptService.On("DisplaySelect", mock.Anything, promptOptionsData()). - Return(prompt.PromptOption{}, nil) + Return(prompt.Option{}, nil) mockPromptService.On("DisplayPrompt", mock.Anything). Return("", errors.New("Mock Error")) @@ -60,16 +60,16 @@ func TestRun(t *testing.T) { t.Run("NonEmptyCommandRunsSuccessfully", func(t *testing.T) { expectedCommand := "ls -la" promptOptions := promptOptionsData() - selectedPromptOption := promptOptions[0] + selectedOption := promptOptions[0] - mockContainerService := containermocks.NewContainerService(t) + mockContainerService := containermocks.NewService(t) mockContainerService.On("GetAll").Return(containersData(), nil) - mockContainerService.On("RunCommand", selectedPromptOption.Value, expectedCommand). + mockContainerService.On("RunCommand", selectedOption.Value, expectedCommand). Return(nil) - mockPromptService := promptmocks.NewPromptService(t) + mockPromptService := promptmocks.NewService(t) mockPromptService.On("DisplaySelect", mock.Anything, promptOptions). - Return(selectedPromptOption, nil) + Return(selectedOption, nil) mockPromptService.On("DisplayPrompt", mock.Anything). Return(expectedCommand, nil) @@ -81,16 +81,16 @@ func TestRun(t *testing.T) { t.Run("EmptyCommandDefaultsToBash", func(t *testing.T) { expectedCommand := "bash" promptOptions := promptOptionsData() - selectedPromptOption := promptOptions[0] + selectedOption := promptOptions[0] - mockContainerService := containermocks.NewContainerService(t) + mockContainerService := containermocks.NewService(t) mockContainerService.On("GetAll").Return(containersData(), nil) - mockContainerService.On("RunCommand", selectedPromptOption.Value, expectedCommand). + mockContainerService.On("RunCommand", selectedOption.Value, expectedCommand). Return(nil) - mockPromptService := promptmocks.NewPromptService(t) + mockPromptService := promptmocks.NewService(t) mockPromptService.On("DisplaySelect", mock.Anything, promptOptions). - Return(selectedPromptOption, nil) + Return(selectedOption, nil) mockPromptService.On("DisplayPrompt", mock.Anything). Return("", nil) @@ -102,18 +102,18 @@ func TestRun(t *testing.T) { t.Run("EmptyCommandAndFailedBashDefaultsToSh", func(t *testing.T) { expectedCommand := "sh" promptOptions := promptOptionsData() - selectedPromptOption := promptOptions[0] + selectedOption := promptOptions[0] - mockContainerService := containermocks.NewContainerService(t) + mockContainerService := containermocks.NewService(t) mockContainerService.On("GetAll").Return(containersData(), nil) - mockContainerService.On("RunCommand", selectedPromptOption.Value, "bash"). + mockContainerService.On("RunCommand", selectedOption.Value, "bash"). Return(errors.New("Mock Error")).Once() - mockContainerService.On("RunCommand", selectedPromptOption.Value, expectedCommand). + mockContainerService.On("RunCommand", selectedOption.Value, expectedCommand). Return(nil).Once() - mockPromptService := promptmocks.NewPromptService(t) + mockPromptService := promptmocks.NewService(t) mockPromptService.On("DisplaySelect", mock.Anything, promptOptions). - Return(selectedPromptOption, nil) + Return(selectedOption, nil) mockPromptService.On("DisplayPrompt", mock.Anything). Return("", nil) @@ -123,8 +123,8 @@ func TestRun(t *testing.T) { }) } -func promptOptionsData() []prompt.PromptOption { - return []prompt.PromptOption{ +func promptOptionsData() []prompt.Option { + return []prompt.Option{ { Label: "[containerName1] (containerImage1) aa64bf12226b", Value: "aa64bf12226bc4dff14310a8fec7d5c5f0439ed2e69b3b590c413220650c0174", diff --git a/internal/container/container.go b/internal/container/container.go index d21c167..77e1071 100644 --- a/internal/container/container.go +++ b/internal/container/container.go @@ -1,13 +1,16 @@ package container +// Container holds container information type Container struct { ID string Names []string Image string } -//go:generate mockery --name ContainerService -type ContainerService interface { +// Service interface for getting containers and running commands against them +// +//go:generate mockery --name Service +type Service interface { GetAll() ([]Container, error) RunCommand(containerID, command string) error Close() diff --git a/internal/container/docker.go b/internal/container/docker.go index 8f3cfdb..b7df257 100644 --- a/internal/container/docker.go +++ b/internal/container/docker.go @@ -11,10 +11,12 @@ import ( "github.com/docker/docker/client" ) +// DockerService for getting Docker containers and running commands against them type DockerService struct { client *client.Client } +// GetAll Docker containers func (s *DockerService) GetAll() ([]Container, error) { var containers []Container @@ -34,6 +36,7 @@ func (s *DockerService) GetAll() ([]Container, error) { return containers, nil } +// RunCommand runs a command in a Docker container func (s *DockerService) RunCommand(containerID string, command string) error { arguments, err := splitCommand(command) if err != nil { @@ -82,6 +85,7 @@ func (s *DockerService) RunCommand(containerID string, command string) error { return err } +// Close closes the client func (s *DockerService) Close() { s.client.Close() } @@ -96,7 +100,8 @@ func splitCommand(command string) ([]string, error) { return arguments, nil } -func NewDockerService() (ContainerService, error) { +// NewDockerService returns a new DockerService pointer +func NewDockerService() (Service, error) { dockerClient, err := client.NewClientWithOpts( client.FromEnv, client.WithAPIVersionNegotiation(), diff --git a/internal/prompt/prompt.go b/internal/prompt/prompt.go index d61145f..15a6f09 100644 --- a/internal/prompt/prompt.go +++ b/internal/prompt/prompt.go @@ -1,12 +1,15 @@ package prompt -type PromptOption struct { +// Option for the select prompt +type Option struct { Label string Value string } -//go:generate mockery --name PromptService -type PromptService interface { - DisplaySelect(label string, options []PromptOption) (PromptOption, error) +// Service interface for displaying prompts +// +//go:generate mockery --name Service +type Service interface { + DisplaySelect(label string, options []Option) (Option, error) DisplayPrompt(label string) (string, error) } diff --git a/internal/prompt/promptui.go b/internal/prompt/promptui.go index a61cf76..1f7de44 100644 --- a/internal/prompt/promptui.go +++ b/internal/prompt/promptui.go @@ -2,12 +2,14 @@ package prompt import "github.com/manifoldco/promptui" +// PromptuiService for displaying prompts type PromptuiService struct{} +// DisplaySelect displays a select prompt func (p *PromptuiService) DisplaySelect( label string, - options []PromptOption, -) (PromptOption, error) { + options []Option, +) (Option, error) { labels := []string{} for _, option := range options { labels = append(labels, option.Label) @@ -19,12 +21,13 @@ func (p *PromptuiService) DisplaySelect( } i, _, err := prompt.Run() if err != nil { - return PromptOption{}, err + return Option{}, err } return options[i], nil } +// DisplayPrompt displays a normal prompt func (p *PromptuiService) DisplayPrompt(label string) (string, error) { prompt := promptui.Prompt{ Label: label, @@ -37,6 +40,7 @@ func (p *PromptuiService) DisplayPrompt(label string) (string, error) { return result, nil } -func NewPromptuiService() PromptService { +// NewPromptuiService returns a new PromptuiService pointer +func NewPromptuiService() Service { return &PromptuiService{} } diff --git a/release.json b/release.json index 18c012b..0e204eb 100644 --- a/release.json +++ b/release.json @@ -1,4 +1,4 @@ { - "version": "1.0.1", + "version": "1.0.2", "go_version": "1.20.4" }