-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* refactor: main.go and separate commands.go * refactor: separate loadConfig & newDockerService * chore: remove print in tests * refactor: use a deployer * refactor: use variable for docker service creator function * refactor: make it more testable * test: defaultConfigLoader * refactor: remove unused vars * refactor: separate config loader * refactor: separate docker_service * test: error conditions in commands.go * test: cover more error conditions * chore: ignore coverage.html * style: format code with Go fmt This commit fixes the style issues introduced in b494663 according to the output from Go fmt. Details: #23 * fix: RVV-B0013 * fix: Unused parameter in function * fix: Types of function parameters can be combined * feat: test main.go * style: Unused method receiver * style: fix Unused parameter in function --------- Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
- Loading branch information
1 parent
c44ae9f
commit 4e03379
Showing
10 changed files
with
687 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,3 +29,5 @@ tmp/ | |
dist/ | ||
|
||
.env | ||
|
||
coverage.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/scmmishra/slick-deploy/internal/caddy" | ||
"github.com/scmmishra/slick-deploy/internal/config" | ||
"github.com/scmmishra/slick-deploy/internal/deploy" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
type Deployer interface { | ||
Deploy(cfg config.DeploymentConfig) error | ||
} | ||
|
||
type DefaultDeployer struct{} | ||
|
||
func (DefaultDeployer) Deploy(cfg config.DeploymentConfig) error { | ||
return deploy.Deploy(cfg) | ||
} | ||
|
||
var defaultDeployer Deployer = DefaultDeployer{} | ||
|
||
func runDeploy(cmd *cobra.Command, deployer Deployer, configLoader ConfigLoader) error { | ||
cfg, err := configLoader(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
return deployer.Deploy(cfg) | ||
} | ||
|
||
func runStatus() error { | ||
dockerService, err := dockerServiceCreator() | ||
if err != nil { | ||
return err | ||
} | ||
return dockerService.GetStatus() | ||
} | ||
|
||
func runLogs(cmd *cobra.Command, configLoader ConfigLoader) error { | ||
cfg, err := configLoader(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
dockerService, err := dockerServiceCreator() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
container := dockerService.FindContainer(cfg.App.ImageName) | ||
if container == nil { | ||
return fmt.Errorf("no container found") | ||
} | ||
|
||
tail, _ := cmd.Flags().GetString("tail") | ||
return dockerService.StreamLogs(container.ID, tail) | ||
} | ||
|
||
func runCaddyInspect(cmd *cobra.Command, configLoader ConfigLoader) error { | ||
cfg, err := configLoader(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
caddyConfig := caddy.ConvertToCaddyfile(cfg.Caddy, 0) // Use 0 as port since we're just inspecting | ||
fmt.Println(caddyConfig) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,276 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"os" | ||
"testing" | ||
|
||
"github.com/scmmishra/slick-deploy/internal/config" | ||
"github.com/scmmishra/slick-deploy/internal/docker" | ||
"github.com/spf13/cobra" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/mock" | ||
) | ||
|
||
var mockLoadConfig func(*cobra.Command) (config.DeploymentConfig, error) | ||
|
||
type MockDeployer struct { | ||
mock.Mock | ||
} | ||
|
||
func (m *MockDeployer) Deploy(cfg config.DeploymentConfig) error { | ||
args := m.Called(cfg) | ||
return args.Error(0) | ||
} | ||
|
||
type MockDockerService struct { | ||
mock.Mock | ||
} | ||
|
||
func (m *MockDockerService) GetStatus() error { | ||
args := m.Called() | ||
return args.Error(0) | ||
} | ||
|
||
func (m *MockDockerService) FindContainer(imageName string) *docker.Container { | ||
args := m.Called(imageName) | ||
if args.Get(0) == nil { | ||
return nil | ||
} | ||
return args.Get(0).(*docker.Container) | ||
} | ||
|
||
func (m *MockDockerService) StreamLogs(containerID, tail string) error { | ||
args := m.Called(containerID, tail) | ||
return args.Error(0) | ||
} | ||
|
||
// Helper function to create a cobra command for testing | ||
func createTestCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "test", | ||
} | ||
cmd.Flags().String("config", "", "Path to the configuration file") | ||
cmd.Flags().String("env", "", "Path to the env file") | ||
return cmd | ||
} | ||
|
||
func TestRunDeploy(t *testing.T) { | ||
mockDeployer := new(MockDeployer) | ||
mockDeployer.On("Deploy", mock.Anything).Return(nil) | ||
|
||
mockConfigLoader := func(*cobra.Command) (config.DeploymentConfig, error) { | ||
return config.DeploymentConfig{}, nil | ||
} | ||
|
||
cmd := createTestCommand() | ||
err := runDeploy(cmd, mockDeployer, mockConfigLoader) | ||
|
||
assert.NoError(t, err) | ||
mockDeployer.AssertExpectations(t) | ||
} | ||
|
||
func TestRunDeploy_ConfigLoaderError(t *testing.T) { | ||
mockDeployer := new(MockDeployer) | ||
mockConfigLoader := func(*cobra.Command) (config.DeploymentConfig, error) { | ||
return config.DeploymentConfig{}, errors.New("config load error") | ||
} | ||
|
||
cmd := createTestCommand() | ||
err := runDeploy(cmd, mockDeployer, mockConfigLoader) | ||
|
||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "config load error") | ||
mockDeployer.AssertNotCalled(t, "Deploy") | ||
} | ||
|
||
func TestRunLogs(t *testing.T) { | ||
mockDockerService := new(MockDockerService) | ||
mockDockerService.On("FindContainer", mock.Anything).Return(&docker.Container{ID: "test-container"}) | ||
mockDockerService.On("StreamLogs", "test-container", "all").Return(nil) | ||
|
||
mockConfigLoader := func(*cobra.Command) (config.DeploymentConfig, error) { | ||
return config.DeploymentConfig{ | ||
App: config.App{ImageName: "test-image"}, | ||
}, nil | ||
} | ||
|
||
originalDockerServiceCreator := dockerServiceCreator | ||
dockerServiceCreator = func() (DockerService, error) { | ||
return mockDockerService, nil | ||
} | ||
defer func() { dockerServiceCreator = originalDockerServiceCreator }() | ||
|
||
cmd := createTestCommand() | ||
cmd.Flags().String("tail", "all", "") | ||
err := runLogs(cmd, mockConfigLoader) | ||
|
||
assert.NoError(t, err) | ||
mockDockerService.AssertExpectations(t) | ||
} | ||
|
||
func TestRunLogs_NoContainer(t *testing.T) { | ||
mockDockerService := new(MockDockerService) | ||
mockDockerService.On("FindContainer", mock.Anything).Return(nil) | ||
|
||
mockConfigLoader := func(*cobra.Command) (config.DeploymentConfig, error) { | ||
return config.DeploymentConfig{ | ||
App: config.App{ImageName: "test-image"}, | ||
}, nil | ||
} | ||
|
||
originalDockerServiceCreator := dockerServiceCreator | ||
dockerServiceCreator = func() (DockerService, error) { | ||
return mockDockerService, nil | ||
} | ||
defer func() { dockerServiceCreator = originalDockerServiceCreator }() | ||
|
||
cmd := createTestCommand() | ||
cmd.Flags().String("tail", "all", "") | ||
err := runLogs(cmd, mockConfigLoader) | ||
|
||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "no container found") | ||
mockDockerService.AssertExpectations(t) | ||
} | ||
|
||
func TestRunLogs_DockerServiceCreatorFails(t *testing.T) { | ||
mockConfigLoader := func(*cobra.Command) (config.DeploymentConfig, error) { | ||
return config.DeploymentConfig{ | ||
App: config.App{ImageName: "test-image"}, | ||
}, nil | ||
} | ||
|
||
originalDockerServiceCreator := dockerServiceCreator | ||
dockerServiceCreator = func() (DockerService, error) { | ||
return nil, errors.New("failed to create Docker service") | ||
} | ||
defer func() { dockerServiceCreator = originalDockerServiceCreator }() | ||
|
||
cmd := createTestCommand() | ||
cmd.Flags().String("tail", "all", "") | ||
err := runLogs(cmd, mockConfigLoader) | ||
|
||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "failed to create Docker service") | ||
} | ||
|
||
func TestRunLogs_ConfigLoaderFails(t *testing.T) { | ||
mockConfigLoader := func(*cobra.Command) (config.DeploymentConfig, error) { | ||
return config.DeploymentConfig{}, errors.New("config loading failed") | ||
} | ||
|
||
mockDockerService := new(MockDockerService) | ||
|
||
originalDockerServiceCreator := dockerServiceCreator | ||
dockerServiceCreator = func() (DockerService, error) { | ||
return mockDockerService, nil | ||
} | ||
defer func() { dockerServiceCreator = originalDockerServiceCreator }() | ||
|
||
cmd := createTestCommand() | ||
cmd.Flags().String("tail", "all", "") | ||
err := runLogs(cmd, mockConfigLoader) | ||
|
||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "config loading failed") | ||
|
||
// Ensure that no methods on mockDockerService were called | ||
mockDockerService.AssertNotCalled(t, "FindContainer") | ||
mockDockerService.AssertNotCalled(t, "StreamLogs") | ||
} | ||
|
||
func TestRunCaddyInspect(t *testing.T) { | ||
mockConfigLoader := func(*cobra.Command) (config.DeploymentConfig, error) { | ||
return config.DeploymentConfig{ | ||
Caddy: config.CaddyConfig{ | ||
Rules: []config.Rule{ | ||
{Match: "http://example.com"}, | ||
}, | ||
}, | ||
}, nil | ||
} | ||
|
||
old := os.Stdout | ||
r, w, _ := os.Pipe() | ||
os.Stdout = w | ||
|
||
cmd := createTestCommand() | ||
err := runCaddyInspect(cmd, mockConfigLoader) | ||
|
||
w.Close() | ||
os.Stdout = old | ||
|
||
var buf bytes.Buffer | ||
_, _ = buf.ReadFrom(r) | ||
output := buf.String() | ||
|
||
assert.NoError(t, err) | ||
assert.Contains(t, output, "http://") | ||
} | ||
|
||
func TestRunCaddyInspect_ConfigError(t *testing.T) { | ||
mockConfigLoader := func(*cobra.Command) (config.DeploymentConfig, error) { | ||
return config.DeploymentConfig{}, errors.New("config load error") | ||
} | ||
|
||
cmd := createTestCommand() | ||
err := runCaddyInspect(cmd, mockConfigLoader) | ||
|
||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "config load error") | ||
} | ||
|
||
func TestRunStatus(t *testing.T) { | ||
mockDockerService := new(MockDockerService) | ||
mockDockerService.On("GetStatus").Return(nil) | ||
|
||
// Save the original dockerServiceCreator | ||
originalDockerServiceCreator := dockerServiceCreator | ||
|
||
// Replace dockerServiceCreator with a mock version | ||
dockerServiceCreator = func() (DockerService, error) { | ||
return mockDockerService, nil | ||
} | ||
|
||
// Restore the original dockerServiceCreator after the test | ||
defer func() { | ||
dockerServiceCreator = originalDockerServiceCreator | ||
}() | ||
|
||
err := runStatus() | ||
|
||
assert.NoError(t, err) | ||
mockDockerService.AssertExpectations(t) | ||
} | ||
|
||
func TestRunStatus_Error(t *testing.T) { | ||
mockDockerService := new(MockDockerService) | ||
mockDockerService.On("GetStatus").Return(errors.New("status error")) | ||
|
||
originalDockerServiceCreator := dockerServiceCreator | ||
dockerServiceCreator = func() (DockerService, error) { | ||
return mockDockerService, nil | ||
} | ||
defer func() { dockerServiceCreator = originalDockerServiceCreator }() | ||
|
||
err := runStatus() | ||
|
||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "status error") | ||
mockDockerService.AssertExpectations(t) | ||
} | ||
|
||
func TestRunStatus_DockerServiceCreatorFails(t *testing.T) { | ||
originalDockerServiceCreator := dockerServiceCreator | ||
dockerServiceCreator = func() (DockerService, error) { | ||
return nil, errors.New("failed to create Docker service") | ||
} | ||
defer func() { dockerServiceCreator = originalDockerServiceCreator }() | ||
|
||
err := runStatus() | ||
|
||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "failed to create Docker service") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/joho/godotenv" | ||
"github.com/scmmishra/slick-deploy/internal/config" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
type ConfigLoader func(*cobra.Command) (config.DeploymentConfig, error) | ||
|
||
func defaultConfigLoader(cmd *cobra.Command) (config.DeploymentConfig, error) { | ||
cfgPath, _ := cmd.Flags().GetString("config") | ||
envPath, _ := cmd.Flags().GetString("env") | ||
|
||
if err := godotenv.Load(envPath); err != nil { | ||
return config.DeploymentConfig{}, fmt.Errorf("failed to load env file: %w", err) | ||
} | ||
|
||
cfg, err := config.LoadConfig(cfgPath) | ||
if err != nil { | ||
return config.DeploymentConfig{}, fmt.Errorf("failed to load config: %w", err) | ||
} | ||
|
||
return cfg, nil | ||
} |
Oops, something went wrong.